]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.3-2.6.11-200503091157.patch
- replaced by linux-2.4-sfq.patch
[packages/kernel.git] / grsecurity-2.1.3-2.6.11-200503091157.patch
1 diff -urNp linux-2.6.11/Makefile linux-2.6.11/Makefile
2 --- linux-2.6.11/Makefile       2005-03-02 02:38:13.000000000 -0500
3 +++ linux-2.6.11/Makefile       2005-03-09 11:56:44.000000000 -0500
4 @@ -561,7 +561,7 @@ export MODLIB
5  
6  
7  ifeq ($(KBUILD_EXTMOD),)
8 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/
9 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/
10  
11  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
12                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
13 diff -urNp linux-2.6.11/arch/alpha/kernel/osf_sys.c linux-2.6.11/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.11/arch/alpha/kernel/osf_sys.c    2005-03-02 02:37:30.000000000 -0500
15 +++ linux-2.6.11/arch/alpha/kernel/osf_sys.c    2005-03-09 11:56:44.000000000 -0500
16 @@ -179,6 +179,11 @@ osf_mmap(unsigned long addr, unsigned lo
17         struct file *file = NULL;
18         unsigned long ret = -EBADF;
19  
20 +#ifdef CONFIG_PAX_RANDEXEC
21 +       if (flags & MAP_MIRROR)
22 +               return -EINVAL;
23 +#endif
24 +
25  #if 0
26         if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
27                 printk("%s: unimplemented OSF mmap flags %04lx\n", 
28 @@ -1288,6 +1293,10 @@ arch_get_unmapped_area(struct file *filp
29            merely specific addresses, but regions of memory -- perhaps
30            this feature should be incorporated into all ports?  */
31  
32 +#ifdef CONFIG_PAX_RANDMMAP
33 +       if (!(current->mm->flags & MF_PAX_RANDMMAP) || !filp)
34 +#endif
35 +
36         if (addr) {
37                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
38                 if (addr != (unsigned long) -ENOMEM)
39 @@ -1295,8 +1304,16 @@ arch_get_unmapped_area(struct file *filp
40         }
41  
42         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
43 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
44 -                                        len, limit);
45 +
46 +       addr = TASK_UNMAPPED_BASE;
47 +
48 +#ifdef CONFIG_PAX_RANDMMAP
49 +       if (current->mm->flags & MF_PAX_RANDMMAP)
50 +               addr += current->mm->delta_mmap;
51 +#endif
52 +
53 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
54 +
55         if (addr != (unsigned long) -ENOMEM)
56                 return addr;
57  
58 diff -urNp linux-2.6.11/arch/alpha/kernel/ptrace.c linux-2.6.11/arch/alpha/kernel/ptrace.c
59 --- linux-2.6.11/arch/alpha/kernel/ptrace.c     2005-03-02 02:38:25.000000000 -0500
60 +++ linux-2.6.11/arch/alpha/kernel/ptrace.c     2005-03-09 11:56:44.000000000 -0500
61 @@ -14,6 +14,7 @@
62  #include <linux/user.h>
63  #include <linux/slab.h>
64  #include <linux/security.h>
65 +#include <linux/grsecurity.h>
66  
67  #include <asm/uaccess.h>
68  #include <asm/pgtable.h>
69 @@ -289,6 +290,9 @@ do_sys_ptrace(long request, long pid, lo
70         if (!child)
71                 goto out_notsk;
72  
73 +       if (gr_handle_ptrace(child, request))
74 +               goto out;
75 +
76         if (request == PTRACE_ATTACH) {
77                 ret = ptrace_attach(child);
78                 goto out;
79 diff -urNp linux-2.6.11/arch/alpha/mm/fault.c linux-2.6.11/arch/alpha/mm/fault.c
80 --- linux-2.6.11/arch/alpha/mm/fault.c  2005-03-02 02:37:52.000000000 -0500
81 +++ linux-2.6.11/arch/alpha/mm/fault.c  2005-03-09 11:56:44.000000000 -0500
82 @@ -25,6 +25,7 @@
83  #include <linux/smp_lock.h>
84  #include <linux/interrupt.h>
85  #include <linux/module.h>
86 +#include <linux/binfmts.h>
87  
88  #include <asm/system.h>
89  #include <asm/uaccess.h>
90 @@ -56,6 +57,142 @@ __load_new_mm_context(struct mm_struct *
91         __reload_thread(pcb);
92  }
93  
94 +#ifdef CONFIG_PAX_PAGEEXEC
95 +/*
96 + * PaX: decide what to do with offenders (regs->pc = fault address)
97 + *
98 + * returns 1 when task should be killed
99 + *         2 when patched PLT trampoline was detected
100 + *         3 when unpatched PLT trampoline was detected
101 + *         4 when legitimate ET_EXEC was detected
102 + */
103 +static int pax_handle_fetch_fault(struct pt_regs *regs)
104 +{
105 +
106 +#ifdef CONFIG_PAX_EMUPLT
107 +       int err;
108 +#endif
109 +
110 +#ifdef CONFIG_PAX_RANDEXEC
111 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
112 +               if (regs->pc >= current->mm->start_code &&
113 +                   regs->pc < current->mm->end_code)
114 +               {
115 +                       if (regs->r26 == regs->pc)
116 +                               return 1;
117 +
118 +                       regs->pc += current->mm->delta_exec;
119 +                       return 4;
120 +               }
121 +       }
122 +#endif
123 +
124 +#ifdef CONFIG_PAX_EMUPLT
125 +       do { /* PaX: patched PLT emulation #1 */
126 +               unsigned int ldah, ldq, jmp;
127 +
128 +               err = get_user(ldah, (unsigned int *)regs->pc);
129 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
130 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
131 +
132 +               if (err)
133 +                       break;
134 +
135 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
136 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
137 +                   jmp == 0x6BFB0000U)
138 +               {
139 +                       unsigned long r27, addr;
140 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
141 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
142 +
143 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
144 +                       err = get_user(r27, (unsigned long*)addr);
145 +                       if (err)
146 +                               break;
147 +
148 +                       regs->r27 = r27;
149 +                       regs->pc = r27;
150 +                       return 2;
151 +               }
152 +       } while (0);
153 +
154 +       do { /* PaX: patched PLT emulation #2 */
155 +               unsigned int ldah, lda, br;
156 +
157 +               err = get_user(ldah, (unsigned int *)regs->pc);
158 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
159 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
160 +
161 +               if (err)
162 +                       break;
163 +
164 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
165 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
166 +                   (br & 0xFFE00000U) == 0xC3E00000U)
167 +               {
168 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
169 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
170 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
171 +
172 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
173 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
174 +                       return 2;
175 +               }
176 +       } while (0);
177 +
178 +       do { /* PaX: unpatched PLT emulation */
179 +               unsigned int br;
180 +
181 +               err = get_user(br, (unsigned int *)regs->pc);
182 +
183 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
184 +                       unsigned int br2, ldq, nop, jmp;
185 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
186 +
187 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
188 +                       err = get_user(br2, (unsigned int *)addr);
189 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
190 +                       err |= get_user(nop, (unsigned int *)(addr+8));
191 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
192 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
193 +
194 +                       if (err)
195 +                               break;
196 +
197 +                       if (br2 == 0xC3600000U &&
198 +                           ldq == 0xA77B000CU &&
199 +                           nop == 0x47FF041FU &&
200 +                           jmp == 0x6B7B0000U)
201 +                       {
202 +                               regs->r28 = regs->pc+4;
203 +                               regs->r27 = addr+16;
204 +                               regs->pc = resolver;
205 +                               return 3;
206 +                       }
207 +               }
208 +       } while (0);
209 +#endif
210 +
211 +       return 1;
212 +}
213 +
214 +void pax_report_insns(void *pc, void *sp)
215 +{
216 +       unsigned long i;
217 +
218 +       printk(KERN_ERR "PAX: bytes at PC: ");
219 +       for (i = 0; i < 5; i++) {
220 +               unsigned int c;
221 +               if (get_user(c, (unsigned int*)pc+i)) {
222 +                       printk("<invalid address>.");
223 +                       break;
224 +               }
225 +               printk("%08x ", c);
226 +       }
227 +       printk("\n");
228 +}
229 +#endif
230  
231  /*
232   * This routine handles page faults.  It determines the address,
233 @@ -125,7 +262,7 @@ do_page_fault(unsigned long address, uns
234                 goto good_area;
235         if (!(vma->vm_flags & VM_GROWSDOWN))
236                 goto bad_area;
237 -       if (expand_stack(vma, address))
238 +       if (expand_stack(current, vma, address))
239                 goto bad_area;
240  
241         /* Ok, we have a good vm_area for this memory access, so
242 @@ -133,8 +270,34 @@ do_page_fault(unsigned long address, uns
243   good_area:
244         si_code = SEGV_ACCERR;
245         if (cause < 0) {
246 -               if (!(vma->vm_flags & VM_EXEC))
247 +               if (!(vma->vm_flags & VM_EXEC)) {
248 +
249 +#ifdef CONFIG_PAX_PAGEEXEC
250 +                       if (!(mm->flags & MF_PAX_PAGEEXEC) || address != regs->pc)
251 +                               goto bad_area;
252 +
253 +                       up_read(&mm->mmap_sem);
254 +                       switch(pax_handle_fetch_fault(regs)) {
255 +
256 +#ifdef CONFIG_PAX_EMUPLT
257 +                       case 2:
258 +                       case 3:
259 +                               return;
260 +#endif
261 +
262 +#ifdef CONFIG_PAX_RANDEXEC
263 +                       case 4:
264 +                               return;
265 +#endif
266 +
267 +                       }
268 +                       pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
269 +                       do_exit(SIGKILL);
270 +#else
271                         goto bad_area;
272 +#endif
273 +
274 +               }
275         } else if (!cause) {
276                 /* Allow reads even for write-only mappings */
277                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
278 diff -urNp linux-2.6.11/arch/arm/mm/fault.c linux-2.6.11/arch/arm/mm/fault.c
279 --- linux-2.6.11/arch/arm/mm/fault.c    2005-03-02 02:38:38.000000000 -0500
280 +++ linux-2.6.11/arch/arm/mm/fault.c    2005-03-09 11:56:44.000000000 -0500
281 @@ -208,7 +208,7 @@ survive:
282         goto survive;
283  
284  check_stack:
285 -       if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
286 +       if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(tsk, vma, addr))
287                 goto good_area;
288  out:
289         return fault;
290 diff -urNp linux-2.6.11/arch/arm/mm/mmap.c linux-2.6.11/arch/arm/mm/mmap.c
291 --- linux-2.6.11/arch/arm/mm/mmap.c     2005-03-02 02:38:10.000000000 -0500
292 +++ linux-2.6.11/arch/arm/mm/mmap.c     2005-03-09 11:56:44.000000000 -0500
293 @@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
294         if (len > TASK_SIZE)
295                 return -ENOMEM;
296  
297 +#ifdef CONFIG_PAX_RANDMMAP
298 +       if (!(mm->flags & MF_PAX_RANDMMAP) || !filp)
299 +#endif
300 +
301         if (addr) {
302                 if (do_align)
303                         addr = COLOUR_ALIGN(addr, pgoff);
304 @@ -88,8 +92,8 @@ full_search:
305                          * Start a new search - just in case we missed
306                          * some holes.
307                          */
308 -                       if (start_addr != TASK_UNMAPPED_BASE) {
309 -                               start_addr = addr = TASK_UNMAPPED_BASE;
310 +                       if (start_addr != mm->mmap_base) {
311 +                               start_addr = addr = mm->mmap_base;
312                                 goto full_search;
313                         }
314                         return -ENOMEM;
315 diff -urNp linux-2.6.11/arch/arm26/mm/fault.c linux-2.6.11/arch/arm26/mm/fault.c
316 --- linux-2.6.11/arch/arm26/mm/fault.c  2005-03-02 02:37:52.000000000 -0500
317 +++ linux-2.6.11/arch/arm26/mm/fault.c  2005-03-09 11:56:44.000000000 -0500
318 @@ -197,7 +197,7 @@ survive:
319         goto survive;
320  
321  check_stack:
322 -       if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
323 +       if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(tsk, vma, addr))
324                 goto good_area;
325  out:
326         return fault;
327 diff -urNp linux-2.6.11/arch/cris/mm/fault.c linux-2.6.11/arch/cris/mm/fault.c
328 --- linux-2.6.11/arch/cris/mm/fault.c   2005-03-02 02:38:25.000000000 -0500
329 +++ linux-2.6.11/arch/cris/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
330 @@ -207,7 +207,7 @@ do_page_fault(unsigned long address, str
331                 if (address + PAGE_SIZE < rdusp())
332                         goto bad_area;
333         }
334 -       if (expand_stack(vma, address))
335 +       if (expand_stack(tsk, vma, address))
336                 goto bad_area;
337  
338         /*
339 diff -urNp linux-2.6.11/arch/i386/Kconfig linux-2.6.11/arch/i386/Kconfig
340 --- linux-2.6.11/arch/i386/Kconfig      2005-03-02 02:37:49.000000000 -0500
341 +++ linux-2.6.11/arch/i386/Kconfig      2005-03-09 11:56:44.000000000 -0500
342 @@ -409,7 +409,7 @@ config X86_POPAD_OK
343  
344  config X86_ALIGNMENT_16
345         bool
346 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
347 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
348         default y
349  
350  config X86_GOOD_APIC
351 diff -urNp linux-2.6.11/arch/i386/kernel/apm.c linux-2.6.11/arch/i386/kernel/apm.c
352 --- linux-2.6.11/arch/i386/kernel/apm.c 2005-03-02 02:37:47.000000000 -0500
353 +++ linux-2.6.11/arch/i386/kernel/apm.c 2005-03-09 11:56:44.000000000 -0500
354 @@ -598,19 +598,39 @@ static u8 apm_bios_call(u32 func, u32 eb
355         int                     cpu;
356         struct desc_struct      save_desc_40;
357  
358 +#ifdef CONFIG_PAX_KERNEXEC
359 +       unsigned long           cr3;
360 +#endif
361 +
362         cpus = apm_save_cpus();
363 -       
364         cpu = get_cpu();
365 -       save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
366 -       per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
367  
368 +#ifdef CONFIG_PAX_KERNEXEC
369 +       pax_open_kernel(flags, cr3);
370 +#endif
371 +
372 +       save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
373 +       cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
374 +
375 +#ifndef CONFIG_PAX_KERNEXEC
376         local_save_flags(flags);
377         APM_DO_CLI;
378 +#endif
379 +
380         APM_DO_SAVE_SEGS;
381         apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
382         APM_DO_RESTORE_SEGS;
383 +
384 +#ifndef CONFIG_PAX_KERNEXEC
385         local_irq_restore(flags);
386 -       per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40;
387 +#endif
388 +
389 +       cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
390 +
391 +#ifdef CONFIG_PAX_KERNEXEC
392 +       pax_close_kernel(flags, cr3);
393 +#endif
394 +
395         put_cpu();
396         apm_restore_cpus(cpus);
397         
398 @@ -640,20 +660,39 @@ static u8 apm_bios_call_simple(u32 func,
399         int                     cpu;
400         struct desc_struct      save_desc_40;
401  
402 +#ifdef CONFIG_PAX_KERNEXEC
403 +       unsigned long           cr3;
404 +#endif
405  
406         cpus = apm_save_cpus();
407 -       
408         cpu = get_cpu();
409 -       save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
410 -       per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
411  
412 +#ifdef CONFIG_PAX_KERNEXEC
413 +       pax_open_kernel(flags, cr3);
414 +#endif
415 +
416 +       save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
417 +       cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
418 +
419 +#ifndef CONFIG_PAX_KERNEXEC
420         local_save_flags(flags);
421         APM_DO_CLI;
422 +#endif
423 +
424         APM_DO_SAVE_SEGS;
425         error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
426         APM_DO_RESTORE_SEGS;
427 +
428 +#ifndef CONFIG_PAX_KERNEXEC
429         local_irq_restore(flags);
430 -       __get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40;
431 +#endif
432 +
433 +       cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
434 +
435 +#ifdef CONFIG_PAX_KERNEXEC
436 +       pax_close_kernel(flags, cr3);
437 +#endif
438 +
439         put_cpu();
440         apm_restore_cpus(cpus);
441         return error;
442 @@ -2294,35 +2333,35 @@ static int __init apm_init(void)
443         apm_bios_entry.segment = APM_CS;
444  
445         for (i = 0; i < NR_CPUS; i++) {
446 -               set_base(per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
447 +               set_base(cpu_gdt_table[i][APM_CS >> 3],
448                          __va((unsigned long)apm_info.bios.cseg << 4));
449 -               set_base(per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
450 +               set_base(cpu_gdt_table[i][APM_CS_16 >> 3],
451                          __va((unsigned long)apm_info.bios.cseg_16 << 4));
452 -               set_base(per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
453 +               set_base(cpu_gdt_table[i][APM_DS >> 3],
454                          __va((unsigned long)apm_info.bios.dseg << 4));
455  #ifndef APM_RELAX_SEGMENTS
456                 if (apm_info.bios.version == 0x100) {
457  #endif
458                         /* For ASUS motherboard, Award BIOS rev 110 (and others?) */
459 -                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 - 1);
460 +                       _set_limit((char *)&cpu_gdt_table[i][APM_CS >> 3], 64 * 1024 - 1);
461                         /* For some unknown machine. */
462 -                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3], 64 * 1024 - 1);
463 +                       _set_limit((char *)&cpu_gdt_table[i][APM_CS_16 >> 3], 64 * 1024 - 1);
464                         /* For the DEC Hinote Ultra CT475 (and others?) */
465 -                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3], 64 * 1024 - 1);
466 +                       _set_limit((char *)&cpu_gdt_table[i][APM_DS >> 3], 64 * 1024 - 1);
467  #ifndef APM_RELAX_SEGMENTS
468                 } else {
469 -                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
470 +                       _set_limit((char *)&cpu_gdt_table[i][APM_CS >> 3],
471                                 (apm_info.bios.cseg_len - 1) & 0xffff);
472 -                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
473 +                       _set_limit((char *)&cpu_gdt_table[i][APM_CS_16 >> 3],
474                                 (apm_info.bios.cseg_16_len - 1) & 0xffff);
475 -                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
476 +                       _set_limit((char *)&cpu_gdt_table[i][APM_DS >> 3],
477                                 (apm_info.bios.dseg_len - 1) & 0xffff);
478                       /* workaround for broken BIOSes */
479                         if (apm_info.bios.cseg_len <= apm_info.bios.offset)
480 -                               _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 -1);
481 +                               _set_limit((char *)&cpu_gdt_table[i][APM_CS >> 3], 64 * 1024 -1);
482                         if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
483                                 /* for the BIOS that assumes granularity = 1 */
484 -                               per_cpu(cpu_gdt_table, i)[APM_DS >> 3].b |= 0x800000;
485 +                               cpu_gdt_table[i][APM_DS >> 3].b |= 0x800000;
486                                 printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
487                         }
488                 }
489 diff -urNp linux-2.6.11/arch/i386/kernel/cpu/common.c linux-2.6.11/arch/i386/kernel/cpu/common.c
490 --- linux-2.6.11/arch/i386/kernel/cpu/common.c  2005-03-02 02:37:47.000000000 -0500
491 +++ linux-2.6.11/arch/i386/kernel/cpu/common.c  2005-03-09 11:56:44.000000000 -0500
492 @@ -3,7 +3,6 @@
493  #include <linux/delay.h>
494  #include <linux/smp.h>
495  #include <linux/module.h>
496 -#include <linux/percpu.h>
497  #include <asm/semaphore.h>
498  #include <asm/processor.h>
499  #include <asm/i387.h>
500 @@ -18,8 +17,7 @@
501  
502  #include "cpu.h"
503  
504 -DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
505 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
506 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
507  
508  static int cachesize_override __initdata = -1;
509  static int disable_x86_fxsr __initdata = 0;
510 @@ -369,6 +367,10 @@ void __init identify_cpu(struct cpuinfo_
511         if (this_cpu->c_init)
512                 this_cpu->c_init(c);
513  
514 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
515 +       clear_bit(X86_FEATURE_SEP, c->x86_capability);
516 +#endif
517 +
518         /* Disable the PN if appropriate */
519         squash_the_stupid_serial_number(c);
520  
521 @@ -555,7 +557,7 @@ void __init early_cpu_init(void)
522  void __init cpu_init (void)
523  {
524         int cpu = smp_processor_id();
525 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
526 +       struct tss_struct * t = init_tss + cpu;
527         struct thread_struct *thread = &current->thread;
528  
529         if (cpu_test_and_set(cpu, cpu_initialized)) {
530 @@ -577,17 +579,16 @@ void __init cpu_init (void)
531          * Initialize the per-CPU GDT with the boot GDT,
532          * and set up the GDT descriptor:
533          */
534 -       memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
535 -              GDT_SIZE);
536 -       cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
537 -       cpu_gdt_descr[cpu].address =
538 -           (unsigned long)&per_cpu(cpu_gdt_table, cpu);
539 +       if (cpu) {
540 +               memcpy(cpu_gdt_table[cpu], cpu_gdt_table[0], GDT_SIZE);
541 +               cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
542 +               cpu_gdt_descr[cpu].address = (unsigned long)cpu_gdt_table[cpu];
543 +       }
544  
545         /*
546          * Set up the per-thread TLS descriptor cache:
547          */
548 -       memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
549 -               GDT_ENTRY_TLS_ENTRIES * 8);
550 +       memcpy(thread->tls_array, cpu_gdt_table[cpu], GDT_ENTRY_TLS_ENTRIES * 8);
551  
552         __asm__ __volatile__("lgdt %0" : : "m" (cpu_gdt_descr[cpu]));
553         __asm__ __volatile__("lidt %0" : : "m" (idt_descr));
554 @@ -609,7 +610,7 @@ void __init cpu_init (void)
555         load_esp0(t, thread);
556         set_tss_desc(cpu,t);
557         load_TR_desc();
558 -       load_LDT(&init_mm.context);
559 +       _load_LDT(&init_mm.context);
560  
561         /* Set up doublefault TSS pointer in the GDT */
562         __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
563 diff -urNp linux-2.6.11/arch/i386/kernel/entry.S linux-2.6.11/arch/i386/kernel/entry.S
564 --- linux-2.6.11/arch/i386/kernel/entry.S       2005-03-02 02:37:51.000000000 -0500
565 +++ linux-2.6.11/arch/i386/kernel/entry.S       2005-03-09 11:56:44.000000000 -0500
566 @@ -229,6 +229,15 @@ sysenter_past_esp:
567         movl TI_flags(%ebp), %ecx
568         testw $_TIF_ALLWORK_MASK, %cx
569         jne syscall_exit_work
570 +
571 +#ifdef CONFIG_PAX_RANDKSTACK
572 +       pushl %eax
573 +       call pax_randomize_kstack
574 +       popl %eax
575 +#endif
576 +
577 +       xorl %ebp,%ebp  /* prevent info leak */
578 +
579  /* if something modifies registers it must also disable sysexit */
580         movl EIP(%esp), %edx
581         movl OLDESP(%esp), %ecx
582 @@ -257,6 +266,11 @@ syscall_exit:
583         movl TI_flags(%ebp), %ecx
584         testw $_TIF_ALLWORK_MASK, %cx   # current->work
585         jne syscall_exit_work
586 +
587 +#ifdef CONFIG_PAX_RANDKSTACK
588 +       call pax_randomize_kstack
589 +#endif
590 +
591  restore_all:
592         RESTORE_ALL
593  
594 @@ -571,7 +585,7 @@ ENTRY(spurious_interrupt_bug)
595         pushl $do_spurious_interrupt_bug
596         jmp error_code
597  
598 -.data
599 +.section .rodata,"a",@progbits
600  ENTRY(sys_call_table)
601         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
602         .long sys_exit
603 diff -urNp linux-2.6.11/arch/i386/kernel/head.S linux-2.6.11/arch/i386/kernel/head.S
604 --- linux-2.6.11/arch/i386/kernel/head.S        2005-03-02 02:37:48.000000000 -0500
605 +++ linux-2.6.11/arch/i386/kernel/head.S        2005-03-09 11:56:44.000000000 -0500
606 @@ -48,6 +48,12 @@
607  
608  
609  /*
610 + * Real beginning of normal "text" segment
611 + */
612 +ENTRY(stext)
613 +ENTRY(_stext)
614 +
615 +/*
616   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
617   * %esi points to the real-mode code as a 32-bit pointer.
618   * CS and DS must be 4 GB flat segments, but we don't depend on
619 @@ -78,6 +84,19 @@ ENTRY(startup_32)
620         shrl $2,%ecx
621         rep ; stosl
622  
623 +#ifdef CONFIG_PAX_KERNEXEC
624 +       movl $ __KERNEL_TEXT_OFFSET,%eax
625 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
626 +       rorl $16,%eax
627 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
628 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
629 +
630 +       movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
631 +       movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
632 +       rorl $16,%eax
633 +       movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
634 +#endif
635 +
636  /*
637   * Initialize page tables.  This creates a PDE and a set of page
638   * tables, which are located immediately beyond _end.  The variable
639 @@ -88,24 +107,42 @@ ENTRY(startup_32)
640   * Warning: don't use %esi or the stack in this code.  However, %esp
641   * can be used as a GPR if you really need it...
642   */
643 -page_pde_offset = (__PAGE_OFFSET >> 20);
644 -
645 +#ifdef CONFIG_X86_PAE
646 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE));
647 +#else
648 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE));
649 +#endif
650         movl $(pg0 - __PAGE_OFFSET), %edi
651 +#ifdef CONFIG_X86_PAE
652 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
653 +#else
654         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
655 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
656 +#endif
657 +       movl $0x063, %eax                       /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
658  10:
659 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
660 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
661         movl %ecx,(%edx)                        /* Store identity PDE entry */
662         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
663 +#ifdef CONFIG_X86_PAE
664 +       movl $0,4(%edx)
665 +       movl $0,page_pde_offset+4(%edx)
666 +       addl $8,%edx
667 +       movl $512, %ecx
668 +#else
669         addl $4,%edx
670         movl $1024, %ecx
671 +#endif
672  11:
673         stosl
674 +#ifdef CONFIG_X86_PAE
675 +       movl $0,(%edi)
676 +       addl $4,%edi
677 +#endif
678         addl $0x1000,%eax
679         loop 11b
680         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
681 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
682 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
683 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
684 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
685         cmpl %ebp,%eax
686         jb 10b
687         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
688 @@ -128,6 +165,11 @@ ENTRY(startup_32_smp)
689         movl %eax,%fs
690         movl %eax,%gs
691  
692 +       /* This is a secondary processor (AP) */
693 +       xorl %ebx,%ebx
694 +       incl %ebx
695 +#endif /* CONFIG_SMP */
696 +
697  /*
698   *     New page tables may be in 4Mbyte page mode and may
699   *     be using the global pages. 
700 @@ -143,26 +185,27 @@ ENTRY(startup_32_smp)
701   *     not yet offset PAGE_OFFSET..
702   */
703  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
704 +3:
705         movl cr4_bits,%edx
706         andl %edx,%edx
707 -       jz 6f
708 +       jz 5f
709         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
710         orl %edx,%eax
711         movl %eax,%cr4
712  
713 -       btl $5, %eax            # check if PAE is enabled
714 -       jnc 6f
715 +#ifdef CONFIG_X86_PAE
716 +       movl %ebx,%edi
717  
718         /* Check if extended functions are implemented */
719         movl $0x80000000, %eax
720         cpuid
721         cmpl $0x80000000, %eax
722 -       jbe 6f
723 +       jbe 4f
724         mov $0x80000001, %eax
725         cpuid
726         /* Execute Disable bit supported? */
727         btl $20, %edx
728 -       jnc 6f
729 +       jnc 4f
730  
731         /* Setup EFER (Extended Feature Enable Register) */
732         movl $0xc0000080, %ecx
733 @@ -172,13 +215,10 @@ ENTRY(startup_32_smp)
734         /* Make changes effective */
735         wrmsr
736  
737 -6:
738 -       /* This is a secondary processor (AP) */
739 -       xorl %ebx,%ebx
740 -       incl %ebx
741 -
742 -3:
743 -#endif /* CONFIG_SMP */
744 +4:
745 +       movl %edi,%ebx
746 +#endif
747 +5:
748  
749  /*
750   * Enable paging
751 @@ -203,9 +243,7 @@ ENTRY(startup_32_smp)
752  
753  #ifdef CONFIG_SMP
754         andl %ebx,%ebx
755 -       jz  1f                          /* Initial CPU cleans BSS */
756 -       jmp checkCPUtype
757 -1:
758 +       jnz  checkCPUtype       /* Initial CPU cleans BSS */
759  #endif /* CONFIG_SMP */
760  
761  /*
762 @@ -402,32 +440,74 @@ ignore_int:
763         popl %eax
764         iret
765  
766 -/*
767 - * Real beginning of normal "text" segment
768 - */
769 -ENTRY(stext)
770 -ENTRY(_stext)
771 -
772 -/*
773 - * BSS section
774 - */
775 -.section ".bss.page_aligned","w"
776 +.section .data.swapper_pg_dir,"a",@progbits
777  ENTRY(swapper_pg_dir)
778 +#ifdef CONFIG_X86_PAE
779 +       .long swapper_pm_dir-__PAGE_OFFSET+1
780 +       .long 0
781 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
782 +       .long 0
783 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
784 +       .long 0
785 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
786 +       .long 0
787 +#else
788 +       .fill 1024,4,0
789 +#endif
790 +
791 +#ifdef CONFIG_PAX_KERNEXEC
792 +ENTRY(kernexec_pg_dir)
793 +#ifdef CONFIG_X86_PAE
794 +       .long kernexec_pm_dir-__PAGE_OFFSET+1
795 +       .long 0
796 +       .long kernexec_pm_dir+512*8-__PAGE_OFFSET+1
797 +       .long 0
798 +       .long kernexec_pm_dir+512*16-__PAGE_OFFSET+1
799 +       .long 0
800 +       .long kernexec_pm_dir+512*24-__PAGE_OFFSET+1
801 +       .long 0
802 +#else
803         .fill 1024,4,0
804 +#endif
805 +#endif
806 +
807 +#ifdef CONFIG_X86_PAE
808 +.section .data.swapper_pm_dir,"a",@progbits
809 +ENTRY(swapper_pm_dir)
810 +       .fill 512,8,0
811 +       .fill 512,8,0
812 +       .fill 512,8,0
813 +       .fill 512,8,0
814 +
815 +#ifdef CONFIG_PAX_KERNEXEC
816 +ENTRY(kernexec_pm_dir)
817 +       .fill 512,8,0
818 +       .fill 512,8,0
819 +       .fill 512,8,0
820 +       .fill 512,8,0
821 +#endif
822 +#endif
823 +
824 +.section .rodata.empty_zero_page,"a",@progbits
825  ENTRY(empty_zero_page)
826         .fill 4096,1,0
827  
828  /*
829 - * This starts the data section.
830 - */
831 -.data
832 + * The IDT has to be page-aligned to simplify the Pentium
833 + * F0 0F bug workaround.. We have a special link segment
834 + * for this.
835 + */
836 +.section .rodata.idt,"a",@progbits
837 +ENTRY(idt_table)
838 +       .fill 256,8,0
839 +
840 +.section .rodata,"a",@progbits
841 +ready: .byte 0
842  
843  ENTRY(stack_start)
844         .long init_thread_union+THREAD_SIZE
845         .long __BOOT_DS
846  
847 -ready: .byte 0
848 -
849  int_msg:
850         .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
851  
852 @@ -469,8 +549,8 @@ cpu_gdt_descr:
853         .align L1_CACHE_BYTES
854  ENTRY(boot_gdt_table)
855         .fill GDT_ENTRY_BOOT_CS,8,0
856 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
857 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
858 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
859 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
860  
861  /*
862   * The Global Descriptor Table contains 28 quadwords, per-CPU.
863 @@ -489,28 +569,27 @@ ENTRY(cpu_gdt_table)
864         .quad 0x0000000000000000        /* 0x4b reserved */
865         .quad 0x0000000000000000        /* 0x53 reserved */
866         .quad 0x0000000000000000        /* 0x5b reserved */
867 -
868 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
869 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
870 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
871 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
872 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
873 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
874 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
875 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
876  
877         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
878         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
879  
880         /* Segments used for calling PnP BIOS */
881 -       .quad 0x00c09a0000000000        /* 0x90 32-bit code */
882 -       .quad 0x00809a0000000000        /* 0x98 16-bit code */
883 -       .quad 0x0080920000000000        /* 0xa0 16-bit data */
884 -       .quad 0x0080920000000000        /* 0xa8 16-bit data */
885 -       .quad 0x0080920000000000        /* 0xb0 16-bit data */
886 +       .quad 0x00c09b0000000000        /* 0x90 32-bit code */
887 +       .quad 0x00809b0000000000        /* 0x98 16-bit code */
888 +       .quad 0x0080930000000000        /* 0xa0 16-bit data */
889 +       .quad 0x0080930000000000        /* 0xa8 16-bit data */
890 +       .quad 0x0080930000000000        /* 0xb0 16-bit data */
891         /*
892          * The APM segments have byte granularity and their bases
893          * and limits are set at run time.
894          */
895 -       .quad 0x00409a0000000000        /* 0xb8 APM CS    code */
896 -       .quad 0x00009a0000000000        /* 0xc0 APM CS 16 code (16 bit) */
897 -       .quad 0x0040920000000000        /* 0xc8 APM DS    data */
898 +       .quad 0x00409b0000000000        /* 0xb8 APM CS    code */
899 +       .quad 0x00009b0000000000        /* 0xc0 APM CS 16 code (16 bit) */
900 +       .quad 0x0040930000000000        /* 0xc8 APM DS    data */
901  
902         .quad 0x0000000000000000        /* 0xd0 - unused */
903         .quad 0x0000000000000000        /* 0xd8 - unused */
904 @@ -519,3 +598,6 @@ ENTRY(cpu_gdt_table)
905         .quad 0x0000000000000000        /* 0xf0 - unused */
906         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
907  
908 +#ifdef CONFIG_SMP
909 +       .fill (NR_CPUS-1)*GDT_ENTRIES,8,0 /* other CPU's GDT */
910 +#endif
911 diff -urNp linux-2.6.11/arch/i386/kernel/init_task.c linux-2.6.11/arch/i386/kernel/init_task.c
912 --- linux-2.6.11/arch/i386/kernel/init_task.c   2005-03-02 02:38:32.000000000 -0500
913 +++ linux-2.6.11/arch/i386/kernel/init_task.c   2005-03-09 11:56:44.000000000 -0500
914 @@ -42,5 +42,4 @@ EXPORT_SYMBOL(init_task);
915   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
916   * no more per-task TSS's.
917   */ 
918 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS;
919 -
920 +struct tss_struct init_tss[NR_CPUS] ____cacheline_maxaligned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
921 diff -urNp linux-2.6.11/arch/i386/kernel/ioport.c linux-2.6.11/arch/i386/kernel/ioport.c
922 --- linux-2.6.11/arch/i386/kernel/ioport.c      2005-03-02 02:38:08.000000000 -0500
923 +++ linux-2.6.11/arch/i386/kernel/ioport.c      2005-03-09 11:56:44.000000000 -0500
924 @@ -15,6 +15,7 @@
925  #include <linux/stddef.h>
926  #include <linux/slab.h>
927  #include <linux/thread_info.h>
928 +#include <linux/grsecurity.h>
929  
930  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
931  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
932 @@ -63,9 +64,16 @@ asmlinkage long sys_ioperm(unsigned long
933  
934         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
935                 return -EINVAL;
936 +#ifdef CONFIG_GRKERNSEC_IO
937 +       if (turn_on) {
938 +               gr_handle_ioperm();
939 +#else
940         if (turn_on && !capable(CAP_SYS_RAWIO))
941 +#endif
942                 return -EPERM;
943 -
944 +#ifdef CONFIG_GRKERNSEC_IO
945 +       }
946 +#endif
947         /*
948          * If it's the first ioperm() call in this thread's lifetime, set the
949          * IO bitmap up. ioperm() is much less timing critical than clone(),
950 @@ -87,7 +95,7 @@ asmlinkage long sys_ioperm(unsigned long
951          * because the ->io_bitmap_max value must match the bitmap
952          * contents:
953          */
954 -       tss = &per_cpu(init_tss, get_cpu());
955 +       tss = init_tss + get_cpu();
956  
957         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
958  
959 @@ -137,8 +145,13 @@ asmlinkage long sys_iopl(unsigned long u
960                 return -EINVAL;
961         /* Trying to gain more privileges? */
962         if (level > old) {
963 +#ifdef CONFIG_GRKERNSEC_IO
964 +               gr_handle_iopl();
965 +               return -EPERM;
966 +#else
967                 if (!capable(CAP_SYS_RAWIO))
968                         return -EPERM;
969 +#endif
970         }
971         regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
972         /* Make sure we return the long way (not sysenter) */
973 diff -urNp linux-2.6.11/arch/i386/kernel/irq.c linux-2.6.11/arch/i386/kernel/irq.c
974 --- linux-2.6.11/arch/i386/kernel/irq.c 2005-03-02 02:37:48.000000000 -0500
975 +++ linux-2.6.11/arch/i386/kernel/irq.c 2005-03-09 11:56:44.000000000 -0500
976 @@ -113,10 +113,10 @@ fastcall unsigned int do_IRQ(struct pt_r
977   * gcc's 3.0 and earlier don't handle that correctly.
978   */
979  static char softirq_stack[NR_CPUS * THREAD_SIZE]
980 -               __attribute__((__aligned__(THREAD_SIZE)));
981 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
982  
983  static char hardirq_stack[NR_CPUS * THREAD_SIZE]
984 -               __attribute__((__aligned__(THREAD_SIZE)));
985 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
986  
987  /*
988   * allocate per-cpu stacks for hardirq and for softirq processing
989 diff -urNp linux-2.6.11/arch/i386/kernel/ldt.c linux-2.6.11/arch/i386/kernel/ldt.c
990 --- linux-2.6.11/arch/i386/kernel/ldt.c 2005-03-02 02:38:13.000000000 -0500
991 +++ linux-2.6.11/arch/i386/kernel/ldt.c 2005-03-09 11:56:44.000000000 -0500
992 @@ -102,6 +102,19 @@ int init_new_context(struct task_struct 
993                 retval = copy_ldt(&mm->context, &old_mm->context);
994                 up(&old_mm->context.sem);
995         }
996 +
997 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
998 +       if (!mm->context.user_cs_limit) {
999 +               mm->context.user_cs_base = 0UL;
1000 +               mm->context.user_cs_limit = ~0UL;
1001 +
1002 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1003 +               cpus_clear(mm->context.cpu_user_cs_mask);
1004 +#endif
1005 +
1006 +       }
1007 +#endif
1008 +
1009         return retval;
1010  }
1011  
1012 @@ -159,7 +172,7 @@ static int read_default_ldt(void __user 
1013  {
1014         int err;
1015         unsigned long size;
1016 -       void *address;
1017 +       const void *address;
1018  
1019         err = 0;
1020         address = &default_ldt[0];
1021 @@ -216,6 +229,13 @@ static int write_ldt(void __user * ptr, 
1022                 }
1023         }
1024  
1025 +#ifdef CONFIG_PAX_SEGMEXEC
1026 +       if ((mm->flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
1027 +               error = -EINVAL;
1028 +               goto out_unlock;
1029 +       }
1030 +#endif
1031 +
1032         entry_1 = LDT_entry_a(&ldt_info);
1033         entry_2 = LDT_entry_b(&ldt_info);
1034         if (oldmode)
1035 diff -urNp linux-2.6.11/arch/i386/kernel/process.c linux-2.6.11/arch/i386/kernel/process.c
1036 --- linux-2.6.11/arch/i386/kernel/process.c     2005-03-02 02:37:30.000000000 -0500
1037 +++ linux-2.6.11/arch/i386/kernel/process.c     2005-03-09 11:56:44.000000000 -0500
1038 @@ -325,7 +325,7 @@ void exit_thread(void)
1039         /* The process may have allocated an io port bitmap... nuke it. */
1040         if (unlikely(NULL != t->io_bitmap_ptr)) {
1041                 int cpu = get_cpu();
1042 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
1043 +               struct tss_struct *tss = init_tss + cpu;
1044  
1045                 kfree(t->io_bitmap_ptr);
1046                 t->io_bitmap_ptr = NULL;
1047 @@ -345,6 +345,9 @@ void flush_thread(void)
1048  {
1049         struct task_struct *tsk = current;
1050  
1051 +       __asm__("movl %0,%%fs\n"
1052 +               "movl %0,%%gs\n"
1053 +               : : "r" (0) : "memory");
1054         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1055         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
1056         /*
1057 @@ -387,7 +390,7 @@ int copy_thread(int nr, unsigned long cl
1058         struct task_struct *tsk;
1059         int err;
1060  
1061 -       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
1062 +       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info - sizeof(unsigned long))) - 1;
1063         *childregs = *regs;
1064         childregs->eax = 0;
1065         childregs->esp = esp;
1066 @@ -492,9 +495,8 @@ void dump_thread(struct pt_regs * regs, 
1067  int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
1068  {
1069         struct pt_regs ptregs;
1070 -       
1071 -       ptregs = *(struct pt_regs *)
1072 -               ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
1073 +
1074 +       ptregs = *(struct pt_regs *)(tsk->thread.esp0 - sizeof(ptregs));
1075         ptregs.xcs &= 0xffff;
1076         ptregs.xds &= 0xffff;
1077         ptregs.xes &= 0xffff;
1078 @@ -576,12 +578,20 @@ struct task_struct fastcall * __switch_t
1079         struct thread_struct *prev = &prev_p->thread,
1080                                  *next = &next_p->thread;
1081         int cpu = smp_processor_id();
1082 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1083 +       struct tss_struct *tss = init_tss + cpu;
1084 +
1085 +#ifdef CONFIG_PAX_KERNEXEC
1086 +       unsigned long flags, cr3;
1087 +#endif
1088  
1089         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1090  
1091         __unlazy_fpu(prev_p);
1092  
1093 +#ifdef CONFIG_PAX_KERNEXEC
1094 +       pax_open_kernel(flags, cr3);
1095 +#endif
1096 +
1097         /*
1098          * Reload esp0, LDT and the page table pointer:
1099          */
1100 @@ -592,6 +602,10 @@ struct task_struct fastcall * __switch_t
1101          */
1102         load_TLS(next, cpu);
1103  
1104 +#ifdef CONFIG_PAX_KERNEXEC
1105 +       pax_close_kernel(flags, cr3);
1106 +#endif
1107 +
1108         /*
1109          * Save away %fs and %gs. No need to save %es and %ds, as
1110          * those are always kernel segments while inside the kernel.
1111 @@ -740,6 +754,10 @@ asmlinkage int sys_set_thread_area(struc
1112         struct desc_struct *desc;
1113         int cpu, idx;
1114  
1115 +#ifdef CONFIG_PAX_KERNEXEC
1116 +       unsigned long flags, cr3;
1117 +#endif
1118 +
1119         if (copy_from_user(&info, u_info, sizeof(info)))
1120                 return -EFAULT;
1121         idx = info.entry_number;
1122 @@ -773,8 +791,17 @@ asmlinkage int sys_set_thread_area(struc
1123                 desc->a = LDT_entry_a(&info);
1124                 desc->b = LDT_entry_b(&info);
1125         }
1126 +
1127 +#ifdef CONFIG_PAX_KERNEXEC
1128 +       pax_open_kernel(flags, cr3);
1129 +#endif
1130 +
1131         load_TLS(t, cpu);
1132  
1133 +#ifdef CONFIG_PAX_KERNEXEC
1134 +       pax_close_kernel(flags, cr3);
1135 +#endif
1136 +
1137         put_cpu();
1138  
1139         return 0;
1140 @@ -828,3 +855,29 @@ asmlinkage int sys_get_thread_area(struc
1141         return 0;
1142  }
1143  
1144 +#ifdef CONFIG_PAX_RANDKSTACK
1145 +asmlinkage void pax_randomize_kstack(void)
1146 +{
1147 +       struct tss_struct *tss = init_tss + smp_processor_id();
1148 +       unsigned long time;
1149 +
1150 +#ifdef CONFIG_PAX_SOFTMODE
1151 +       if (!pax_aslr)
1152 +               return;
1153 +#endif
1154 +
1155 +       rdtscl(time);
1156 +
1157 +       /* P4 seems to return a 0 LSB, ignore it */
1158 +#ifdef CONFIG_MPENTIUM4
1159 +       time &= 0x3EUL;
1160 +       time <<= 1;
1161 +#else
1162 +       time &= 0x1FUL;
1163 +       time <<= 2;
1164 +#endif
1165 +
1166 +       tss->esp0 ^= time;
1167 +       current->thread.esp0 = tss->esp0;
1168 +}
1169 +#endif
1170 diff -urNp linux-2.6.11/arch/i386/kernel/ptrace.c linux-2.6.11/arch/i386/kernel/ptrace.c
1171 --- linux-2.6.11/arch/i386/kernel/ptrace.c      2005-03-02 02:37:51.000000000 -0500
1172 +++ linux-2.6.11/arch/i386/kernel/ptrace.c      2005-03-09 11:56:44.000000000 -0500
1173 @@ -15,6 +15,7 @@
1174  #include <linux/user.h>
1175  #include <linux/security.h>
1176  #include <linux/audit.h>
1177 +#include <linux/grsecurity.h>
1178  
1179  #include <asm/uaccess.h>
1180  #include <asm/pgtable.h>
1181 @@ -384,6 +385,9 @@ asmlinkage int sys_ptrace(long request, 
1182         if (pid == 1)           /* you may not mess with init */
1183                 goto out_tsk;
1184  
1185 +       if (gr_handle_ptrace(child, request))
1186 +               goto out_tsk;
1187 +
1188         if (request == PTRACE_ATTACH) {
1189                 ret = ptrace_attach(child);
1190                 goto out_tsk;
1191 @@ -462,6 +466,17 @@ asmlinkage int sys_ptrace(long request, 
1192                           if(addr == (long) &dummy->u_debugreg[5]) break;
1193                           if(addr < (long) &dummy->u_debugreg[4] &&
1194                              ((unsigned long) data) >= TASK_SIZE-3) break;
1195 +
1196 +#ifdef CONFIG_GRKERNSEC
1197 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
1198 +                            addr <= (long) &dummy->u_debugreg[3]){
1199 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
1200 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
1201 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
1202 +                               if((type & 1) && (data & align))
1203 +                                       break;
1204 +                         }
1205 +#endif
1206                           
1207                           /* Sanity-check data. Take one half-byte at once with
1208                            * check = (val >> (16 + 4*i)) & 0xf. It contains the
1209 diff -urNp linux-2.6.11/arch/i386/kernel/reboot.c linux-2.6.11/arch/i386/kernel/reboot.c
1210 --- linux-2.6.11/arch/i386/kernel/reboot.c      2005-03-02 02:37:52.000000000 -0500
1211 +++ linux-2.6.11/arch/i386/kernel/reboot.c      2005-03-09 11:56:44.000000000 -0500
1212 @@ -152,18 +152,18 @@ core_initcall(reboot_init);
1213     doesn't work with at least one type of 486 motherboard.  It is easy
1214     to stop this code working; hence the copious comments. */
1215  
1216 -static unsigned long long
1217 +static const unsigned long long
1218  real_mode_gdt_entries [3] =
1219  {
1220         0x0000000000000000ULL,  /* Null descriptor */
1221 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
1222 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
1223 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
1224 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
1225  };
1226  
1227  static struct
1228  {
1229         unsigned short       size __attribute__ ((packed));
1230 -       unsigned long long * base __attribute__ ((packed));
1231 +       const unsigned long long * base __attribute__ ((packed));
1232  }
1233  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
1234  real_mode_idt = { 0x3ff, NULL },
1235 diff -urNp linux-2.6.11/arch/i386/kernel/setup.c linux-2.6.11/arch/i386/kernel/setup.c
1236 --- linux-2.6.11/arch/i386/kernel/setup.c       2005-03-02 02:38:08.000000000 -0500
1237 +++ linux-2.6.11/arch/i386/kernel/setup.c       2005-03-09 11:56:44.000000000 -0500
1238 @@ -73,7 +73,11 @@ struct cpuinfo_x86 new_cpu_data __initda
1239  /* common cpu data for all cpus */
1240  struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
1241  
1242 +#ifdef CONFIG_X86_PAE
1243 +unsigned long mmu_cr4_features = X86_CR4_PAE;
1244 +#else
1245  unsigned long mmu_cr4_features;
1246 +#endif
1247  EXPORT_SYMBOL_GPL(mmu_cr4_features);
1248  
1249  #ifdef CONFIG_ACPI_INTERPRETER
1250 @@ -1411,7 +1415,7 @@ void __init setup_arch(char **cmdline_p)
1251  
1252         code_resource.start = virt_to_phys(_text);
1253         code_resource.end = virt_to_phys(_etext)-1;
1254 -       data_resource.start = virt_to_phys(_etext);
1255 +       data_resource.start = virt_to_phys(_data);
1256         data_resource.end = virt_to_phys(_edata)-1;
1257  
1258         parse_cmdline_early(cmdline_p);
1259 @@ -1481,6 +1485,15 @@ void __init setup_arch(char **cmdline_p)
1260  #endif
1261  }
1262  
1263 +#ifdef CONFIG_PAX_SOFTMODE
1264 +static int __init setup_pax_softmode(char *str)
1265 +{
1266 +       get_option (&str, &pax_softmode);
1267 +       return 1;
1268 +}
1269 +__setup("pax_softmode=", setup_pax_softmode);
1270 +#endif
1271 +
1272  #include "setup_arch_post.h"
1273  /*
1274   * Local Variables:
1275 diff -urNp linux-2.6.11/arch/i386/kernel/signal.c linux-2.6.11/arch/i386/kernel/signal.c
1276 --- linux-2.6.11/arch/i386/kernel/signal.c      2005-03-02 02:38:08.000000000 -0500
1277 +++ linux-2.6.11/arch/i386/kernel/signal.c      2005-03-09 11:56:44.000000000 -0500
1278 @@ -380,7 +380,17 @@ static void setup_frame(int sig, struct 
1279                         goto give_sigsegv;
1280         }
1281  
1282 +#ifdef CONFIG_PAX_NOVSYSCALL
1283 +       restorer = frame->retcode;
1284 +#else
1285         restorer = &__kernel_sigreturn;
1286 +
1287 +#ifdef CONFIG_PAX_SEGMEXEC
1288 +       if (current->mm->flags & MF_PAX_SEGMEXEC)
1289 +               restorer -= SEGMEXEC_TASK_SIZE;
1290 +#endif
1291 +#endif
1292 +
1293         if (ka->sa.sa_flags & SA_RESTORER)
1294                 restorer = ka->sa.sa_restorer;
1295  
1296 @@ -475,7 +485,18 @@ static void setup_rt_frame(int sig, stru
1297                 goto give_sigsegv;
1298  
1299         /* Set up to return from userspace.  */
1300 +
1301 +#ifdef CONFIG_PAX_NOVSYSCALL
1302 +       restorer = frame->retcode;
1303 +#else
1304         restorer = &__kernel_rt_sigreturn;
1305 +
1306 +#ifdef CONFIG_PAX_SEGMEXEC
1307 +       if (current->mm->flags & MF_PAX_SEGMEXEC)
1308 +               restorer -= SEGMEXEC_TASK_SIZE;
1309 +#endif
1310 +#endif
1311 +
1312         if (ka->sa.sa_flags & SA_RESTORER)
1313                 restorer = ka->sa.sa_restorer;
1314         err |= __put_user(restorer, &frame->pretcode);
1315 diff -urNp linux-2.6.11/arch/i386/kernel/sys_i386.c linux-2.6.11/arch/i386/kernel/sys_i386.c
1316 --- linux-2.6.11/arch/i386/kernel/sys_i386.c    2005-03-02 02:38:32.000000000 -0500
1317 +++ linux-2.6.11/arch/i386/kernel/sys_i386.c    2005-03-09 11:56:44.000000000 -0500
1318 @@ -49,6 +49,11 @@ static inline long do_mmap2(
1319         int error = -EBADF;
1320         struct file * file = NULL;
1321  
1322 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
1323 +       if (flags & MAP_MIRROR)
1324 +               return -EINVAL;
1325 +#endif
1326 +
1327         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1328         if (!(flags & MAP_ANONYMOUS)) {
1329                 file = fget(fd);
1330 @@ -106,6 +111,182 @@ out:
1331         return err;
1332  }
1333  
1334 +unsigned long
1335 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
1336 +               unsigned long len, unsigned long pgoff, unsigned long flags)
1337 +{
1338 +       struct mm_struct *mm = current->mm;
1339 +       struct vm_area_struct *vma;
1340 +       unsigned long start_addr, start_mmap, task_size = TASK_SIZE;
1341 +
1342 +#ifdef CONFIG_PAX_SEGMEXEC
1343 +       if (mm->flags & MF_PAX_SEGMEXEC)
1344 +               task_size = SEGMEXEC_TASK_SIZE;
1345 +#endif
1346 +
1347 +       if (len > task_size)
1348 +               return -ENOMEM;
1349 +
1350 +#ifdef CONFIG_PAX_RANDMMAP
1351 +       if (!(mm->flags & MF_PAX_RANDMMAP) || !filp)
1352 +#endif
1353 +
1354 +       if (addr) {
1355 +               addr = PAGE_ALIGN(addr);
1356 +               vma = find_vma(mm, addr);
1357 +               if (task_size - len >= addr &&
1358 +                   (!vma || addr + len <= vma->vm_start))
1359 +                       return addr;
1360 +       }
1361 +       start_addr = addr = mm->free_area_cache;
1362 +       start_mmap = PAGE_ALIGN(task_size/3);
1363 +
1364 +#ifdef CONFIG_PAX_RANDMMAP
1365 +       if (mm->flags & MF_PAX_RANDMMAP)
1366 +               start_mmap += mm->delta_mmap;
1367 +#endif
1368 +
1369 +       if (!(flags & MAP_EXECUTABLE) && start_addr < start_mmap)
1370 +               start_addr = addr = start_mmap;
1371 +       else if ((flags & MAP_EXECUTABLE) && start_addr >= start_mmap)
1372 +               start_addr = addr = mm->mmap_base;
1373 +
1374 +full_search:
1375 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
1376 +               /* At this point:  (!vma || addr < vma->vm_end). */
1377 +               if (task_size - len < addr) {
1378 +                       /*
1379 +                        * Start a new search - just in case we missed
1380 +                        * some holes.
1381 +                        */
1382 +                       if (start_addr != mm->mmap_base) {
1383 +                               start_addr = addr = mm->mmap_base;
1384 +                               goto full_search;
1385 +                       }
1386 +                       return -ENOMEM;
1387 +               }
1388 +               if (!vma || (addr + len <= vma->vm_start && (addr + len <= mm->start_brk || start_mmap <= addr))) {
1389 +                       /*
1390 +                        * Remember the place where we stopped the search:
1391 +                        */
1392 +                       mm->free_area_cache = addr + len;
1393 +                       return addr;
1394 +               }
1395 +               if (addr < start_mmap && addr + len > mm->start_brk) {
1396 +                       addr = start_mmap;
1397 +                       goto full_search;
1398 +               } else
1399 +                       addr = vma->vm_end;
1400 +       }
1401 +}
1402 +
1403 +unsigned long
1404 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
1405 +                         const unsigned long len, const unsigned long pgoff,
1406 +                         const unsigned long flags)
1407 +{
1408 +       struct vm_area_struct *vma;
1409 +       struct mm_struct *mm = current->mm;
1410 +       unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
1411 +       int first_time = 1;
1412 +
1413 +       if (flags & MAP_EXECUTABLE) {
1414 +               mm->mmap_base = TASK_UNMAPPED_BASE;
1415 +
1416 +#ifdef CONFIG_PAX_RANDMMAP
1417 +               if (mm->flags & MF_PAX_RANDMMAP)
1418 +                       mm->mmap_base += mm->delta_mmap;
1419 +#endif
1420 +
1421 +               mm->free_area_cache = mm->mmap_base;
1422 +               addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
1423 +               mm->free_area_cache = base;
1424 +               mm->mmap_base = base;
1425 +               return addr;
1426 +       }
1427 +
1428 +#ifdef CONFIG_PAX_SEGMEXEC
1429 +       if (mm->flags & MF_PAX_SEGMEXEC)
1430 +               task_size = SEGMEXEC_TASK_SIZE;
1431 +#endif
1432 +
1433 +       /* requested length too big for entire address space */
1434 +       if (len > task_size)
1435 +               return -ENOMEM;
1436 +
1437 +       /* dont allow allocations above current base */
1438 +       if (mm->free_area_cache > base)
1439 +               mm->free_area_cache = base;
1440 +
1441 +#ifdef CONFIG_PAX_RANDMMAP
1442 +       if (!(mm->flags & MF_PAX_RANDMMAP) || !filp)
1443 +#endif
1444 +
1445 +       /* requesting a specific address */
1446 +       if (addr) {
1447 +               addr = PAGE_ALIGN(addr);
1448 +               vma = find_vma(mm, addr);
1449 +               if (task_size - len >= addr &&
1450 +                               (!vma || addr + len <= vma->vm_start))
1451 +                       return addr;
1452 +       }
1453 +
1454 +try_again:
1455 +       /* make sure it can fit in the remaining address space */
1456 +       if (mm->free_area_cache < len)
1457 +               goto fail;
1458 +
1459 +       /* either no address requested or cant fit in requested address hole */
1460 +       addr = (mm->free_area_cache - len) & PAGE_MASK;
1461 +       do {
1462 +               /*
1463 +                * Lookup failure means no vma is above this address,
1464 +                * i.e. return with success:
1465 +                */
1466 +               if (!(vma = find_vma(mm, addr)))
1467 +                       return addr;
1468 +
1469 +               /*
1470 +                * new region fits between prev_vma->vm_end and
1471 +                * vma->vm_start, use it:
1472 +                */
1473 +               if (addr+len <= vma->vm_start)
1474 +                       /* remember the address as a hint for next time */
1475 +                       return (mm->free_area_cache = addr);
1476 +               else
1477 +                       /* pull free_area_cache down to the first hole */
1478 +                       if (mm->free_area_cache == vma->vm_end)
1479 +                               mm->free_area_cache = vma->vm_start;
1480 +
1481 +               /* try just below the current vma->vm_start */
1482 +               addr = vma->vm_start-len;
1483 +       } while (len <= vma->vm_start);
1484 +
1485 +fail:
1486 +       /*
1487 +       * if hint left us with no space for the requested
1488 +       * mapping then try again:
1489 +       */
1490 +       if (first_time) {
1491 +               mm->free_area_cache = base;
1492 +               first_time = 0;
1493 +               goto try_again;
1494 +       }
1495 +       /*
1496 +        * A failed mmap() very likely causes application failure,
1497 +        * so fall back to the bottom-up function here. This scenario
1498 +        * can happen with large stack limits and large mmap()
1499 +        * allocations.
1500 +        */
1501 +       mm->free_area_cache = TASK_UNMAPPED_BASE;
1502 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
1503 +       /*
1504 +        * Restore the topdown base:
1505 +        */
1506 +       mm->free_area_cache = base;
1507 +
1508 +       return addr;
1509 +}
1510  
1511  struct sel_arg_struct {
1512         unsigned long n;
1513 diff -urNp linux-2.6.11/arch/i386/kernel/sysenter.c linux-2.6.11/arch/i386/kernel/sysenter.c
1514 --- linux-2.6.11/arch/i386/kernel/sysenter.c    2005-03-02 02:38:33.000000000 -0500
1515 +++ linux-2.6.11/arch/i386/kernel/sysenter.c    2005-03-09 11:56:44.000000000 -0500
1516 @@ -24,7 +24,7 @@ extern asmlinkage void sysenter_entry(vo
1517  void enable_sep_cpu(void *info)
1518  {
1519         int cpu = get_cpu();
1520 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1521 +       struct tss_struct *tss = init_tss + cpu;
1522  
1523         tss->ss1 = __KERNEL_CS;
1524         tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
1525 @@ -41,6 +41,7 @@ void enable_sep_cpu(void *info)
1526  extern const char vsyscall_int80_start, vsyscall_int80_end;
1527  extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
1528  
1529 +#ifndef CONFIG_PAX_NOVSYSCALL
1530  static int __init sysenter_setup(void)
1531  {
1532         void *page = (void *)get_zeroed_page(GFP_ATOMIC);
1533 @@ -63,3 +64,4 @@ static int __init sysenter_setup(void)
1534  }
1535  
1536  __initcall(sysenter_setup);
1537 +#endif
1538 diff -urNp linux-2.6.11/arch/i386/kernel/traps.c linux-2.6.11/arch/i386/kernel/traps.c
1539 --- linux-2.6.11/arch/i386/kernel/traps.c       2005-03-02 02:37:49.000000000 -0500
1540 +++ linux-2.6.11/arch/i386/kernel/traps.c       2005-03-09 11:56:44.000000000 -0500
1541 @@ -27,6 +27,7 @@
1542  #include <linux/ptrace.h>
1543  #include <linux/utsname.h>
1544  #include <linux/kprobes.h>
1545 +#include <linux/binfmts.h>
1546  
1547  #ifdef CONFIG_EISA
1548  #include <linux/ioport.h>
1549 @@ -58,18 +59,13 @@
1550  
1551  asmlinkage int system_call(void);
1552  
1553 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1554 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1555                 { 0, 0 }, { 0, 0 } };
1556  
1557  /* Do we ignore FPU interrupts ? */
1558  char ignore_fpu_irq = 0;
1559  
1560 -/*
1561 - * The IDT has to be page-aligned to simplify the Pentium
1562 - * F0 0F bug workaround.. We have a special link segment
1563 - * for this.
1564 - */
1565 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
1566 +extern struct desc_struct idt_table[256];
1567  
1568  asmlinkage void divide_error(void);
1569  asmlinkage void debug(void);
1570 @@ -115,6 +111,7 @@ static inline unsigned long print_contex
1571                                 unsigned long *stack, unsigned long ebp)
1572  {
1573         unsigned long addr;
1574 +       int i = kstack_depth_to_print;
1575  
1576  #ifdef CONFIG_FRAME_POINTER
1577         while (valid_stack_ptr(tinfo, (void *)ebp)) {
1578 @@ -123,6 +120,7 @@ static inline unsigned long print_contex
1579                 print_symbol("%s", addr);
1580                 printk("\n");
1581                 ebp = *(unsigned long *)ebp;
1582 +               --i;
1583         }
1584  #else
1585         while (valid_stack_ptr(tinfo, stack)) {
1586 @@ -131,6 +129,7 @@ static inline unsigned long print_contex
1587                         printk(" [<%08lx>]", addr);
1588                         print_symbol(" %s", addr);
1589                         printk("\n");
1590 +                       --i;
1591                 }
1592         }
1593  #endif
1594 @@ -240,7 +239,7 @@ void show_registers(struct pt_regs *regs
1595  
1596                 printk("Code: ");
1597  
1598 -               eip = (u8 *)regs->eip - 43;
1599 +               eip = (u8 *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
1600                 for (i = 0; i < 64; i++, eip++) {
1601                         unsigned char c;
1602  
1603 @@ -268,7 +267,7 @@ static void handle_BUG(struct pt_regs *r
1604         if (regs->xcs & 3)
1605                 goto no_bug;            /* Not in kernel */
1606  
1607 -       eip = regs->eip;
1608 +       eip = regs->eip + __KERNEL_TEXT_OFFSET;
1609  
1610         if (eip < PAGE_OFFSET)
1611                 goto no_bug;
1612 @@ -456,7 +455,7 @@ DO_ERROR_INFO(17, SIGBUS, "alignment che
1613  fastcall void do_general_protection(struct pt_regs * regs, long error_code)
1614  {
1615         int cpu = get_cpu();
1616 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1617 +       struct tss_struct *tss = &init_tss[cpu];
1618         struct thread_struct *thread = &current->thread;
1619  
1620         /*
1621 @@ -491,6 +490,24 @@ fastcall void do_general_protection(stru
1622         if (!(regs->xcs & 3))
1623                 goto gp_in_kernel;
1624  
1625 +#ifdef CONFIG_PAX_PAGEEXEC
1626 +       if (current->mm) {
1627 +               struct mm_struct *mm = current->mm;
1628 +               unsigned long limit;
1629 +
1630 +               if (mm->flags & MF_PAX_PAGEEXEC) {
1631 +                       down_write(&mm->mmap_sem);
1632 +                       limit = mm->context.user_cs_limit;
1633 +                       if (limit < TASK_SIZE) {
1634 +                               track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
1635 +                               up_write(&mm->mmap_sem);
1636 +                               return;
1637 +                       }
1638 +                       up_write(&mm->mmap_sem);
1639 +               }
1640 +       }
1641 +#endif
1642 +
1643         current->thread.error_code = error_code;
1644         current->thread.trap_no = 13;
1645         force_sig(SIGSEGV, current);
1646 @@ -506,6 +523,13 @@ gp_in_kernel:
1647                 if (notify_die(DIE_GPF, "general protection fault", regs,
1648                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
1649                         return;
1650 +
1651 +#ifdef CONFIG_PAX_KERNEXEC
1652 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
1653 +                       die("PAX: suspicious general protection fault", regs, error_code);
1654 +               else
1655 +#endif
1656 +
1657                 die("general protection fault", regs, error_code);
1658         }
1659  }
1660 @@ -932,6 +956,8 @@ asmlinkage void math_emulate(long arg)
1661  #ifdef CONFIG_X86_F00F_BUG
1662  void __init trap_init_f00f_bug(void)
1663  {
1664 +
1665 +#ifndef CONFIG_PAX_KERNEXEC
1666         __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
1667  
1668         /*
1669 @@ -940,6 +966,8 @@ void __init trap_init_f00f_bug(void)
1670          */
1671         idt_descr.address = fix_to_virt(FIX_F00F_IDT);
1672         __asm__ __volatile__("lidt %0" : : "m" (idt_descr));
1673 +#endif
1674 +
1675  }
1676  #endif
1677  
1678 diff -urNp linux-2.6.11/arch/i386/kernel/vm86.c linux-2.6.11/arch/i386/kernel/vm86.c
1679 --- linux-2.6.11/arch/i386/kernel/vm86.c        2005-03-02 02:37:48.000000000 -0500
1680 +++ linux-2.6.11/arch/i386/kernel/vm86.c        2005-03-09 11:56:44.000000000 -0500
1681 @@ -121,7 +121,7 @@ struct pt_regs * fastcall save_v86_state
1682                 do_exit(SIGSEGV);
1683         }
1684  
1685 -       tss = &per_cpu(init_tss, get_cpu());
1686 +       tss = init_tss + get_cpu();
1687         current->thread.esp0 = current->thread.saved_esp0;
1688         current->thread.sysenter_cs = __KERNEL_CS;
1689         load_esp0(tss, &current->thread);
1690 @@ -312,7 +312,7 @@ static void do_sys_vm86(struct kernel_vm
1691         asm volatile("movl %%fs,%0":"=m" (tsk->thread.saved_fs));
1692         asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs));
1693  
1694 -       tss = &per_cpu(init_tss, get_cpu());
1695 +       tss = init_tss + get_cpu();
1696         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
1697         if (cpu_has_sep)
1698                 tsk->thread.sysenter_cs = 0;
1699 diff -urNp linux-2.6.11/arch/i386/kernel/vmlinux.lds.S linux-2.6.11/arch/i386/kernel/vmlinux.lds.S
1700 --- linux-2.6.11/arch/i386/kernel/vmlinux.lds.S 2005-03-02 02:38:37.000000000 -0500
1701 +++ linux-2.6.11/arch/i386/kernel/vmlinux.lds.S 2005-03-09 11:56:44.000000000 -0500
1702 @@ -2,9 +2,12 @@
1703   * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1704   */
1705  
1706 +#include <linux/config.h>
1707 +
1708  #include <asm-generic/vmlinux.lds.h>
1709  #include <asm/thread_info.h>
1710  #include <asm/page.h>
1711 +#include <asm/segment.h>
1712  
1713  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1714  OUTPUT_ARCH(i386)
1715 @@ -13,56 +16,15 @@ jiffies = jiffies_64;
1716  SECTIONS
1717  {
1718    . = __PAGE_OFFSET + 0x100000;
1719 -  /* read-only */
1720 -  _text = .;                   /* Text and read-only data */
1721 -  .text : {
1722 -       *(.text)
1723 -       SCHED_TEXT
1724 -       LOCK_TEXT
1725 -       *(.fixup)
1726 -       *(.gnu.warning)
1727 -       } = 0x9090
1728 -
1729 -  _etext = .;                  /* End of text section */
1730 -
1731 -  . = ALIGN(16);               /* Exception table */
1732 -  __start___ex_table = .;
1733 -  __ex_table : { *(__ex_table) }
1734 -  __stop___ex_table = .;
1735 -
1736 -  RODATA
1737 -
1738 -  /* writeable */
1739 -  .data : {                    /* Data */
1740 -       *(.data)
1741 -       CONSTRUCTORS
1742 +  .text.startup : {
1743 +       BYTE(0xEA) /* jmp far */
1744 +       LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
1745 +       SHORT(__BOOT_CS)
1746         }
1747  
1748 -  . = ALIGN(4096);
1749 -  __nosave_begin = .;
1750 -  .data_nosave : { *(.data.nosave) }
1751 -  . = ALIGN(4096);
1752 -  __nosave_end = .;
1753 -
1754 -  . = ALIGN(4096);
1755 -  .data.page_aligned : { *(.data.idt) }
1756 -
1757 -  . = ALIGN(32);
1758 -  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1759 -
1760 -  _edata = .;                  /* End of data section */
1761 -
1762 -  . = ALIGN(THREAD_SIZE);      /* init_task */
1763 -  .data.init_task : { *(.data.init_task) }
1764 -
1765    /* will be freed after init */
1766    . = ALIGN(4096);             /* Init code and data */
1767    __init_begin = .;
1768 -  .init.text : { 
1769 -       _sinittext = .;
1770 -       *(.init.text)
1771 -       _einittext = .;
1772 -  }
1773    .init.data : { *(.init.data) }
1774    . = ALIGN(16);
1775    __setup_start = .;
1776 @@ -88,9 +50,13 @@ SECTIONS
1777    .altinstructions : { *(.altinstructions) } 
1778    __alt_instructions_end = .; 
1779   .altinstr_replacement : { *(.altinstr_replacement) } 
1780 +
1781 +#ifndef CONFIG_PAX_KERNEXEC
1782    /* .exit.text is discard at runtime, not link time, to deal with references
1783       from .altinstructions and .eh_frame */
1784    .exit.text : { *(.exit.text) }
1785 +#endif
1786 +
1787    .exit.data : { *(.exit.data) }
1788    . = ALIGN(4096);
1789    __initramfs_start = .;
1790 @@ -100,15 +66,107 @@ SECTIONS
1791    __per_cpu_start = .;
1792    .data.percpu  : { *(.data.percpu) }
1793    __per_cpu_end = .;
1794 +
1795 +  /* read-only */
1796 +
1797 +#ifdef CONFIG_PAX_KERNEXEC
1798 +  __init_text_start = .;
1799 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT (__init_text_start) {
1800 +       _sinittext = .;
1801 +       *(.init.text)
1802 +       _einittext = .;
1803 +       *(.exit.text)
1804 +       . = ALIGN(4*1024*1024) - 1;
1805 +       BYTE(0)
1806 +  }
1807 +  . = ALIGN(4096);
1808 +  __init_end = . + __KERNEL_TEXT_OFFSET;
1809 +  /* freed after init ends here */
1810 +
1811 +/*
1812 + * PaX: this must be kept in synch with the KERNEL_CS base
1813 + * in the GDTs in arch/i386/kernel/head.S
1814 + */
1815 +  _text = .;                   /* Text and read-only data */
1816 +  .text : AT (. + __KERNEL_TEXT_OFFSET) {
1817 +#else
1818 +  .init.text : {
1819 +       _sinittext = .;
1820 +       *(.init.text)
1821 +       _einittext = .;
1822 +  }
1823    . = ALIGN(4096);
1824    __init_end = .;
1825    /* freed after init ends here */
1826 -       
1827 +
1828 +  _text = .;                   /* Text and read-only data */
1829 +  .text : {
1830 +#endif
1831 +
1832 +       *(.text)
1833 +       SCHED_TEXT
1834 +       LOCK_TEXT
1835 +       *(.fixup)
1836 +       *(.gnu.warning)
1837 +       } = 0x9090
1838 +
1839 +  _etext = .;                  /* End of text section */
1840 +  . += __KERNEL_TEXT_OFFSET;
1841 +  . = ALIGN(4096);             /* Exception table */
1842 +  __start___ex_table = .;
1843 +  __ex_table : { *(__ex_table) }
1844 +  __stop___ex_table = .;
1845 +
1846 +  . = ALIGN(4096);
1847 +  .rodata.page_aligned : {
1848 +       *(.rodata.empty_zero_page)
1849 +       *(.rodata.idt)
1850 +       }
1851 +
1852 +  RODATA
1853 +
1854 +#ifdef CONFIG_PAX_KERNEXEC
1855 +  . = ALIGN(4*1024*1024);
1856 +#else
1857 +  . = ALIGN(32);
1858 +#endif
1859 +
1860 +  /* writeable */
1861 +  _data = .;
1862 +  .data : {                    /* Data */
1863 +       *(.data)
1864 +       CONSTRUCTORS
1865 +       }
1866 +
1867 +  . = ALIGN(4096);
1868 +  __nosave_begin = .;
1869 +  .data_nosave : { *(.data.nosave) }
1870 +  . = ALIGN(4096);
1871 +  __nosave_end = .;
1872 +
1873 +  . = ALIGN(32);
1874 +  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1875 +
1876 +  . = ALIGN(THREAD_SIZE);      /* init_task */
1877 +  .data.init_task : { *(.data.init_task) }
1878 +
1879 +  . = ALIGN(4096);
1880 +  .data.page_aligned : {
1881 +
1882 +#ifdef CONFIG_X86_PAE
1883 +       *(.data.swapper_pm_dir)
1884 +#endif
1885 +
1886 +       *(.data.swapper_pg_dir)
1887 +       }
1888 +
1889 +  _edata = .;                  /* End of data section */
1890 +
1891    __bss_start = .;             /* BSS */
1892    .bss : {
1893         *(.bss.page_aligned)
1894         *(.bss)
1895 -  }
1896 +       }
1897    . = ALIGN(4);
1898    __bss_stop = .; 
1899  
1900 diff -urNp linux-2.6.11/arch/i386/mm/fault.c linux-2.6.11/arch/i386/mm/fault.c
1901 --- linux-2.6.11/arch/i386/mm/fault.c   2005-03-02 02:37:30.000000000 -0500
1902 +++ linux-2.6.11/arch/i386/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
1903 @@ -21,6 +21,9 @@
1904  #include <linux/vt_kern.h>             /* For unblank_screen() */
1905  #include <linux/highmem.h>
1906  #include <linux/module.h>
1907 +#include <linux/unistd.h>
1908 +#include <linux/compiler.h>
1909 +#include <linux/binfmts.h>
1910  
1911  #include <asm/system.h>
1912  #include <asm/uaccess.h>
1913 @@ -81,7 +84,7 @@ static inline unsigned long get_segment_
1914  
1915         /* Unlikely, but must come before segment checks. */
1916         if (unlikely((regs->eflags & VM_MASK) != 0))
1917 -               return eip + (seg << 4);
1918 +               return (eip & 0xFFFF) + (seg << 4);
1919         
1920         /* By far the most common cases. */
1921         if (likely(seg == __USER_CS || seg == __KERNEL_CS))
1922 @@ -107,7 +110,7 @@ static inline unsigned long get_segment_
1923                 desc = (void *)desc + (seg & ~7);
1924         } else {
1925                 /* Must disable preemption while reading the GDT. */
1926 -               desc = (u32 *)&per_cpu(cpu_gdt_table, get_cpu());
1927 +               desc = (u32 *)&cpu_gdt_table[get_cpu()];
1928                 desc = (void *)desc + (seg & ~7);
1929         }
1930  
1931 @@ -201,6 +204,31 @@ static inline int is_prefetch(struct pt_
1932  
1933  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
1934  
1935 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
1936 +static int pax_handle_fetch_fault(struct pt_regs *regs);
1937 +#endif
1938 +
1939 +#ifdef CONFIG_PAX_PAGEEXEC
1940 +/* PaX: called with the page_table_lock spinlock held */
1941 +static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
1942 +{
1943 +       pgd_t *pgd;
1944 +       pud_t *pud;
1945 +       pmd_t *pmd;
1946 +
1947 +       pgd = pgd_offset(mm, address);
1948 +       if (!pgd || !pgd_present(*pgd))
1949 +               return 0;
1950 +       pud = pud_offset(pgd, address);
1951 +       if (!pud || !pud_present(*pud))
1952 +               return 0;
1953 +       pmd = pmd_offset(pud, address);
1954 +       if (!pmd || !pmd_present(*pmd))
1955 +               return 0;
1956 +       return pte_offset_map(pmd, address);
1957 +}
1958 +#endif
1959 +
1960  /*
1961   * This routine handles page faults.  It determines the address,
1962   * and the problem, and then passes it off to one of the appropriate
1963 @@ -217,10 +245,14 @@ fastcall void do_page_fault(struct pt_re
1964         struct mm_struct *mm;
1965         struct vm_area_struct * vma;
1966         unsigned long address;
1967 -       unsigned long page;
1968         int write;
1969         siginfo_t info;
1970  
1971 +#ifdef CONFIG_PAX_PAGEEXEC
1972 +       pte_t *pte;
1973 +       unsigned char pte_mask1, pte_mask2;
1974 +#endif
1975 +
1976         /* get the address */
1977         __asm__("movl %%cr2,%0":"=r" (address));
1978  
1979 @@ -232,6 +264,7 @@ fastcall void do_page_fault(struct pt_re
1980                 local_irq_enable();
1981  
1982         tsk = current;
1983 +       mm = tsk->mm;
1984  
1985         info.si_code = SEGV_MAPERR;
1986  
1987 @@ -258,14 +291,99 @@ fastcall void do_page_fault(struct pt_re
1988                 goto bad_area_nosemaphore;
1989         } 
1990  
1991 -       mm = tsk->mm;
1992 -
1993         /*
1994          * If we're in an interrupt, have no user context or are running in an
1995          * atomic region then we must not take the fault..
1996          */
1997         if (in_atomic() || !mm)
1998 -               goto bad_area_nosemaphore;
1999 +               goto bad_area_nopax;
2000 +
2001 +#ifdef CONFIG_PAX_PAGEEXEC
2002 +       if (unlikely((error_code & 5) != 5 ||
2003 +                    (regs->eflags & X86_EFLAGS_VM) ||
2004 +                    !(mm->flags & MF_PAX_PAGEEXEC)))
2005 +               goto not_pax_fault;
2006 +
2007 +       /* PaX: it's our fault, let's handle it if we can */
2008 +
2009 +       /* PaX: take a look at read faults before acquiring any locks */
2010 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
2011 +               /* instruction fetch attempt from a protected page in user mode */
2012 +               switch (pax_handle_fetch_fault(regs)) {
2013 +
2014 +#ifdef CONFIG_PAX_RANDEXEC
2015 +               case 3:
2016 +                       return;
2017 +#endif
2018 +
2019 +#ifdef CONFIG_PAX_EMUTRAMP
2020 +               case 2:
2021 +                       return;
2022 +#endif
2023 +
2024 +               }
2025 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2026 +               do_exit(SIGKILL);
2027 +       }
2028 +
2029 +       spin_lock(&mm->page_table_lock);
2030 +       pte = pax_get_pte(mm, address);
2031 +       if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
2032 +               pte_unmap(pte);
2033 +               spin_unlock(&mm->page_table_lock);
2034 +               goto not_pax_fault;
2035 +       }
2036 +
2037 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
2038 +               /* write attempt to a protected page in user mode */
2039 +               pte_unmap(pte);
2040 +               spin_unlock(&mm->page_table_lock);
2041 +               goto not_pax_fault;
2042 +       }
2043 +
2044 +       pte_mask1 = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
2045 +
2046 +#ifdef CONFIG_SMP
2047 +       if (likely(cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)) && address >= get_limit(regs->xcs))
2048 +               pte_mask2 = 0;
2049 +       else
2050 +               pte_mask2 = _PAGE_USER;
2051 +#else
2052 +       pte_mask2 = (address >= get_limit(regs->xcs)) ? 0 : _PAGE_USER;
2053 +#endif
2054 +
2055 +       /*
2056 +        * PaX: fill DTLB with user rights and retry
2057 +        */
2058 +       __asm__ __volatile__ (
2059 +               "orb %2,%1\n"
2060 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
2061 +/*
2062 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
2063 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
2064 + * page fault when examined during a TLB load attempt. this is true not only
2065 + * for PTEs holding a non-present entry but also present entries that will
2066 + * raise a page fault (such as those set up by PaX, or the copy-on-write
2067 + * mechanism). in effect it means that we do *not* need to flush the TLBs
2068 + * for our target pages since their PTEs are simply not in the TLBs at all.
2069 +
2070 + * the best thing in omitting it is that we gain around 15-20% speed in the
2071 + * fast path of the page fault handler and can get rid of tracing since we
2072 + * can no longer flush unintended entries.
2073 + */
2074 +               "invlpg %0\n"
2075 +#endif
2076 +               "testb $0,%0\n"
2077 +               "xorb %3,%1\n"
2078 +               :
2079 +               : "m" (*(char*)address), "m" (*(char*)pte), "q" (pte_mask1), "q" (pte_mask2)
2080 +               : "memory", "cc");
2081 +       pte_unmap(pte);
2082 +       spin_unlock(&mm->page_table_lock);
2083 +       return;
2084 +
2085 +not_pax_fault:
2086 +#endif
2087  
2088         /* When running in the kernel we expect faults to occur only to
2089          * addresses in user space.  All other faults represent errors in the
2090 @@ -285,7 +403,7 @@ fastcall void do_page_fault(struct pt_re
2091         if (!down_read_trylock(&mm->mmap_sem)) {
2092                 if ((error_code & 4) == 0 &&
2093                     !search_exception_tables(regs->eip))
2094 -                       goto bad_area_nosemaphore;
2095 +                       goto bad_area_nopax;
2096                 down_read(&mm->mmap_sem);
2097         }
2098  
2099 @@ -306,7 +424,7 @@ fastcall void do_page_fault(struct pt_re
2100                 if (address + 32 < regs->esp)
2101                         goto bad_area;
2102         }
2103 -       if (expand_stack(vma, address))
2104 +       if (expand_stack(tsk, vma, address))
2105                 goto bad_area;
2106  /*
2107   * Ok, we have a good vm_area for this memory access, so
2108 @@ -374,6 +492,45 @@ bad_area:
2109         up_read(&mm->mmap_sem);
2110  
2111  bad_area_nosemaphore:
2112 +
2113 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2114 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
2115 +
2116 +#ifdef CONFIG_PAX_PAGEEXEC
2117 +               if ((mm->flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
2118 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2119 +                       do_exit(SIGKILL);
2120 +               }
2121 +#endif
2122 +
2123 +#ifdef CONFIG_PAX_SEGMEXEC
2124 +               if ((mm->flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
2125 +
2126 +#if defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
2127 +                       switch (pax_handle_fetch_fault(regs)) {
2128 +
2129 +#ifdef CONFIG_PAX_RANDEXEC
2130 +                       case 3:
2131 +                               return;
2132 +#endif
2133 +
2134 +#ifdef CONFIG_PAX_EMUTRAMP
2135 +                       case 2:
2136 +                               return;
2137 +#endif
2138 +
2139 +                       }
2140 +#endif
2141 +
2142 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2143 +                       do_exit(SIGKILL);
2144 +               }
2145 +#endif
2146 +
2147 +       }
2148 +#endif
2149 +
2150 +bad_area_nopax:
2151         /* User mode accesses just cause a SIGSEGV */
2152         if (error_code & 4) {
2153                 /* 
2154 @@ -441,28 +598,52 @@ no_context:
2155  #endif
2156         if (address < PAGE_SIZE)
2157                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
2158 +
2159 +#ifdef CONFIG_PAX_KERNEXEC
2160 +       else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address &&
2161 +                address < init_mm.end_code + __KERNEL_TEXT_OFFSET)
2162 +               if (tsk->curr_ip)
2163 +                       printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
2164 +                                        NIPQUAD(tsk->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
2165 +               else
2166 +                       printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
2167 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
2168 +#endif
2169 +
2170         else
2171                 printk(KERN_ALERT "Unable to handle kernel paging request");
2172         printk(" at virtual address %08lx\n",address);
2173         printk(KERN_ALERT " printing eip:\n");
2174         printk("%08lx\n", regs->eip);
2175 -       asm("movl %%cr3,%0":"=r" (page));
2176 -       page = ((unsigned long *) __va(page))[address >> 22];
2177 -       printk(KERN_ALERT "*pde = %08lx\n", page);
2178 -       /*
2179 -        * We must not directly access the pte in the highpte
2180 -        * case, the page table might be allocated in highmem.
2181 -        * And lets rather not kmap-atomic the pte, just in case
2182 -        * it's allocated already.
2183 -        */
2184 +       {
2185 +               unsigned long index = pgd_index(address);
2186 +               unsigned long pgd_paddr;
2187 +               pgd_t *pgd;
2188 +               pud_t *pud;
2189 +               pmd_t *pmd;
2190 +               pte_t *pte;
2191 +
2192 +               asm("movl %%cr3,%0":"=r" (pgd_paddr));
2193 +               pgd = index + (pgd_t *)__va(pgd_paddr);
2194 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
2195 +               if (pgd_present(*pgd)) {
2196 +                       pud = pud_offset(pgd, address);
2197 +                       pmd = pmd_offset(pud, address);
2198 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
2199 +                       /*
2200 +                        * We must not directly access the pte in the highpte
2201 +                        * case, the page table might be allocated in highmem.
2202 +                        * And lets rather not kmap-atomic the pte, just in case
2203 +                        * it's allocated already.
2204 +                        */
2205  #ifndef CONFIG_HIGHPTE
2206 -       if (page & 1) {
2207 -               page &= PAGE_MASK;
2208 -               address &= 0x003ff000;
2209 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
2210 -               printk(KERN_ALERT "*pte = %08lx\n", page);
2211 -       }
2212 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
2213 +                               pte = pte_offset_kernel(pmd, address);
2214 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
2215 +                       }
2216  #endif
2217 +               }
2218 +       }
2219         die("Oops", regs, error_code);
2220         bust_spinlocks(0);
2221         do_exit(SIGKILL);
2222 @@ -513,7 +694,7 @@ vmalloc_fault:
2223                  * Do _not_ use "tsk" here. We might be inside
2224                  * an interrupt in the middle of a task switch..
2225                  */
2226 -               int index = pgd_index(address);
2227 +               unsigned long index = pgd_index(address);
2228                 unsigned long pgd_paddr;
2229                 pgd_t *pgd, *pgd_k;
2230                 pud_t *pud, *pud_k;
2231 @@ -550,3 +731,255 @@ vmalloc_fault:
2232                 return;
2233         }
2234  }
2235 +
2236 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
2237 +/*
2238 + * PaX: decide what to do with offenders (regs->eip = fault address)
2239 + *
2240 + * returns 1 when task should be killed
2241 + *         2 when gcc trampoline was detected
2242 + *         3 when legitimate ET_EXEC was detected
2243 + */
2244 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2245 +{
2246 +
2247 +#ifdef CONFIG_PAX_EMUTRAMP
2248 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
2249 +#endif
2250 +
2251 +#if defined(CONFIG_PAX_RANDEXEC) || defined(CONFIG_PAX_EMUTRAMP)
2252 +       int err;
2253 +#endif
2254 +
2255 +       if (regs->eflags & X86_EFLAGS_VM)
2256 +               return 1;
2257 +
2258 +#ifdef CONFIG_PAX_RANDEXEC
2259 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
2260 +               unsigned long esp_4;
2261 +
2262 +               if (regs->eip >= current->mm->start_code &&
2263 +                   regs->eip < current->mm->end_code)
2264 +               {
2265 +                       err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
2266 +                       if (err || esp_4 == regs->eip)
2267 +                               return 1;
2268 +
2269 +                       regs->eip += current->mm->delta_exec;
2270 +                       return 3;
2271 +               }
2272 +       }
2273 +#endif
2274 +
2275 +       if (!(current->mm->flags & MF_PAX_EMUTRAMP))
2276 +               return 1;
2277 +
2278 +#ifdef CONFIG_PAX_EMUTRAMP
2279 +       do { /* PaX: gcc trampoline emulation #1 */
2280 +               unsigned char mov1, mov2;
2281 +               unsigned short jmp;
2282 +               unsigned long addr1, addr2, ret;
2283 +               unsigned short call;
2284 +
2285 +               err = get_user(mov1, (unsigned char *)regs->eip);
2286 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
2287 +               err |= get_user(mov2, (unsigned char *)(regs->eip + 5));
2288 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
2289 +               err |= get_user(jmp, (unsigned short *)(regs->eip + 10));
2290 +               err |= get_user(ret, (unsigned long *)regs->esp);
2291 +
2292 +               if (err)
2293 +                       break;
2294 +
2295 +               err = get_user(call, (unsigned short *)(ret-2));
2296 +               if (err)
2297 +                       break;
2298 +
2299 +               if ((mov1 & 0xF8) == 0xB8 &&
2300 +                   (mov2 & 0xF8) == 0xB8 &&
2301 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
2302 +                   (jmp & 0xF8FF) == 0xE0FF &&
2303 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
2304 +                   (call & 0xF8FF) == 0xD0FF &&
2305 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
2306 +               {
2307 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
2308 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
2309 +                       regs->eip = addr2;
2310 +                       return 2;
2311 +               }
2312 +       } while (0);
2313 +
2314 +       do { /* PaX: gcc trampoline emulation #2 */
2315 +               unsigned char mov, jmp;
2316 +               unsigned long addr1, addr2, ret;
2317 +               unsigned short call;
2318 +
2319 +               err = get_user(mov, (unsigned char *)regs->eip);
2320 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
2321 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
2322 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
2323 +               err |= get_user(ret, (unsigned long *)regs->esp);
2324 +
2325 +               if (err)
2326 +                       break;
2327 +
2328 +               err = get_user(call, (unsigned short *)(ret-2));
2329 +               if (err)
2330 +                       break;
2331 +
2332 +               if ((mov & 0xF8) == 0xB8 &&
2333 +                   jmp == 0xE9 &&
2334 +                   (call & 0xF8FF) == 0xD0FF &&
2335 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
2336 +               {
2337 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
2338 +                       regs->eip += addr2 + 10;
2339 +                       return 2;
2340 +               }
2341 +       } while (0);
2342 +
2343 +       do { /* PaX: gcc trampoline emulation #3 */
2344 +               unsigned char mov, jmp;
2345 +               char offset;
2346 +               unsigned long addr1, addr2, ret;
2347 +               unsigned short call;
2348 +
2349 +               err = get_user(mov, (unsigned char *)regs->eip);
2350 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
2351 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
2352 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
2353 +               err |= get_user(ret, (unsigned long *)regs->esp);
2354 +
2355 +               if (err)
2356 +                       break;
2357 +
2358 +               err = get_user(call, (unsigned short *)(ret-3));
2359 +               err |= get_user(offset, (char *)(ret-1));
2360 +               if (err)
2361 +                       break;
2362 +
2363 +               if ((mov & 0xF8) == 0xB8 &&
2364 +                   jmp == 0xE9 &&
2365 +                   call == 0x55FF)
2366 +               {
2367 +                       unsigned long addr;
2368 +
2369 +                       err = get_user(addr, (unsigned long*)(regs->ebp + (unsigned long)(long)offset));
2370 +                       if (err || regs->eip != addr)
2371 +                               break;
2372 +
2373 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
2374 +                       regs->eip += addr2 + 10;
2375 +                       return 2;
2376 +               }
2377 +       } while (0);
2378 +
2379 +       do { /* PaX: gcc trampoline emulation #4 */
2380 +               unsigned char mov, jmp, sib;
2381 +               char offset;
2382 +               unsigned long addr1, addr2, ret;
2383 +               unsigned short call;
2384 +
2385 +               err = get_user(mov, (unsigned char *)regs->eip);
2386 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
2387 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
2388 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
2389 +               err |= get_user(ret, (unsigned long *)regs->esp);
2390 +
2391 +               if (err)
2392 +                       break;
2393 +
2394 +               err = get_user(call, (unsigned short *)(ret-4));
2395 +               err |= get_user(sib, (unsigned char *)(ret-2));
2396 +               err |= get_user(offset, (char *)(ret-1));
2397 +               if (err)
2398 +                       break;
2399 +
2400 +               if ((mov & 0xF8) == 0xB8 &&
2401 +                   jmp == 0xE9 &&
2402 +                   call == 0x54FF &&
2403 +                   sib == 0x24)
2404 +               {
2405 +                       unsigned long addr;
2406 +
2407 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + (unsigned long)(long)offset));
2408 +                       if (err || regs->eip != addr)
2409 +                               break;
2410 +
2411 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
2412 +                       regs->eip += addr2 + 10;
2413 +                       return 2;
2414 +               }
2415 +       } while (0);
2416 +
2417 +       do { /* PaX: gcc trampoline emulation #5 */
2418 +               unsigned char mov, jmp, sib;
2419 +               unsigned long addr1, addr2, ret, offset;
2420 +               unsigned short call;
2421 +
2422 +               err = get_user(mov, (unsigned char *)regs->eip);
2423 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
2424 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
2425 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
2426 +               err |= get_user(ret, (unsigned long *)regs->esp);
2427 +
2428 +               if (err)
2429 +                       break;
2430 +
2431 +               err = get_user(call, (unsigned short *)(ret-7));
2432 +               err |= get_user(sib, (unsigned char *)(ret-5));
2433 +               err |= get_user(offset, (unsigned long *)(ret-4));
2434 +               if (err)
2435 +                       break;
2436 +
2437 +               if ((mov & 0xF8) == 0xB8 &&
2438 +                   jmp == 0xE9 &&
2439 +                   call == 0x94FF &&
2440 +                   sib == 0x24)
2441 +               {
2442 +                       unsigned long addr;
2443 +
2444 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + offset));
2445 +                       if (err || regs->eip != addr)
2446 +                               break;
2447 +
2448 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
2449 +                       regs->eip += addr2 + 10;
2450 +                       return 2;
2451 +               }
2452 +       } while (0);
2453 +#endif
2454 +
2455 +       return 1; /* PaX in action */
2456 +}
2457 +#endif
2458 +
2459 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2460 +void pax_report_insns(void *pc, void *sp)
2461 +{
2462 +       unsigned long i;
2463 +
2464 +       printk(KERN_ERR "PAX: bytes at PC: ");
2465 +       for (i = 0; i < 20; i++) {
2466 +               unsigned char c;
2467 +               if (get_user(c, (unsigned char*)pc+i)) {
2468 +                       printk("<invalid address>.");
2469 +                       break;
2470 +               }
2471 +               printk("%02x ", c);
2472 +       }
2473 +       printk("\n");
2474 +
2475 +       printk(KERN_ERR "PAX: bytes at SP: ");
2476 +       for (i = 0; i < 20; i++) {
2477 +               unsigned long c;
2478 +               if (get_user(c, (unsigned long*)sp+i)) {
2479 +                       printk("<invalid address>.");
2480 +                       break;
2481 +               }
2482 +               printk("%08lx ", c);
2483 +       }
2484 +       printk("\n");
2485 +}
2486 +#endif
2487 diff -urNp linux-2.6.11/arch/i386/mm/init.c linux-2.6.11/arch/i386/mm/init.c
2488 --- linux-2.6.11/arch/i386/mm/init.c    2005-03-02 02:38:17.000000000 -0500
2489 +++ linux-2.6.11/arch/i386/mm/init.c    2005-03-09 11:56:44.000000000 -0500
2490 @@ -39,6 +39,7 @@
2491  #include <asm/tlb.h>
2492  #include <asm/tlbflush.h>
2493  #include <asm/sections.h>
2494 +#include <asm/desc.h>
2495  
2496  unsigned int __VMALLOC_RESERVE = 128 << 20;
2497  
2498 @@ -48,30 +49,6 @@ unsigned long highstart_pfn, highend_pfn
2499  static int noinline do_test_wp_bit(void);
2500  
2501  /*
2502 - * Creates a middle page table and puts a pointer to it in the
2503 - * given global directory entry. This only returns the gd entry
2504 - * in non-PAE compilation mode, since the middle layer is folded.
2505 - */
2506 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
2507 -{
2508 -       pud_t *pud;
2509 -       pmd_t *pmd_table;
2510 -               
2511 -#ifdef CONFIG_X86_PAE
2512 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
2513 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
2514 -       pud = pud_offset(pgd, 0);
2515 -       if (pmd_table != pmd_offset(pud, 0)) 
2516 -               BUG();
2517 -#else
2518 -       pud = pud_offset(pgd, 0);
2519 -       pmd_table = pmd_offset(pud, 0);
2520 -#endif
2521 -
2522 -       return pmd_table;
2523 -}
2524 -
2525 -/*
2526   * Create a page table and place a pointer to it in a middle page
2527   * directory entry.
2528   */
2529 @@ -114,8 +91,6 @@ static void __init page_table_range_init
2530         pgd = pgd_base + pgd_idx;
2531  
2532         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
2533 -               if (pgd_none(*pgd)) 
2534 -                       one_md_table_init(pgd);
2535                 pud = pud_offset(pgd, vaddr);
2536                 pmd = pmd_offset(pud, vaddr);
2537                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
2538 @@ -144,6 +119,7 @@ static void __init kernel_physical_mappi
2539  {
2540         unsigned long pfn;
2541         pgd_t *pgd;
2542 +       pud_t *pud;
2543         pmd_t *pmd;
2544         pte_t *pte;
2545         int pgd_idx, pmd_idx, pte_ofs;
2546 @@ -153,7 +129,8 @@ static void __init kernel_physical_mappi
2547         pfn = 0;
2548  
2549         for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
2550 -               pmd = one_md_table_init(pgd);
2551 +               pud = pud_offset(pgd, 0);
2552 +               pmd = pmd_offset(pud, 0);
2553                 if (pfn >= max_low_pfn)
2554                         continue;
2555                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
2556 @@ -312,13 +289,6 @@ static void __init pagetable_init (void)
2557         unsigned long vaddr;
2558         pgd_t *pgd_base = swapper_pg_dir;
2559  
2560 -#ifdef CONFIG_X86_PAE
2561 -       int i;
2562 -       /* Init entries of the first-level page table to the zero page */
2563 -       for (i = 0; i < PTRS_PER_PGD; i++)
2564 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
2565 -#endif
2566 -
2567         /* Enable PSE if available */
2568         if (cpu_has_pse) {
2569                 set_in_cr4(X86_CR4_PSE);
2570 @@ -342,17 +312,6 @@ static void __init pagetable_init (void)
2571         page_table_range_init(vaddr, 0, pgd_base);
2572  
2573         permanent_kmaps_init(pgd_base);
2574 -
2575 -#ifdef CONFIG_X86_PAE
2576 -       /*
2577 -        * Add low memory identity-mappings - SMP needs it when
2578 -        * starting up on an AP from real-mode. In the non-PAE
2579 -        * case we already have these mappings through head.S.
2580 -        * All user-space mappings are explicitly cleared after
2581 -        * SMP startup.
2582 -        */
2583 -       pgd_base[0] = pgd_base[USER_PTRS_PER_PGD];
2584 -#endif
2585  }
2586  
2587  #if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND)
2588 @@ -386,11 +345,7 @@ void zap_low_mappings (void)
2589          * us, because pgd_clear() is a no-op on i386.
2590          */
2591         for (i = 0; i < USER_PTRS_PER_PGD; i++)
2592 -#ifdef CONFIG_X86_PAE
2593 -               set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
2594 -#else
2595                 set_pgd(swapper_pg_dir+i, __pgd(0));
2596 -#endif
2597         flush_tlb_all();
2598  }
2599  
2600 @@ -508,15 +463,17 @@ void __init paging_init(void)
2601  
2602         load_cr3(swapper_pg_dir);
2603  
2604 +       __flush_tlb_all();
2605 +
2606 +#ifdef CONFIG_PAX_KERNEXEC
2607 +
2608  #ifdef CONFIG_X86_PAE
2609 -       /*
2610 -        * We will bail out later - printk doesn't work right now so
2611 -        * the user would just see a hanging kernel.
2612 -        */
2613 -       if (cpu_has_pae)
2614 -               set_in_cr4(X86_CR4_PAE);
2615 +       memcpy(kernexec_pm_dir, swapper_pm_dir, sizeof(kernexec_pm_dir));
2616 +#else
2617 +       memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
2618 +#endif
2619 +
2620  #endif
2621 -       __flush_tlb_all();
2622  
2623         kmap_init();
2624         zone_sizes_init();
2625 @@ -611,7 +568,7 @@ void __init mem_init(void)
2626         set_highmem_pages_init(bad_ppro);
2627  
2628         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
2629 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
2630 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
2631         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
2632  
2633         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
2634 @@ -628,10 +585,6 @@ void __init mem_init(void)
2635                 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
2636                );
2637  
2638 -#ifdef CONFIG_X86_PAE
2639 -       if (!cpu_has_pae)
2640 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
2641 -#endif
2642         if (boot_cpu_data.wp_works_ok < 0)
2643                 test_wp_bit();
2644  
2645 @@ -702,6 +655,46 @@ void free_initmem(void)
2646  {
2647         unsigned long addr;
2648  
2649 +#ifdef CONFIG_PAX_KERNEXEC
2650 +       /* PaX: limit KERNEL_CS to actual size */
2651 +       {
2652 +               unsigned long limit;
2653 +               int cpu;
2654 +               pgd_t *pgd;
2655 +               pud_t *pud;
2656 +               pmd_t *pmd;
2657 +
2658 +               limit = (unsigned long)&_etext >> PAGE_SHIFT;
2659 +               for (cpu = 0; cpu < NR_CPUS; cpu++) {
2660 +                       cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
2661 +                       cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
2662 +               }
2663 +
2664 +       /* PaX: make KERNEL_CS read-only */
2665 +               for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
2666 +                       pgd = pgd_offset_k(addr);
2667 +                       pud = pud_offset(pgd, addr);
2668 +                       pmd = pmd_offset(pud, addr);
2669 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_GLOBAL));
2670 +               }
2671 +
2672 +#ifdef CONFIG_X86_PAE
2673 +               memcpy(kernexec_pm_dir, swapper_pm_dir, sizeof(kernexec_pm_dir));
2674 +#else
2675 +               memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
2676 +#endif
2677 +
2678 +               for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
2679 +                       pgd = pgd_offset_k(addr);
2680 +                       pud = pud_offset(pgd, addr);
2681 +                       pmd = pmd_offset(pud, addr);
2682 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
2683 +               }
2684 +               flush_tlb_all();
2685 +       }
2686 +#endif
2687 +
2688 +       memset(__init_begin, 0, (unsigned long)&__init_end - (unsigned long)&__init_begin);
2689         addr = (unsigned long)(&__init_begin);
2690         for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
2691                 ClearPageReserved(virt_to_page(addr));
2692 diff -urNp linux-2.6.11/arch/i386/mm/mmap.c linux-2.6.11/arch/i386/mm/mmap.c
2693 --- linux-2.6.11/arch/i386/mm/mmap.c    2005-03-02 02:38:08.000000000 -0500
2694 +++ linux-2.6.11/arch/i386/mm/mmap.c    2005-03-09 11:56:44.000000000 -0500
2695 @@ -38,13 +38,19 @@
2696  static inline unsigned long mmap_base(struct mm_struct *mm)
2697  {
2698         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
2699 +       unsigned long task_size = TASK_SIZE;
2700 +
2701 +#ifdef CONFIG_PAX_SEGMEXEC
2702 +       if (mm->flags & MF_PAX_SEGMEXEC)
2703 +               task_size = SEGMEXEC_TASK_SIZE;
2704 +#endif
2705  
2706         if (gap < MIN_GAP)
2707                 gap = MIN_GAP;
2708         else if (gap > MAX_GAP)
2709                 gap = MAX_GAP;
2710  
2711 -       return TASK_SIZE - (gap & PAGE_MASK);
2712 +       return task_size - (gap & PAGE_MASK);
2713  }
2714  
2715  /*
2716 @@ -61,10 +67,22 @@ void arch_pick_mmap_layout(struct mm_str
2717                         (current->personality & ADDR_COMPAT_LAYOUT) ||
2718                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
2719                 mm->mmap_base = TASK_UNMAPPED_BASE;
2720 +
2721 +#ifdef CONFIG_PAX_RANDMMAP
2722 +               if (mm->flags & MF_PAX_RANDMMAP)
2723 +                       mm->mmap_base += mm->delta_mmap;
2724 +#endif
2725 +
2726                 mm->get_unmapped_area = arch_get_unmapped_area;
2727                 mm->unmap_area = arch_unmap_area;
2728         } else {
2729                 mm->mmap_base = mmap_base(mm);
2730 +
2731 +#ifdef CONFIG_PAX_RANDMMAP
2732 +               if (mm->flags & MF_PAX_RANDMMAP)
2733 +                       mm->mmap_base -= mm->delta_mmap;
2734 +#endif
2735 +
2736                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2737                 mm->unmap_area = arch_unmap_area_topdown;
2738         }
2739 diff -urNp linux-2.6.11/arch/i386/pci/pcbios.c linux-2.6.11/arch/i386/pci/pcbios.c
2740 --- linux-2.6.11/arch/i386/pci/pcbios.c 2005-03-02 02:38:34.000000000 -0500
2741 +++ linux-2.6.11/arch/i386/pci/pcbios.c 2005-03-09 11:56:44.000000000 -0500
2742 @@ -6,7 +6,7 @@
2743  #include <linux/init.h>
2744  #include "pci.h"
2745  #include "pci-functions.h"
2746 -
2747 +#include <asm/desc.h>
2748  
2749  /* BIOS32 signature: "_32_" */
2750  #define BIOS32_SIGNATURE       (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
2751 diff -urNp linux-2.6.11/arch/i386/power/cpu.c linux-2.6.11/arch/i386/power/cpu.c
2752 --- linux-2.6.11/arch/i386/power/cpu.c  2005-03-02 02:38:18.000000000 -0500
2753 +++ linux-2.6.11/arch/i386/power/cpu.c  2005-03-09 11:56:44.000000000 -0500
2754 @@ -83,10 +83,9 @@ do_fpu_end(void)
2755  static void fix_processor_context(void)
2756  {
2757         int cpu = smp_processor_id();
2758 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
2759 +       struct tss_struct * t = init_tss + cpu;
2760  
2761         set_tss_desc(cpu,t);    /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
2762 -        per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TSS].b &= 0xfffffdff;
2763  
2764         load_TR_desc();                         /* This does ltr */
2765         load_LDT(&current->active_mm->context); /* This does lldt */
2766 diff -urNp linux-2.6.11/arch/ia64/ia32/binfmt_elf32.c linux-2.6.11/arch/ia64/ia32/binfmt_elf32.c
2767 --- linux-2.6.11/arch/ia64/ia32/binfmt_elf32.c  2005-03-02 02:38:38.000000000 -0500
2768 +++ linux-2.6.11/arch/ia64/ia32/binfmt_elf32.c  2005-03-09 11:56:44.000000000 -0500
2769 @@ -43,6 +43,17 @@ static void elf32_set_personality (void)
2770  
2771  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
2772  
2773 +#ifdef CONFIG_PAX_ASLR
2774 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
2775 +
2776 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
2777 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
2778 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
2779 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
2780 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
2781 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
2782 +#endif
2783 +
2784  /* Ugly but avoids duplication */
2785  #include "../../../fs/binfmt_elf.c"
2786  
2787 diff -urNp linux-2.6.11/arch/ia64/ia32/ia32priv.h linux-2.6.11/arch/ia64/ia32/ia32priv.h
2788 --- linux-2.6.11/arch/ia64/ia32/ia32priv.h      2005-03-02 02:38:32.000000000 -0500
2789 +++ linux-2.6.11/arch/ia64/ia32/ia32priv.h      2005-03-09 11:56:44.000000000 -0500
2790 @@ -326,10 +326,17 @@ struct old_linux32_dirent {
2791  #define ELF_ARCH       EM_386
2792  
2793  #define IA32_PAGE_OFFSET       0xc0000000
2794 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
2795  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
2796  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
2797  
2798 +#ifdef CONFIG_PAX_RANDUSTACK
2799 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
2800 +#else
2801 +#define __IA32_DELTA_STACK     0UL
2802 +#endif
2803 +
2804 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
2805 +
2806  /*
2807   * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
2808   * access them.
2809 diff -urNp linux-2.6.11/arch/ia64/ia32/sys_ia32.c linux-2.6.11/arch/ia64/ia32/sys_ia32.c
2810 --- linux-2.6.11/arch/ia64/ia32/sys_ia32.c      2005-03-02 02:38:12.000000000 -0500
2811 +++ linux-2.6.11/arch/ia64/ia32/sys_ia32.c      2005-03-09 11:56:44.000000000 -0500
2812 @@ -939,6 +939,11 @@ sys32_mmap (struct mmap_arg_struct __use
2813  
2814         flags = a.flags;
2815  
2816 +#ifdef CONFIG_PAX_RANDEXEC
2817 +       if (flags & MAP_MIRROR)
2818 +               return -EINVAL;
2819 +#endif
2820 +
2821         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2822         if (!(flags & MAP_ANONYMOUS)) {
2823                 file = fget(a.fd);
2824 @@ -960,6 +965,11 @@ sys32_mmap2 (unsigned int addr, unsigned
2825         struct file *file = NULL;
2826         unsigned long retval;
2827  
2828 +#ifdef CONFIG_PAX_RANDEXEC
2829 +       if (flags & MAP_MIRROR)
2830 +               return -EINVAL;
2831 +#endif
2832 +
2833         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2834         if (!(flags & MAP_ANONYMOUS)) {
2835                 file = fget(fd);
2836 diff -urNp linux-2.6.11/arch/ia64/kernel/ptrace.c linux-2.6.11/arch/ia64/kernel/ptrace.c
2837 --- linux-2.6.11/arch/ia64/kernel/ptrace.c      2005-03-02 02:38:33.000000000 -0500
2838 +++ linux-2.6.11/arch/ia64/kernel/ptrace.c      2005-03-09 11:56:44.000000000 -0500
2839 @@ -17,6 +17,7 @@
2840  #include <linux/user.h>
2841  #include <linux/security.h>
2842  #include <linux/audit.h>
2843 +#include <linux/grsecurity.h>
2844  
2845  #include <asm/pgtable.h>
2846  #include <asm/processor.h>
2847 @@ -1424,6 +1425,9 @@ sys_ptrace (long request, pid_t pid, uns
2848         if (pid == 1)           /* no messing around with init! */
2849                 goto out_tsk;
2850  
2851 +       if (gr_handle_ptrace(child, request))
2852 +               goto out_tsk;
2853 +
2854         if (request == PTRACE_ATTACH) {
2855                 ret = ptrace_attach(child);
2856                 goto out_tsk;
2857 diff -urNp linux-2.6.11/arch/ia64/kernel/sys_ia64.c linux-2.6.11/arch/ia64/kernel/sys_ia64.c
2858 --- linux-2.6.11/arch/ia64/kernel/sys_ia64.c    2005-03-02 02:38:10.000000000 -0500
2859 +++ linux-2.6.11/arch/ia64/kernel/sys_ia64.c    2005-03-09 11:56:44.000000000 -0500
2860 @@ -27,7 +27,7 @@ arch_get_unmapped_area (struct file *fil
2861                         unsigned long pgoff, unsigned long flags)
2862  {
2863         long map_shared = (flags & MAP_SHARED);
2864 -       unsigned long start_addr, align_mask = PAGE_SIZE - 1;
2865 +       unsigned long start_addr, align_mask = PAGE_SIZE - 1, task_unmapped_base = TASK_UNMAPPED_BASE;
2866         struct mm_struct *mm = current->mm;
2867         struct vm_area_struct *vma;
2868  
2869 @@ -38,6 +38,15 @@ arch_get_unmapped_area (struct file *fil
2870         if (REGION_NUMBER(addr) == REGION_HPAGE)
2871                 addr = 0;
2872  #endif
2873 +
2874 +#ifdef CONFIG_PAX_RANDMMAP
2875 +       if (mm->flags & MF_PAX_RANDMMAP)
2876 +               task_unmapped_base += mm->delta_mmap;
2877 +       if ((mm->flags & MF_PAX_RANDMMAP) && addr && filp)
2878 +               addr = mm->free_area_cache;
2879 +       else
2880 +#endif
2881 +
2882         if (!addr)
2883                 addr = mm->free_area_cache;
2884  
2885 @@ -56,9 +65,9 @@ arch_get_unmapped_area (struct file *fil
2886         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2887                 /* At this point:  (!vma || addr < vma->vm_end). */
2888                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
2889 -                       if (start_addr != TASK_UNMAPPED_BASE) {
2890 +                       if (start_addr != task_unmapped_base) {
2891                                 /* Start a new search --- just in case we missed some holes.  */
2892 -                               addr = TASK_UNMAPPED_BASE;
2893 +                               addr = task_unmapped_base;
2894                                 goto full_search;
2895                         }
2896                         return -ENOMEM;
2897 @@ -184,6 +193,11 @@ do_mmap2 (unsigned long addr, unsigned l
2898         unsigned long roff;
2899         struct file *file = NULL;
2900  
2901 +#ifdef CONFIG_PAX_RANDEXEC
2902 +       if (flags & MAP_MIRROR)
2903 +               return -EINVAL;
2904 +#endif
2905 +
2906         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2907         if (!(flags & MAP_ANONYMOUS)) {
2908                 file = fget(fd);
2909 diff -urNp linux-2.6.11/arch/ia64/mm/fault.c linux-2.6.11/arch/ia64/mm/fault.c
2910 --- linux-2.6.11/arch/ia64/mm/fault.c   2005-03-02 02:38:32.000000000 -0500
2911 +++ linux-2.6.11/arch/ia64/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
2912 @@ -9,6 +9,7 @@
2913  #include <linux/mm.h>
2914  #include <linux/smp_lock.h>
2915  #include <linux/interrupt.h>
2916 +#include <linux/binfmts.h>
2917  
2918  #include <asm/pgtable.h>
2919  #include <asm/processor.h>
2920 @@ -35,6 +36,10 @@ expand_backing_store (struct vm_area_str
2921         if (address - vma->vm_start > current->signal->rlim[RLIMIT_STACK].rlim_cur
2922             || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->signal->rlim[RLIMIT_AS].rlim_cur))
2923                 return -ENOMEM;
2924 +       if ((vma->vm_flags & VM_LOCKED) &&
2925 +           ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) > current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur &&
2926 +           !capable(CAP_IPC_LOCK))
2927 +               return -ENOMEM;
2928         vma->vm_end += PAGE_SIZE;
2929         vma->vm_mm->total_vm += grow;
2930         if (vma->vm_flags & VM_LOCKED)
2931 @@ -75,6 +80,54 @@ mapped_kernel_page_is_present (unsigned 
2932         return pte_present(pte);
2933  }
2934  
2935 +#ifdef CONFIG_PAX_PAGEEXEC
2936 +/*
2937 + * PaX: decide what to do with offenders (regs->cr_iip = fault address)
2938 + *
2939 + * returns 1 when task should be killed
2940 + *         2 when legitimate ET_EXEC was detected
2941 + */
2942 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2943 +{
2944 +
2945 +#ifdef CONFIG_PAX_RANDEXEC
2946 +       int err;
2947 +
2948 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
2949 +               if (regs->cr_iip >= current->mm->start_code &&
2950 +                   regs->cr_iip < current->mm->end_code)
2951 +               {
2952 +#if 0
2953 +                       /* PaX: this needs fixing */
2954 +                       if (regs->b0 == regs->cr_iip)
2955 +                               return 1;
2956 +#endif
2957 +                       regs->cr_iip += current->mm->delta_exec;
2958 +                       return 2;
2959 +               }
2960 +       }
2961 +#endif
2962 +
2963 +       return 1;
2964 +}
2965 +
2966 +void pax_report_insns(void *pc, void *sp)
2967 +{
2968 +       unsigned long i;
2969 +
2970 +       printk(KERN_ERR "PAX: bytes at PC: ");
2971 +       for (i = 0; i < 8; i++) {
2972 +               unsigned int c;
2973 +               if (get_user(c, (unsigned int*)pc+i)) {
2974 +                       printk("<invalid address>.");
2975 +                       break;
2976 +               }
2977 +               printk("%08x ", c);
2978 +       }
2979 +       printk("\n");
2980 +}
2981 +#endif
2982 +
2983  void
2984  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
2985  {
2986 @@ -130,9 +183,31 @@ ia64_do_page_fault (unsigned long addres
2987                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
2988                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
2989  
2990 -       if ((vma->vm_flags & mask) != mask)
2991 +       if ((vma->vm_flags & mask) != mask) {
2992 +
2993 +#ifdef CONFIG_PAX_PAGEEXEC
2994 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
2995 +                       if (!(mm->flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
2996 +                               goto bad_area;
2997 +
2998 +                       up_read(&mm->mmap_sem);
2999 +                       switch(pax_handle_fetch_fault(regs)) {
3000 +
3001 +#ifdef CONFIG_PAX_RANDEXEC
3002 +                       case 2:
3003 +                               return;
3004 +#endif
3005 +
3006 +                       }
3007 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
3008 +                       do_exit(SIGKILL);
3009 +               }
3010 +#endif
3011 +
3012                 goto bad_area;
3013  
3014 +       }
3015 +
3016    survive:
3017         /*
3018          * If for any reason at all we couldn't handle the fault, make
3019 @@ -169,7 +244,7 @@ ia64_do_page_fault (unsigned long addres
3020                 if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
3021                     || REGION_OFFSET(address) >= RGN_MAP_LIMIT)
3022                         goto bad_area;
3023 -               if (expand_stack(vma, address))
3024 +               if (expand_stack(current, vma, address))
3025                         goto bad_area;
3026         } else {
3027                 vma = prev_vma;
3028 diff -urNp linux-2.6.11/arch/m32r/mm/fault.c linux-2.6.11/arch/m32r/mm/fault.c
3029 --- linux-2.6.11/arch/m32r/mm/fault.c   2005-03-02 02:37:52.000000000 -0500
3030 +++ linux-2.6.11/arch/m32r/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
3031 @@ -186,7 +186,7 @@ asmlinkage void do_page_fault(struct pt_
3032                         goto bad_area;
3033         }
3034  #endif
3035 -       if (expand_stack(vma, address))
3036 +       if (expand_stack(tsk, vma, address))
3037                 goto bad_area;
3038  /*
3039   * Ok, we have a good vm_area for this memory access, so
3040 diff -urNp linux-2.6.11/arch/m68k/mm/fault.c linux-2.6.11/arch/m68k/mm/fault.c
3041 --- linux-2.6.11/arch/m68k/mm/fault.c   2005-03-02 02:38:08.000000000 -0500
3042 +++ linux-2.6.11/arch/m68k/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
3043 @@ -121,7 +121,7 @@ int do_page_fault(struct pt_regs *regs, 
3044                 if (address + 256 < rdusp())
3045                         goto map_err;
3046         }
3047 -       if (expand_stack(vma, address))
3048 +       if (expand_stack(current, vma, address))
3049                 goto map_err;
3050  
3051  /*
3052 diff -urNp linux-2.6.11/arch/mips/kernel/binfmt_elfn32.c linux-2.6.11/arch/mips/kernel/binfmt_elfn32.c
3053 --- linux-2.6.11/arch/mips/kernel/binfmt_elfn32.c       2005-03-02 02:38:10.000000000 -0500
3054 +++ linux-2.6.11/arch/mips/kernel/binfmt_elfn32.c       2005-03-09 11:56:44.000000000 -0500
3055 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
3056  #undef ELF_ET_DYN_BASE
3057  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
3058  
3059 +#ifdef CONFIG_PAX_ASLR
3060 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
3061 +
3062 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
3063 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3064 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
3065 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3066 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
3067 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3068 +#endif
3069 +
3070  #include <asm/processor.h>
3071  #include <linux/module.h>
3072  #include <linux/config.h>
3073 diff -urNp linux-2.6.11/arch/mips/kernel/binfmt_elfo32.c linux-2.6.11/arch/mips/kernel/binfmt_elfo32.c
3074 --- linux-2.6.11/arch/mips/kernel/binfmt_elfo32.c       2005-03-02 02:37:55.000000000 -0500
3075 +++ linux-2.6.11/arch/mips/kernel/binfmt_elfo32.c       2005-03-09 11:56:44.000000000 -0500
3076 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
3077  #undef ELF_ET_DYN_BASE
3078  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
3079  
3080 +#ifdef CONFIG_PAX_ASLR
3081 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
3082 +
3083 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
3084 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3085 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
3086 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3087 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
3088 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3089 +#endif
3090 +
3091  #include <asm/processor.h>
3092  #include <linux/module.h>
3093  #include <linux/config.h>
3094 diff -urNp linux-2.6.11/arch/mips/kernel/syscall.c linux-2.6.11/arch/mips/kernel/syscall.c
3095 --- linux-2.6.11/arch/mips/kernel/syscall.c     2005-03-02 02:38:18.000000000 -0500
3096 +++ linux-2.6.11/arch/mips/kernel/syscall.c     2005-03-09 11:56:44.000000000 -0500
3097 @@ -84,6 +84,11 @@ unsigned long arch_get_unmapped_area(str
3098         do_color_align = 0;
3099         if (filp || (flags & MAP_SHARED))
3100                 do_color_align = 1;
3101 +
3102 +#ifdef CONFIG_PAX_RANDMMAP
3103 +       if (!(current->mm->flags & MF_PAX_RANDMMAP) || !filp)
3104 +#endif
3105 +
3106         if (addr) {
3107                 if (do_color_align)
3108                         addr = COLOUR_ALIGN(addr, pgoff);
3109 @@ -94,6 +99,13 @@ unsigned long arch_get_unmapped_area(str
3110                     (!vmm || addr + len <= vmm->vm_start))
3111                         return addr;
3112         }
3113 +
3114 +#ifdef CONFIG_PAX_RANDMMAP
3115 +       if ((current->mm->flags & MF_PAX_RANDMMAP) && (!addr || filp))
3116 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3117 +       else
3118 +#endif
3119 +
3120         addr = TASK_UNMAPPED_BASE;
3121         if (do_color_align)
3122                 addr = COLOUR_ALIGN(addr, pgoff);
3123 diff -urNp linux-2.6.11/arch/mips/mm/fault.c linux-2.6.11/arch/mips/mm/fault.c
3124 --- linux-2.6.11/arch/mips/mm/fault.c   2005-03-02 02:37:51.000000000 -0500
3125 +++ linux-2.6.11/arch/mips/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
3126 @@ -26,6 +26,24 @@
3127  #include <asm/uaccess.h>
3128  #include <asm/ptrace.h>
3129  
3130 +#ifdef CONFIG_PAX_PAGEEXEC
3131 +void pax_report_insns(void *pc)
3132 +{
3133 +       unsigned long i;
3134 +
3135 +       printk(KERN_ERR "PAX: bytes at PC: ");
3136 +       for (i = 0; i < 5; i++) {
3137 +               unsigned int c;
3138 +               if (get_user(c, (unsigned int*)pc+i)) {
3139 +                       printk("<invalid address>.");
3140 +                       break;
3141 +               }
3142 +               printk("%08x ", c);
3143 +       }
3144 +       printk("\n");
3145 +}
3146 +#endif
3147 +
3148  /*
3149   * This routine handles page faults.  It determines the address,
3150   * and the problem, and then passes it off to one of the appropriate
3151 @@ -75,7 +93,7 @@ asmlinkage void do_page_fault(struct pt_
3152                 goto good_area;
3153         if (!(vma->vm_flags & VM_GROWSDOWN))
3154                 goto bad_area;
3155 -       if (expand_stack(vma, address))
3156 +       if (expand_stack(tsk, vma, address))
3157                 goto bad_area;
3158  /*
3159   * Ok, we have a good vm_area for this memory access, so
3160 diff -urNp linux-2.6.11/arch/parisc/kernel/ptrace.c linux-2.6.11/arch/parisc/kernel/ptrace.c
3161 --- linux-2.6.11/arch/parisc/kernel/ptrace.c    2005-03-02 02:37:48.000000000 -0500
3162 +++ linux-2.6.11/arch/parisc/kernel/ptrace.c    2005-03-09 11:56:44.000000000 -0500
3163 @@ -17,6 +17,7 @@
3164  #include <linux/personality.h>
3165  #include <linux/security.h>
3166  #include <linux/compat.h>
3167 +#include <linux/grsecurity.h>
3168  
3169  #include <asm/uaccess.h>
3170  #include <asm/pgtable.h>
3171 @@ -114,6 +115,9 @@ long sys_ptrace(long request, pid_t pid,
3172         if (pid == 1)           /* no messing around with init! */
3173                 goto out_tsk;
3174  
3175 +       if (gr_handle_ptrace(child, request))
3176 +               goto out_tsk;
3177 +
3178         if (request == PTRACE_ATTACH) {
3179                 ret = ptrace_attach(child);
3180                 goto out_tsk;
3181 diff -urNp linux-2.6.11/arch/parisc/kernel/sys_parisc.c linux-2.6.11/arch/parisc/kernel/sys_parisc.c
3182 --- linux-2.6.11/arch/parisc/kernel/sys_parisc.c        2005-03-02 02:38:25.000000000 -0500
3183 +++ linux-2.6.11/arch/parisc/kernel/sys_parisc.c        2005-03-09 11:56:44.000000000 -0500
3184 @@ -104,6 +104,13 @@ unsigned long arch_get_unmapped_area(str
3185  {
3186         if (len > TASK_SIZE)
3187                 return -ENOMEM;
3188 +
3189 +#ifdef CONFIG_PAX_RANDMMAP
3190 +       if ((current->mm->flags & MF_PAX_RANDMMAP) && (!addr || filp))
3191 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3192 +       else
3193 +#endif
3194 +
3195         if (!addr)
3196                 addr = TASK_UNMAPPED_BASE;
3197  
3198 @@ -123,6 +130,12 @@ static unsigned long do_mmap2(unsigned l
3199  {
3200         struct file * file = NULL;
3201         unsigned long error = -EBADF;
3202 +
3203 +#ifdef CONFIG_PAX_RANDEXEC
3204 +       if (flags & MAP_MIRROR)
3205 +               return -EINVAL;
3206 +#endif
3207 +
3208         if (!(flags & MAP_ANONYMOUS)) {
3209                 file = fget(fd);
3210                 if (!file)
3211 diff -urNp linux-2.6.11/arch/parisc/kernel/traps.c linux-2.6.11/arch/parisc/kernel/traps.c
3212 --- linux-2.6.11/arch/parisc/kernel/traps.c     2005-03-02 02:38:33.000000000 -0500
3213 +++ linux-2.6.11/arch/parisc/kernel/traps.c     2005-03-09 11:56:44.000000000 -0500
3214 @@ -680,9 +680,7 @@ void handle_interruption(int code, struc
3215  
3216                         down_read(&current->mm->mmap_sem);
3217                         vma = find_vma(current->mm,regs->iaoq[0]);
3218 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
3219 -                               && (vma->vm_flags & VM_EXEC)) {
3220 -
3221 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
3222                                 fault_address = regs->iaoq[0];
3223                                 fault_space = regs->iasq[0];
3224  
3225 diff -urNp linux-2.6.11/arch/parisc/mm/fault.c linux-2.6.11/arch/parisc/mm/fault.c
3226 --- linux-2.6.11/arch/parisc/mm/fault.c 2005-03-02 02:38:25.000000000 -0500
3227 +++ linux-2.6.11/arch/parisc/mm/fault.c 2005-03-09 11:56:44.000000000 -0500
3228 @@ -16,6 +16,8 @@
3229  #include <linux/sched.h>
3230  #include <linux/interrupt.h>
3231  #include <linux/module.h>
3232 +#include <linux/unistd.h>
3233 +#include <linux/binfmts.h>
3234  
3235  #include <asm/uaccess.h>
3236  #include <asm/traps.h>
3237 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
3238  static unsigned long
3239  parisc_acctyp(unsigned long code, unsigned int inst)
3240  {
3241 -       if (code == 6 || code == 16)
3242 +       if (code == 6 || code == 7 || code == 16)
3243             return VM_EXEC;
3244  
3245         switch (inst & 0xf0000000) {
3246 @@ -143,6 +145,139 @@ parisc_acctyp(unsigned long code, unsign
3247                         }
3248  #endif
3249  
3250 +#ifdef CONFIG_PAX_PAGEEXEC
3251 +/*
3252 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
3253 + *
3254 + * returns 1 when task should be killed
3255 + *         2 when rt_sigreturn trampoline was detected
3256 + *         3 when unpatched PLT trampoline was detected
3257 + *         4 when legitimate ET_EXEC was detected
3258 + */
3259 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3260 +{
3261 +
3262 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUTRAMP)
3263 +       int err;
3264 +#endif
3265 +
3266 +#ifdef CONFIG_PAX_RANDEXEC
3267 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
3268 +               if (instruction_pointer(regs) >= current->mm->start_code &&
3269 +                   instruction_pointer(regs) < current->mm->end_code)
3270 +               {
3271 +#if 0
3272 +                       /* PaX: this needs fixing */
3273 +                       if ((regs->gr[2] & ~3UL) == instruction_pointer(regs))
3274 +                               return 1;
3275 +#endif
3276 +                       regs->iaoq[0] += current->mm->delta_exec;
3277 +                       if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code &&
3278 +                           (regs->iaoq[1] & ~3UL) < current->mm->end_code)
3279 +                               regs->iaoq[1] += current->mm->delta_exec;
3280 +                       return 4;
3281 +               }
3282 +       }
3283 +#endif
3284 +
3285 +#ifdef CONFIG_PAX_EMUPLT
3286 +       do { /* PaX: unpatched PLT emulation */
3287 +               unsigned int bl, depwi;
3288 +
3289 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
3290 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
3291 +
3292 +               if (err)
3293 +                       break;
3294 +
3295 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
3296 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
3297 +
3298 +                       err = get_user(ldw, (unsigned int*)addr);
3299 +                       err |= get_user(bv, (unsigned int*)(addr+4));
3300 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
3301 +
3302 +                       if (err)
3303 +                               break;
3304 +
3305 +                       if (ldw == 0x0E801096U &&
3306 +                           bv == 0xEAC0C000U &&
3307 +                           ldw2 == 0x0E881095U)
3308 +                       {
3309 +                               unsigned int resolver, map;
3310 +
3311 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
3312 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
3313 +                               if (err)
3314 +                                       break;
3315 +
3316 +                               regs->gr[20] = instruction_pointer(regs)+8;
3317 +                               regs->gr[21] = map;
3318 +                               regs->gr[22] = resolver;
3319 +                               regs->iaoq[0] = resolver | 3UL;
3320 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
3321 +                               return 3;
3322 +                       }
3323 +               }
3324 +       } while (0);
3325 +#endif
3326 +
3327 +#ifdef CONFIG_PAX_EMUTRAMP
3328 +
3329 +#ifndef CONFIG_PAX_EMUSIGRT
3330 +       if (!(current->mm->flags & MF_PAX_EMUTRAMP))
3331 +               return 1;
3332 +#endif
3333 +
3334 +       do { /* PaX: rt_sigreturn emulation */
3335 +               unsigned int ldi1, ldi2, bel, nop;
3336 +
3337 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
3338 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
3339 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
3340 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
3341 +
3342 +               if (err)
3343 +                       break;
3344 +
3345 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
3346 +                   ldi2 == 0x3414015AU &&
3347 +                   bel == 0xE4008200U &&
3348 +                   nop == 0x08000240U)
3349 +               {
3350 +                       regs->gr[25] = (ldi1 & 2) >> 1;
3351 +                       regs->gr[20] = __NR_rt_sigreturn;
3352 +                       regs->gr[31] = regs->iaoq[1] + 16;
3353 +                       regs->sr[0] = regs->iasq[1];
3354 +                       regs->iaoq[0] = 0x100UL;
3355 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
3356 +                       regs->iasq[0] = regs->sr[2];
3357 +                       regs->iasq[1] = regs->sr[2];
3358 +                       return 2;
3359 +               }
3360 +       } while (0);
3361 +#endif
3362 +
3363 +       return 1;
3364 +}
3365 +
3366 +void pax_report_insns(void *pc, void *sp)
3367 +{
3368 +       unsigned long i;
3369 +
3370 +       printk(KERN_ERR "PAX: bytes at PC: ");
3371 +       for (i = 0; i < 5; i++) {
3372 +               unsigned int c;
3373 +               if (get_user(c, (unsigned int*)pc+i)) {
3374 +                       printk("<invalid address>.");
3375 +                       break;
3376 +               }
3377 +               printk("%08x ", c);
3378 +       }
3379 +       printk("\n");
3380 +}
3381 +#endif
3382 +
3383  void do_page_fault(struct pt_regs *regs, unsigned long code,
3384                               unsigned long address)
3385  {
3386 @@ -168,8 +303,38 @@ good_area:
3387  
3388         acc_type = parisc_acctyp(code,regs->iir);
3389  
3390 -       if ((vma->vm_flags & acc_type) != acc_type)
3391 +       if ((vma->vm_flags & acc_type) != acc_type) {
3392 +
3393 +#ifdef CONFIG_PAX_PAGEEXEC
3394 +               if ((mm->flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
3395 +                   (address & ~3UL) == instruction_pointer(regs))
3396 +               {
3397 +                       up_read(&mm->mmap_sem);
3398 +                       switch(pax_handle_fetch_fault(regs)) {
3399 +
3400 +#ifdef CONFIG_PAX_RANDEXEC
3401 +                       case 4:
3402 +                               return;
3403 +#endif
3404 +
3405 +#ifdef CONFIG_PAX_EMUPLT
3406 +                       case 3:
3407 +                               return;
3408 +#endif
3409 +
3410 +#ifdef CONFIG_PAX_EMUTRAMP
3411 +                       case 2:
3412 +                               return;
3413 +#endif
3414 +
3415 +                       }
3416 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
3417 +                       do_exit(SIGKILL);
3418 +               }
3419 +#endif
3420 +
3421                 goto bad_area;
3422 +       }
3423  
3424         /*
3425          * If for any reason at all we couldn't handle the fault, make
3426 @@ -199,7 +364,7 @@ good_area:
3427  
3428  check_expansion:
3429         vma = prev_vma;
3430 -       if (vma && (expand_stack(vma, address) == 0))
3431 +       if (vma && (expand_stack(tsk, vma, address) == 0))
3432                 goto good_area;
3433  
3434  /*
3435 diff -urNp linux-2.6.11/arch/ppc/kernel/ptrace.c linux-2.6.11/arch/ppc/kernel/ptrace.c
3436 --- linux-2.6.11/arch/ppc/kernel/ptrace.c       2005-03-02 02:37:51.000000000 -0500
3437 +++ linux-2.6.11/arch/ppc/kernel/ptrace.c       2005-03-09 11:56:44.000000000 -0500
3438 @@ -26,6 +26,7 @@
3439  #include <linux/ptrace.h>
3440  #include <linux/user.h>
3441  #include <linux/security.h>
3442 +#include <linux/grsecurity.h>
3443  
3444  #include <asm/uaccess.h>
3445  #include <asm/page.h>
3446 @@ -267,6 +268,9 @@ int sys_ptrace(long request, long pid, l
3447         if (pid == 1)           /* you may not mess with init */
3448                 goto out_tsk;
3449  
3450 +       if (gr_handle_ptrace(child, request))
3451 +               goto out_tsk;
3452 +
3453         if (request == PTRACE_ATTACH) {
3454                 ret = ptrace_attach(child);
3455                 goto out_tsk;
3456 diff -urNp linux-2.6.11/arch/ppc/kernel/syscalls.c linux-2.6.11/arch/ppc/kernel/syscalls.c
3457 --- linux-2.6.11/arch/ppc/kernel/syscalls.c     2005-03-02 02:38:26.000000000 -0500
3458 +++ linux-2.6.11/arch/ppc/kernel/syscalls.c     2005-03-09 11:56:44.000000000 -0500
3459 @@ -165,6 +165,11 @@ do_mmap2(unsigned long addr, size_t len,
3460         struct file * file = NULL;
3461         int ret = -EBADF;
3462  
3463 +#ifdef CONFIG_PAX_RANDEXEC
3464 +       if (flags & MAP_MIRROR)
3465 +               return -EINVAL;
3466 +#endif
3467 +
3468         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3469         if (!(flags & MAP_ANONYMOUS)) {
3470                 if (!(file = fget(fd)))
3471 diff -urNp linux-2.6.11/arch/ppc/mm/fault.c linux-2.6.11/arch/ppc/mm/fault.c
3472 --- linux-2.6.11/arch/ppc/mm/fault.c    2005-03-02 02:37:52.000000000 -0500
3473 +++ linux-2.6.11/arch/ppc/mm/fault.c    2005-03-09 11:56:44.000000000 -0500
3474 @@ -28,6 +28,11 @@
3475  #include <linux/interrupt.h>
3476  #include <linux/highmem.h>
3477  #include <linux/module.h>
3478 +#include <linux/slab.h>
3479 +#include <linux/pagemap.h>
3480 +#include <linux/compiler.h>
3481 +#include <linux/binfmts.h>
3482 +#include <linux/unistd.h>
3483  
3484  #include <asm/page.h>
3485  #include <asm/pgtable.h>
3486 @@ -51,6 +56,363 @@ unsigned long pte_misses;   /* updated by 
3487  unsigned long pte_errors;      /* updated by do_page_fault() */
3488  unsigned int probingmem;
3489  
3490 +#ifdef CONFIG_PAX_EMUSIGRT
3491 +void pax_syscall_close(struct vm_area_struct * vma)
3492 +{
3493 +       vma->vm_mm->call_syscall = 0UL;
3494 +}
3495 +
3496 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
3497 +{
3498 +       struct page* page;
3499 +       unsigned int *kaddr;
3500 +
3501 +       page = alloc_page(GFP_HIGHUSER);
3502 +       if (!page)
3503 +               return NOPAGE_OOM;
3504 +
3505 +       kaddr = kmap(page);
3506 +       memset(kaddr, 0, PAGE_SIZE);
3507 +       kaddr[0] = 0x44000002U; /* sc */
3508 +       __flush_dcache_icache(kaddr);
3509 +       kunmap(page);
3510 +       if (type)
3511 +               *type = VM_FAULT_MAJOR;
3512 +       return page;
3513 +}
3514 +
3515 +static struct vm_operations_struct pax_vm_ops = {
3516 +       close:          pax_syscall_close,
3517 +       nopage:         pax_syscall_nopage,
3518 +};
3519 +
3520 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3521 +{
3522 +       memset(vma, 0, sizeof(*vma));
3523 +       vma->vm_mm = current->mm;
3524 +       vma->vm_start = addr;
3525 +       vma->vm_end = addr + PAGE_SIZE;
3526 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3527 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3528 +       vma->vm_ops = &pax_vm_ops;
3529 +       insert_vm_struct(current->mm, vma);
3530 +       ++current->mm->total_vm;
3531 +}
3532 +#endif
3533 +
3534 +#ifdef CONFIG_PAX_PAGEEXEC
3535 +/*
3536 + * PaX: decide what to do with offenders (regs->nip = fault address)
3537 + *
3538 + * returns 1 when task should be killed
3539 + *         2 when patched GOT trampoline was detected
3540 + *         3 when patched PLT trampoline was detected
3541 + *         4 when unpatched PLT trampoline was detected
3542 + *         5 when legitimate ET_EXEC was detected
3543 + *         6 when sigreturn trampoline was detected
3544 + *         7 when rt_sigreturn trampoline was detected
3545 + */
3546 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3547 +{
3548 +
3549 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
3550 +       int err;
3551 +#endif
3552 +
3553 +#ifdef CONFIG_PAX_RANDEXEC
3554 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
3555 +               if (regs->nip >= current->mm->start_code &&
3556 +                   regs->nip < current->mm->end_code)
3557 +               {
3558 +                       if (regs->link == regs->nip)
3559 +                               return 1;
3560 +
3561 +                       regs->nip += current->mm->delta_exec;
3562 +                       return 5;
3563 +               }
3564 +       }
3565 +#endif
3566 +
3567 +#ifdef CONFIG_PAX_EMUPLT
3568 +       do { /* PaX: patched GOT emulation */
3569 +               unsigned int blrl;
3570 +
3571 +               err = get_user(blrl, (unsigned int*)regs->nip);
3572 +
3573 +               if (!err && blrl == 0x4E800021U) {
3574 +                       unsigned long temp = regs->nip;
3575 +
3576 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
3577 +                       regs->link = temp + 4UL;
3578 +                       return 2;
3579 +               }
3580 +       } while (0);
3581 +
3582 +       do { /* PaX: patched PLT emulation #1 */
3583 +               unsigned int b;
3584 +
3585 +               err = get_user(b, (unsigned int *)regs->nip);
3586 +
3587 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
3588 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
3589 +                       return 3;
3590 +               }
3591 +       } while (0);
3592 +
3593 +       do { /* PaX: unpatched PLT emulation #1 */
3594 +               unsigned int li, b;
3595 +
3596 +               err = get_user(li, (unsigned int *)regs->nip);
3597 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
3598 +
3599 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3600 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3601 +                       unsigned long addr = b | 0xFC000000UL;
3602 +
3603 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3604 +                       err = get_user(rlwinm, (unsigned int*)addr);
3605 +                       err |= get_user(add, (unsigned int*)(addr+4));
3606 +                       err |= get_user(li2, (unsigned int*)(addr+8));
3607 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
3608 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
3609 +                       err |= get_user(li3, (unsigned int*)(addr+20));
3610 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
3611 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
3612 +
3613 +                       if (err)
3614 +                               break;
3615 +
3616 +                       if (rlwinm == 0x556C083CU &&
3617 +                           add == 0x7D6C5A14U &&
3618 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
3619 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3620 +                           mtctr == 0x7D8903A6U &&
3621 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
3622 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3623 +                           bctr == 0x4E800420U)
3624 +                       {
3625 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3626 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3627 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3628 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3629 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
3630 +                               regs->nip = regs->ctr;
3631 +                               return 4;
3632 +                       }
3633 +               }
3634 +       } while (0);
3635 +
3636 +#if 0
3637 +       do { /* PaX: unpatched PLT emulation #2 */
3638 +               unsigned int lis, lwzu, b, bctr;
3639 +
3640 +               err = get_user(lis, (unsigned int *)regs->nip);
3641 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
3642 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
3643 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
3644 +
3645 +               if (err)
3646 +                       break;
3647 +
3648 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
3649 +                   (lwzu & 0xU) == 0xU &&
3650 +                   (b & 0xFC000003U) == 0x48000000U &&
3651 +                   bctr == 0x4E800420U)
3652 +               {
3653 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3654 +                       unsigned long addr = b | 0xFC000000UL;
3655 +
3656 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3657 +                       err = get_user(addis, (unsigned int*)addr);
3658 +                       err |= get_user(addi, (unsigned int*)(addr+4));
3659 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
3660 +                       err |= get_user(add, (unsigned int*)(addr+12));
3661 +                       err |= get_user(li2, (unsigned int*)(addr+16));
3662 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
3663 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
3664 +                       err |= get_user(li3, (unsigned int*)(addr+28));
3665 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
3666 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
3667 +
3668 +                       if (err)
3669 +                               break;
3670 +
3671 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3672 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
3673 +                           rlwinm == 0x556C083CU &&
3674 +                           add == 0x7D6C5A14U &&
3675 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
3676 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3677 +                           mtctr == 0x7D8903A6U &&
3678 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
3679 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3680 +                           bctr == 0x4E800420U)
3681 +                       {
3682 +                               regs->gpr[PT_R11] = 
3683 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3684 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3685 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3686 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3687 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
3688 +                               regs->nip = regs->ctr;
3689 +                               return 4;
3690 +                       }
3691 +               }
3692 +       } while (0);
3693 +#endif
3694 +
3695 +       do { /* PaX: unpatched PLT emulation #3 */
3696 +               unsigned int li, b;
3697 +
3698 +               err = get_user(li, (unsigned int *)regs->nip);
3699 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
3700 +
3701 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3702 +                       unsigned int addis, lwz, mtctr, bctr;
3703 +                       unsigned long addr = b | 0xFC000000UL;
3704 +
3705 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3706 +                       err = get_user(addis, (unsigned int*)addr);
3707 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
3708 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
3709 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
3710 +
3711 +                       if (err)
3712 +                               break;
3713 +
3714 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3715 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
3716 +                           mtctr == 0x7D6903A6U &&
3717 +                           bctr == 0x4E800420U)
3718 +                       {
3719 +                               unsigned int r11;
3720 +
3721 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3722 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3723 +
3724 +                               err = get_user(r11, (unsigned int*)addr);
3725 +                               if (err)
3726 +                                       break;
3727 +
3728 +                               regs->gpr[PT_R11] = r11;
3729 +                               regs->ctr = r11;
3730 +                               regs->nip = r11;
3731 +                               return 4;
3732 +                       }
3733 +               }
3734 +       } while (0);
3735 +#endif
3736 +
3737 +#ifdef CONFIG_PAX_EMUSIGRT
3738 +       do { /* PaX: sigreturn emulation */
3739 +               unsigned int li, sc;
3740 +
3741 +               err = get_user(li, (unsigned int *)regs->nip);
3742 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
3743 +
3744 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
3745 +                       struct vm_area_struct *vma;
3746 +                       unsigned long call_syscall;
3747 +
3748 +                       down_read(&current->mm->mmap_sem);
3749 +                       call_syscall = current->mm->call_syscall;
3750 +                       up_read(&current->mm->mmap_sem);
3751 +                       if (likely(call_syscall))
3752 +                               goto emulate;
3753 +
3754 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3755 +
3756 +                       down_write(&current->mm->mmap_sem);
3757 +                       if (current->mm->call_syscall) {
3758 +                               call_syscall = current->mm->call_syscall;
3759 +                               up_write(&current->mm->mmap_sem);
3760 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3761 +                               goto emulate;
3762 +                       }
3763 +
3764 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3765 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
3766 +                               up_write(&current->mm->mmap_sem);
3767 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3768 +                               return 1;
3769 +                       }
3770 +
3771 +                       pax_insert_vma(vma, call_syscall);
3772 +                       current->mm->call_syscall = call_syscall;
3773 +                       up_write(&current->mm->mmap_sem);
3774 +
3775 +emulate:
3776 +                       regs->gpr[PT_R0] = __NR_sigreturn;
3777 +                       regs->nip = call_syscall;
3778 +                       return 6;
3779 +               }
3780 +       } while (0);
3781 +
3782 +       do { /* PaX: rt_sigreturn emulation */
3783 +               unsigned int li, sc;
3784 +
3785 +               err = get_user(li, (unsigned int *)regs->nip);
3786 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
3787 +
3788 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
3789 +                       struct vm_area_struct *vma;
3790 +                       unsigned int call_syscall;
3791 +
3792 +                       down_read(&current->mm->mmap_sem);
3793 +                       call_syscall = current->mm->call_syscall;
3794 +                       up_read(&current->mm->mmap_sem);
3795 +                       if (likely(call_syscall))
3796 +                               goto rt_emulate;
3797 +
3798 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3799 +
3800 +                       down_write(&current->mm->mmap_sem);
3801 +                       if (current->mm->call_syscall) {
3802 +                               call_syscall = current->mm->call_syscall;
3803 +                               up_write(&current->mm->mmap_sem);
3804 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3805 +                               goto rt_emulate;
3806 +                       }
3807 +
3808 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3809 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
3810 +                               up_write(&current->mm->mmap_sem);
3811 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3812 +                               return 1;
3813 +                       }
3814 +
3815 +                       pax_insert_vma(vma, call_syscall);
3816 +                       current->mm->call_syscall = call_syscall;
3817 +                       up_write(&current->mm->mmap_sem);
3818 +
3819 +rt_emulate:
3820 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
3821 +                       regs->nip = call_syscall;
3822 +                       return 7;
3823 +               }
3824 +       } while (0);
3825 +#endif
3826 +
3827 +       return 1;
3828 +}
3829 +
3830 +void pax_report_insns(void *pc, void *sp)
3831 +{
3832 +       unsigned long i;
3833 +
3834 +       printk(KERN_ERR "PAX: bytes at PC: ");
3835 +       for (i = 0; i < 5; i++) {
3836 +               unsigned int c;
3837 +               if (get_user(c, (unsigned int*)pc+i)) {
3838 +                       printk("<invalid address>.");
3839 +                       break;
3840 +               }
3841 +               printk("%08x ", c);
3842 +       }
3843 +       printk("\n");
3844 +}
3845 +#endif
3846 +
3847  /*
3848   * Check whether the instruction at regs->nip is a store using
3849   * an update addressing form which will update r1.
3850 @@ -111,7 +473,7 @@ int do_page_fault(struct pt_regs *regs, 
3851          * indicate errors in DSISR but can validly be set in SRR1.
3852          */
3853         if (TRAP(regs) == 0x400)
3854 -               error_code &= 0x48200000;
3855 +               error_code &= 0x58200000;
3856         else
3857                 is_write = error_code & 0x02000000;
3858  #endif /* CONFIG_4xx || CONFIG_BOOKE */
3859 @@ -175,7 +537,7 @@ int do_page_fault(struct pt_regs *regs, 
3860                     && (!user_mode(regs) || !store_updates_sp(regs)))
3861                         goto bad_area;
3862         }
3863 -       if (expand_stack(vma, address))
3864 +       if (expand_stack(current, vma, address))
3865                 goto bad_area;
3866  
3867  good_area:
3868 @@ -205,15 +567,14 @@ good_area:
3869         } else if (TRAP(regs) == 0x400) {
3870                 pte_t *ptep;
3871  
3872 -#if 0
3873 +#if 1
3874                 /* It would be nice to actually enforce the VM execute
3875                    permission on CPUs which can do so, but far too
3876                    much stuff in userspace doesn't get the permissions
3877                    right, so we let any page be executed for now. */
3878                 if (! (vma->vm_flags & VM_EXEC))
3879                         goto bad_area;
3880 -#endif
3881 -
3882 +#else
3883                 /* Since 4xx/Book-E supports per-page execute permission,
3884                  * we lazily flush dcache to icache. */
3885                 ptep = NULL;
3886 @@ -233,6 +594,7 @@ good_area:
3887                 if (ptep != NULL)
3888                         pte_unmap(ptep);
3889  #endif
3890 +#endif
3891         /* a read */
3892         } else {
3893                 /* protection fault */
3894 @@ -278,6 +640,38 @@ bad_area:
3895  
3896         /* User mode accesses cause a SIGSEGV */
3897         if (user_mode(regs)) {
3898 +
3899 +#ifdef CONFIG_PAX_PAGEEXEC
3900 +               if (mm->flags & MF_PAX_PAGEEXEC) {
3901 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
3902 +                               switch (pax_handle_fetch_fault(regs)) {
3903 +
3904 +#ifdef CONFIG_PAX_EMUPLT
3905 +                               case 2:
3906 +                               case 3:
3907 +                               case 4:
3908 +                                       return 0;
3909 +#endif
3910 +
3911 +#ifdef CONFIG_PAX_RANDEXEC
3912 +                               case 5:
3913 +                                       return 0;
3914 +#endif
3915 +
3916 +#ifdef CONFIG_PAX_EMUSIGRT
3917 +                               case 6:
3918 +                               case 7:
3919 +                                       return 0;
3920 +#endif
3921 +
3922 +                               }
3923 +
3924 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
3925 +                               do_exit(SIGKILL);
3926 +                       }
3927 +               }
3928 +#endif
3929 +
3930                 info.si_signo = SIGSEGV;
3931                 info.si_errno = 0;
3932                 info.si_code = code;
3933 diff -urNp linux-2.6.11/arch/ppc64/kernel/syscalls.c linux-2.6.11/arch/ppc64/kernel/syscalls.c
3934 --- linux-2.6.11/arch/ppc64/kernel/syscalls.c   2005-03-02 02:38:13.000000000 -0500
3935 +++ linux-2.6.11/arch/ppc64/kernel/syscalls.c   2005-03-09 11:56:44.000000000 -0500
3936 @@ -183,6 +183,11 @@ unsigned long sys_mmap(unsigned long add
3937         struct file * file = NULL;
3938         unsigned long ret = -EBADF;
3939  
3940 +#ifdef CONFIG_PAX_RANDEXEC
3941 +       if (flags & MAP_MIRROR)
3942 +               return -EINVAL;
3943 +#endif
3944 +
3945         if (!(flags & MAP_ANONYMOUS)) {
3946                 if (!(file = fget(fd)))
3947                         goto out;
3948 diff -urNp linux-2.6.11/arch/ppc64/mm/fault.c linux-2.6.11/arch/ppc64/mm/fault.c
3949 --- linux-2.6.11/arch/ppc64/mm/fault.c  2005-03-02 02:38:17.000000000 -0500
3950 +++ linux-2.6.11/arch/ppc64/mm/fault.c  2005-03-09 11:56:44.000000000 -0500
3951 @@ -29,6 +29,7 @@
3952  #include <linux/interrupt.h>
3953  #include <linux/smp_lock.h>
3954  #include <linux/module.h>
3955 +#include <linux/binfmts.h>
3956  
3957  #include <asm/page.h>
3958  #include <asm/pgtable.h>
3959 @@ -76,6 +77,54 @@ static int store_updates_sp(struct pt_re
3960         return 0;
3961  }
3962  
3963 +#ifdef CONFIG_PAX_PAGEEXEC
3964 +/*
3965 + * PaX: decide what to do with offenders (regs->nip = fault address)
3966 + *
3967 + * returns 1 when task should be killed
3968 + *         2 when legitimate ET_EXEC was detected
3969 + */
3970 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3971 +{
3972 +
3973 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
3974 +       int err;
3975 +#endif
3976 +
3977 +#ifdef CONFIG_PAX_RANDEXEC
3978 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
3979 +               if (regs->nip >= current->mm->start_code &&
3980 +                   regs->nip < current->mm->end_code)
3981 +               {
3982 +                       if (regs->link == regs->nip)
3983 +                               return 1;
3984 +
3985 +                       regs->nip += current->mm->delta_exec;
3986 +                       return 2;
3987 +               }
3988 +       }
3989 +#endif
3990 +
3991 +       return 1;
3992 +}
3993 +
3994 +void pax_report_insns(void *pc, void *sp)
3995 +{
3996 +       unsigned long i;
3997 +
3998 +       printk(KERN_ERR "PAX: bytes at PC: ");
3999 +       for (i = 0; i < 5; i++) {
4000 +               unsigned int c;
4001 +               if (get_user(c, (unsigned int*)pc+i)) {
4002 +                       printk("<invalid address>.");
4003 +                       break;
4004 +               }
4005 +               printk("%08x ", c);
4006 +       }
4007 +       printk("\n");
4008 +}
4009 +#endif
4010 +
4011  /*
4012   * The error_code parameter is
4013   *  - DSISR for a non-SLB data access fault,
4014 @@ -193,7 +242,7 @@ int do_page_fault(struct pt_regs *regs, 
4015                         goto bad_area;
4016         }
4017  
4018 -       if (expand_stack(vma, address))
4019 +       if (expand_stack(current, vma, address))
4020                 goto bad_area;
4021  
4022  good_area:
4023 @@ -243,6 +292,25 @@ bad_area:
4024  bad_area_nosemaphore:
4025         /* User mode accesses cause a SIGSEGV */
4026         if (user_mode(regs)) {
4027 +
4028 +#ifdef CONFIG_PAX_PAGEEXEC
4029 +               if (mm->flags & MF_PAX_PAGEEXEC) {
4030 +                       if ((regs->trap == 0x400) && (regs->nip == address)) {
4031 +                               switch (pax_handle_fetch_fault(regs)) {
4032 +
4033 +#ifdef CONFIG_PAX_RANDEXEC
4034 +                               case 2:
4035 +                                       return;
4036 +#endif
4037 +
4038 +                               }
4039 +
4040 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
4041 +                               do_exit(SIGKILL);
4042 +                       }
4043 +               }
4044 +#endif
4045 +
4046                 info.si_signo = SIGSEGV;
4047                 info.si_errno = 0;
4048                 info.si_code = code;
4049 diff -urNp linux-2.6.11/arch/s390/mm/fault.c linux-2.6.11/arch/s390/mm/fault.c
4050 --- linux-2.6.11/arch/s390/mm/fault.c   2005-03-02 02:38:38.000000000 -0500
4051 +++ linux-2.6.11/arch/s390/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
4052 @@ -225,7 +225,7 @@ do_exception(struct pt_regs *regs, unsig
4053                  goto good_area;
4054          if (!(vma->vm_flags & VM_GROWSDOWN))
4055                  goto bad_area;
4056 -        if (expand_stack(vma, address))
4057 +        if (expand_stack(tsk, vma, address))
4058                  goto bad_area;
4059  /*
4060   * Ok, we have a good vm_area for this memory access, so
4061 diff -urNp linux-2.6.11/arch/sh/mm/fault.c linux-2.6.11/arch/sh/mm/fault.c
4062 --- linux-2.6.11/arch/sh/mm/fault.c     2005-03-02 02:37:52.000000000 -0500
4063 +++ linux-2.6.11/arch/sh/mm/fault.c     2005-03-09 11:56:44.000000000 -0500
4064 @@ -69,7 +69,7 @@ asmlinkage void do_page_fault(struct pt_
4065                 goto good_area;
4066         if (!(vma->vm_flags & VM_GROWSDOWN))
4067                 goto bad_area;
4068 -       if (expand_stack(vma, address))
4069 +       if (expand_stack(tsk, vma, address))
4070                 goto bad_area;
4071  /*
4072   * Ok, we have a good vm_area for this memory access, so
4073 diff -urNp linux-2.6.11/arch/sh64/mm/fault.c linux-2.6.11/arch/sh64/mm/fault.c
4074 --- linux-2.6.11/arch/sh64/mm/fault.c   2005-03-02 02:38:08.000000000 -0500
4075 +++ linux-2.6.11/arch/sh64/mm/fault.c   2005-03-09 11:56:44.000000000 -0500
4076 @@ -188,7 +188,7 @@ asmlinkage void do_page_fault(struct pt_
4077  #endif
4078                 goto bad_area;
4079         }
4080 -       if (expand_stack(vma, address)) {
4081 +       if (expand_stack(tsk, vma, address)) {
4082  #ifdef DEBUG_FAULT
4083                 print_task(tsk);
4084                 printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
4085 diff -urNp linux-2.6.11/arch/sparc/Makefile linux-2.6.11/arch/sparc/Makefile
4086 --- linux-2.6.11/arch/sparc/Makefile    2005-03-02 02:37:49.000000000 -0500
4087 +++ linux-2.6.11/arch/sparc/Makefile    2005-03-09 11:56:44.000000000 -0500
4088 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
4089  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
4090  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
4091  CORE_Y         := $(core-y)
4092 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/
4093 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/
4094  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
4095  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
4096  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
4097 diff -urNp linux-2.6.11/arch/sparc/kernel/ptrace.c linux-2.6.11/arch/sparc/kernel/ptrace.c
4098 --- linux-2.6.11/arch/sparc/kernel/ptrace.c     2005-03-02 02:38:33.000000000 -0500
4099 +++ linux-2.6.11/arch/sparc/kernel/ptrace.c     2005-03-09 11:56:44.000000000 -0500
4100 @@ -18,6 +18,7 @@
4101  #include <linux/smp.h>
4102  #include <linux/smp_lock.h>
4103  #include <linux/security.h>
4104 +#include <linux/grsecurity.h>
4105  
4106  #include <asm/pgtable.h>
4107  #include <asm/system.h>
4108 @@ -322,6 +323,11 @@ asmlinkage void do_ptrace(struct pt_regs
4109                 goto out;
4110         }
4111  
4112 +       if (gr_handle_ptrace(child, request)) {
4113 +               pt_error_return(regs, EPERM);
4114 +               goto out_tsk;
4115 +       }
4116 +
4117         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
4118             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
4119                 if (ptrace_attach(child)) {
4120 diff -urNp linux-2.6.11/arch/sparc/kernel/sys_sparc.c linux-2.6.11/arch/sparc/kernel/sys_sparc.c
4121 --- linux-2.6.11/arch/sparc/kernel/sys_sparc.c  2005-03-02 02:38:00.000000000 -0500
4122 +++ linux-2.6.11/arch/sparc/kernel/sys_sparc.c  2005-03-09 11:56:44.000000000 -0500
4123 @@ -55,6 +55,13 @@ unsigned long arch_get_unmapped_area(str
4124                 return -ENOMEM;
4125         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
4126                 return -ENOMEM;
4127 +
4128 +#ifdef CONFIG_PAX_RANDMMAP
4129 +       if ((current->mm->flags & MF_PAX_RANDMMAP) && (!addr || filp))
4130 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
4131 +       else
4132 +#endif
4133 +
4134         if (!addr)
4135                 addr = TASK_UNMAPPED_BASE;
4136  
4137 @@ -227,6 +234,11 @@ static unsigned long do_mmap2(unsigned l
4138         struct file * file = NULL;
4139         unsigned long retval = -EBADF;
4140  
4141 +#ifdef CONFIG_PAX_RANDEXEC
4142 +       if (flags & MAP_MIRROR)
4143 +               return -EINVAL;
4144 +#endif
4145 +
4146         if (!(flags & MAP_ANONYMOUS)) {
4147                 file = fget(fd);
4148                 if (!file)
4149 diff -urNp linux-2.6.11/arch/sparc/kernel/sys_sunos.c linux-2.6.11/arch/sparc/kernel/sys_sunos.c
4150 --- linux-2.6.11/arch/sparc/kernel/sys_sunos.c  2005-03-02 02:38:07.000000000 -0500
4151 +++ linux-2.6.11/arch/sparc/kernel/sys_sunos.c  2005-03-09 11:56:44.000000000 -0500
4152 @@ -71,6 +71,11 @@ asmlinkage unsigned long sunos_mmap(unsi
4153         struct file * file = NULL;
4154         unsigned long retval, ret_type;
4155  
4156 +#ifdef CONFIG_PAX_RANDEXEC
4157 +       if (flags & MAP_MIRROR)
4158 +               return -EINVAL;
4159 +#endif
4160 +
4161         if (flags & MAP_NORESERVE) {
4162                 static int cnt;
4163                 if (cnt++ < 10)
4164 diff -urNp linux-2.6.11/arch/sparc/mm/fault.c linux-2.6.11/arch/sparc/mm/fault.c
4165 --- linux-2.6.11/arch/sparc/mm/fault.c  2005-03-02 02:38:37.000000000 -0500
4166 +++ linux-2.6.11/arch/sparc/mm/fault.c  2005-03-09 11:56:44.000000000 -0500
4167 @@ -21,6 +21,10 @@
4168  #include <linux/smp_lock.h>
4169  #include <linux/interrupt.h>
4170  #include <linux/module.h>
4171 +#include <linux/slab.h>
4172 +#include <linux/pagemap.h>
4173 +#include <linux/compiler.h>
4174 +#include <linux/binfmts.h>
4175  
4176  #include <asm/system.h>
4177  #include <asm/segment.h>
4178 @@ -220,6 +224,269 @@ static unsigned long compute_si_addr(str
4179         return safe_compute_effective_address(regs, insn);
4180  }
4181  
4182 +#ifdef CONFIG_PAX_PAGEEXEC
4183 +void pax_emuplt_close(struct vm_area_struct * vma)
4184 +{
4185 +       vma->vm_mm->call_dl_resolve = 0UL;
4186 +}
4187 +
4188 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
4189 +{
4190 +       struct page* page;
4191 +       unsigned int *kaddr;
4192 +
4193 +       page = alloc_page(GFP_HIGHUSER);
4194 +       if (!page)
4195 +               return NOPAGE_OOM;
4196 +
4197 +       kaddr = kmap(page);
4198 +       memset(kaddr, 0, PAGE_SIZE);
4199 +       kaddr[0] = 0x9DE3BFA8U; /* save */
4200 +       flush_dcache_page(page);
4201 +       kunmap(page);
4202 +       if (type)
4203 +               *type = VM_FAULT_MAJOR;
4204 +
4205 +       return page;
4206 +}
4207 +
4208 +static struct vm_operations_struct pax_vm_ops = {
4209 +       close:          pax_emuplt_close,
4210 +       nopage:         pax_emuplt_nopage,
4211 +};
4212 +
4213 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4214 +{
4215 +       memset(vma, 0, sizeof(*vma));
4216 +       vma->vm_mm = current->mm;
4217 +       vma->vm_start = addr;
4218 +       vma->vm_end = addr + PAGE_SIZE;
4219 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4220 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
4221 +       vma->vm_ops = &pax_vm_ops;
4222 +       insert_vm_struct(current->mm, vma);
4223 +       ++current->mm->total_vm;
4224 +}
4225 +
4226 +/*
4227 + * PaX: decide what to do with offenders (regs->pc = fault address)
4228 + *
4229 + * returns 1 when task should be killed
4230 + *         2 when patched PLT trampoline was detected
4231 + *         3 when unpatched PLT trampoline was detected
4232 + *         4 when legitimate ET_EXEC was detected
4233 + */
4234 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4235 +{
4236 +
4237 +#ifdef CONFIG_PAX_EMUPLT
4238 +       int err;
4239 +#endif
4240 +
4241 +#ifdef CONFIG_PAX_RANDEXEC
4242 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
4243 +               if (regs->pc >= current->mm->start_code &&
4244 +                   regs->pc < current->mm->end_code)
4245 +               {
4246 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
4247 +                               return 1;
4248 +
4249 +                       regs->pc += current->mm->delta_exec;
4250 +                       if (regs->npc >= current->mm->start_code &&
4251 +                           regs->npc < current->mm->end_code)
4252 +                               regs->npc += current->mm->delta_exec;
4253 +                       return 4;
4254 +               }
4255 +               if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
4256 +                   regs->pc < current->mm->end_code + current->mm->delta_exec)
4257 +               {
4258 +                       regs->pc -= current->mm->delta_exec;
4259 +                       if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
4260 +                           regs->npc < current->mm->end_code + current->mm->delta_exec)
4261 +                               regs->npc -= current->mm->delta_exec;
4262 +               }
4263 +       }
4264 +#endif
4265 +
4266 +#ifdef CONFIG_PAX_EMUPLT
4267 +       do { /* PaX: patched PLT emulation #1 */
4268 +               unsigned int sethi1, sethi2, jmpl;
4269 +
4270 +               err = get_user(sethi1, (unsigned int*)regs->pc);
4271 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
4272 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
4273 +
4274 +               if (err)
4275 +                       break;
4276 +
4277 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4278 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
4279 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
4280 +               {
4281 +                       unsigned int addr;
4282 +
4283 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4284 +                       addr = regs->u_regs[UREG_G1];
4285 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4286 +                       regs->pc = addr;
4287 +                       regs->npc = addr+4;
4288 +                       return 2;
4289 +               }
4290 +       } while (0);
4291 +
4292 +       { /* PaX: patched PLT emulation #2 */
4293 +               unsigned int ba;
4294 +
4295 +               err = get_user(ba, (unsigned int*)regs->pc);
4296 +
4297 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4298 +                       unsigned int addr;
4299 +
4300 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4301 +                       regs->pc = addr;
4302 +                       regs->npc = addr+4;
4303 +                       return 2;
4304 +               }
4305 +       }
4306 +
4307 +       do { /* PaX: patched PLT emulation #3 */
4308 +               unsigned int sethi, jmpl, nop;
4309 +
4310 +               err = get_user(sethi, (unsigned int*)regs->pc);
4311 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
4312 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
4313 +
4314 +               if (err)
4315 +                       break;
4316 +
4317 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4318 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4319 +                   nop == 0x01000000U)
4320 +               {
4321 +                       unsigned int addr;
4322 +
4323 +                       addr = (sethi & 0x003FFFFFU) << 10;
4324 +                       regs->u_regs[UREG_G1] = addr;
4325 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4326 +                       regs->pc = addr;
4327 +                       regs->npc = addr+4;
4328 +                       return 2;
4329 +               }
4330 +       } while (0);
4331 +
4332 +       do { /* PaX: unpatched PLT emulation step 1 */
4333 +               unsigned int sethi, ba, nop;
4334 +
4335 +               err = get_user(sethi, (unsigned int*)regs->pc);
4336 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
4337 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
4338 +
4339 +               if (err)
4340 +                       break;
4341 +
4342 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4343 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4344 +                   nop == 0x01000000U)
4345 +               {
4346 +                       unsigned int addr, save, call;
4347 +
4348 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
4349 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4350 +                       else
4351 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
4352 +
4353 +                       err = get_user(save, (unsigned int*)addr);
4354 +                       err |= get_user(call, (unsigned int*)(addr+4));
4355 +                       err |= get_user(nop, (unsigned int*)(addr+8));
4356 +                       if (err)
4357 +                               break;
4358 +
4359 +                       if (save == 0x9DE3BFA8U &&
4360 +                           (call & 0xC0000000U) == 0x40000000U &&
4361 +                           nop == 0x01000000U)
4362 +                       {
4363 +                               struct vm_area_struct *vma;
4364 +                               unsigned long call_dl_resolve;
4365 +
4366 +                               down_read(&current->mm->mmap_sem);
4367 +                               call_dl_resolve = current->mm->call_dl_resolve;
4368 +                               up_read(&current->mm->mmap_sem);
4369 +                               if (likely(call_dl_resolve))
4370 +                                       goto emulate;
4371 +
4372 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4373 +
4374 +                               down_write(&current->mm->mmap_sem);
4375 +                               if (current->mm->call_dl_resolve) {
4376 +                                       call_dl_resolve = current->mm->call_dl_resolve;
4377 +                                       up_write(&current->mm->mmap_sem);
4378 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4379 +                                       goto emulate;
4380 +                               }
4381 +
4382 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4383 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4384 +                                       up_write(&current->mm->mmap_sem);
4385 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4386 +                                       return 1;
4387 +                               }
4388 +
4389 +                               pax_insert_vma(vma, call_dl_resolve);
4390 +                               current->mm->call_dl_resolve = call_dl_resolve;
4391 +                               up_write(&current->mm->mmap_sem);
4392 +
4393 +emulate:
4394 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4395 +                               regs->pc = call_dl_resolve;
4396 +                               regs->npc = addr+4;
4397 +                               return 3;
4398 +                       }
4399 +               }
4400 +       } while (0);
4401 +
4402 +       do { /* PaX: unpatched PLT emulation step 2 */
4403 +               unsigned int save, call, nop;
4404 +
4405 +               err = get_user(save, (unsigned int*)(regs->pc-4));
4406 +               err |= get_user(call, (unsigned int*)regs->pc);
4407 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
4408 +               if (err)
4409 +                       break;
4410 +
4411 +               if (save == 0x9DE3BFA8U &&
4412 +                   (call & 0xC0000000U) == 0x40000000U &&
4413 +                   nop == 0x01000000U)
4414 +               {
4415 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
4416 +
4417 +                       regs->u_regs[UREG_RETPC] = regs->pc;
4418 +                       regs->pc = dl_resolve;
4419 +                       regs->npc = dl_resolve+4;
4420 +                       return 3;
4421 +               }
4422 +       } while (0);
4423 +#endif
4424 +
4425 +       return 1;
4426 +}
4427 +
4428 +void pax_report_insns(void *pc, void *sp)
4429 +{
4430 +       unsigned long i;
4431 +
4432 +       printk(KERN_ERR "PAX: bytes at PC: ");
4433 +       for (i = 0; i < 5; i++) {
4434 +               unsigned int c;
4435 +               if (get_user(c, (unsigned int*)pc+i)) {
4436 +                       printk("<invalid address>.");
4437 +                       break;
4438 +               }
4439 +               printk("%08x ", c);
4440 +       }
4441 +       printk("\n");
4442 +}
4443 +#endif
4444 +
4445  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
4446                                unsigned long address)
4447  {
4448 @@ -271,7 +538,7 @@ asmlinkage void do_sparc_fault(struct pt
4449                 goto good_area;
4450         if(!(vma->vm_flags & VM_GROWSDOWN))
4451                 goto bad_area;
4452 -       if(expand_stack(vma, address))
4453 +       if(expand_stack(current, vma, address))
4454                 goto bad_area;
4455         /*
4456          * Ok, we have a good vm_area for this memory access, so
4457 @@ -283,6 +550,29 @@ good_area:
4458                 if(!(vma->vm_flags & VM_WRITE))
4459                         goto bad_area;
4460         } else {
4461 +
4462 +#ifdef CONFIG_PAX_PAGEEXEC
4463 +               if ((mm->flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
4464 +                       up_read(&mm->mmap_sem);
4465 +                       switch (pax_handle_fetch_fault(regs)) {
4466 +
4467 +#ifdef CONFIG_PAX_EMUPLT
4468 +                       case 2:
4469 +                       case 3:
4470 +                               return;
4471 +#endif
4472 +
4473 +#ifdef CONFIG_PAX_RANDEXEC
4474 +                       case 4:
4475 +                               return;
4476 +#endif
4477 +
4478 +                       }
4479 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
4480 +                       do_exit(SIGKILL);
4481 +               }
4482 +#endif
4483 +
4484                 /* Allow reads even for write-only mappings */
4485                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
4486                         goto bad_area;
4487 @@ -525,7 +815,7 @@ inline void force_user_fault(unsigned lo
4488                 goto good_area;
4489         if(!(vma->vm_flags & VM_GROWSDOWN))
4490                 goto bad_area;
4491 -       if(expand_stack(vma, address))
4492 +       if(expand_stack(tsk, vma, address))
4493                 goto bad_area;
4494  good_area:
4495         info.si_code = SEGV_ACCERR;
4496 diff -urNp linux-2.6.11/arch/sparc/mm/init.c linux-2.6.11/arch/sparc/mm/init.c
4497 --- linux-2.6.11/arch/sparc/mm/init.c   2005-03-02 02:38:08.000000000 -0500
4498 +++ linux-2.6.11/arch/sparc/mm/init.c   2005-03-09 11:56:44.000000000 -0500
4499 @@ -337,17 +337,17 @@ void __init paging_init(void)
4500  
4501         /* Initialize the protection map with non-constant, MMU dependent values. */
4502         protection_map[0] = PAGE_NONE;
4503 -       protection_map[1] = PAGE_READONLY;
4504 -       protection_map[2] = PAGE_COPY;
4505 -       protection_map[3] = PAGE_COPY;
4506 +       protection_map[1] = PAGE_READONLY_NOEXEC;
4507 +       protection_map[2] = PAGE_COPY_NOEXEC;
4508 +       protection_map[3] = PAGE_COPY_NOEXEC;
4509         protection_map[4] = PAGE_READONLY;
4510         protection_map[5] = PAGE_READONLY;
4511         protection_map[6] = PAGE_COPY;
4512         protection_map[7] = PAGE_COPY;
4513         protection_map[8] = PAGE_NONE;
4514 -       protection_map[9] = PAGE_READONLY;
4515 -       protection_map[10] = PAGE_SHARED;
4516 -       protection_map[11] = PAGE_SHARED;
4517 +       protection_map[9] = PAGE_READONLY_NOEXEC;
4518 +       protection_map[10] = PAGE_SHARED_NOEXEC;
4519 +       protection_map[11] = PAGE_SHARED_NOEXEC;
4520         protection_map[12] = PAGE_READONLY;
4521         protection_map[13] = PAGE_READONLY;
4522         protection_map[14] = PAGE_SHARED;
4523 diff -urNp linux-2.6.11/arch/sparc/mm/srmmu.c linux-2.6.11/arch/sparc/mm/srmmu.c
4524 --- linux-2.6.11/arch/sparc/mm/srmmu.c  2005-03-02 02:38:10.000000000 -0500
4525 +++ linux-2.6.11/arch/sparc/mm/srmmu.c  2005-03-09 11:56:44.000000000 -0500
4526 @@ -2147,6 +2147,13 @@ void __init ld_mmu_srmmu(void)
4527         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
4528         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
4529         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
4530 +
4531 +#ifdef CONFIG_PAX_PAGEEXEC
4532 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
4533 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
4534 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
4535 +#endif
4536 +
4537         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
4538         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
4539         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
4540 diff -urNp linux-2.6.11/arch/sparc64/kernel/ptrace.c linux-2.6.11/arch/sparc64/kernel/ptrace.c
4541 --- linux-2.6.11/arch/sparc64/kernel/ptrace.c   2005-03-02 02:38:32.000000000 -0500
4542 +++ linux-2.6.11/arch/sparc64/kernel/ptrace.c   2005-03-09 11:56:44.000000000 -0500
4543 @@ -19,6 +19,7 @@
4544  #include <linux/smp.h>
4545  #include <linux/smp_lock.h>
4546  #include <linux/security.h>
4547 +#include <linux/grsecurity.h>
4548  
4549  #include <asm/asi.h>
4550  #include <asm/pgtable.h>
4551 @@ -173,6 +174,11 @@ asmlinkage void do_ptrace(struct pt_regs
4552                 goto out;
4553         }
4554  
4555 +       if (gr_handle_ptrace(child, (long)request)) {
4556 +               pt_error_return(regs, EPERM);
4557 +               goto out_tsk;
4558 +       }
4559 +
4560         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
4561             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
4562                 if (ptrace_attach(child)) {
4563 diff -urNp linux-2.6.11/arch/sparc64/kernel/sys_sparc.c linux-2.6.11/arch/sparc64/kernel/sys_sparc.c
4564 --- linux-2.6.11/arch/sparc64/kernel/sys_sparc.c        2005-03-02 02:38:10.000000000 -0500
4565 +++ linux-2.6.11/arch/sparc64/kernel/sys_sparc.c        2005-03-09 11:56:44.000000000 -0500
4566 @@ -49,7 +49,7 @@ unsigned long arch_get_unmapped_area(str
4567  {
4568         struct mm_struct *mm = current->mm;
4569         struct vm_area_struct * vma;
4570 -       unsigned long task_size = TASK_SIZE;
4571 +       unsigned long task_size = TASK_SIZE, task_unmapped_base = TASK_UNMAPPED_BASE;
4572         unsigned long start_addr;
4573         int do_color_align;
4574  
4575 @@ -72,6 +72,12 @@ unsigned long arch_get_unmapped_area(str
4576         if (filp || (flags & MAP_SHARED))
4577                 do_color_align = 1;
4578  
4579 +#ifdef CONFIG_PAX_RANDMMAP
4580 +       if (mm->flags & MF_PAX_RANDMMAP)
4581 +               task_unmapped_base += mm->delta_mmap;
4582 +       if (!(mm->flags & MF_PAX_RANDMMAP) || !filp)
4583 +#endif
4584 +
4585         if (addr) {
4586                 if (do_color_align)
4587                         addr = COLOUR_ALIGN(addr, pgoff);
4588 @@ -101,8 +107,8 @@ full_search:
4589                         vma = find_vma(mm, PAGE_OFFSET);
4590                 }
4591                 if (task_size < addr) {
4592 -                       if (start_addr != TASK_UNMAPPED_BASE) {
4593 -                               start_addr = addr = TASK_UNMAPPED_BASE;
4594 +                       if (start_addr != task_unmapped_base) {
4595 +                               start_addr = addr = task_unmapped_base;
4596                                 goto full_search;
4597                         }
4598                         return -ENOMEM;
4599 @@ -322,6 +328,11 @@ asmlinkage unsigned long sys_mmap(unsign
4600         struct file * file = NULL;
4601         unsigned long retval = -EBADF;
4602  
4603 +#ifdef CONFIG_PAX_RANDEXEC
4604 +       if (flags & MAP_MIRROR)
4605 +               return -EINVAL;
4606 +#endif
4607 +
4608         if (!(flags & MAP_ANONYMOUS)) {
4609                 file = fget(fd);
4610                 if (!file)
4611 diff -urNp linux-2.6.11/arch/sparc64/kernel/sys_sunos32.c linux-2.6.11/arch/sparc64/kernel/sys_sunos32.c
4612 --- linux-2.6.11/arch/sparc64/kernel/sys_sunos32.c      2005-03-02 02:38:12.000000000 -0500
4613 +++ linux-2.6.11/arch/sparc64/kernel/sys_sunos32.c      2005-03-09 11:56:44.000000000 -0500
4614 @@ -66,6 +66,11 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 
4615         struct file *file = NULL;
4616         unsigned long retval, ret_type;
4617  
4618 +#ifdef CONFIG_PAX_RANDEXEC
4619 +       if (flags & MAP_MIRROR)
4620 +               return -EINVAL;
4621 +#endif
4622 +
4623         if (flags & MAP_NORESERVE) {
4624                 static int cnt;
4625                 if (cnt++ < 10)
4626 diff -urNp linux-2.6.11/arch/sparc64/mm/fault.c linux-2.6.11/arch/sparc64/mm/fault.c
4627 --- linux-2.6.11/arch/sparc64/mm/fault.c        2005-03-02 02:38:26.000000000 -0500
4628 +++ linux-2.6.11/arch/sparc64/mm/fault.c        2005-03-09 11:56:44.000000000 -0500
4629 @@ -18,6 +18,10 @@
4630  #include <linux/smp_lock.h>
4631  #include <linux/init.h>
4632  #include <linux/interrupt.h>
4633 +#include <linux/slab.h>
4634 +#include <linux/pagemap.h>
4635 +#include <linux/compiler.h>
4636 +#include <linux/binfmts.h>
4637  
4638  #include <asm/page.h>
4639  #include <asm/pgtable.h>
4640 @@ -318,6 +322,386 @@ cannot_handle:
4641         unhandled_fault (address, current, regs);
4642  }
4643  
4644 +#ifdef CONFIG_PAX_PAGEEXEC
4645 +#ifdef CONFIG_PAX_EMUPLT
4646 +static void pax_emuplt_close(struct vm_area_struct * vma)
4647 +{
4648 +       vma->vm_mm->call_dl_resolve = 0UL;
4649 +}
4650 +
4651 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
4652 +{
4653 +       struct page* page;
4654 +       unsigned int *kaddr;
4655 +
4656 +       page = alloc_page(GFP_HIGHUSER);
4657 +       if (!page)
4658 +               return NOPAGE_OOM;
4659 +
4660 +       kaddr = kmap(page);
4661 +       memset(kaddr, 0, PAGE_SIZE);
4662 +       kaddr[0] = 0x9DE3BFA8U; /* save */
4663 +       flush_dcache_page(page);
4664 +       kunmap(page);
4665 +       if (type)
4666 +               *type = VM_FAULT_MAJOR;
4667 +       return page;
4668 +}
4669 +
4670 +static struct vm_operations_struct pax_vm_ops = {
4671 +       close:          pax_emuplt_close,
4672 +       nopage:         pax_emuplt_nopage,
4673 +};
4674 +
4675 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4676 +{
4677 +       memset(vma, 0, sizeof(*vma));
4678 +       vma->vm_mm = current->mm;
4679 +       vma->vm_start = addr;
4680 +       vma->vm_end = addr + PAGE_SIZE;
4681 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4682 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
4683 +       vma->vm_ops = &pax_vm_ops;
4684 +       insert_vm_struct(current->mm, vma);
4685 +       ++current->mm->total_vm;
4686 +}
4687 +#endif
4688 +
4689 +/*
4690 + * PaX: decide what to do with offenders (regs->tpc = fault address)
4691 + *
4692 + * returns 1 when task should be killed
4693 + *         2 when patched PLT trampoline was detected
4694 + *         3 when unpatched PLT trampoline was detected
4695 + *         4 when legitimate ET_EXEC was detected
4696 + */
4697 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4698 +{
4699 +
4700 +#ifdef CONFIG_PAX_EMUPLT
4701 +       int err;
4702 +#endif
4703 +
4704 +#ifdef CONFIG_PAX_RANDEXEC
4705 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
4706 +               if (regs->tpc >= current->mm->start_code &&
4707 +                   regs->tpc < current->mm->end_code)
4708 +               {
4709 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
4710 +                               return 1;
4711 +
4712 +                       regs->tpc += current->mm->delta_exec;
4713 +                       if (regs->tnpc >= current->mm->start_code &&
4714 +                           regs->tnpc < current->mm->end_code)
4715 +                               regs->tnpc += current->mm->delta_exec;
4716 +                       return 4;
4717 +               }
4718 +               if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
4719 +                   regs->tpc < current->mm->end_code + current->mm->delta_exec)
4720 +               {
4721 +                       regs->tpc -= current->mm->delta_exec;
4722 +                       if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
4723 +                           regs->tnpc < current->mm->end_code + current->mm->delta_exec)
4724 +                               regs->tnpc -= current->mm->delta_exec;
4725 +               }
4726 +       }
4727 +#endif
4728 +
4729 +#ifdef CONFIG_PAX_EMUPLT
4730 +       do { /* PaX: patched PLT emulation #1 */
4731 +               unsigned int sethi1, sethi2, jmpl;
4732 +
4733 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4734 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4735 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
4736 +
4737 +               if (err)
4738 +                       break;
4739 +
4740 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4741 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
4742 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
4743 +               {
4744 +                       unsigned long addr;
4745 +
4746 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4747 +                       addr = regs->u_regs[UREG_G1];
4748 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4749 +                       regs->tpc = addr;
4750 +                       regs->tnpc = addr+4;
4751 +                       return 2;
4752 +               }
4753 +       } while (0);
4754 +
4755 +       { /* PaX: patched PLT emulation #2 */
4756 +               unsigned int ba;
4757 +
4758 +               err = get_user(ba, (unsigned int*)regs->tpc);
4759 +
4760 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4761 +                       unsigned long addr;
4762 +
4763 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4764 +                       regs->tpc = addr;
4765 +                       regs->tnpc = addr+4;
4766 +                       return 2;
4767 +               }
4768 +       }
4769 +
4770 +       do { /* PaX: patched PLT emulation #3 */
4771 +               unsigned int sethi, jmpl, nop;
4772 +
4773 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4774 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
4775 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4776 +
4777 +               if (err)
4778 +                       break;
4779 +
4780 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4781 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4782 +                   nop == 0x01000000U)
4783 +               {
4784 +                       unsigned long addr;
4785 +
4786 +                       addr = (sethi & 0x003FFFFFU) << 10;
4787 +                       regs->u_regs[UREG_G1] = addr;
4788 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4789 +                       regs->tpc = addr;
4790 +                       regs->tnpc = addr+4;
4791 +                       return 2;
4792 +               }
4793 +       } while (0);
4794 +
4795 +       do { /* PaX: patched PLT emulation #4 */
4796 +               unsigned int mov1, call, mov2;
4797 +
4798 +               err = get_user(mov1, (unsigned int*)regs->tpc);
4799 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
4800 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
4801 +
4802 +               if (err)
4803 +                       break;
4804 +
4805 +               if (mov1 == 0x8210000FU &&
4806 +                   (call & 0xC0000000U) == 0x40000000U &&
4807 +                   mov2 == 0x9E100001U)
4808 +               {
4809 +                       unsigned long addr;
4810 +
4811 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4812 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4813 +                       regs->tpc = addr;
4814 +                       regs->tnpc = addr+4;
4815 +                       return 2;
4816 +               }
4817 +       } while (0);
4818 +
4819 +       do { /* PaX: patched PLT emulation #5 */
4820 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4821 +
4822 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4823 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4824 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
4825 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
4826 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
4827 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
4828 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
4829 +
4830 +               if (err)
4831 +                       break;
4832 +
4833 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4834 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4835 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
4836 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
4837 +                   sllx == 0x83287020 &&
4838 +                   jmpl == 0x81C04005U &&
4839 +                   nop == 0x01000000U)
4840 +               {
4841 +                       unsigned long addr;
4842 +
4843 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4844 +                       regs->u_regs[UREG_G1] <<= 32;
4845 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4846 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4847 +                       regs->tpc = addr;
4848 +                       regs->tnpc = addr+4;
4849 +                       return 2;
4850 +               }
4851 +       } while (0);
4852 +
4853 +       do { /* PaX: patched PLT emulation #6 */
4854 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
4855 +
4856 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4857 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4858 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
4859 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
4860 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
4861 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
4862 +
4863 +               if (err)
4864 +                       break;
4865 +
4866 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4867 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4868 +                   sllx == 0x83287020 &&
4869 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
4870 +                   jmpl == 0x81C04005U &&
4871 +                   nop == 0x01000000U)
4872 +               {
4873 +                       unsigned long addr;
4874 +
4875 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
4876 +                       regs->u_regs[UREG_G1] <<= 32;
4877 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
4878 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4879 +                       regs->tpc = addr;
4880 +                       regs->tnpc = addr+4;
4881 +                       return 2;
4882 +               }
4883 +       } while (0);
4884 +
4885 +       do { /* PaX: patched PLT emulation #7 */
4886 +               unsigned int sethi, ba, nop;
4887 +
4888 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4889 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
4890 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4891 +
4892 +               if (err)
4893 +                       break;
4894 +
4895 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4896 +                   (ba & 0xFFF00000U) == 0x30600000U &&
4897 +                   nop == 0x01000000U)
4898 +               {
4899 +                       unsigned long addr;
4900 +
4901 +                       addr = (sethi & 0x003FFFFFU) << 10;
4902 +                       regs->u_regs[UREG_G1] = addr;
4903 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4904 +                       regs->tpc = addr;
4905 +                       regs->tnpc = addr+4;
4906 +                       return 2;
4907 +               }
4908 +       } while (0);
4909 +
4910 +       do { /* PaX: unpatched PLT emulation step 1 */
4911 +               unsigned int sethi, ba, nop;
4912 +
4913 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4914 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
4915 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4916 +
4917 +               if (err)
4918 +                       break;
4919 +
4920 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4921 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4922 +                   nop == 0x01000000U)
4923 +               {
4924 +                       unsigned long addr;
4925 +                       unsigned int save, call;
4926 +
4927 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
4928 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4929 +                       else
4930 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4931 +
4932 +                       err = get_user(save, (unsigned int*)addr);
4933 +                       err |= get_user(call, (unsigned int*)(addr+4));
4934 +                       err |= get_user(nop, (unsigned int*)(addr+8));
4935 +                       if (err)
4936 +                               break;
4937 +
4938 +                       if (save == 0x9DE3BFA8U &&
4939 +                           (call & 0xC0000000U) == 0x40000000U &&
4940 +                           nop == 0x01000000U)
4941 +                       {
4942 +                               struct vm_area_struct *vma;
4943 +                               unsigned long call_dl_resolve;
4944 +
4945 +                               down_read(&current->mm->mmap_sem);
4946 +                               call_dl_resolve = current->mm->call_dl_resolve;
4947 +                               up_read(&current->mm->mmap_sem);
4948 +                               if (likely(call_dl_resolve))
4949 +                                       goto emulate;
4950 +
4951 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4952 +
4953 +                               down_write(&current->mm->mmap_sem);
4954 +                               if (current->mm->call_dl_resolve) {
4955 +                                       call_dl_resolve = current->mm->call_dl_resolve;
4956 +                                       up_write(&current->mm->mmap_sem);
4957 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4958 +                                       goto emulate;
4959 +                               }
4960 +
4961 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4962 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4963 +                                       up_write(&current->mm->mmap_sem);
4964 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4965 +                                       return 1;
4966 +                               }
4967 +
4968 +                               pax_insert_vma(vma, call_dl_resolve);
4969 +                               current->mm->call_dl_resolve = call_dl_resolve;
4970 +                               up_write(&current->mm->mmap_sem);
4971 +
4972 +emulate:
4973 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4974 +                               regs->tpc = call_dl_resolve;
4975 +                               regs->tnpc = addr+4;
4976 +                               return 3;
4977 +                       }
4978 +               }
4979 +       } while (0);
4980 +
4981 +       do { /* PaX: unpatched PLT emulation step 2 */
4982 +               unsigned int save, call, nop;
4983 +
4984 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
4985 +               err |= get_user(call, (unsigned int*)regs->tpc);
4986 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
4987 +               if (err)
4988 +                       break;
4989 +
4990 +               if (save == 0x9DE3BFA8U &&
4991 +                   (call & 0xC0000000U) == 0x40000000U &&
4992 +                   nop == 0x01000000U)
4993 +               {
4994 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4995 +
4996 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
4997 +                       regs->tpc = dl_resolve;
4998 +                       regs->tnpc = dl_resolve+4;
4999 +                       return 3;
5000 +               }
5001 +       } while (0);
5002 +#endif
5003 +
5004 +       return 1;
5005 +}
5006 +
5007 +void pax_report_insns(void *pc, void *sp)
5008 +{
5009 +       unsigned long i;
5010 +
5011 +       printk(KERN_ERR "PAX: bytes at PC: ");
5012 +       for (i = 0; i < 5; i++) {
5013 +               unsigned int c;
5014 +               if (get_user(c, (unsigned int*)pc+i)) {
5015 +                       printk("<invalid address>.");
5016 +                       break;
5017 +               }
5018 +               printk("%08x ", c);
5019 +       }
5020 +       printk("\n");
5021 +}
5022 +#endif
5023 +
5024  asmlinkage void do_sparc64_fault(struct pt_regs *regs)
5025  {
5026         struct mm_struct *mm = current->mm;
5027 @@ -360,8 +744,10 @@ asmlinkage void do_sparc64_fault(struct 
5028                 goto intr_or_no_mm;
5029  
5030         if (test_thread_flag(TIF_32BIT)) {
5031 -               if (!(regs->tstate & TSTATE_PRIV))
5032 +               if (!(regs->tstate & TSTATE_PRIV)) {
5033                         regs->tpc &= 0xffffffff;
5034 +                       regs->tnpc &= 0xffffffff;
5035 +               }
5036                 address &= 0xffffffff;
5037         }
5038  
5039 @@ -378,6 +764,34 @@ asmlinkage void do_sparc64_fault(struct 
5040         if (!vma)
5041                 goto bad_area;
5042  
5043 +#ifdef CONFIG_PAX_PAGEEXEC
5044 +       /* PaX: detect ITLB misses on non-exec pages */
5045 +       if ((mm->flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
5046 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
5047 +       {
5048 +               if (address != regs->tpc)
5049 +                       goto good_area;
5050 +
5051 +               up_read(&mm->mmap_sem);
5052 +               switch (pax_handle_fetch_fault(regs)) {
5053 +
5054 +#ifdef CONFIG_PAX_EMUPLT
5055 +               case 2:
5056 +               case 3:
5057 +                       goto fault_done;
5058 +#endif
5059 +
5060 +#ifdef CONFIG_PAX_RANDEXEC
5061 +               case 4:
5062 +                       goto fault_done;
5063 +#endif
5064 +
5065 +               }
5066 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
5067 +               do_exit(SIGKILL);
5068 +       }
5069 +#endif
5070 +
5071         /* Pure DTLB misses do not tell us whether the fault causing
5072          * load/store/atomic was a write or not, it only says that there
5073          * was no match.  So in such a case we (carefully) read the
5074 @@ -421,7 +835,7 @@ continue_fault:
5075                                 goto bad_area;
5076                 }
5077         }
5078 -       if (expand_stack(vma, address))
5079 +       if (expand_stack(current, vma, address))
5080                 goto bad_area;
5081         /*
5082          * Ok, we have a good vm_area for this memory access, so
5083 diff -urNp linux-2.6.11/arch/sparc64/solaris/misc.c linux-2.6.11/arch/sparc64/solaris/misc.c
5084 --- linux-2.6.11/arch/sparc64/solaris/misc.c    2005-03-02 02:38:26.000000000 -0500
5085 +++ linux-2.6.11/arch/sparc64/solaris/misc.c    2005-03-09 11:56:44.000000000 -0500
5086 @@ -56,6 +56,11 @@ static u32 do_solaris_mmap(u32 addr, u32
5087         struct file *file = NULL;
5088         unsigned long retval, ret_type;
5089  
5090 +#ifdef CONFIG_PAX_RANDEXEC
5091 +       if (flags & MAP_MIRROR)
5092 +               return -EINVAL;
5093 +#endif
5094 +
5095         /* Do we need it here? */
5096         set_personality(PER_SVR4);
5097         if (flags & MAP_NORESERVE) {
5098 diff -urNp linux-2.6.11/arch/um/kernel/trap_kern.c linux-2.6.11/arch/um/kernel/trap_kern.c
5099 --- linux-2.6.11/arch/um/kernel/trap_kern.c     2005-03-02 02:37:47.000000000 -0500
5100 +++ linux-2.6.11/arch/um/kernel/trap_kern.c     2005-03-09 11:56:44.000000000 -0500
5101 @@ -50,7 +50,7 @@ int handle_page_fault(unsigned long addr
5102                 goto out;
5103         else if(!ARCH_IS_STACKGROW(address))
5104                 goto out;
5105 -       else if(expand_stack(vma, address)) 
5106 +       else if(expand_stack(current, vma, address)) 
5107                 goto out;
5108  
5109   good_area:
5110 diff -urNp linux-2.6.11/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.11/arch/x86_64/ia32/ia32_binfmt.c
5111 --- linux-2.6.11/arch/x86_64/ia32/ia32_binfmt.c 2005-03-02 02:37:46.000000000 -0500
5112 +++ linux-2.6.11/arch/x86_64/ia32/ia32_binfmt.c 2005-03-09 11:56:44.000000000 -0500
5113 @@ -186,6 +186,17 @@ struct elf_prpsinfo
5114  //#include <asm/ia32.h>
5115  #include <linux/elf.h>
5116  
5117 +#ifdef CONFIG_PAX_ASLR
5118 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
5119 +
5120 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5121 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
5122 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5123 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
5124 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5125 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 24)
5126 +#endif
5127 +
5128  typedef struct user_i387_ia32_struct elf_fpregset_t;
5129  typedef struct user32_fxsr_struct elf_fpxregset_t;
5130  
5131 diff -urNp linux-2.6.11/arch/x86_64/ia32/sys_ia32.c linux-2.6.11/arch/x86_64/ia32/sys_ia32.c
5132 --- linux-2.6.11/arch/x86_64/ia32/sys_ia32.c    2005-03-02 02:38:07.000000000 -0500
5133 +++ linux-2.6.11/arch/x86_64/ia32/sys_ia32.c    2005-03-09 11:56:44.000000000 -0500
5134 @@ -209,6 +209,11 @@ sys32_mmap(struct mmap_arg_struct __user
5135         if (a.offset & ~PAGE_MASK)
5136                 return -EINVAL; 
5137  
5138 +#ifdef CONFIG_PAX_RANDEXEC
5139 +       if (a.flags & MAP_MIRROR)
5140 +               return -EINVAL;
5141 +#endif
5142 +
5143         if (!(a.flags & MAP_ANONYMOUS)) {
5144                 file = fget(a.fd);
5145                 if (!file)
5146 @@ -841,6 +846,11 @@ asmlinkage long sys32_mmap2(unsigned lon
5147         unsigned long error;
5148         struct file * file = NULL;
5149  
5150 +#ifdef CONFIG_PAX_RANDEXEC
5151 +       if (flags & MAP_MIRROR)
5152 +               return -EINVAL;
5153 +#endif
5154 +
5155         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
5156         if (!(flags & MAP_ANONYMOUS)) {
5157                 file = fget(fd);
5158 diff -urNp linux-2.6.11/arch/x86_64/kernel/ptrace.c linux-2.6.11/arch/x86_64/kernel/ptrace.c
5159 --- linux-2.6.11/arch/x86_64/kernel/ptrace.c    2005-03-02 02:37:53.000000000 -0500
5160 +++ linux-2.6.11/arch/x86_64/kernel/ptrace.c    2005-03-09 11:56:44.000000000 -0500
5161 @@ -214,6 +214,9 @@ asmlinkage long sys_ptrace(long request,
5162         if (pid == 1)           /* you may not mess with init */
5163                 goto out_tsk;
5164  
5165 +        if (gr_handle_ptrace(child, request))
5166 +                goto out_tsk;
5167 +
5168         if (request == PTRACE_ATTACH) {
5169                 ret = ptrace_attach(child);
5170                 goto out_tsk;
5171 diff -urNp linux-2.6.11/arch/x86_64/kernel/sys_x86_64.c linux-2.6.11/arch/x86_64/kernel/sys_x86_64.c
5172 --- linux-2.6.11/arch/x86_64/kernel/sys_x86_64.c        2005-03-02 02:38:13.000000000 -0500
5173 +++ linux-2.6.11/arch/x86_64/kernel/sys_x86_64.c        2005-03-09 11:56:44.000000000 -0500
5174 @@ -48,6 +48,11 @@ long sys_mmap(unsigned long addr, unsign
5175         if (off & ~PAGE_MASK)
5176                 goto out;
5177  
5178 +#ifdef CONFIG_PAX_RANDEXEC
5179 +       if (flags & MAP_MIRROR)
5180 +               goto out;
5181 +#endif
5182 +
5183         error = -EBADF;
5184         file = NULL;
5185         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
5186 @@ -102,6 +107,15 @@ arch_get_unmapped_area(struct file *filp
5187         
5188         find_start_end(flags, &begin, &end); 
5189  
5190 +#ifdef CONFIG_PAX_RANDMMAP
5191 +       if ((mm->flags & MF_PAX_RANDMMAP) && (!addr || filp)) {
5192 +               if (begin == 0x40000000)
5193 +                       begin += mm->delta_mmap & 0x0FFFFFFFU;
5194 +               else
5195 +                       begin += mm->delta_mmap;
5196 +       }
5197 +#endif
5198 +
5199         if (len > end)
5200                 return -ENOMEM;
5201  
5202 diff -urNp linux-2.6.11/arch/x86_64/mm/fault.c linux-2.6.11/arch/x86_64/mm/fault.c
5203 --- linux-2.6.11/arch/x86_64/mm/fault.c 2005-03-02 02:37:31.000000000 -0500
5204 +++ linux-2.6.11/arch/x86_64/mm/fault.c 2005-03-09 11:56:44.000000000 -0500
5205 @@ -24,6 +24,7 @@
5206  #include <linux/compiler.h>
5207  #include <linux/module.h>
5208  #include <linux/kprobes.h>
5209 +#include <linux/binfmts.h>
5210  
5211  #include <asm/system.h>
5212  #include <asm/uaccess.h>
5213 @@ -280,6 +281,63 @@ static int vmalloc_fault(unsigned long a
5214         return 0;
5215  }
5216  
5217 +#ifdef CONFIG_PAX_PAGEEXEC
5218 +/*
5219 + * PaX: decide what to do with offenders (regs->rip = fault address)
5220 + *
5221 + * returns 1 when task should be killed
5222 + *         2 when legitimate ET_EXEC was detected
5223 + */
5224 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5225 +{
5226 +
5227 +#ifdef CONFIG_PAX_RANDEXEC
5228 +       int err;
5229 +
5230 +       if (current->mm->flags & MF_PAX_RANDEXEC) {
5231 +               if (regs->rip >= current->mm->start_code &&
5232 +                   regs->rip < current->mm->end_code)
5233 +               {
5234 +                       if (test_thread_flag(TIF_IA32)) {
5235 +                               unsigned int esp_4;
5236 +
5237 +                               err = get_user(esp_4, (unsigned int*)(regs->rsp-4UL));
5238 +                               if (err || esp_4 == regs->rip)
5239 +                                       return 1;
5240 +                       } else {
5241 +                               unsigned long esp_8;
5242 +
5243 +                               err = get_user(esp_8, (unsigned long*)(regs->rsp-8UL));
5244 +                               if (err || esp_8 == regs->rip)
5245 +                                       return 1;
5246 +                       }
5247 +
5248 +                       regs->rip += current->mm->delta_exec;
5249 +                       return 2;
5250 +               }
5251 +       }
5252 +#endif
5253 +
5254 +       return 1;
5255 +}
5256 +
5257 +void pax_report_insns(void *pc, void *sp)
5258 +{
5259 +       unsigned long i;
5260 +
5261 +       printk(KERN_ERR "PAX: bytes at PC: ");
5262 +       for (i = 0; i < 20; i++) {
5263 +               unsigned int c;
5264 +               if (get_user(c, (unsigned char*)pc+i)) {
5265 +                       printk("<invalid address>.");
5266 +                       break;
5267 +               }
5268 +               printk("%08x ", c);
5269 +       }
5270 +       printk("\n");
5271 +}
5272 +#endif
5273 +
5274  int page_fault_trace = 0;
5275  int exception_trace = 1;
5276  
5277 @@ -405,7 +463,7 @@ asmlinkage void do_page_fault(struct pt_
5278                 if (address + 128 < regs->rsp)
5279                         goto bad_area;
5280         }
5281 -       if (expand_stack(vma, address))
5282 +       if (expand_stack(tsk, vma, address))
5283                 goto bad_area;
5284  /*
5285   * Ok, we have a good vm_area for this memory access, so
5286 @@ -414,6 +472,8 @@ asmlinkage void do_page_fault(struct pt_
5287  good_area:
5288         info.si_code = SEGV_ACCERR;
5289         write = 0;
5290 +       if ((error_code & 16) && !(vma->vm_flags & VM_EXEC))
5291 +               goto bad_area;
5292         switch (error_code & 3) {
5293                 default:        /* 3: write, present */
5294                         /* fall through */
5295 @@ -491,7 +551,22 @@ bad_area_nosemaphore:
5296                                         tsk->comm, tsk->pid, address, regs->rip,
5297                                         regs->rsp, error_code);
5298                 }
5299 -       
5300 +
5301 +#ifdef CONFIG_PAX_PAGEEXEC
5302 +               if (mm && (mm->flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
5303 +                       switch(pax_handle_fetch_fault(regs)) {
5304 +
5305 +#ifdef CONFIG_PAX_RANDEXEC
5306 +                       case 2:
5307 +                               return;
5308 +#endif
5309 +
5310 +                       }
5311 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
5312 +                       do_exit(SIGKILL);
5313 +               }
5314 +#endif
5315 +
5316                 tsk->thread.cr2 = address;
5317                 /* Kernel addresses are always protection faults */
5318                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
5319 diff -urNp linux-2.6.11/drivers/char/keyboard.c linux-2.6.11/drivers/char/keyboard.c
5320 --- linux-2.6.11/drivers/char/keyboard.c        2005-03-02 02:38:37.000000000 -0500
5321 +++ linux-2.6.11/drivers/char/keyboard.c        2005-03-09 11:56:44.000000000 -0500
5322 @@ -606,6 +606,16 @@ static void k_spec(struct vc_data *vc, u
5323              kbd->kbdmode == VC_MEDIUMRAW) && 
5324              value != KVAL(K_SAK))
5325                 return;         /* SAK is allowed even in raw mode */
5326 +
5327 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
5328 +       {
5329 +               void *func = fn_handler[value];
5330 +               if (func == fn_show_state || func == fn_show_ptregs ||
5331 +                   func == fn_show_mem)
5332 +                       return;
5333 +       }
5334 +#endif
5335 +
5336         fn_handler[value](vc, regs);
5337  }
5338  
5339 diff -urNp linux-2.6.11/drivers/char/mem.c linux-2.6.11/drivers/char/mem.c
5340 --- linux-2.6.11/drivers/char/mem.c     2005-03-02 02:38:09.000000000 -0500
5341 +++ linux-2.6.11/drivers/char/mem.c     2005-03-09 11:56:44.000000000 -0500
5342 @@ -23,6 +23,7 @@
5343  #include <linux/devfs_fs_kernel.h>
5344  #include <linux/ptrace.h>
5345  #include <linux/device.h>
5346 +#include <linux/grsecurity.h>
5347  
5348  #include <asm/uaccess.h>
5349  #include <asm/io.h>
5350 @@ -35,6 +36,10 @@
5351  extern void tapechar_init(void);
5352  #endif
5353  
5354 +#ifdef CONFIG_GRKERNSEC
5355 +extern struct file_operations grsec_fops;
5356 +#endif
5357 +
5358  /*
5359   * Architectures vary in how they handle caching for addresses
5360   * outside of main memory.
5361 @@ -187,6 +192,12 @@ static ssize_t write_mem(struct file * f
5362  
5363         if (!valid_phys_addr_range(p, &count))
5364                 return -EFAULT;
5365 +
5366 +#ifdef CONFIG_GRKERNSEC_KMEM
5367 +       gr_handle_mem_write();
5368 +       return -EPERM;
5369 +#endif
5370 +
5371         return do_write_mem(__va(p), p, buf, count, ppos);
5372  }
5373  
5374 @@ -201,6 +212,11 @@ static int mmap_mem(struct file * file, 
5375                 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
5376  #endif
5377  
5378 +#ifdef CONFIG_GRKERNSEC_KMEM
5379 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
5380 +               return -EPERM;
5381 +#endif
5382 +
5383         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
5384         if (remap_pfn_range(vma,
5385                             vma->vm_start,
5386 @@ -289,6 +305,11 @@ static ssize_t write_kmem(struct file * 
5387         ssize_t written;
5388         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
5389  
5390 +#ifdef CONFIG_GRKERNSEC_KMEM
5391 +       gr_handle_kmem_write();
5392 +       return -EPERM;
5393 +#endif
5394 +
5395         if (p < (unsigned long) high_memory) {
5396  
5397                 wrote = count;
5398 @@ -415,7 +436,23 @@ static inline size_t read_zero_pagealign
5399                         count = size;
5400  
5401                 zap_page_range(vma, addr, count, NULL);
5402 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
5403 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
5404 +
5405 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
5406 +               if (vma->vm_flags & VM_MIRROR) {
5407 +                       unsigned long addr_m;
5408 +                       struct vm_area_struct * vma_m;
5409 +
5410 +                       addr_m = vma->vm_start + vma->vm_mirror;
5411 +                       vma_m = find_vma(mm, addr_m);
5412 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
5413 +                               addr_m = addr + vma->vm_mirror;
5414 +                               zap_page_range(vma_m, addr_m, count, NULL);
5415 +                       } else
5416 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
5417 +                                      addr, vma->vm_start);
5418 +               }
5419 +#endif
5420  
5421                 size -= count;
5422                 buf += count;
5423 @@ -564,6 +601,16 @@ static loff_t memory_lseek(struct file *
5424  
5425  static int open_port(struct inode * inode, struct file * filp)
5426  {
5427 +#ifdef CONFIG_GRKERNSEC_KMEM
5428 +       gr_handle_open_port();
5429 +       return -EPERM;
5430 +#endif
5431 +
5432 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5433 +}
5434 +
5435 +static int open_mem(struct inode * inode, struct file * filp)
5436 +{
5437         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5438  }
5439  
5440 @@ -572,7 +619,6 @@ static int open_port(struct inode * inod
5441  #define full_lseek      null_lseek
5442  #define write_zero     write_null
5443  #define read_full       read_zero
5444 -#define open_mem       open_port
5445  #define open_kmem      open_mem
5446  
5447  static struct file_operations mem_fops = {
5448 @@ -673,6 +719,11 @@ static int memory_open(struct inode * in
5449                 case 11:
5450                         filp->f_op = &kmsg_fops;
5451                         break;
5452 +#ifdef CONFIG_GRKERNSEC
5453 +               case 12:
5454 +                       filp->f_op = &grsec_fops;
5455 +                       break;
5456 +#endif
5457                 default:
5458                         return -ENXIO;
5459         }
5460 @@ -702,6 +753,9 @@ static const struct {
5461         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
5462         {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
5463         {11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops},
5464 +#ifdef CONFIG_GRKERNSEC
5465 +       {12,"grsec",   S_IRUSR | S_IWUGO,           &grsec_fops},
5466 +#endif
5467  };
5468  
5469  static struct class_simple *mem_class;
5470 diff -urNp linux-2.6.11/drivers/char/random.c linux-2.6.11/drivers/char/random.c
5471 --- linux-2.6.11/drivers/char/random.c  2005-03-02 02:37:48.000000000 -0500
5472 +++ linux-2.6.11/drivers/char/random.c  2005-03-09 11:56:44.000000000 -0500
5473 @@ -256,9 +256,15 @@
5474  /*
5475   * Configuration information
5476   */
5477 +#ifdef CONFIG_GRKERNSEC_RANDNET
5478 +#define DEFAULT_POOL_SIZE 1024
5479 +#define SECONDARY_POOL_SIZE 256
5480 +#define BATCH_ENTROPY_SIZE 512
5481 +#else
5482  #define DEFAULT_POOL_SIZE 512
5483  #define SECONDARY_POOL_SIZE 128
5484  #define BATCH_ENTROPY_SIZE 256
5485 +#endif
5486  #define USE_SHA
5487  
5488  /*
5489 @@ -1965,7 +1971,7 @@ static void sysctl_init_random(struct en
5490   *
5491   ********************************************************************/
5492  
5493 -#ifdef CONFIG_INET
5494 +#if defined(CONFIG_INET) || defined(CONFIG_PAX_ASLR)
5495  /*
5496   * TCP initial sequence number picking.  This uses the random number
5497   * generator to pick an initial secret value.  This value is hashed
5498 @@ -2383,3 +2389,25 @@ __u32 check_tcp_syn_cookie(__u32 cookie,
5499  }
5500  #endif
5501  #endif /* CONFIG_INET */
5502 +
5503 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
5504 +unsigned long pax_get_random_long(void)
5505 +{
5506 +       static time_t   rekey_time;
5507 +       static __u32    secret[12];
5508 +       time_t          t;
5509 +
5510 +       /*
5511 +        * Pick a random secret every REKEY_INTERVAL seconds.
5512 +        */
5513 +       t = get_seconds();
5514 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
5515 +               rekey_time = t;
5516 +               get_random_bytes(secret, sizeof(secret));
5517 +       }
5518 +
5519 +       secret[1] = halfMD4Transform(secret+8, secret);
5520 +       secret[0] = halfMD4Transform(secret+8, secret);
5521 +       return *(unsigned long *)secret;
5522 +}
5523 +#endif
5524 diff -urNp linux-2.6.11/drivers/char/vt_ioctl.c linux-2.6.11/drivers/char/vt_ioctl.c
5525 --- linux-2.6.11/drivers/char/vt_ioctl.c        2005-03-02 02:38:38.000000000 -0500
5526 +++ linux-2.6.11/drivers/char/vt_ioctl.c        2005-03-09 11:56:44.000000000 -0500
5527 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
5528         case KDSKBENT:
5529                 if (!perm)
5530                         return -EPERM;
5531 +
5532 +#ifdef CONFIG_GRKERNSEC
5533 +               if (!capable(CAP_SYS_TTY_CONFIG))
5534 +                       return -EPERM;
5535 +#endif
5536 +
5537                 if (!i && v == K_NOSUCHMAP) {
5538                         /* disallocate map */
5539                         key_map = key_maps[s];
5540 @@ -233,6 +239,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
5541                         goto reterr;
5542                 }
5543  
5544 +#ifdef CONFIG_GRKERNSEC
5545 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
5546 +                       ret = -EPERM;
5547 +                       goto reterr;
5548 +               }
5549 +#endif
5550 +
5551                 q = func_table[i];
5552                 first_free = funcbufptr + (funcbufsize - funcbufleft);
5553                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
5554 diff -urNp linux-2.6.11/drivers/net/wan/sdla_ppp.c linux-2.6.11/drivers/net/wan/sdla_ppp.c
5555 --- linux-2.6.11/drivers/net/wan/sdla_ppp.c     2005-03-02 02:37:49.000000000 -0500
5556 +++ linux-2.6.11/drivers/net/wan/sdla_ppp.c     2005-03-09 11:56:44.000000000 -0500
5557 @@ -450,7 +450,7 @@ static int update(struct wan_device *wan
5558         sdla_t* card = wandev->private;
5559         struct net_device* dev;
5560          volatile ppp_private_area_t *ppp_priv_area;
5561 -       ppp_flags_t *flags = card->flags;
5562 +       ppp_flags_t *flags;
5563         unsigned long timeout;
5564  
5565         /* sanity checks */
5566 @@ -474,6 +474,7 @@ static int update(struct wan_device *wan
5567         
5568         ppp_priv_area->update_comms_stats = 2;
5569         ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
5570 +       flags = card->flags;
5571         flags->imask |= PPP_INTR_TIMER; 
5572         
5573         /* wait a maximum of 1 second for the statistics to be updated */ 
5574 diff -urNp linux-2.6.11/drivers/pci/proc.c linux-2.6.11/drivers/pci/proc.c
5575 --- linux-2.6.11/drivers/pci/proc.c     2005-03-02 02:38:10.000000000 -0500
5576 +++ linux-2.6.11/drivers/pci/proc.c     2005-03-09 11:56:44.000000000 -0500
5577 @@ -565,7 +565,15 @@ static struct file_operations proc_pci_o
5578  
5579  static void legacy_proc_init(void)
5580  {
5581 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
5582 +#ifdef CONFIG_GRKERNSEC_PROC_USER
5583 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
5584 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
5585 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
5586 +#endif
5587 +#else
5588         struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
5589 +#endif
5590         if (entry)
5591                 entry->proc_fops = &proc_pci_operations;
5592  }
5593 @@ -594,7 +602,15 @@ static int __init pci_proc_init(void)
5594  {
5595         struct proc_dir_entry *entry;
5596         struct pci_dev *dev = NULL;
5597 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
5598 +#ifdef CONFIG_GRKERNSEC_PROC_USER
5599 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
5600 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
5601 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
5602 +#endif
5603 +#else
5604         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
5605 +#endif
5606         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
5607         if (entry)
5608                 entry->proc_fops = &proc_bus_pci_dev_operations;
5609 diff -urNp linux-2.6.11/drivers/pnp/pnpbios/bioscalls.c linux-2.6.11/drivers/pnp/pnpbios/bioscalls.c
5610 --- linux-2.6.11/drivers/pnp/pnpbios/bioscalls.c        2005-03-02 02:38:13.000000000 -0500
5611 +++ linux-2.6.11/drivers/pnp/pnpbios/bioscalls.c        2005-03-09 11:56:44.000000000 -0500
5612 @@ -69,17 +69,17 @@ __asm__(
5613  
5614  #define Q_SET_SEL(cpu, selname, address, size) \
5615  do { \
5616 -set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \
5617 -set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \
5618 +set_base(cpu_gdt_table[cpu][(selname) >> 3], __va((u32)(address))); \
5619 +set_limit(cpu_gdt_table[cpu][(selname) >> 3], size); \
5620  } while(0)
5621  
5622  #define Q2_SET_SEL(cpu, selname, address, size) \
5623  do { \
5624 -set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \
5625 -set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \
5626 +set_base(cpu_gdt_table[cpu][(selname) >> 3], (u32)(address)); \
5627 +set_limit(cpu_gdt_table[cpu][(selname) >> 3], size); \
5628  } while(0)
5629  
5630 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
5631 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
5632  
5633  /*
5634   * At some point we want to use this stack frame pointer to unwind
5635 @@ -107,6 +107,10 @@ static inline u16 call_pnp_bios(u16 func
5636         struct desc_struct save_desc_40;
5637         int cpu;
5638  
5639 +#ifdef CONFIG_PAX_KERNEXEC
5640 +       unsigned long cr3;
5641 +#endif
5642 +
5643         /*
5644          * PnP BIOSes are generally not terribly re-entrant.
5645          * Also, don't rely on them to save everything correctly.
5646 @@ -115,12 +119,17 @@ static inline u16 call_pnp_bios(u16 func
5647                 return PNP_FUNCTION_NOT_SUPPORTED;
5648  
5649         cpu = get_cpu();
5650 -       save_desc_40 = per_cpu(cpu_gdt_table,cpu)[0x40 / 8];
5651 -       per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = bad_bios_desc;
5652  
5653         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
5654         spin_lock_irqsave(&pnp_bios_lock, flags);
5655  
5656 +#ifdef CONFIG_PAX_KERNEXEC
5657 +       pax_open_kernel_noirq(cr3);
5658 +#endif
5659 +
5660 +       save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
5661 +       cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
5662 +
5663         /* The lock prevents us bouncing CPU here */
5664         if (ts1_size)
5665                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
5666 @@ -156,9 +165,14 @@ static inline u16 call_pnp_bios(u16 func
5667                   "i" (0)
5668                 : "memory"
5669         );
5670 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
5671  
5672 -       per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = save_desc_40;
5673 +       cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
5674 +
5675 +#ifdef CONFIG_PAX_KERNEXEC
5676 +       pax_close_kernel_noirq(cr3);
5677 +#endif
5678 +
5679 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
5680         put_cpu();
5681  
5682         /* If we get here and this is set then the PnP BIOS faulted on us. */
5683 diff -urNp linux-2.6.11/drivers/video/vesafb.c linux-2.6.11/drivers/video/vesafb.c
5684 --- linux-2.6.11/drivers/video/vesafb.c 2005-03-02 02:37:48.000000000 -0500
5685 +++ linux-2.6.11/drivers/video/vesafb.c 2005-03-09 11:56:44.000000000 -0500
5686 @@ -268,7 +268,7 @@ static int __init vesafb_probe(struct de
5687                 size_remap = size_total;
5688         vesafb_fix.smem_len = size_remap;
5689  
5690 -#ifndef __i386__
5691 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
5692         screen_info.vesapm_seg = 0;
5693  #endif
5694  
5695 diff -urNp linux-2.6.11/fs/Kconfig linux-2.6.11/fs/Kconfig
5696 --- linux-2.6.11/fs/Kconfig     2005-03-02 02:38:10.000000000 -0500
5697 +++ linux-2.6.11/fs/Kconfig     2005-03-09 11:56:44.000000000 -0500
5698 @@ -715,7 +715,7 @@ config PROC_FS
5699  
5700  config PROC_KCORE
5701         bool "/proc/kcore support" if !ARM
5702 -       depends on PROC_FS && MMU
5703 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
5704  
5705  config SYSFS
5706         bool "sysfs file system support" if EMBEDDED
5707 diff -urNp linux-2.6.11/fs/binfmt_aout.c linux-2.6.11/fs/binfmt_aout.c
5708 --- linux-2.6.11/fs/binfmt_aout.c       2005-03-02 02:38:37.000000000 -0500
5709 +++ linux-2.6.11/fs/binfmt_aout.c       2005-03-09 11:56:44.000000000 -0500
5710 @@ -24,6 +24,7 @@
5711  #include <linux/binfmts.h>
5712  #include <linux/personality.h>
5713  #include <linux/init.h>
5714 +#include <linux/grsecurity.h>
5715  
5716  #include <asm/system.h>
5717  #include <asm/uaccess.h>
5718 @@ -125,10 +126,12 @@ static int aout_core_dump(long signr, st
5719  /* If the size of the dump file exceeds the rlimit, then see what would happen
5720     if we wrote the stack, but not the data area.  */
5721  #ifdef __sparc__
5722 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
5723         if ((dump.u_dsize+dump.u_ssize) >
5724             current->signal->rlim[RLIMIT_CORE].rlim_cur)
5725                 dump.u_dsize = 0;
5726  #else
5727 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
5728         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
5729             current->signal->rlim[RLIMIT_CORE].rlim_cur)
5730                 dump.u_dsize = 0;
5731 @@ -136,10 +139,12 @@ static int aout_core_dump(long signr, st
5732  
5733  /* Make sure we have enough room to write the stack and data areas. */
5734  #ifdef __sparc__
5735 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
5736         if ((dump.u_ssize) >
5737             current->signal->rlim[RLIMIT_CORE].rlim_cur)
5738                 dump.u_ssize = 0;
5739  #else
5740 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
5741         if ((dump.u_ssize+1) * PAGE_SIZE >
5742             current->signal->rlim[RLIMIT_CORE].rlim_cur)
5743                 dump.u_ssize = 0;
5744 @@ -289,6 +294,8 @@ static int load_aout_binary(struct linux
5745         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
5746         if (rlim >= RLIM_INFINITY)
5747                 rlim = ~0;
5748 +
5749 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
5750         if (ex.a_data + ex.a_bss > rlim)
5751                 return -ENOMEM;
5752  
5753 @@ -317,10 +324,33 @@ static int load_aout_binary(struct linux
5754                 (current->mm->start_brk = N_BSSADDR(ex));
5755         current->mm->free_area_cache = current->mm->mmap_base;
5756  
5757 +#ifdef CONFIG_PAX_RANDMMAP
5758 +       if (current->mm->flags & MF_PAX_RANDMMAP)
5759 +               current->mm->free_area_cache += current->mm->delta_mmap;
5760 +#endif
5761 +
5762         current->mm->rss = 0;
5763         current->mm->mmap = NULL;
5764         compute_creds(bprm);
5765         current->flags &= ~PF_FORKNOEXEC;
5766 +
5767 +#ifdef CONFIG_PAX_PAGEEXEC
5768 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
5769 +               current->mm->flags |= MF_PAX_PAGEEXEC;
5770 +
5771 +#ifdef CONFIG_PAX_EMUTRAMP
5772 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
5773 +                       current->mm->flags |= MF_PAX_EMUTRAMP;
5774 +#endif
5775 +
5776 +#ifdef CONFIG_PAX_MPROTECT
5777 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
5778 +                       current->mm->flags |= MF_PAX_MPROTECT;
5779 +#endif
5780 +
5781 +       }
5782 +#endif
5783 +
5784  #ifdef __sparc__
5785         if (N_MAGIC(ex) == NMAGIC) {
5786                 loff_t pos = fd_offset;
5787 @@ -416,7 +446,7 @@ static int load_aout_binary(struct linux
5788  
5789                 down_write(&current->mm->mmap_sem);
5790                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
5791 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
5792 +                               PROT_READ | PROT_WRITE,
5793                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
5794                                 fd_offset + ex.a_text);
5795                 up_write(&current->mm->mmap_sem);
5796 diff -urNp linux-2.6.11/fs/binfmt_elf.c linux-2.6.11/fs/binfmt_elf.c
5797 --- linux-2.6.11/fs/binfmt_elf.c        2005-03-02 02:38:08.000000000 -0500
5798 +++ linux-2.6.11/fs/binfmt_elf.c        2005-03-09 11:56:44.000000000 -0500
5799 @@ -37,11 +37,17 @@
5800  #include <linux/pagemap.h>
5801  #include <linux/security.h>
5802  #include <linux/syscalls.h>
5803 +#include <linux/grsecurity.h>
5804 +#include <linux/random.h>
5805  
5806  #include <asm/uaccess.h>
5807  #include <asm/param.h>
5808  #include <asm/page.h>
5809  
5810 +#ifdef CONFIG_PAX_SEGMEXEC
5811 +#include <asm/desc.h>
5812 +#endif
5813 +
5814  #include <linux/elf.h>
5815  
5816  static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
5817 @@ -89,18 +95,32 @@ static struct linux_binfmt elf_format = 
5818  
5819  static int set_brk(unsigned long start, unsigned long end)
5820  {
5821 +       unsigned long e = end, retval;
5822 +
5823         start = ELF_PAGEALIGN(start);
5824         end = ELF_PAGEALIGN(end);
5825 +
5826 +       down_write(&current->mm->mmap_sem);
5827         if (end > start) {
5828 -               unsigned long addr;
5829 -               down_write(&current->mm->mmap_sem);
5830 -               addr = do_brk(start, end - start);
5831 -               up_write(&current->mm->mmap_sem);
5832 -               if (BAD_ADDR(addr))
5833 -                       return addr;
5834 +               retval = do_brk(start, end - start);
5835 +               if (BAD_ADDR(retval))
5836 +                       goto out;
5837 +
5838 +#ifdef CONFIG_PAX_RANDEXEC
5839 +               if (current->mm->flags & MF_PAX_RANDEXEC) {
5840 +                       retval = __do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
5841 +                       if (BAD_ADDR(retval))
5842 +                               goto out;
5843 +               }
5844 +#endif
5845 +
5846         }
5847 -       current->mm->start_brk = current->mm->brk = end;
5848 -       return 0;
5849 +       current->mm->start_brk = current->mm->brk = e;
5850 +       retval = 0UL;
5851 +
5852 +out:
5853 +       up_write(&current->mm->mmap_sem);
5854 +       return retval;
5855  }
5856  
5857  
5858 @@ -321,6 +341,7 @@ static unsigned long load_elf_interp(str
5859         unsigned long last_bss = 0, elf_bss = 0;
5860         unsigned long error = ~0UL;
5861         int retval, i, size;
5862 +       unsigned long task_size = TASK_SIZE;
5863  
5864         /* First of all, some simple consistency checks */
5865         if (interp_elf_ex->e_type != ET_EXEC &&
5866 @@ -358,6 +379,11 @@ static unsigned long load_elf_interp(str
5867                 goto out_close;
5868         }
5869  
5870 +#ifdef CONFIG_PAX_SEGMEXEC
5871 +       if (current->mm->flags & MF_PAX_SEGMEXEC)
5872 +               task_size = SEGMEXEC_TASK_SIZE;
5873 +#endif
5874 +
5875         eppnt = elf_phdata;
5876         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
5877           if (eppnt->p_type == PT_LOAD) {
5878 @@ -389,8 +415,8 @@ static unsigned long load_elf_interp(str
5879              * <= p_memsize so it is only necessary to check p_memsz.
5880              */
5881             k = load_addr + eppnt->p_vaddr;
5882 -           if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
5883 -               eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
5884 +           if (k > task_size || eppnt->p_filesz > eppnt->p_memsz ||
5885 +               eppnt->p_memsz > task_size || task_size - eppnt->p_memsz < k) {
5886                 error = -ENOMEM;
5887                 goto out_close;
5888             }
5889 @@ -491,6 +517,227 @@ out:
5890         return elf_entry;
5891  }
5892  
5893 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
5894 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
5895 +{
5896 +       unsigned long pax_flags = 0UL;
5897 +
5898 +#ifdef CONFIG_PAX_PAGEEXEC
5899 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
5900 +               pax_flags |= MF_PAX_PAGEEXEC;
5901 +#endif
5902 +
5903 +#ifdef CONFIG_PAX_SEGMEXEC
5904 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
5905 +               pax_flags |= MF_PAX_SEGMEXEC;
5906 +#endif
5907 +
5908 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
5909 +       if (pax_flags & MF_PAX_PAGEEXEC)
5910 +               pax_flags &= ~MF_PAX_SEGMEXEC;
5911 +#endif
5912 +
5913 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
5914 +       if (pax_flags & MF_PAX_SEGMEXEC)
5915 +               pax_flags &= ~MF_PAX_PAGEEXEC;
5916 +#endif
5917 +
5918 +#ifdef CONFIG_PAX_EMUTRAMP
5919 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
5920 +               pax_flags |= MF_PAX_EMUTRAMP;
5921 +#endif
5922 +
5923 +#ifdef CONFIG_PAX_MPROTECT
5924 +       if (elf_phdata->p_flags & PF_MPROTECT)
5925 +               pax_flags |= MF_PAX_MPROTECT;
5926 +#endif
5927 +
5928 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
5929 +
5930 +#ifdef CONFIG_PAX_SOFTMODE
5931 +       if (pax_aslr)
5932 +#endif
5933 +
5934 +       if (elf_phdata->p_flags & PF_RANDMMAP)
5935 +               pax_flags |= MF_PAX_RANDMMAP;
5936 +#endif
5937 +
5938 +#ifdef CONFIG_PAX_RANDEXEC
5939 +
5940 +#ifdef CONFIG_PAX_SOFTMODE
5941 +       if (pax_aslr)
5942 +#endif
5943 +
5944 +       if (elf_phdata->p_flags & PF_RANDEXEC)
5945 +               pax_flags |= MF_PAX_RANDEXEC;
5946 +#endif
5947 +
5948 +       return pax_flags;
5949 +}
5950 +#endif
5951 +
5952 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
5953 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
5954 +{
5955 +       unsigned long pax_flags = 0UL;
5956 +
5957 +#ifdef CONFIG_PAX_PAGEEXEC
5958 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
5959 +               pax_flags |= MF_PAX_PAGEEXEC;
5960 +#endif
5961 +
5962 +#ifdef CONFIG_PAX_SEGMEXEC
5963 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
5964 +               pax_flags |= MF_PAX_SEGMEXEC;
5965 +#endif
5966 +
5967 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
5968 +       if (pax_flags & MF_PAX_PAGEEXEC)
5969 +               pax_flags &= ~MF_PAX_SEGMEXEC;
5970 +#endif
5971 +
5972 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
5973 +       if (pax_flags & MF_PAX_SEGMEXEC)
5974 +               pax_flags &= ~MF_PAX_PAGEEXEC;
5975 +#endif
5976 +
5977 +#ifdef CONFIG_PAX_EMUTRAMP
5978 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
5979 +               pax_flags |= MF_PAX_EMUTRAMP;
5980 +#endif
5981 +
5982 +#ifdef CONFIG_PAX_MPROTECT
5983 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
5984 +               pax_flags |= MF_PAX_MPROTECT;
5985 +#endif
5986 +
5987 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
5988 +
5989 +#ifdef CONFIG_PAX_SOFTMODE
5990 +       if (pax_aslr)
5991 +#endif
5992 +
5993 +       if (!(elf_phdata->p_flags & PF_NORANDMMAP))
5994 +               pax_flags |= MF_PAX_RANDMMAP;
5995 +#endif
5996 +
5997 +#ifdef CONFIG_PAX_RANDEXEC
5998 +
5999 +#ifdef CONFIG_PAX_SOFTMODE
6000 +       if (pax_aslr)
6001 +#endif
6002 +
6003 +       if (!(elf_phdata->p_flags & PF_NORANDEXEC))
6004 +               pax_flags |= MF_PAX_RANDEXEC;
6005 +#endif
6006 +
6007 +       return pax_flags;
6008 +}
6009 +#endif
6010 +
6011 +#ifdef CONFIG_PAX_EI_PAX
6012 +static int pax_parse_ei_pax(const struct elfhdr * const elf_ex)
6013 +{
6014 +       unsigned long pax_flags = 0UL;
6015 +
6016 +#ifdef CONFIG_PAX_PAGEEXEC
6017 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
6018 +               pax_flags |= MF_PAX_PAGEEXEC;
6019 +#endif
6020 +
6021 +#ifdef CONFIG_PAX_SEGMEXEC
6022 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
6023 +               pax_flags |= MF_PAX_SEGMEXEC;
6024 +#endif
6025 +
6026 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
6027 +       if (pax_flags & MF_PAX_PAGEEXEC)
6028 +               pax_flags &= ~MF_PAX_SEGMEXEC;
6029 +#endif
6030 +
6031 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
6032 +       if (pax_flags & MF_PAX_SEGMEXEC)
6033 +               pax_flags &= ~MF_PAX_PAGEEXEC;
6034 +#endif
6035 +
6036 +#ifdef CONFIG_PAX_EMUTRAMP
6037 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
6038 +               pax_flags |= MF_PAX_EMUTRAMP;
6039 +#endif
6040 +
6041 +#ifdef CONFIG_PAX_MPROTECT
6042 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
6043 +               pax_flags |= MF_PAX_MPROTECT;
6044 +#endif
6045 +
6046 +#ifdef CONFIG_PAX_ASLR
6047 +
6048 +#ifdef CONFIG_PAX_SOFTMODE
6049 +       if (pax_aslr)
6050 +#endif
6051 +
6052 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
6053 +               pax_flags |= MF_PAX_RANDMMAP;
6054 +#endif
6055 +
6056 +#ifdef CONFIG_PAX_RANDEXEC
6057 +
6058 +#ifdef CONFIG_PAX_SOFTMODE
6059 +       if (pax_aslr)
6060 +#endif
6061 +
6062 +       if ((elf_ex->e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex->e_type == ET_EXEC) && (pax_flags & MF_PAX_MPROTECT))
6063 +               pax_flags |= MF_PAX_RANDEXEC;
6064 +#endif
6065 +
6066 +       return pax_flags;
6067 +}
6068 +#endif
6069 +
6070 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
6071 +static int pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
6072 +{
6073 +       unsigned long pax_flags = 0UL;
6074 +
6075 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6076 +       unsigned long i;
6077 +#endif
6078 +
6079 +#ifdef CONFIG_PAX_EI_PAX
6080 +       pax_flags = pax_parse_ei_pax(elf_ex);
6081 +#endif
6082 +
6083 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6084 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
6085 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
6086 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
6087 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
6088 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
6089 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
6090 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)) ||
6091 +                           ((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))) ||
6092 +                           (!(elf_phdata[i].p_flags & PF_NORANDEXEC) && (elf_ex->e_type == ET_DYN || (elf_phdata[i].p_flags & PF_NOMPROTECT))))
6093 +                               return -EINVAL;
6094 +
6095 +#ifdef CONFIG_PAX_SOFTMODE
6096 +                       if (pax_softmode)
6097 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
6098 +                       else
6099 +#endif
6100 +
6101 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
6102 +                       break;
6103 +               }
6104 +#endif
6105 +
6106 +       if (0 > pax_check_flags(&pax_flags))
6107 +               return -EINVAL;
6108 +
6109 +       current->mm->flags |= pax_flags;
6110 +       return 0;
6111 +}
6112 +#endif
6113 +
6114  /*
6115   * These are the functions used to load ELF style executables and shared
6116   * libraries.  There is no binary dependent code anywhere else.
6117 @@ -527,6 +774,12 @@ static int load_elf_binary(struct linux_
6118                 struct elfhdr interp_elf_ex;
6119                 struct exec interp_ex;
6120         } *loc;
6121 +       unsigned long task_size = TASK_SIZE;
6122 +
6123 +#ifdef CONFIG_PAX_RANDEXEC
6124 +       unsigned long load_addr_random = 0UL;
6125 +       unsigned long load_bias_random = 0UL;
6126 +#endif
6127  
6128         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
6129         if (!loc) {
6130 @@ -752,11 +1005,78 @@ static int load_elf_binary(struct linux_
6131         current->mm->end_code = 0;
6132         current->mm->mmap = NULL;
6133         current->flags &= ~PF_FORKNOEXEC;
6134 +
6135 +#ifdef CONFIG_PAX_DLRESOLVE
6136 +       current->mm->call_dl_resolve = 0UL;
6137 +#endif
6138 +
6139 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
6140 +       current->mm->call_syscall = 0UL;
6141 +#endif
6142 +
6143 +#ifdef CONFIG_PAX_ASLR
6144 +       current->mm->delta_mmap = 0UL;
6145 +       current->mm->delta_exec = 0UL;
6146 +       current->mm->delta_stack = 0UL;
6147 +#endif
6148 +
6149         current->mm->def_flags = def_flags;
6150  
6151 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
6152 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
6153 +               send_sig(SIGKILL, current, 0);
6154 +               goto out_free_dentry;
6155 +       }
6156 +#endif
6157 +
6158 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
6159 +       pax_set_initial_flags(bprm);
6160 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
6161 +       if (pax_set_initial_flags_func)
6162 +               (pax_set_initial_flags_func)(bprm);
6163 +#endif
6164 +
6165 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
6166 +       if (current->mm->flags & MF_PAX_PAGEEXEC)
6167 +               current->mm->context.user_cs_limit = PAGE_SIZE;
6168 +#endif
6169 +
6170 +#ifdef CONFIG_PAX_SEGMEXEC
6171 +       if (current->mm->flags & MF_PAX_SEGMEXEC) {
6172 +               int cpu = get_cpu();
6173 +
6174 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
6175 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
6176 +               set_user_cs(current->mm, cpu);
6177 +               put_cpu();
6178 +               task_size = SEGMEXEC_TASK_SIZE;
6179 +       }
6180 +#endif
6181 +
6182 +#ifdef CONFIG_PAX_ASLR
6183 +       if (current->mm->flags & MF_PAX_RANDMMAP) {
6184 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
6185 +
6186 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
6187 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
6188 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
6189 +       }
6190 +#endif
6191 +
6192 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6193 +       if (current->mm->flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
6194 +               executable_stack = EXSTACK_DEFAULT;
6195 +#endif
6196 +
6197         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
6198            may depend on the personality.  */
6199         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
6200 +
6201 +
6202 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6203 +       if (!(current->mm->flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
6204 +#endif
6205 +
6206         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
6207                 current->personality |= READ_IMPLIES_EXEC;
6208  
6209 @@ -828,12 +1148,93 @@ static int load_elf_binary(struct linux_
6210                            base, as well as whatever program they might try to exec.  This
6211                            is because the brk will follow the loader, and is not movable.  */
6212                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
6213 +
6214 +#ifdef CONFIG_PAX_RANDMMAP
6215 +                       /* PaX: randomize base address at the default exe base if requested */
6216 +                       if (current->mm->flags & MF_PAX_RANDMMAP) {
6217 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
6218 +                               elf_flags |= MAP_FIXED;
6219 +                       }
6220 +#endif
6221 +
6222                 }
6223  
6224 -               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
6225 -               if (BAD_ADDR(error)) {
6226 -                       send_sig(SIGKILL, current, 0);
6227 -                       goto out_free_dentry;
6228 +#ifdef CONFIG_PAX_RANDEXEC
6229 +               if ((current->mm->flags & MF_PAX_RANDEXEC) && (loc->elf_ex.e_type == ET_EXEC)) {
6230 +                       error = -ENOMEM;
6231 +
6232 +#ifdef CONFIG_PAX_PAGEEXEC
6233 +                       if (current->mm->flags & MF_PAX_PAGEEXEC)
6234 +                               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
6235 +#endif
6236 +
6237 +#ifdef CONFIG_PAX_SEGMEXEC
6238 +                       if (current->mm->flags & MF_PAX_SEGMEXEC) {
6239 +                               unsigned long addr, len;
6240 +
6241 +                               addr = ELF_PAGESTART(load_bias + vaddr);
6242 +                               len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
6243 +                               if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len) {
6244 +                                       send_sig(SIGKILL, current, 0);
6245 +                                       goto out_free_dentry;
6246 +                               }
6247 +                               down_write(&current->mm->mmap_sem);
6248 +                               error = __do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
6249 +                               up_write(&current->mm->mmap_sem);
6250 +                       }
6251 +#endif
6252 +
6253 +                       if (BAD_ADDR(error)) {
6254 +                               send_sig(SIGKILL, current, 0);
6255 +                               goto out_free_dentry;
6256 +                       }
6257 +
6258 +                       /* PaX: mirror at a randomized base */
6259 +                       down_write(&current->mm->mmap_sem);
6260 +
6261 +                       if (!load_addr_set) {
6262 +                               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);
6263 +                               if (BAD_ADDR(load_addr_random)) {
6264 +                                       up_write(&current->mm->mmap_sem);
6265 +                                       send_sig(SIGKILL, current, 0);
6266 +                                       goto out_free_dentry;
6267 +                               }
6268 +                               load_bias_random = load_addr_random - vaddr;
6269 +                       }
6270 +
6271 +#ifdef CONFIG_PAX_PAGEEXEC
6272 +                       if (current->mm->flags & MF_PAX_PAGEEXEC)
6273 +                               load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
6274 +#endif
6275 +
6276 +#ifdef CONFIG_PAX_SEGMEXEC
6277 +                       if (current->mm->flags & MF_PAX_SEGMEXEC) {
6278 +                               if (elf_prot & PROT_EXEC) {
6279 +                                       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);
6280 +                                       if (!BAD_ADDR(load_addr_random)) {
6281 +                                               load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
6282 +                                               if (!BAD_ADDR(load_addr_random))
6283 +                                                       load_addr_random -= SEGMEXEC_TASK_SIZE;
6284 +                                       }
6285 +                               } else
6286 +                                       load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
6287 +                       }
6288 +#endif
6289 +
6290 +                       up_write(&current->mm->mmap_sem);
6291 +                       if (BAD_ADDR(load_addr_random)) {
6292 +                               send_sig(SIGKILL, current, 0);
6293 +                               goto out_free_dentry;
6294 +                       }
6295 +               } else
6296 +#endif
6297 +
6298 +               {
6299 +                       error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
6300 +                       if (BAD_ADDR(error)) {
6301 +                               send_sig(SIGKILL, current, 0);
6302 +                               goto out_free_dentry;
6303 +                       }
6304                 }
6305  
6306                 if (!load_addr_set) {
6307 @@ -845,6 +1246,11 @@ static int load_elf_binary(struct linux_
6308                                 load_addr += load_bias;
6309                                 reloc_func_desc = load_bias;
6310                         }
6311 +
6312 +#ifdef CONFIG_PAX_RANDEXEC
6313 +                       current->mm->delta_exec = load_addr_random - load_addr;
6314 +#endif
6315 +
6316                 }
6317                 k = elf_ppnt->p_vaddr;
6318                 if (k < start_code) start_code = k;
6319 @@ -855,9 +1261,9 @@ static int load_elf_binary(struct linux_
6320                  * allowed task size. Note that p_filesz must always be
6321                  * <= p_memsz so it is only necessary to check p_memsz.
6322                  */
6323 -               if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
6324 -                   elf_ppnt->p_memsz > TASK_SIZE ||
6325 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
6326 +               if (k > task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
6327 +                   elf_ppnt->p_memsz > task_size ||
6328 +                   task_size - elf_ppnt->p_memsz < k) {
6329                         /* set_brk can never work.  Avoid overflows.  */
6330                         send_sig(SIGKILL, current, 0);
6331                         goto out_free_dentry;
6332 @@ -884,6 +1290,16 @@ static int load_elf_binary(struct linux_
6333         start_data += load_bias;
6334         end_data += load_bias;
6335  
6336 +#ifdef CONFIG_PAX_RANDMMAP
6337 +
6338 +#ifdef CONFIG_PAX_SOFTMODE
6339 +       if (pax_aslr)
6340 +#endif
6341 +
6342 +       elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
6343 +#undef pax_delta_mask
6344 +#endif
6345 +
6346         /* Calling set_brk effectively mmaps the pages that we need
6347          * for the bss and break sections.  We must do this before
6348          * mapping in the interpreter, to make sure it doesn't wind
6349 @@ -1126,9 +1542,11 @@ static int maydump(struct vm_area_struct
6350         if (vma->vm_flags & (VM_IO | VM_SHARED | VM_RESERVED))
6351                 return 0;
6352  
6353 +#if 0
6354         /* If it hasn't been written to, don't write it out */
6355         if (!vma->anon_vma)
6356                 return 0;
6357 +#endif
6358  
6359         return 1;
6360  }
6361 @@ -1181,8 +1599,11 @@ static int writenote(struct memelfnote *
6362  #undef DUMP_SEEK
6363  
6364  #define DUMP_WRITE(addr, nr)   \
6365 +       do { \
6366 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
6367         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
6368 -               goto end_coredump;
6369 +               goto end_coredump; \
6370 +       } while (0);
6371  #define DUMP_SEEK(off) \
6372         if (!dump_seek(file, (off))) \
6373                 goto end_coredump;
6374 diff -urNp linux-2.6.11/fs/binfmt_flat.c linux-2.6.11/fs/binfmt_flat.c
6375 --- linux-2.6.11/fs/binfmt_flat.c       2005-03-02 02:37:30.000000000 -0500
6376 +++ linux-2.6.11/fs/binfmt_flat.c       2005-03-09 11:56:44.000000000 -0500
6377 @@ -540,7 +540,9 @@ static int load_flat_file(struct linux_b
6378                                 realdatastart = (unsigned long) -ENOMEM;
6379                         printk("Unable to allocate RAM for process data, errno %d\n",
6380                                         (int)-datapos);
6381 +                       down_write(&current->mm->mmap_sem);
6382                         do_munmap(current->mm, textpos, text_len);
6383 +                       up_write(&current->mm->mmap_sem);
6384                         return realdatastart;
6385                 }
6386                 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
6387 @@ -561,8 +563,10 @@ static int load_flat_file(struct linux_b
6388                 }
6389                 if (result >= (unsigned long)-4096) {
6390                         printk("Unable to read data+bss, errno %d\n", (int)-result);
6391 +                       down_write(&current->mm->mmap_sem);
6392                         do_munmap(current->mm, textpos, text_len);
6393                         do_munmap(current->mm, realdatastart, data_len + extra);
6394 +                       up_write(&current->mm->mmap_sem);
6395                         return result;
6396                 }
6397  
6398 @@ -624,8 +628,10 @@ static int load_flat_file(struct linux_b
6399                 }
6400                 if (result >= (unsigned long)-4096) {
6401                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
6402 +                       down_write(&current->mm->mmap_sem);
6403                         do_munmap(current->mm, textpos, text_len + data_len + extra +
6404                                 MAX_SHARED_LIBS * sizeof(unsigned long));
6405 +                       up_write(&current->mm->mmap_sem);
6406                         return result;
6407                 }
6408         }
6409 diff -urNp linux-2.6.11/fs/binfmt_misc.c linux-2.6.11/fs/binfmt_misc.c
6410 --- linux-2.6.11/fs/binfmt_misc.c       2005-03-02 02:38:00.000000000 -0500
6411 +++ linux-2.6.11/fs/binfmt_misc.c       2005-03-09 11:56:44.000000000 -0500
6412 @@ -112,9 +112,11 @@ static int load_misc_binary(struct linux
6413         struct files_struct *files = NULL;
6414  
6415         retval = -ENOEXEC;
6416 -       if (!enabled)
6417 +       if (!enabled || bprm->misc)
6418                 goto _ret;
6419  
6420 +       bprm->misc++;
6421 +
6422         /* to keep locking time low, we copy the interpreter string */
6423         read_lock(&entries_lock);
6424         fmt = check_file(bprm);
6425 diff -urNp linux-2.6.11/fs/buffer.c linux-2.6.11/fs/buffer.c
6426 --- linux-2.6.11/fs/buffer.c    2005-03-02 02:38:10.000000000 -0500
6427 +++ linux-2.6.11/fs/buffer.c    2005-03-09 11:56:44.000000000 -0500
6428 @@ -39,6 +39,7 @@
6429  #include <linux/notifier.h>
6430  #include <linux/cpu.h>
6431  #include <linux/bitops.h>
6432 +#include <linux/grsecurity.h>
6433  
6434  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
6435  static void invalidate_bh_lrus(void);
6436 @@ -2167,6 +2168,7 @@ int generic_cont_expand(struct inode *in
6437  
6438         err = -EFBIG;
6439          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
6440 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
6441         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
6442                 send_sig(SIGXFSZ, current, 0);
6443                 goto out;
6444 diff -urNp linux-2.6.11/fs/compat.c linux-2.6.11/fs/compat.c
6445 --- linux-2.6.11/fs/compat.c    2005-03-02 02:38:08.000000000 -0500
6446 +++ linux-2.6.11/fs/compat.c    2005-03-09 11:56:44.000000000 -0500
6447 @@ -43,6 +43,7 @@
6448  #include <linux/nfsd/syscall.h>
6449  #include <linux/personality.h>
6450  #include <linux/rwsem.h>
6451 +#include <linux/grsecurity.h>
6452  
6453  #include <net/sock.h>          /* siocdevprivate_ioctl */
6454  
6455 @@ -1427,6 +1428,11 @@ int compat_do_execve(char * filename,
6456         struct file *file;
6457         int retval;
6458         int i;
6459 +#ifdef CONFIG_GRKERNSEC
6460 +       struct file *old_exec_file;
6461 +       struct acl_subject_label *old_acl;
6462 +       struct rlimit old_rlim[RLIM_NLIMITS];
6463 +#endif
6464  
6465         retval = -ENOMEM;
6466         bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
6467 @@ -1445,6 +1451,15 @@ int compat_do_execve(char * filename,
6468         bprm->file = file;
6469         bprm->filename = filename;
6470         bprm->interp = filename;
6471 +
6472 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
6473 +       retval = -EAGAIN;
6474 +       if (gr_handle_nproc())
6475 +               goto out_file;
6476 +       retval = -EACCES;
6477 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
6478 +               goto out_file;
6479 +
6480         bprm->mm = mm_alloc();
6481         retval = -ENOMEM;
6482         if (!bprm->mm)
6483 @@ -1483,16 +1498,52 @@ int compat_do_execve(char * filename,
6484         if (retval < 0)
6485                 goto out;
6486  
6487 +       if (!gr_tpe_allow(file)) {
6488 +               retval = -EACCES;
6489 +               goto out;
6490 +       }
6491 +
6492 +       if (gr_check_crash_exec(file)) {
6493 +               retval = -EACCES;
6494 +               goto out;
6495 +       }
6496 +
6497 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
6498 +
6499 +       gr_handle_exec_args(bprm, argv);
6500 +
6501 +#ifdef CONFIG_GRKERNSEC
6502 +       old_acl = current->acl;
6503 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
6504 +       old_exec_file = current->exec_file;
6505 +       get_file(file);
6506 +       current->exec_file = file;
6507 +#endif
6508 +
6509 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
6510 +
6511         retval = search_binary_handler(bprm, regs);
6512         if (retval >= 0) {
6513                 free_arg_pages(bprm);
6514  
6515 +#ifdef CONFIG_GRKERNSEC
6516 +               if (old_exec_file)
6517 +                       fput(old_exec_file);
6518 +#endif
6519 +
6520                 /* execve success */
6521                 security_bprm_free(bprm);
6522                 kfree(bprm);
6523                 return retval;
6524         }
6525  
6526 +#ifdef CONFIG_GRKERNSEC
6527 +       current->acl = old_acl;
6528 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
6529 +       fput(current->exec_file);
6530 +       current->exec_file = old_exec_file;
6531 +#endif
6532 +
6533  out:
6534         /* Something went wrong, return the inode and free the argument pages*/
6535         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
6536 diff -urNp linux-2.6.11/fs/dcache.c linux-2.6.11/fs/dcache.c
6537 --- linux-2.6.11/fs/dcache.c    2005-03-02 02:37:48.000000000 -0500
6538 +++ linux-2.6.11/fs/dcache.c    2005-03-09 11:56:44.000000000 -0500
6539 @@ -1351,7 +1351,7 @@ already_unhashed:
6540   *
6541   * "buflen" should be positive. Caller holds the dcache_lock.
6542   */
6543 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
6544 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
6545                         struct dentry *root, struct vfsmount *rootmnt,
6546                         char *buffer, int buflen)
6547  {
6548 diff -urNp linux-2.6.11/fs/exec.c linux-2.6.11/fs/exec.c
6549 --- linux-2.6.11/fs/exec.c      2005-03-02 02:38:06.000000000 -0500
6550 +++ linux-2.6.11/fs/exec.c      2005-03-09 11:56:44.000000000 -0500
6551 @@ -48,6 +48,7 @@
6552  #include <linux/syscalls.h>
6553  #include <linux/rmap.h>
6554  #include <linux/acct.h>
6555 +#include <linux/grsecurity.h>
6556  
6557  #include <asm/uaccess.h>
6558  #include <asm/mmu_context.h>
6559 @@ -63,6 +64,20 @@ char core_pattern[65] = "core";
6560  static struct linux_binfmt *formats;
6561  static DEFINE_RWLOCK(binfmt_lock);
6562  
6563 +#ifdef CONFIG_PAX_SOFTMODE
6564 +
6565 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
6566 +unsigned int pax_aslr=1;
6567 +#endif
6568 +
6569 +unsigned int pax_softmode;
6570 +#endif
6571 +
6572 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
6573 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
6574 +EXPORT_SYMBOL(pax_set_initial_flags_func);
6575 +#endif
6576 +
6577  int register_binfmt(struct linux_binfmt * fmt)
6578  {
6579         struct linux_binfmt ** tmp = &formats;
6580 @@ -309,6 +324,10 @@ void install_arg_page(struct vm_area_str
6581         if (unlikely(anon_vma_prepare(vma)))
6582                 goto out_sig;
6583  
6584 +#ifdef CONFIG_PAX_SEGMEXEC
6585 +       if (page_count(page) == 1)
6586 +#endif
6587 +
6588         flush_dcache_page(page);
6589         pgd = pgd_offset(mm, address);
6590  
6591 @@ -327,6 +346,11 @@ void install_arg_page(struct vm_area_str
6592                 goto out;
6593         }
6594         mm->rss++;
6595 +
6596 +#ifdef CONFIG_PAX_SEGMEXEC
6597 +       if (page_count(page) == 1)
6598 +#endif
6599 +
6600         lru_cache_add_active(page);
6601         set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(
6602                                         page, vma->vm_page_prot))));
6603 @@ -355,6 +379,10 @@ int setup_arg_pages(struct linux_binprm 
6604         int i, ret;
6605         long arg_size;
6606  
6607 +#ifdef CONFIG_PAX_SEGMEXEC
6608 +       struct vm_area_struct *mpnt_m = NULL;
6609 +#endif
6610 +
6611  #ifdef CONFIG_STACK_GROWSUP
6612         /* Move the argument and environment strings to the bottom of the
6613          * stack space.
6614 @@ -416,8 +444,24 @@ int setup_arg_pages(struct linux_binprm 
6615         if (!mpnt)
6616                 return -ENOMEM;
6617  
6618 +#ifdef CONFIG_PAX_SEGMEXEC
6619 +       if ((mm->flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
6620 +               mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6621 +               if (!mpnt_m) {
6622 +                       kmem_cache_free(vm_area_cachep, mpnt);
6623 +                       return -ENOMEM;
6624 +               }
6625 +       }
6626 +#endif
6627 +
6628         if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) {
6629                 kmem_cache_free(vm_area_cachep, mpnt);
6630 +
6631 +#ifdef CONFIG_PAX_SEGMEXEC
6632 +               if (mpnt_m)
6633 +                       kmem_cache_free(vm_area_cachep, mpnt_m);
6634 +#endif
6635 +
6636                 return -ENOMEM;
6637         }
6638  
6639 @@ -443,6 +487,13 @@ int setup_arg_pages(struct linux_binprm 
6640                 else
6641                         mpnt->vm_flags = VM_STACK_FLAGS;
6642                 mpnt->vm_flags |= mm->def_flags;
6643 +
6644 +#ifdef CONFIG_PAX_PAGEEXEC
6645 +               if (!(mm->flags & MF_PAX_PAGEEXEC))
6646 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & 0x7];
6647 +               else
6648 +#endif
6649 +
6650                 mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
6651                 if ((ret = insert_vm_struct(mm, mpnt))) {
6652                         up_write(&mm->mmap_sem);
6653 @@ -450,6 +501,30 @@ int setup_arg_pages(struct linux_binprm 
6654                         return ret;
6655                 }
6656                 mm->stack_vm = mm->total_vm = vma_pages(mpnt);
6657 +
6658 +#ifdef CONFIG_PAX_SEGMEXEC
6659 +               if (mpnt_m) {
6660 +                       *mpnt_m = *mpnt;
6661 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
6662 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
6663 +                               mpnt_m->vm_page_prot = PAGE_NONE;
6664 +                       }
6665 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
6666 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
6667 +                       mpnt_m->vm_flags |= VM_MIRROR;
6668 +                       mpnt->vm_flags |= VM_MIRROR;
6669 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
6670 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
6671 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
6672 +                               up_write(&mm->mmap_sem);
6673 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
6674 +                               return ret;
6675 +                       }
6676 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
6677 +                       mm->total_vm += (mpnt_m->vm_end - mpnt_m->vm_start) >> PAGE_SHIFT;
6678 +               }
6679 +#endif
6680 +
6681         }
6682  
6683         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
6684 @@ -457,6 +532,14 @@ int setup_arg_pages(struct linux_binprm 
6685                 if (page) {
6686                         bprm->page[i] = NULL;
6687                         install_arg_page(mpnt, page, stack_base);
6688 +
6689 +#ifdef CONFIG_PAX_SEGMEXEC
6690 +                       if (mpnt_m) {
6691 +                               page_cache_get(page);
6692 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
6693 +                       }
6694 +#endif
6695 +
6696                 }
6697                 stack_base += PAGE_SIZE;
6698         }
6699 @@ -1128,6 +1211,11 @@ int do_execve(char * filename,
6700         struct file *file;
6701         int retval;
6702         int i;
6703 +#ifdef CONFIG_GRKERNSEC
6704 +       struct file *old_exec_file;
6705 +       struct acl_subject_label *old_acl;
6706 +       struct rlimit old_rlim[RLIM_NLIMITS];
6707 +#endif
6708  
6709         retval = -ENOMEM;
6710         bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
6711 @@ -1140,10 +1228,33 @@ int do_execve(char * filename,
6712         if (IS_ERR(file))
6713                 goto out_kfree;
6714  
6715 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
6716 +
6717 +       if (gr_handle_nproc()) {
6718 +               allow_write_access(file);
6719 +               fput(file);
6720 +               return -EAGAIN;
6721 +       }
6722 +
6723 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
6724 +               allow_write_access(file);
6725 +               fput(file);
6726 +               return -EACCES;
6727 +       }
6728 +
6729         sched_exec();
6730  
6731         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
6732  
6733 +#ifdef CONFIG_PAX_RANDUSTACK
6734 +
6735 +#ifdef CONFIG_PAX_SOFTMODE
6736 +       if (pax_aslr)
6737 +#endif
6738 +
6739 +       bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
6740 +#endif
6741 +
6742         bprm->file = file;
6743         bprm->filename = filename;
6744         bprm->interp = filename;
6745 @@ -1185,8 +1296,38 @@ int do_execve(char * filename,
6746         if (retval < 0)
6747                 goto out;
6748  
6749 +       if (!gr_tpe_allow(file)) {
6750 +               retval = -EACCES;
6751 +               goto out;
6752 +       }
6753 +
6754 +       if (gr_check_crash_exec(file)) {
6755 +               retval = -EACCES;
6756 +               goto out;
6757 +       }
6758 +
6759 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
6760 +
6761 +       gr_handle_exec_args(bprm, argv);
6762 +
6763 +#ifdef CONFIG_GRKERNSEC
6764 +       old_acl = current->acl;
6765 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
6766 +       old_exec_file = current->exec_file;
6767 +       get_file(file);
6768 +       current->exec_file = file;
6769 +#endif
6770 +
6771 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
6772 +       if (retval < 0)
6773 +               goto out_fail;
6774 +
6775         retval = search_binary_handler(bprm,regs);
6776         if (retval >= 0) {
6777 +#ifdef CONFIG_GRKERNSEC
6778 +               if (old_exec_file)
6779 +                       fput(old_exec_file);
6780 +#endif
6781                 free_arg_pages(bprm);
6782  
6783                 /* execve success */
6784 @@ -1197,6 +1338,14 @@ int do_execve(char * filename,
6785                 return retval;
6786         }
6787  
6788 +out_fail:
6789 +#ifdef CONFIG_GRKERNSEC
6790 +       current->acl = old_acl;
6791 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
6792 +       fput(current->exec_file);
6793 +       current->exec_file = old_exec_file;
6794 +#endif
6795 +
6796  out:
6797         /* Something went wrong, return the inode and free the argument pages*/
6798         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
6799 @@ -1357,6 +1506,126 @@ static void format_corename(char *corena
6800         *out_ptr = 0;
6801  }
6802  
6803 +int pax_check_flags(unsigned long * flags)
6804 +{
6805 +       int retval = 0;
6806 +
6807 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
6808 +       if (*flags & MF_PAX_SEGMEXEC)
6809 +       {
6810 +               *flags &= ~MF_PAX_SEGMEXEC;
6811 +               retval = -EINVAL;
6812 +       }
6813 +#endif
6814 +
6815 +       if ((*flags & MF_PAX_PAGEEXEC)
6816 +
6817 +#ifdef CONFIG_PAX_PAGEEXEC
6818 +           &&  (*flags & MF_PAX_SEGMEXEC)
6819 +#endif
6820 +
6821 +          )
6822 +       {
6823 +               *flags &= ~MF_PAX_PAGEEXEC;
6824 +               retval = -EINVAL;
6825 +       }
6826 +
6827 +       if ((*flags & MF_PAX_MPROTECT)
6828 +
6829 +#ifdef CONFIG_PAX_MPROTECT
6830 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
6831 +#endif
6832 +
6833 +          )
6834 +       {
6835 +               *flags &= ~MF_PAX_MPROTECT;
6836 +               retval = -EINVAL;
6837 +       }
6838 +
6839 +       if ((*flags & MF_PAX_EMUTRAMP)
6840 +
6841 +#ifdef CONFIG_PAX_EMUTRAMP
6842 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
6843 +#endif
6844 +
6845 +          )
6846 +       {
6847 +               *flags &= ~MF_PAX_EMUTRAMP;
6848 +               retval = -EINVAL;
6849 +       }
6850 +
6851 +       if ((*flags & MF_PAX_RANDEXEC)
6852 +
6853 +#ifdef CONFIG_PAX_RANDEXEC
6854 +           && !(*flags & MF_PAX_MPROTECT)
6855 +#endif
6856 +
6857 +          )
6858 +       {
6859 +               *flags &= ~MF_PAX_RANDEXEC;
6860 +               retval = -EINVAL;
6861 +       }
6862 +
6863 +       return retval;
6864 +}
6865 +
6866 +EXPORT_SYMBOL(pax_check_flags);
6867 +
6868 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6869 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
6870 +{
6871 +       struct task_struct *tsk = current;
6872 +       struct mm_struct *mm = current->mm;
6873 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
6874 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
6875 +       char* path_exec=NULL;
6876 +       char* path_fault=NULL;
6877 +       unsigned long start=0UL, end=0UL, offset=0UL;
6878 +
6879 +       if (buffer_exec && buffer_fault) {
6880 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
6881 +
6882 +               down_read(&mm->mmap_sem);
6883 +               vma = mm->mmap;
6884 +               while (vma && (!vma_exec || !vma_fault)) {
6885 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
6886 +                               vma_exec = vma;
6887 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
6888 +                               vma_fault = vma;
6889 +                       vma = vma->vm_next;
6890 +               }
6891 +               if (vma_exec) {
6892 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
6893 +                       if (IS_ERR(path_exec))
6894 +                               path_exec = "<path too long>";
6895 +               }
6896 +               if (vma_fault) {
6897 +                       start = vma_fault->vm_start;
6898 +                       end = vma_fault->vm_end;
6899 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
6900 +                       if (vma_fault->vm_file) {
6901 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
6902 +                               if (IS_ERR(path_fault))
6903 +                                       path_fault = "<path too long>";
6904 +                       } else
6905 +                               path_fault = "<anonymous mapping>";
6906 +               }
6907 +               up_read(&mm->mmap_sem);
6908 +       }
6909 +       if (tsk->curr_ip)
6910 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: execution attempt in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->curr_ip), path_fault, start, end, offset);
6911 +       else
6912 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
6913 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
6914 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
6915 +                       tsk->uid, tsk->euid, pc, sp);
6916 +       free_page((unsigned long)buffer_exec);
6917 +       free_page((unsigned long)buffer_fault);
6918 +       pax_report_insns(pc, sp);
6919 +       do_coredump(SIGKILL, SIGKILL, regs);
6920 +}
6921 +#endif
6922 +
6923  static void zap_threads (struct mm_struct *mm)
6924  {
6925         struct task_struct *g, *p;
6926 @@ -1455,6 +1724,9 @@ int do_coredump(long signr, int exit_cod
6927         current->signal->group_stop_count = 0;
6928         clear_thread_flag(TIF_SIGPENDING);
6929  
6930 +       if (signr == SIGKILL || signr == SIGILL)
6931 +               gr_handle_brute_attach(current);
6932 +
6933         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
6934                 goto fail_unlock;
6935  
6936 @@ -1480,7 +1752,7 @@ int do_coredump(long signr, int exit_cod
6937                 goto close_fail;
6938         if (!file->f_op->write)
6939                 goto close_fail;
6940 -       if (do_truncate(file->f_dentry, 0) != 0)
6941 +       if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
6942                 goto close_fail;
6943  
6944         retval = binfmt->core_dump(signr, regs, file);
6945 diff -urNp linux-2.6.11/fs/fcntl.c linux-2.6.11/fs/fcntl.c
6946 --- linux-2.6.11/fs/fcntl.c     2005-03-02 02:38:13.000000000 -0500
6947 +++ linux-2.6.11/fs/fcntl.c     2005-03-09 11:56:44.000000000 -0500
6948 @@ -15,6 +15,7 @@
6949  #include <linux/module.h>
6950  #include <linux/security.h>
6951  #include <linux/ptrace.h>
6952 +#include <linux/grsecurity.h>
6953  
6954  #include <asm/poll.h>
6955  #include <asm/siginfo.h>
6956 @@ -55,6 +56,7 @@ static int locate_fd(struct files_struct
6957         int error;
6958  
6959         error = -EINVAL;
6960 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
6961         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
6962                 goto out;
6963  
6964 @@ -74,6 +76,7 @@ repeat:
6965         }
6966         
6967         error = -EMFILE;
6968 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6969         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
6970                 goto out;
6971  
6972 @@ -123,6 +126,8 @@ asmlinkage long sys_dup2(unsigned int ol
6973         struct file * file, *tofree;
6974         struct files_struct * files = current->files;
6975  
6976 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6977 +
6978         spin_lock(&files->file_lock);
6979         if (!(file = fcheck(oldfd)))
6980                 goto out_unlock;
6981 @@ -404,7 +409,8 @@ static inline int sigio_perm(struct task
6982         return (((fown->euid == 0) ||
6983                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
6984                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
6985 -               !security_file_send_sigiotask(p, fown, sig));
6986 +               !security_file_send_sigiotask(p, fown, sig) &&
6987 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
6988  }
6989  
6990  static void send_sigio_to_task(struct task_struct *p,
6991 diff -urNp linux-2.6.11/fs/namei.c linux-2.6.11/fs/namei.c
6992 --- linux-2.6.11/fs/namei.c     2005-03-02 02:37:55.000000000 -0500
6993 +++ linux-2.6.11/fs/namei.c     2005-03-09 11:56:44.000000000 -0500
6994 @@ -28,6 +28,7 @@
6995  #include <linux/syscalls.h>
6996  #include <linux/mount.h>
6997  #include <linux/audit.h>
6998 +#include <linux/grsecurity.h>
6999  #include <asm/namei.h>
7000  #include <asm/uaccess.h>
7001  
7002 @@ -519,6 +520,13 @@ static inline int do_follow_link(struct 
7003         err = security_inode_follow_link(dentry, nd);
7004         if (err)
7005                 goto loop;
7006 +
7007 +       if (gr_handle_follow_link(dentry->d_parent->d_inode,
7008 +                                 dentry->d_inode, dentry, nd->mnt)) {
7009 +               err = -EACCES;
7010 +               goto loop;
7011 +       }
7012 +
7013         current->link_count++;
7014         current->total_link_count++;
7015         nd->depth++;
7016 @@ -871,11 +879,18 @@ return_reval:
7017                                 break;
7018                 }
7019  return_base:
7020 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
7021 +                       path_release(nd);
7022 +                       return -ENOENT;
7023 +               }
7024                 return 0;
7025  out_dput:
7026                 dput(next.dentry);
7027                 break;
7028         }
7029 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
7030 +               err = -ENOENT;
7031 +
7032         path_release(nd);
7033  return_err:
7034         return err;
7035 @@ -1325,7 +1340,7 @@ int may_open(struct nameidata *nd, int a
7036                 if (!error) {
7037                         DQUOT_INIT(inode);
7038                         
7039 -                       error = do_truncate(dentry, 0);
7040 +                       error = do_truncate(dentry, 0, nd->mnt);
7041                 }
7042                 put_write_access(inode);
7043                 if (error)
7044 @@ -1376,6 +1391,17 @@ int open_namei(const char * pathname, in
7045                 error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
7046                 if (error)
7047                         return error;
7048 +
7049 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
7050 +                       error = -EPERM;
7051 +                       goto exit;
7052 +               }
7053 +
7054 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
7055 +                       error = -EACCES;
7056 +                       goto exit;
7057 +               }
7058 +
7059                 goto ok;
7060         }
7061  
7062 @@ -1409,9 +1435,19 @@ do_last:
7063  
7064         /* Negative dentry, just create the file */
7065         if (!dentry->d_inode) {
7066 +               if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
7067 +                       error = -EACCES;
7068 +                       up(&dir->d_inode->i_sem);
7069 +                       goto exit_dput;
7070 +               }
7071 +
7072                 if (!IS_POSIXACL(dir->d_inode))
7073                         mode &= ~current->fs->umask;
7074                 error = vfs_create(dir->d_inode, dentry, mode, nd);
7075 +
7076 +               if (!error)
7077 +                       gr_handle_create(dentry, nd->mnt);
7078 +
7079                 up(&dir->d_inode->i_sem);
7080                 dput(nd->dentry);
7081                 nd->dentry = dentry;
7082 @@ -1426,6 +1462,25 @@ do_last:
7083         /*
7084          * It already exists.
7085          */
7086 +
7087 +       if (gr_handle_rawio(dentry->d_inode)) {
7088 +               error = -EPERM;
7089 +               up(&dir->d_inode->i_sem);
7090 +               goto exit_dput;
7091 +       }
7092 +
7093 +       if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
7094 +               up(&dir->d_inode->i_sem);
7095 +               error = -EACCES;
7096 +               goto exit_dput;
7097 +       }
7098 +
7099 +       if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
7100 +               up(&dir->d_inode->i_sem);
7101 +               error = -EACCES;
7102 +               goto exit_dput;
7103 +       }
7104 +
7105         up(&dir->d_inode->i_sem);
7106  
7107         error = -EEXIST;
7108 @@ -1479,6 +1534,13 @@ do_link:
7109         error = security_inode_follow_link(dentry, nd);
7110         if (error)
7111                 goto exit_dput;
7112 +
7113 +       if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
7114 +                                 dentry, nd->mnt)) {
7115 +               error = -EACCES;
7116 +               goto exit_dput;
7117 +       }
7118 +
7119         error = __do_follow_link(dentry, nd);
7120         dput(dentry);
7121         if (error)
7122 @@ -1585,6 +1647,22 @@ asmlinkage long sys_mknod(const char __u
7123         if (!IS_POSIXACL(nd.dentry->d_inode))
7124                 mode &= ~current->fs->umask;
7125         if (!IS_ERR(dentry)) {
7126 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
7127 +                       error = -EPERM;
7128 +                       dput(dentry);
7129 +                       up(&nd.dentry->d_inode->i_sem);
7130 +                       path_release(&nd);
7131 +                       goto out;
7132 +               }
7133 +
7134 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
7135 +                       error = -EACCES;
7136 +                       dput(dentry);
7137 +                       up(&nd.dentry->d_inode->i_sem);
7138 +                       path_release(&nd);
7139 +                       goto out;
7140 +               }
7141 +
7142                 switch (mode & S_IFMT) {
7143                 case 0: case S_IFREG:
7144                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
7145 @@ -1602,6 +1680,10 @@ asmlinkage long sys_mknod(const char __u
7146                 default:
7147                         error = -EINVAL;
7148                 }
7149 +
7150 +               if (!error)
7151 +                       gr_handle_create(dentry, nd.mnt);
7152 +
7153                 dput(dentry);
7154         }
7155         up(&nd.dentry->d_inode->i_sem);
7156 @@ -1653,9 +1735,19 @@ asmlinkage long sys_mkdir(const char __u
7157                 dentry = lookup_create(&nd, 1);
7158                 error = PTR_ERR(dentry);
7159                 if (!IS_ERR(dentry)) {
7160 +                       error = 0;
7161                         if (!IS_POSIXACL(nd.dentry->d_inode))
7162                                 mode &= ~current->fs->umask;
7163 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
7164 +
7165 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
7166 +                               error = -EACCES;
7167 +
7168 +                       if (!error)
7169 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
7170 +
7171 +                       if (!error)
7172 +                               gr_handle_create(dentry, nd.mnt);
7173 +
7174                         dput(dentry);
7175                 }
7176                 up(&nd.dentry->d_inode->i_sem);
7177 @@ -1739,6 +1831,8 @@ asmlinkage long sys_rmdir(const char __u
7178         char * name;
7179         struct dentry *dentry;
7180         struct nameidata nd;
7181 +       ino_t saved_ino = 0;
7182 +       dev_t saved_dev = 0;
7183  
7184         name = getname(pathname);
7185         if(IS_ERR(name))
7186 @@ -1763,7 +1857,21 @@ asmlinkage long sys_rmdir(const char __u
7187         dentry = lookup_hash(&nd.last, nd.dentry);
7188         error = PTR_ERR(dentry);
7189         if (!IS_ERR(dentry)) {
7190 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
7191 +               error = 0;
7192 +               if (dentry->d_inode) {
7193 +                       if (dentry->d_inode->i_nlink <= 1) {
7194 +                               saved_ino = dentry->d_inode->i_ino;
7195 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
7196 +                       }
7197 +
7198 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
7199 +                               error = -EACCES;
7200 +               }
7201 +
7202 +               if (!error)
7203 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
7204 +               if (!error && (saved_dev || saved_ino))
7205 +                       gr_handle_delete(saved_ino, saved_dev);
7206                 dput(dentry);
7207         }
7208         up(&nd.dentry->d_inode->i_sem);
7209 @@ -1817,6 +1925,8 @@ asmlinkage long sys_unlink(const char __
7210         struct dentry *dentry;
7211         struct nameidata nd;
7212         struct inode *inode = NULL;
7213 +       ino_t saved_ino = 0;
7214 +       dev_t saved_dev = 0;
7215  
7216         name = getname(pathname);
7217         if(IS_ERR(name))
7218 @@ -1832,13 +1942,26 @@ asmlinkage long sys_unlink(const char __
7219         dentry = lookup_hash(&nd.last, nd.dentry);
7220         error = PTR_ERR(dentry);
7221         if (!IS_ERR(dentry)) {
7222 +               error = 0;
7223                 /* Why not before? Because we want correct error value */
7224                 if (nd.last.name[nd.last.len])
7225                         goto slashes;
7226                 inode = dentry->d_inode;
7227 -               if (inode)
7228 +               if (inode) {
7229 +                       if (inode->i_nlink <= 1) {
7230 +                               saved_ino = inode->i_ino;
7231 +                               saved_dev = inode->i_sb->s_dev;
7232 +                       }
7233 +
7234 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
7235 +                               error = -EACCES;
7236 +
7237                         atomic_inc(&inode->i_count);
7238 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
7239 +               }
7240 +               if (!error)
7241 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
7242 +               if (!error && (saved_ino || saved_dev))
7243 +                       gr_handle_delete(saved_ino, saved_dev);
7244         exit2:
7245                 dput(dentry);
7246         }
7247 @@ -1901,7 +2024,15 @@ asmlinkage long sys_symlink(const char _
7248                 dentry = lookup_create(&nd, 0);
7249                 error = PTR_ERR(dentry);
7250                 if (!IS_ERR(dentry)) {
7251 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
7252 +                       error = 0;
7253 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
7254 +                               error = -EACCES;
7255 +
7256 +                       if (!error)
7257 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
7258 +
7259 +                       if (!error)
7260 +                               gr_handle_create(dentry, nd.mnt);
7261                         dput(dentry);
7262                 }
7263                 up(&nd.dentry->d_inode->i_sem);
7264 @@ -1985,7 +2116,20 @@ asmlinkage long sys_link(const char __us
7265         new_dentry = lookup_create(&nd, 0);
7266         error = PTR_ERR(new_dentry);
7267         if (!IS_ERR(new_dentry)) {
7268 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
7269 +               error = 0;
7270 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
7271 +                                      old_nd.dentry->d_inode,
7272 +                                      old_nd.dentry->d_inode->i_mode, to))
7273 +                       error = -EPERM;
7274 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
7275 +                                       old_nd.dentry, old_nd.mnt, to))
7276 +                       error = -EACCES;
7277 +               if (!error)
7278 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
7279 +
7280 +               if (!error)
7281 +                       gr_handle_create(new_dentry, nd.mnt);
7282 +
7283                 dput(new_dentry);
7284         }
7285         up(&nd.dentry->d_inode->i_sem);
7286 @@ -2207,8 +2351,16 @@ static inline int do_rename(const char *
7287         if (new_dentry == trap)
7288                 goto exit5;
7289  
7290 -       error = vfs_rename(old_dir->d_inode, old_dentry,
7291 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
7292 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
7293 +                                    newname);
7294 +
7295 +       if (!error)
7296 +               error = vfs_rename(old_dir->d_inode, old_dentry,
7297                                    new_dir->d_inode, new_dentry);
7298 +       if (!error)
7299 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
7300 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
7301  exit5:
7302         dput(new_dentry);
7303  exit4:
7304 diff -urNp linux-2.6.11/fs/namespace.c linux-2.6.11/fs/namespace.c
7305 --- linux-2.6.11/fs/namespace.c 2005-03-02 02:38:13.000000000 -0500
7306 +++ linux-2.6.11/fs/namespace.c 2005-03-09 11:56:44.000000000 -0500
7307 @@ -22,6 +22,8 @@
7308  #include <linux/namei.h>
7309  #include <linux/security.h>
7310  #include <linux/mount.h>
7311 +#include <linux/sched.h>
7312 +#include <linux/grsecurity.h>
7313  #include <asm/uaccess.h>
7314  #include <asm/unistd.h>
7315  
7316 @@ -426,6 +428,8 @@ static int do_umount(struct vfsmount *mn
7317                         DQUOT_OFF(sb);
7318                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
7319                         unlock_kernel();
7320 +
7321 +                       gr_log_remount(mnt->mnt_devname, retval);
7322                 }
7323                 up_write(&sb->s_umount);
7324                 return retval;
7325 @@ -454,6 +458,9 @@ static int do_umount(struct vfsmount *mn
7326         if (retval)
7327                 security_sb_umount_busy(mnt);
7328         up_write(&current->namespace->sem);
7329 +
7330 +       gr_log_unmount(mnt->mnt_devname, retval);
7331 +
7332         return retval;
7333  }
7334  
7335 @@ -1044,6 +1051,11 @@ long do_mount(char * dev_name, char * di
7336         if (retval)
7337                 goto dput_out;
7338  
7339 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
7340 +               retval = -EPERM;
7341 +               goto dput_out;
7342 +       }
7343 +
7344         if (flags & MS_REMOUNT)
7345                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
7346                                     data_page);
7347 @@ -1056,6 +1068,9 @@ long do_mount(char * dev_name, char * di
7348                                       dev_name, data_page);
7349  dput_out:
7350         path_release(&nd);
7351 +
7352 +       gr_log_mount(dev_name, dir_name, retval);
7353 +
7354         return retval;
7355  }
7356  
7357 @@ -1276,6 +1291,9 @@ asmlinkage long sys_pivot_root(const cha
7358         if (!capable(CAP_SYS_ADMIN))
7359                 return -EPERM;
7360  
7361 +       if (gr_handle_chroot_pivot())
7362 +               return -EPERM;
7363 +
7364         lock_kernel();
7365  
7366         error = __user_walk(new_root, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
7367 diff -urNp linux-2.6.11/fs/open.c linux-2.6.11/fs/open.c
7368 --- linux-2.6.11/fs/open.c      2005-03-02 02:37:47.000000000 -0500
7369 +++ linux-2.6.11/fs/open.c      2005-03-09 11:56:44.000000000 -0500
7370 @@ -23,6 +23,7 @@
7371  #include <linux/fs.h>
7372  #include <linux/pagemap.h>
7373  #include <linux/syscalls.h>
7374 +#include <linux/grsecurity.h>
7375  
7376  #include <asm/unistd.h>
7377  
7378 @@ -192,7 +193,7 @@ out:
7379         return error;
7380  }
7381  
7382 -int do_truncate(struct dentry *dentry, loff_t length)
7383 +int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
7384  {
7385         int err;
7386         struct iattr newattrs;
7387 @@ -201,6 +202,9 @@ int do_truncate(struct dentry *dentry, l
7388         if (length < 0)
7389                 return -EINVAL;
7390  
7391 +       if (!gr_acl_handle_truncate(dentry, mnt))
7392 +               return -EACCES;
7393 +
7394         newattrs.ia_size = length;
7395         newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
7396  
7397 @@ -260,7 +264,7 @@ static inline long do_sys_truncate(const
7398         error = locks_verify_truncate(inode, NULL, length);
7399         if (!error) {
7400                 DQUOT_INIT(inode);
7401 -               error = do_truncate(nd.dentry, length);
7402 +               error = do_truncate(nd.dentry, length, nd.mnt);
7403         }
7404         put_write_access(inode);
7405  
7406 @@ -312,7 +316,7 @@ static inline long do_sys_ftruncate(unsi
7407  
7408         error = locks_verify_truncate(inode, file, length);
7409         if (!error)
7410 -               error = do_truncate(dentry, length);
7411 +               error = do_truncate(dentry, length, file->f_vfsmnt);
7412  out_putf:
7413         fput(file);
7414  out:
7415 @@ -391,6 +395,11 @@ asmlinkage long sys_utime(char __user * 
7416                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
7417                         goto dput_and_out;
7418         }
7419 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
7420 +               error = -EACCES;
7421 +               goto dput_and_out;
7422 +       }
7423 +
7424         down(&inode->i_sem);
7425         error = notify_change(nd.dentry, &newattrs);
7426         up(&inode->i_sem);
7427 @@ -444,6 +453,12 @@ long do_utimes(char __user * filename, s
7428                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
7429                         goto dput_and_out;
7430         }
7431 +
7432 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
7433 +               error = -EACCES;
7434 +               goto dput_and_out;
7435 +       }
7436 +
7437         down(&inode->i_sem);
7438         error = notify_change(nd.dentry, &newattrs);
7439         up(&inode->i_sem);
7440 @@ -505,6 +520,10 @@ asmlinkage long sys_access(const char __
7441                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
7442                    && !special_file(nd.dentry->d_inode->i_mode))
7443                         res = -EROFS;
7444 +
7445 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
7446 +                       res = -EACCES;
7447 +
7448                 path_release(&nd);
7449         }
7450  
7451 @@ -528,6 +547,8 @@ asmlinkage long sys_chdir(const char __u
7452         if (error)
7453                 goto dput_and_out;
7454  
7455 +       gr_log_chdir(nd.dentry, nd.mnt);
7456 +
7457         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
7458  
7459  dput_and_out:
7460 @@ -558,6 +579,13 @@ asmlinkage long sys_fchdir(unsigned int 
7461                 goto out_putf;
7462  
7463         error = permission(inode, MAY_EXEC, NULL);
7464 +
7465 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
7466 +               error = -EPERM;
7467 +
7468 +       if (!error)
7469 +               gr_log_chdir(dentry, mnt);
7470 +
7471         if (!error)
7472                 set_fs_pwd(current->fs, mnt, dentry);
7473  out_putf:
7474 @@ -583,8 +611,16 @@ asmlinkage long sys_chroot(const char __
7475         if (!capable(CAP_SYS_CHROOT))
7476                 goto dput_and_out;
7477  
7478 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
7479 +               goto dput_and_out;
7480 +
7481         set_fs_root(current->fs, nd.mnt, nd.dentry);
7482         set_fs_altroot();
7483 +
7484 +       gr_handle_chroot_caps(current);
7485 +
7486 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
7487 +
7488         error = 0;
7489  dput_and_out:
7490         path_release(&nd);
7491 @@ -613,9 +649,22 @@ asmlinkage long sys_fchmod(unsigned int 
7492         err = -EPERM;
7493         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7494                 goto out_putf;
7495 +
7496 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
7497 +               err = -EACCES;
7498 +               goto out_putf;
7499 +       }
7500 +
7501         down(&inode->i_sem);
7502         if (mode == (mode_t) -1)
7503                 mode = inode->i_mode;
7504 +
7505 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
7506 +               err = -EPERM;
7507 +               up(&inode->i_sem);
7508 +               goto out_putf;
7509 +       }
7510 +
7511         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
7512         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
7513         err = notify_change(dentry, &newattrs);
7514 @@ -647,9 +696,21 @@ asmlinkage long sys_chmod(const char __u
7515         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7516                 goto dput_and_out;
7517  
7518 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
7519 +               error = -EACCES;
7520 +               goto dput_and_out;
7521 +       }
7522 +
7523         down(&inode->i_sem);
7524         if (mode == (mode_t) -1)
7525                 mode = inode->i_mode;
7526 +
7527 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
7528 +               error = -EACCES;
7529 +               up(&inode->i_sem);
7530 +               goto dput_and_out;
7531 +       }
7532 +
7533         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
7534         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
7535         error = notify_change(nd.dentry, &newattrs);
7536 @@ -661,7 +722,7 @@ out:
7537         return error;
7538  }
7539  
7540 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
7541 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
7542  {
7543         struct inode * inode;
7544         int error;
7545 @@ -678,6 +739,12 @@ static int chown_common(struct dentry * 
7546         error = -EPERM;
7547         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7548                 goto out;
7549 +
7550 +       if (!gr_acl_handle_chown(dentry, mnt)) {
7551 +               error = -EACCES;
7552 +               goto out;
7553 +       }
7554 +
7555         newattrs.ia_valid =  ATTR_CTIME;
7556         if (user != (uid_t) -1) {
7557                 newattrs.ia_valid |= ATTR_UID;
7558 @@ -703,7 +770,7 @@ asmlinkage long sys_chown(const char __u
7559  
7560         error = user_path_walk(filename, &nd);
7561         if (!error) {
7562 -               error = chown_common(nd.dentry, user, group);
7563 +               error = chown_common(nd.dentry, user, group, nd.mnt);
7564                 path_release(&nd);
7565         }
7566         return error;
7567 @@ -716,7 +783,7 @@ asmlinkage long sys_lchown(const char __
7568  
7569         error = user_path_walk_link(filename, &nd);
7570         if (!error) {
7571 -               error = chown_common(nd.dentry, user, group);
7572 +               error = chown_common(nd.dentry, user, group, nd.mnt);
7573                 path_release(&nd);
7574         }
7575         return error;
7576 @@ -730,7 +797,8 @@ asmlinkage long sys_fchown(unsigned int 
7577  
7578         file = fget(fd);
7579         if (file) {
7580 -               error = chown_common(file->f_dentry, user, group);
7581 +               error = chown_common(file->f_dentry, user,
7582 +                                    group, file->f_vfsmnt);
7583                 fput(file);
7584         }
7585         return error;
7586 @@ -852,6 +920,7 @@ repeat:
7587          * N.B. For clone tasks sharing a files structure, this test
7588          * will limit the total number of files that can be opened.
7589          */
7590 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
7591         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
7592                 goto out;
7593  
7594 diff -urNp linux-2.6.11/fs/proc/array.c linux-2.6.11/fs/proc/array.c
7595 --- linux-2.6.11/fs/proc/array.c        2005-03-02 02:38:10.000000000 -0500
7596 +++ linux-2.6.11/fs/proc/array.c        2005-03-09 11:56:44.000000000 -0500
7597 @@ -281,6 +281,22 @@ static inline char *task_cap(struct task
7598                             cap_t(p->cap_effective));
7599  }
7600  
7601 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
7602 +static inline char *task_pax(struct task_struct *p, char *buffer)
7603 +{
7604 +       if (p->mm)
7605 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c%c\n",
7606 +                               p->mm->flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
7607 +                               p->mm->flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
7608 +                               p->mm->flags & MF_PAX_MPROTECT ? 'M' : 'm',
7609 +                               p->mm->flags & MF_PAX_RANDMMAP ? 'R' : 'r',
7610 +                               p->mm->flags & MF_PAX_RANDEXEC ? 'X' : 'x',
7611 +                               p->mm->flags & MF_PAX_SEGMEXEC ? 'S' : 's');
7612 +       else
7613 +               return buffer + sprintf(buffer, "PaX:\t------\n");
7614 +}
7615 +#endif
7616 +
7617  int proc_pid_status(struct task_struct *task, char * buffer)
7618  {
7619         char * orig = buffer;
7620 @@ -298,9 +314,20 @@ int proc_pid_status(struct task_struct *
7621  #if defined(CONFIG_ARCH_S390)
7622         buffer = task_show_regs(task, buffer);
7623  #endif
7624 +
7625 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
7626 +       buffer = task_pax(task, buffer);
7627 +#endif
7628 +
7629         return buffer - orig;
7630  }
7631  
7632 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7633 +#define PAX_RAND_FLAGS (task->mm && (task->mm->flags & MF_PAX_RANDMMAP || \
7634 +                       task->mm->flags & MF_PAX_SEGMEXEC || \
7635 +                       task->mm->flags & MF_PAX_RANDEXEC))
7636 +#endif
7637 +
7638  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
7639  {
7640         unsigned long vsize, eip, esp, wchan = ~0UL;
7641 @@ -385,6 +412,19 @@ static int do_task_stat(struct task_stru
7642                 stime = task->stime;
7643         }
7644  
7645 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7646 +       if (PAX_RAND_FLAGS) {
7647 +               eip = 0;
7648 +               esp = 0;
7649 +               wchan = 0;
7650 +       }
7651 +#endif
7652 +#ifdef CONFIG_GRKERNSEC_HIDESYM
7653 +       wchan = 0;
7654 +       eip =0;
7655 +       esp =0;
7656 +#endif
7657 +
7658         /* scale priority and nice values from timeslices to -20..20 */
7659         /* to make it look like a "normal" Unix priority/nice value  */
7660         priority = task_prio(task);
7661 @@ -425,9 +465,15 @@ static int do_task_stat(struct task_stru
7662                 vsize,
7663                 mm ? mm->rss : 0, /* you might want to shift this left 3 */
7664                 rsslim,
7665 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7666 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
7667 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
7668 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
7669 +#else
7670                 mm ? mm->start_code : 0,
7671                 mm ? mm->end_code : 0,
7672                 mm ? mm->start_stack : 0,
7673 +#endif
7674                 esp,
7675                 eip,
7676                 /* The signal information here is obsolete.
7677 @@ -473,3 +519,14 @@ int proc_pid_statm(struct task_struct *t
7678         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
7679                        size, resident, shared, text, lib, data, 0);
7680  }
7681 +
7682 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7683 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
7684 +{
7685 +       int len;
7686 +
7687 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
7688 +       return len;
7689 +}
7690 +#endif
7691 +
7692 diff -urNp linux-2.6.11/fs/proc/base.c linux-2.6.11/fs/proc/base.c
7693 --- linux-2.6.11/fs/proc/base.c 2005-03-02 02:38:12.000000000 -0500
7694 +++ linux-2.6.11/fs/proc/base.c 2005-03-09 11:56:44.000000000 -0500
7695 @@ -32,6 +32,7 @@
7696  #include <linux/mount.h>
7697  #include <linux/security.h>
7698  #include <linux/ptrace.h>
7699 +#include <linux/grsecurity.h>
7700  #include "internal.h"
7701  
7702  /*
7703 @@ -74,6 +75,9 @@ enum pid_directory_inos {
7704  #ifdef CONFIG_AUDITSYSCALL
7705         PROC_TGID_LOGINUID,
7706  #endif
7707 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7708 +       PROC_TGID_IPADDR,
7709 +#endif
7710         PROC_TGID_FD_DIR,
7711         PROC_TGID_OOM_SCORE,
7712         PROC_TGID_OOM_ADJUST,
7713 @@ -134,6 +138,9 @@ static struct pid_entry tgid_base_stuff[
7714         E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
7715         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
7716         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
7717 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7718 +       E(PROC_TGID_IPADDR,     "ipaddr",  S_IFREG|S_IRUSR),
7719 +#endif
7720  #ifdef CONFIG_SECURITY
7721         E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
7722  #endif
7723 @@ -269,7 +276,7 @@ static int proc_root_link(struct inode *
7724         (task->parent == current && \
7725         (task->ptrace & PT_PTRACED) && \
7726          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
7727 -        security_ptrace(current,task) == 0))
7728 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
7729  
7730  static int may_ptrace_attach(struct task_struct *task)
7731  {
7732 @@ -284,13 +291,15 @@ static int may_ptrace_attach(struct task
7733              (current->uid != task->uid) ||
7734              (current->gid != task->egid) ||
7735              (current->gid != task->sgid) ||
7736 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
7737 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
7738                 goto out;
7739         rmb();
7740 -       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
7741 +       if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
7742                 goto out;
7743         if (security_ptrace(current, task))
7744                 goto out;
7745 +       if (gr_handle_proc_ptrace(task))
7746 +               goto out;
7747  
7748         retval = 1;
7749  out:
7750 @@ -464,9 +473,25 @@ out:
7751  
7752  static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
7753  {
7754 +       int ret = -EACCES;
7755 +       struct task_struct *task;
7756 +
7757         if (generic_permission(inode, mask, NULL) != 0)
7758 -               return -EACCES;
7759 -       return proc_check_root(inode);
7760 +               goto out;
7761 +
7762 +       ret = proc_check_root(inode);
7763 +       if (ret)
7764 +               goto out;
7765 +
7766 +       task = proc_task(inode);
7767 +
7768 +       if (!task)
7769 +               goto out;
7770 +
7771 +       ret = gr_acl_handle_procpidmem(task);
7772 +
7773 +out:
7774 +       return ret;
7775  }
7776  
7777  extern struct seq_operations proc_pid_maps_op;
7778 @@ -1067,6 +1092,9 @@ static struct inode *proc_pid_make_inode
7779                 inode->i_uid = task->euid;
7780                 inode->i_gid = task->egid;
7781         }
7782 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7783 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7784 +#endif
7785         security_task_to_inode(task, inode);
7786  
7787  out:
7788 @@ -1095,7 +1123,9 @@ static int pid_revalidate(struct dentry 
7789         if (pid_alive(task)) {
7790                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
7791                         inode->i_uid = task->euid;
7792 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
7793                         inode->i_gid = task->egid;
7794 +#endif
7795                 } else {
7796                         inode->i_uid = 0;
7797                         inode->i_gid = 0;
7798 @@ -1416,6 +1446,12 @@ static struct dentry *proc_pident_lookup
7799                         inode->i_fop = &proc_info_file_operations;
7800                         ei->op.proc_read = proc_pid_status;
7801                         break;
7802 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7803 +               case PROC_TGID_IPADDR:
7804 +                       inode->i_fop = &proc_info_file_operations;
7805 +                       ei->op.proc_read = proc_pid_ipaddr;
7806 +                       break;
7807 +#endif
7808                 case PROC_TID_STAT:
7809                         inode->i_fop = &proc_info_file_operations;
7810                         ei->op.proc_read = proc_tid_stat;
7811 @@ -1692,6 +1728,22 @@ struct dentry *proc_pid_lookup(struct in
7812         if (!task)
7813                 goto out;
7814  
7815 +       if (gr_check_hidden_task(task)) {
7816 +               put_task_struct(task);
7817 +               goto out;
7818 +       }
7819 +
7820 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
7821 +       if (current->uid && (task->uid != current->uid)
7822 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7823 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7824 +#endif
7825 +       ) {
7826 +               put_task_struct(task);
7827 +               goto out;
7828 +       }
7829 +#endif
7830 +
7831         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
7832  
7833  
7834 @@ -1699,7 +1751,15 @@ struct dentry *proc_pid_lookup(struct in
7835                 put_task_struct(task);
7836                 goto out;
7837         }
7838 +
7839 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7840 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
7841 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7842 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
7843 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7844 +#else
7845         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
7846 +#endif
7847         inode->i_op = &proc_tgid_base_inode_operations;
7848         inode->i_fop = &proc_tgid_base_operations;
7849         inode->i_nlink = 3;
7850 @@ -1783,6 +1843,9 @@ out:
7851  static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
7852  {
7853         struct task_struct *p;
7854 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
7855 +       struct task_struct *tmp = current;
7856 +#endif
7857         int nr_tgids = 0;
7858  
7859         index--;
7860 @@ -1803,6 +1866,18 @@ static int get_tgid_list(int index, unsi
7861                 int tgid = p->pid;
7862                 if (!pid_alive(p))
7863                         continue;
7864 +               if (gr_pid_is_chrooted(p))
7865 +                       continue;
7866 +               if (gr_check_hidden_task(p))
7867 +                       continue;
7868 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
7869 +               if (tmp->uid && (p->uid != tmp->uid)
7870 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7871 +                   && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7872 +#endif
7873 +               )
7874 +                       continue;
7875 +#endif
7876                 if (--index >= 0)
7877                         continue;
7878                 tgids[nr_tgids] = tgid;
7879 diff -urNp linux-2.6.11/fs/proc/inode.c linux-2.6.11/fs/proc/inode.c
7880 --- linux-2.6.11/fs/proc/inode.c        2005-03-02 02:38:25.000000000 -0500
7881 +++ linux-2.6.11/fs/proc/inode.c        2005-03-09 11:56:44.000000000 -0500
7882 @@ -209,7 +209,11 @@ struct inode *proc_get_inode(struct supe
7883                 if (de->mode) {
7884                         inode->i_mode = de->mode;
7885                         inode->i_uid = de->uid;
7886 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7887 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7888 +#else
7889                         inode->i_gid = de->gid;
7890 +#endif
7891                 }
7892                 if (de->size)
7893                         inode->i_size = de->size;
7894 diff -urNp linux-2.6.11/fs/proc/internal.h linux-2.6.11/fs/proc/internal.h
7895 --- linux-2.6.11/fs/proc/internal.h     2005-03-02 02:37:48.000000000 -0500
7896 +++ linux-2.6.11/fs/proc/internal.h     2005-03-09 11:56:44.000000000 -0500
7897 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
7898  extern int proc_tgid_stat(struct task_struct *, char *);
7899  extern int proc_pid_status(struct task_struct *, char *);
7900  extern int proc_pid_statm(struct task_struct *, char *);
7901 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7902 +extern int proc_pid_ipaddr(struct task_struct*,char*);
7903 +#endif
7904  
7905  static inline struct task_struct *proc_task(struct inode *inode)
7906  {
7907 diff -urNp linux-2.6.11/fs/proc/proc_misc.c linux-2.6.11/fs/proc/proc_misc.c
7908 --- linux-2.6.11/fs/proc/proc_misc.c    2005-03-02 02:37:49.000000000 -0500
7909 +++ linux-2.6.11/fs/proc/proc_misc.c    2005-03-09 11:56:44.000000000 -0500
7910 @@ -547,6 +547,8 @@ void create_seq_entry(char *name, mode_t
7911  void __init proc_misc_init(void)
7912  {
7913         struct proc_dir_entry *entry;
7914 +       int gr_mode = 0;
7915 +
7916         static struct {
7917                 char *name;
7918                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
7919 @@ -561,9 +563,13 @@ void __init proc_misc_init(void)
7920  #ifdef CONFIG_STRAM_PROC
7921                 {"stram",       stram_read_proc},
7922  #endif
7923 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7924                 {"devices",     devices_read_proc},
7925 +#endif
7926                 {"filesystems", filesystems_read_proc},
7927 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7928                 {"cmdline",     cmdline_read_proc},
7929 +#endif
7930                 {"locks",       locks_read_proc},
7931                 {"execdomains", execdomains_read_proc},
7932                 {NULL,}
7933 @@ -571,6 +577,16 @@ void __init proc_misc_init(void)
7934         for (p = simple_ones; p->name; p++)
7935                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
7936  
7937 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7938 +       gr_mode = S_IRUSR;
7939 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7940 +       gr_mode = S_IRUSR | S_IRGRP;
7941 +#endif
7942 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7943 +       create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
7944 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
7945 +#endif
7946 +
7947         proc_symlink("mounts", NULL, "self/mounts");
7948  
7949         /* And now for trickier ones */
7950 @@ -581,17 +597,21 @@ void __init proc_misc_init(void)
7951         create_seq_entry("partitions", 0, &proc_partitions_operations);
7952         create_seq_entry("stat", 0, &proc_stat_operations);
7953         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
7954 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7955 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
7956 +#else
7957         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
7958 +#endif
7959         create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
7960         create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
7961         create_seq_entry("diskstats", 0, &proc_diskstats_operations);
7962  #ifdef CONFIG_MODULES
7963 -       create_seq_entry("modules", 0, &proc_modules_operations);
7964 +       create_seq_entry("modules", gr_mode, &proc_modules_operations);
7965  #endif
7966  #ifdef CONFIG_SCHEDSTATS
7967         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
7968  #endif
7969 -#ifdef CONFIG_PROC_KCORE
7970 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
7971         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
7972         if (proc_root_kcore) {
7973                 proc_root_kcore->proc_fops = &proc_kcore_operations;
7974 diff -urNp linux-2.6.11/fs/proc/root.c linux-2.6.11/fs/proc/root.c
7975 --- linux-2.6.11/fs/proc/root.c 2005-03-02 02:38:17.000000000 -0500
7976 +++ linux-2.6.11/fs/proc/root.c 2005-03-09 11:56:44.000000000 -0500
7977 @@ -52,7 +52,13 @@ void __init proc_root_init(void)
7978                 return;
7979         }
7980         proc_misc_init();
7981 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7982 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
7983 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7984 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
7985 +#else
7986         proc_net = proc_mkdir("net", NULL);
7987 +#endif
7988         proc_net_stat = proc_mkdir("net/stat", NULL);
7989  
7990  #ifdef CONFIG_SYSVIPC
7991 @@ -76,7 +82,15 @@ void __init proc_root_init(void)
7992  #ifdef CONFIG_PROC_DEVICETREE
7993         proc_device_tree_init();
7994  #endif
7995 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7996 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7997 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
7998 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7999 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
8000 +#endif
8001 +#else
8002         proc_bus = proc_mkdir("bus", NULL);
8003 +#endif
8004  }
8005  
8006  static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
8007 diff -urNp linux-2.6.11/fs/proc/task_mmu.c linux-2.6.11/fs/proc/task_mmu.c
8008 --- linux-2.6.11/fs/proc/task_mmu.c     2005-03-02 02:37:49.000000000 -0500
8009 +++ linux-2.6.11/fs/proc/task_mmu.c     2005-03-09 11:56:44.000000000 -0500
8010 @@ -21,13 +21,25 @@ char *task_mem(struct mm_struct *mm, cha
8011                 "VmStk:\t%8lu kB\n"
8012                 "VmExe:\t%8lu kB\n"
8013                 "VmLib:\t%8lu kB\n"
8014 -               "VmPTE:\t%8lu kB\n",
8015 -               (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
8016 +               "VmPTE:\t%8lu kB\n"
8017 +
8018 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8019 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
8020 +#endif
8021 +
8022 +               ,(mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
8023                 mm->locked_vm << (PAGE_SHIFT-10),
8024                 mm->rss << (PAGE_SHIFT-10),
8025                 data << (PAGE_SHIFT-10),
8026                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
8027 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
8028 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
8029 +
8030 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8031 +               , mm->context.user_cs_base, mm->context.user_cs_limit
8032 +#endif
8033 +
8034 +               );
8035 +
8036         return buffer;
8037  }
8038  
8039 @@ -77,8 +89,17 @@ out:
8040         return result;
8041  }
8042  
8043 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8044 +#define PAX_RAND_FLAGS (task->mm && (task->mm->flags & MF_PAX_RANDMMAP || \
8045 +                       task->mm->flags & MF_PAX_SEGMEXEC || \
8046 +                       task->mm->flags & MF_PAX_RANDEXEC))
8047 +#endif
8048 +
8049  static int show_map(struct seq_file *m, void *v)
8050  {
8051 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8052 +       struct task_struct *task = m->private;
8053 +#endif
8054         struct vm_area_struct *map = v;
8055         struct file *file = map->vm_file;
8056         int flags = map->vm_flags;
8057 @@ -93,13 +114,23 @@ static int show_map(struct seq_file *m, 
8058         }
8059  
8060         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
8061 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8062 +                       PAX_RAND_FLAGS ? 0UL : map->vm_start,
8063 +                       PAX_RAND_FLAGS ? 0UL : map->vm_end,
8064 +#else
8065                         map->vm_start,
8066                         map->vm_end,
8067 +#endif
8068 +
8069                         flags & VM_READ ? 'r' : '-',
8070                         flags & VM_WRITE ? 'w' : '-',
8071                         flags & VM_EXEC ? 'x' : '-',
8072                         flags & VM_MAYSHARE ? 's' : 'p',
8073 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8074 +                       PAX_RAND_FLAGS ? 0UL : map->vm_pgoff << PAGE_SHIFT,
8075 +#else
8076                         map->vm_pgoff << PAGE_SHIFT,
8077 +#endif
8078                         MAJOR(dev), MINOR(dev), ino, &len);
8079  
8080         if (map->vm_file) {
8081 diff -urNp linux-2.6.11/fs/readdir.c linux-2.6.11/fs/readdir.c
8082 --- linux-2.6.11/fs/readdir.c   2005-03-02 02:38:08.000000000 -0500
8083 +++ linux-2.6.11/fs/readdir.c   2005-03-09 11:56:44.000000000 -0500
8084 @@ -16,6 +16,8 @@
8085  #include <linux/security.h>
8086  #include <linux/syscalls.h>
8087  #include <linux/unistd.h>
8088 +#include <linux/namei.h>
8089 +#include <linux/grsecurity.h>
8090  
8091  #include <asm/uaccess.h>
8092  
8093 @@ -65,6 +67,7 @@ struct old_linux_dirent {
8094  
8095  struct readdir_callback {
8096         struct old_linux_dirent __user * dirent;
8097 +       struct file * file;
8098         int result;
8099  };
8100  
8101 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
8102  
8103         if (buf->result)
8104                 return -EINVAL;
8105 +
8106 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8107 +               return 0;
8108 +
8109         buf->result++;
8110         dirent = buf->dirent;
8111         if (!access_ok(VERIFY_WRITE, dirent,
8112 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
8113  
8114         buf.result = 0;
8115         buf.dirent = dirent;
8116 +       buf.file = file;
8117  
8118         error = vfs_readdir(file, fillonedir, &buf);
8119         if (error >= 0)
8120 @@ -133,6 +141,7 @@ struct linux_dirent {
8121  struct getdents_callback {
8122         struct linux_dirent __user * current_dir;
8123         struct linux_dirent __user * previous;
8124 +       struct file * file;
8125         int count;
8126         int error;
8127  };
8128 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
8129         buf->error = -EINVAL;   /* only used if we fail.. */
8130         if (reclen > buf->count)
8131                 return -EINVAL;
8132 +
8133 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8134 +               return 0;
8135 +
8136         dirent = buf->previous;
8137         if (dirent) {
8138                 if (__put_user(offset, &dirent->d_off))
8139 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
8140  
8141         buf.current_dir = dirent;
8142         buf.previous = NULL;
8143 +       buf.file = file;
8144         buf.count = count;
8145         buf.error = 0;
8146  
8147 @@ -217,6 +231,7 @@ out:
8148  struct getdents_callback64 {
8149         struct linux_dirent64 __user * current_dir;
8150         struct linux_dirent64 __user * previous;
8151 +       struct file * file;
8152         int count;
8153         int error;
8154  };
8155 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
8156         buf->error = -EINVAL;   /* only used if we fail.. */
8157         if (reclen > buf->count)
8158                 return -EINVAL;
8159 +
8160 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8161 +               return 0;
8162 +
8163         dirent = buf->previous;
8164         if (dirent) {
8165                 if (__put_user(offset, &dirent->d_off))
8166 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned 
8167  
8168         buf.current_dir = dirent;
8169         buf.previous = NULL;
8170 +       buf.file = file;
8171         buf.count = count;
8172         buf.error = 0;
8173  
8174 diff -urNp linux-2.6.11/fs/xfs/linux-2.6/xfs_file.c linux-2.6.11/fs/xfs/linux-2.6/xfs_file.c
8175 --- linux-2.6.11/fs/xfs/linux-2.6/xfs_file.c    2005-03-02 02:38:09.000000000 -0500
8176 +++ linux-2.6.11/fs/xfs/linux-2.6/xfs_file.c    2005-03-09 11:56:44.000000000 -0500
8177 @@ -407,6 +407,11 @@ linvfs_file_mmap(
8178                         return error;
8179         }
8180  
8181 +#ifdef CONFIG_PAX_PAGEEXEC
8182 +       if (vma->vm_mm->flags & MF_PAX_PAGEEXEC)
8183 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
8184 +#endif
8185 +
8186         vma->vm_ops = &linvfs_file_vm_ops;
8187  
8188         VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
8189 diff -urNp linux-2.6.11/grsecurity/Kconfig linux-2.6.11/grsecurity/Kconfig
8190 --- linux-2.6.11/grsecurity/Kconfig     1969-12-31 19:00:00.000000000 -0500
8191 +++ linux-2.6.11/grsecurity/Kconfig     2005-03-09 11:56:44.000000000 -0500
8192 @@ -0,0 +1,866 @@
8193 +#
8194 +# grecurity configuration
8195 +#
8196 +
8197 +menu "Grsecurity"
8198 +
8199 +config GRKERNSEC
8200 +       bool "Grsecurity"
8201 +       select CRYPTO
8202 +       select CRYPTO_SHA256
8203 +       help
8204 +         If you say Y here, you will be able to configure many features
8205 +         that will enhance the security of your system.  It is highly
8206 +         recommended that you say Y here and read through the help
8207 +         for each option so that you fully understand the features and
8208 +         can evaluate their usefulness for your machine.
8209 +
8210 +choice
8211 +       prompt "Security Level"
8212 +       depends GRKERNSEC
8213 +       default GRKERNSEC_CUSTOM
8214 +
8215 +config GRKERNSEC_LOW
8216 +       bool "Low"
8217 +       select GRKERNSEC_LINK
8218 +       select GRKERNSEC_FIFO
8219 +       select GRKERNSEC_RANDPID
8220 +       select GRKERNSEC_EXECVE
8221 +       select GRKERNSEC_RANDNET
8222 +       select GRKERNSEC_DMESG
8223 +       select GRKERNSEC_CHROOT_CHDIR
8224 +       help
8225 +         If you choose this option, several of the grsecurity options will
8226 +         be enabled that will give you greater protection against a number
8227 +         of attacks, while assuring that none of your software will have any
8228 +         conflicts with the additional security measures.  If you run a lot
8229 +         of unusual software, or you are having problems with the higher
8230 +         security levels, you should say Y here.  With this option, the
8231 +         following features are enabled:
8232 +
8233 +         - Linking restrictions
8234 +         - FIFO restrictions
8235 +         - Randomized PIDs
8236 +         - Enforcing RLIMIT_NPROC on execve
8237 +         - Restricted dmesg
8238 +         - Enforced chdir("/") on chroot
8239 +
8240 +config GRKERNSEC_MEDIUM
8241 +       bool "Medium"
8242 +       select PAX
8243 +       select PAX_EI_PAX
8244 +       select PAX_PT_PAX_FLAGS
8245 +       select PAX_HAVE_ACL_FLAGS
8246 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
8247 +       select GRKERNSEC_CHROOT_SYSCTL
8248 +       select GRKERNSEC_LINK
8249 +       select GRKERNSEC_FIFO
8250 +       select GRKERNSEC_RANDPID
8251 +       select GRKERNSEC_EXECVE
8252 +       select GRKERNSEC_DMESG
8253 +       select GRKERNSEC_RANDNET
8254 +       select GRKERNSEC_RANDSRC
8255 +       select GRKERNSEC_FORKFAIL
8256 +       select GRKERNSEC_TIME
8257 +       select GRKERNSEC_SIGNAL
8258 +       select GRKERNSEC_CHROOT
8259 +       select GRKERNSEC_CHROOT_UNIX
8260 +       select GRKERNSEC_CHROOT_MOUNT
8261 +       select GRKERNSEC_CHROOT_PIVOT
8262 +       select GRKERNSEC_CHROOT_DOUBLE
8263 +       select GRKERNSEC_CHROOT_CHDIR
8264 +       select GRKERNSEC_CHROOT_MKNOD
8265 +       select GRKERNSEC_PROC
8266 +       select GRKERNSEC_PROC_USERGROUP
8267 +       select PAX_RANDUSTACK
8268 +       select PAX_ASLR
8269 +       select PAX_RANDMMAP
8270 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
8271 +
8272 +       help
8273 +         If you say Y here, several features in addition to those included
8274 +         in the low additional security level will be enabled.  These
8275 +         features provide even more security to your system, though in rare
8276 +         cases they may be incompatible with very old or poorly written
8277 +         software.  If you enable this option, make sure that your auth
8278 +         service (identd) is running as gid 1001.  With this option, 
8279 +         the following features (in addition to those provided in the 
8280 +         low additional security level) will be enabled:
8281 +
8282 +         - Randomized TCP source ports
8283 +         - Failed fork logging
8284 +         - Time change logging
8285 +         - Signal logging
8286 +         - Deny mounts in chroot
8287 +         - Deny double chrooting
8288 +         - Deny sysctl writes in chroot
8289 +         - Deny mknod in chroot
8290 +         - Deny access to abstract AF_UNIX sockets out of chroot
8291 +         - Deny pivot_root in chroot
8292 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
8293 +         - /proc restrictions with special GID set to 10 (usually wheel)
8294 +         - Address Space Layout Randomization (ASLR)
8295 +
8296 +config GRKERNSEC_HIGH
8297 +       bool "High"
8298 +       select GRKERNSEC_LINK
8299 +       select GRKERNSEC_FIFO
8300 +       select GRKERNSEC_RANDPID
8301 +       select GRKERNSEC_EXECVE
8302 +       select GRKERNSEC_DMESG
8303 +       select GRKERNSEC_RANDSRC
8304 +       select GRKERNSEC_FORKFAIL
8305 +       select GRKERNSEC_TIME
8306 +       select GRKERNSEC_SIGNAL
8307 +       select GRKERNSEC_CHROOT_SHMAT
8308 +       select GRKERNSEC_CHROOT_UNIX
8309 +       select GRKERNSEC_CHROOT_MOUNT
8310 +       select GRKERNSEC_CHROOT_FCHDIR
8311 +       select GRKERNSEC_CHROOT_PIVOT
8312 +       select GRKERNSEC_CHROOT_DOUBLE
8313 +       select GRKERNSEC_CHROOT_CHDIR
8314 +       select GRKERNSEC_CHROOT_MKNOD
8315 +       select GRKERNSEC_CHROOT_CAPS
8316 +       select GRKERNSEC_CHROOT_SYSCTL
8317 +       select GRKERNSEC_CHROOT_FINDTASK
8318 +       select GRKERNSEC_PROC
8319 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
8320 +       select GRKERNSEC_HIDESYM
8321 +       select GRKERNSEC_BRUTE
8322 +       select GRKERNSEC_SHM if (SYSVIPC)
8323 +       select GRKERNSEC_PROC_USERGROUP
8324 +       select GRKERNSEC_KMEM
8325 +       select GRKERNSEC_RESLOG
8326 +       select GRKERNSEC_RANDNET
8327 +       select GRKERNSEC_PROC_ADD
8328 +       select GRKERNSEC_CHROOT_CHMOD
8329 +       select GRKERNSEC_CHROOT_NICE
8330 +       select GRKERNSEC_AUDIT_MOUNT
8331 +       select PAX
8332 +       select PAX_RANDUSTACK
8333 +       select PAX_ASLR
8334 +       select PAX_RANDMMAP
8335 +       select PAX_NOEXEC
8336 +       select PAX_MPROTECT
8337 +       select PAX_EI_PAX
8338 +       select PAX_PT_PAX_FLAGS
8339 +       select PAX_HAVE_ACL_FLAGS
8340 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
8341 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
8342 +       select PAX_SEGMEXEC if (X86 && !X86_64)
8343 +       select PAX_PAGEEXEC if (!X86)
8344 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
8345 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
8346 +       select PAX_SYSCALL if (PPC32)
8347 +       select PAX_EMUTRAMP if (PARISC)
8348 +       select PAX_EMUSIGRT if (PARISC)
8349 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
8350 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
8351 +       help
8352 +         If you say Y here, many of the features of grsecurity will be
8353 +         enabled, which will protect you against many kinds of attacks
8354 +         against your system.  The heightened security comes at a cost
8355 +         of an increased chance of incompatibilities with rare software
8356 +         on your machine.  Since this security level enables PaX, you should
8357 +         view <http://pax.grsecurity.net> and read about the PaX
8358 +         project.  While you are there, download chpax and run it on
8359 +         binaries that cause problems with PaX.  Also remember that
8360 +         since the /proc restrictions are enabled, you must run your
8361 +         identd as gid 1001.  This security level enables the following 
8362 +         features in addition to those listed in the low and medium 
8363 +         security levels:
8364 +
8365 +         - Additional /proc restrictions
8366 +         - Chmod restrictions in chroot
8367 +         - No signals, ptrace, or viewing of processes outside of chroot
8368 +         - Capability restrictions in chroot
8369 +         - Deny fchdir out of chroot
8370 +         - Priority restrictions in chroot
8371 +         - Segmentation-based implementation of PaX
8372 +         - Mprotect restrictions
8373 +         - Removal of addresses from /proc/<pid>/[maps|stat]
8374 +         - Kernel stack randomization
8375 +         - Mount/unmount/remount logging
8376 +         - Kernel symbol hiding
8377 +         - Destroy unused shared memory        
8378 +config GRKERNSEC_CUSTOM
8379 +       bool "Custom"
8380 +       help
8381 +         If you say Y here, you will be able to configure every grsecurity
8382 +         option, which allows you to enable many more features that aren't
8383 +         covered in the basic security levels.  These additional features
8384 +         include TPE, socket restrictions, and the sysctl system for
8385 +         grsecurity.  It is advised that you read through the help for
8386 +         each option to determine its usefulness in your situation.
8387 +
8388 +endchoice
8389 +
8390 +menu "Address Space Protection"
8391 +depends on GRKERNSEC
8392 +
8393 +config GRKERNSEC_KMEM
8394 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
8395 +       help
8396 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
8397 +         be written to via mmap or otherwise to modify the running kernel.
8398 +         /dev/port will also not be allowed to be opened. If you have module
8399 +         support disabled, enabling this will close up four ways that are
8400 +         currently used  to insert malicious code into the running kernel.
8401 +         Even with all these features enabled, we still highly recommend that
8402 +         you use the RBAC system, as it is still possible for an attacker to
8403 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
8404 +         If you are not using XFree86, you may be able to stop this additional
8405 +         case by enabling the 'Disable privileged I/O' option. Though nothing
8406 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
8407 +         but only to video memory, which is the only writing we allow in this
8408 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
8409 +         not be allowed to mprotect it with PROT_WRITE later.
8410 +         It is highly recommended that you say Y here if you meet all the
8411 +         conditions above.
8412 +
8413 +config GRKERNSEC_IO
8414 +       bool "Disable privileged I/O"
8415 +       depends on X86
8416 +       select RTC
8417 +       help
8418 +         If you say Y here, all ioperm and iopl calls will return an error.
8419 +         Ioperm and iopl can be used to modify the running kernel.
8420 +         Unfortunately, some programs need this access to operate properly,
8421 +         the most notable of which are XFree86 and hwclock.  hwclock can be
8422 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
8423 +         enabled if this option is enabled, to ensure that hwclock operates
8424 +         correctly.  XFree86 still will not operate correctly with this option
8425 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
8426 +         and you still want to protect your kernel against modification,
8427 +         use the RBAC system.
8428 +
8429 +config GRKERNSEC_PROC_MEMMAP
8430 +       bool "Remove addresses from /proc/<pid>/[maps|stat]"
8431 +       depends on PAX_NOEXEC || PAX_ASLR
8432 +       help
8433 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
8434 +         give no information about the addresses of its mappings if
8435 +         PaX features that rely on random addresses are enabled on the task.
8436 +         If you use PaX it is greatly recommended that you say Y here as it
8437 +         closes up a hole that makes the full ASLR useless for suid
8438 +         binaries.
8439 +
8440 +config GRKERNSEC_BRUTE
8441 +       bool "Deter exploit bruteforcing"
8442 +       help
8443 +         If you say Y here, attempts to bruteforce exploits against forking
8444 +         daemons such as apache or sshd will be deterred.  When a child of a
8445 +         forking daemon is killed by PaX or crashes due to an illegal
8446 +         instruction, the parent process will be delayed 30 seconds upon every
8447 +         subsequent fork until the administrator is able to assess the
8448 +         situation and restart the daemon.  It is recommended that you also
8449 +         enable signal logging in the auditing section so that logs are
8450 +         generated when a process performs an illegal instruction.
8451 +
8452 +config GRKERNSEC_HIDESYM
8453 +       bool "Hide kernel symbols"
8454 +       help
8455 +         If you say Y here, getting information on loaded modules, and
8456 +         displaying all kernel symbols through a syscall will be restricted
8457 +         to users with CAP_SYS_MODULE.  This option is only effective
8458 +         provided the following conditions are met:
8459 +         1) The kernel using grsecurity is not precompiled by some distribution
8460 +         2) You are using the RBAC system and hiding other files such as your
8461 +            kernel image and System.map
8462 +         3) You have the additional /proc restrictions enabled, which removes
8463 +            /proc/kcore
8464 +         If the above conditions are met, this option will aid to provide a
8465 +         useful protection against local and remote kernel exploitation of
8466 +         overflows and arbitrary read/write vulnerabilities.
8467 +
8468 +endmenu
8469 +menu "Role Based Access Control Options"
8470 +depends on GRKERNSEC
8471 +
8472 +config GRKERNSEC_ACL_HIDEKERN
8473 +       bool "Hide kernel processes"
8474 +       help
8475 +         If you say Y here, all kernel threads will be hidden to all
8476 +         processes but those whose subject has the "view hidden processes"
8477 +         flag.
8478 +
8479 +config GRKERNSEC_ACL_MAXTRIES
8480 +       int "Maximum tries before password lockout"
8481 +       default 3
8482 +       help
8483 +         This option enforces the maximum number of times a user can attempt
8484 +         to authorize themselves with the grsecurity RBAC system before being
8485 +         denied the ability to attempt authorization again for a specified time.
8486 +         The lower the number, the harder it will be to brute-force a password.
8487 +
8488 +config GRKERNSEC_ACL_TIMEOUT
8489 +       int "Time to wait after max password tries, in seconds"
8490 +       default 30
8491 +       help
8492 +         This option specifies the time the user must wait after attempting to
8493 +         authorize to the RBAC system with the maximum number of invalid
8494 +         passwords.  The higher the number, the harder it will be to brute-force
8495 +         a password.
8496 +
8497 +endmenu
8498 +menu "Filesystem Protections"
8499 +depends on GRKERNSEC
8500 +
8501 +config GRKERNSEC_PROC
8502 +       bool "Proc restrictions"
8503 +       help
8504 +         If you say Y here, the permissions of the /proc filesystem
8505 +         will be altered to enhance system security and privacy.  You MUST
8506 +         choose either a user only restriction or a user and group restriction.
8507 +         Depending upon the option you choose, you can either restrict users to
8508 +         see only the processes they themselves run, or choose a group that can
8509 +         view all processes and files normally restricted to root if you choose
8510 +         the "restrict to user only" option.  NOTE: If you're running identd as
8511 +         a non-root user, you will have to run it as the group you specify here.
8512 +
8513 +config GRKERNSEC_PROC_USER
8514 +       bool "Restrict /proc to user only"
8515 +       depends on GRKERNSEC_PROC
8516 +       help
8517 +         If you say Y here, non-root users will only be able to view their own
8518 +         processes, and restricts them from viewing network-related information,
8519 +         and viewing kernel symbol and module information.
8520 +
8521 +config GRKERNSEC_PROC_USERGROUP
8522 +       bool "Allow special group"
8523 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
8524 +       help
8525 +         If you say Y here, you will be able to select a group that will be
8526 +         able to view all processes, network-related information, and
8527 +         kernel and symbol information.  This option is useful if you want
8528 +         to run identd as a non-root user.
8529 +
8530 +config GRKERNSEC_PROC_GID
8531 +       int "GID for special group"
8532 +       depends on GRKERNSEC_PROC_USERGROUP
8533 +       default 1001
8534 +
8535 +config GRKERNSEC_PROC_ADD
8536 +       bool "Additional restrictions"
8537 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
8538 +       help
8539 +         If you say Y here, additional restrictions will be placed on
8540 +         /proc that keep normal users from viewing device information and 
8541 +         slabinfo information that could be useful for exploits.
8542 +
8543 +config GRKERNSEC_LINK
8544 +       bool "Linking restrictions"
8545 +       help
8546 +         If you say Y here, /tmp race exploits will be prevented, since users
8547 +         will no longer be able to follow symlinks owned by other users in
8548 +         world-writable +t directories (i.e. /tmp), unless the owner of the
8549 +         symlink is the owner of the directory. users will also not be
8550 +         able to hardlink to files they do not own.  If the sysctl option is
8551 +         enabled, a sysctl option with name "linking_restrictions" is created.
8552 +
8553 +config GRKERNSEC_FIFO
8554 +       bool "FIFO restrictions"
8555 +       help
8556 +         If you say Y here, users will not be able to write to FIFOs they don't
8557 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
8558 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
8559 +         option is enabled, a sysctl option with name "fifo_restrictions" is
8560 +         created.
8561 +
8562 +config GRKERNSEC_CHROOT
8563 +       bool "Chroot jail restrictions"
8564 +       help
8565 +         If you say Y here, you will be able to choose several options that will
8566 +         make breaking out of a chrooted jail much more difficult.  If you
8567 +         encounter no software incompatibilities with the following options, it
8568 +         is recommended that you enable each one.
8569 +
8570 +config GRKERNSEC_CHROOT_MOUNT
8571 +       bool "Deny mounts"
8572 +       depends on GRKERNSEC_CHROOT
8573 +       help
8574 +         If you say Y here, processes inside a chroot will not be able to
8575 +         mount or remount filesystems.  If the sysctl option is enabled, a
8576 +         sysctl option with name "chroot_deny_mount" is created.
8577 +
8578 +config GRKERNSEC_CHROOT_DOUBLE
8579 +       bool "Deny double-chroots"
8580 +       depends on GRKERNSEC_CHROOT
8581 +       help
8582 +         If you say Y here, processes inside a chroot will not be able to chroot
8583 +         again outside the chroot.  This is a widely used method of breaking
8584 +         out of a chroot jail and should not be allowed.  If the sysctl 
8585 +         option is enabled, a sysctl option with name 
8586 +         "chroot_deny_chroot" is created.
8587 +
8588 +config GRKERNSEC_CHROOT_PIVOT
8589 +       bool "Deny pivot_root in chroot"
8590 +       depends on GRKERNSEC_CHROOT
8591 +       help
8592 +         If you say Y here, processes inside a chroot will not be able to use
8593 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
8594 +         works similar to chroot in that it changes the root filesystem.  This
8595 +         function could be misused in a chrooted process to attempt to break out
8596 +         of the chroot, and therefore should not be allowed.  If the sysctl
8597 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
8598 +         created.
8599 +
8600 +config GRKERNSEC_CHROOT_CHDIR
8601 +       bool "Enforce chdir(\"/\") on all chroots"
8602 +       depends on GRKERNSEC_CHROOT
8603 +       help
8604 +         If you say Y here, the current working directory of all newly-chrooted
8605 +         applications will be set to the the root directory of the chroot.
8606 +         The man page on chroot(2) states:
8607 +         Note that this call does not change  the  current  working
8608 +         directory,  so  that `.' can be outside the tree rooted at
8609 +         `/'.  In particular, the  super-user  can  escape  from  a
8610 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
8611 +
8612 +         It is recommended that you say Y here, since it's not known to break
8613 +         any software.  If the sysctl option is enabled, a sysctl option with
8614 +         name "chroot_enforce_chdir" is created.
8615 +
8616 +config GRKERNSEC_CHROOT_CHMOD
8617 +       bool "Deny (f)chmod +s"
8618 +       depends on GRKERNSEC_CHROOT
8619 +       help
8620 +         If you say Y here, processes inside a chroot will not be able to chmod
8621 +         or fchmod files to make them have suid or sgid bits.  This protects
8622 +         against another published method of breaking a chroot.  If the sysctl
8623 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
8624 +         created.
8625 +
8626 +config GRKERNSEC_CHROOT_FCHDIR
8627 +       bool "Deny fchdir out of chroot"
8628 +       depends on GRKERNSEC_CHROOT
8629 +       help
8630 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
8631 +         to a file descriptor of the chrooting process that points to a directory
8632 +         outside the filesystem will be stopped.  If the sysctl option
8633 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
8634 +
8635 +config GRKERNSEC_CHROOT_MKNOD
8636 +       bool "Deny mknod"
8637 +       depends on GRKERNSEC_CHROOT
8638 +       help
8639 +         If you say Y here, processes inside a chroot will not be allowed to
8640 +         mknod.  The problem with using mknod inside a chroot is that it
8641 +         would allow an attacker to create a device entry that is the same
8642 +         as one on the physical root of your system, which could range from
8643 +         anything from the console device to a device for your harddrive (which
8644 +         they could then use to wipe the drive or steal data).  It is recommended
8645 +         that you say Y here, unless you run into software incompatibilities.
8646 +         If the sysctl option is enabled, a sysctl option with name
8647 +         "chroot_deny_mknod" is created.
8648 +
8649 +config GRKERNSEC_CHROOT_SHMAT
8650 +       bool "Deny shmat() out of chroot"
8651 +       depends on GRKERNSEC_CHROOT
8652 +       help
8653 +         If you say Y here, processes inside a chroot will not be able to attach
8654 +         to shared memory segments that were created outside of the chroot jail.
8655 +         It is recommended that you say Y here.  If the sysctl option is enabled,
8656 +         a sysctl option with name "chroot_deny_shmat" is created.
8657 +
8658 +config GRKERNSEC_CHROOT_UNIX
8659 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
8660 +       depends on GRKERNSEC_CHROOT
8661 +       help
8662 +         If you say Y here, processes inside a chroot will not be able to
8663 +         connect to abstract (meaning not belonging to a filesystem) Unix
8664 +         domain sockets that were bound outside of a chroot.  It is recommended
8665 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
8666 +         with name "chroot_deny_unix" is created.
8667 +
8668 +config GRKERNSEC_CHROOT_FINDTASK
8669 +       bool "Protect outside processes"
8670 +       depends on GRKERNSEC_CHROOT
8671 +       help
8672 +         If you say Y here, processes inside a chroot will not be able to
8673 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
8674 +         getsid, or view any process outside of the chroot.  If the sysctl
8675 +         option is enabled, a sysctl option with name "chroot_findtask" is
8676 +         created.
8677 +
8678 +config GRKERNSEC_CHROOT_NICE
8679 +       bool "Restrict priority changes"
8680 +       depends on GRKERNSEC_CHROOT
8681 +       help
8682 +         If you say Y here, processes inside a chroot will not be able to raise
8683 +         the priority of processes in the chroot, or alter the priority of
8684 +         processes outside the chroot.  This provides more security than simply
8685 +         removing CAP_SYS_NICE from the process' capability set.  If the
8686 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
8687 +         is created.
8688 +
8689 +config GRKERNSEC_CHROOT_SYSCTL
8690 +       bool "Deny sysctl writes"
8691 +       depends on GRKERNSEC_CHROOT
8692 +       help
8693 +         If you say Y here, an attacker in a chroot will not be able to
8694 +         write to sysctl entries, either by sysctl(2) or through a /proc
8695 +         interface.  It is strongly recommended that you say Y here. If the
8696 +         sysctl option is enabled, a sysctl option with name
8697 +         "chroot_deny_sysctl" is created.
8698 +
8699 +config GRKERNSEC_CHROOT_CAPS
8700 +       bool "Capability restrictions"
8701 +       depends on GRKERNSEC_CHROOT
8702 +       help
8703 +         If you say Y here, the capabilities on all root processes within a
8704 +         chroot jail will be lowered to stop module insertion, raw i/o,
8705 +         system and net admin tasks, rebooting the system, modifying immutable
8706 +         files, modifying IPC owned by another, and changing the system time.
8707 +         This is left an option because it can break some apps.  Disable this
8708 +         if your chrooted apps are having problems performing those kinds of
8709 +         tasks.  If the sysctl option is enabled, a sysctl option with
8710 +         name "chroot_caps" is created.
8711 +
8712 +endmenu
8713 +menu "Kernel Auditing"
8714 +depends on GRKERNSEC
8715 +
8716 +config GRKERNSEC_AUDIT_GROUP
8717 +       bool "Single group for auditing"
8718 +       help
8719 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
8720 +         will only operate on a group you specify.  This option is recommended
8721 +         if you only want to watch certain users instead of having a large
8722 +         amount of logs from the entire system.  If the sysctl option is enabled,
8723 +         a sysctl option with name "audit_group" is created.
8724 +
8725 +config GRKERNSEC_AUDIT_GID
8726 +       int "GID for auditing"
8727 +       depends on GRKERNSEC_AUDIT_GROUP
8728 +       default 1007
8729 +
8730 +config GRKERNSEC_EXECLOG
8731 +       bool "Exec logging"
8732 +       help
8733 +         If you say Y here, all execve() calls will be logged (since the
8734 +         other exec*() calls are frontends to execve(), all execution
8735 +         will be logged).  Useful for shell-servers that like to keep track
8736 +         of their users.  If the sysctl option is enabled, a sysctl option with
8737 +         name "exec_logging" is created.
8738 +         WARNING: This option when enabled will produce a LOT of logs, especially
8739 +         on an active system.
8740 +
8741 +config GRKERNSEC_RESLOG
8742 +       bool "Resource logging"
8743 +       help
8744 +         If you say Y here, all attempts to overstep resource limits will
8745 +         be logged with the resource name, the requested size, and the current
8746 +         limit.  It is highly recommended that you say Y here.
8747 +
8748 +config GRKERNSEC_CHROOT_EXECLOG
8749 +       bool "Log execs within chroot"
8750 +       help
8751 +         If you say Y here, all executions inside a chroot jail will be logged
8752 +         to syslog.  This can cause a large amount of logs if certain
8753 +         applications (eg. djb's daemontools) are installed on the system, and
8754 +         is therefore left as an option.  If the sysctl option is enabled, a
8755 +         sysctl option with name "chroot_execlog" is created.
8756 +
8757 +config GRKERNSEC_AUDIT_CHDIR
8758 +       bool "Chdir logging"
8759 +       help
8760 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
8761 +         option is enabled, a sysctl option with name "audit_chdir" is created.
8762 +
8763 +config GRKERNSEC_AUDIT_MOUNT
8764 +       bool "(Un)Mount logging"
8765 +       help
8766 +         If you say Y here, all mounts and unmounts will be logged.  If the
8767 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
8768 +         created.
8769 +
8770 +config GRKERNSEC_AUDIT_IPC
8771 +       bool "IPC logging"
8772 +       help
8773 +         If you say Y here, creation and removal of message queues, semaphores,
8774 +         and shared memory will be logged.  If the sysctl option is enabled, a
8775 +         sysctl option with name "audit_ipc" is created.
8776 +
8777 +config GRKERNSEC_SIGNAL
8778 +       bool "Signal logging"
8779 +       help
8780 +         If you say Y here, certain important signals will be logged, such as
8781 +         SIGSEGV, which will as a result inform you of when a error in a program
8782 +         occurred, which in some cases could mean a possible exploit attempt.
8783 +         If the sysctl option is enabled, a sysctl option with name
8784 +         "signal_logging" is created.
8785 +
8786 +config GRKERNSEC_FORKFAIL
8787 +       bool "Fork failure logging"
8788 +       help
8789 +         If you say Y here, all failed fork() attempts will be logged.
8790 +         This could suggest a fork bomb, or someone attempting to overstep
8791 +         their process limit.  If the sysctl option is enabled, a sysctl option
8792 +         with name "forkfail_logging" is created.
8793 +
8794 +config GRKERNSEC_TIME
8795 +       bool "Time change logging"
8796 +       help
8797 +         If you say Y here, any changes of the system clock will be logged.
8798 +         If the sysctl option is enabled, a sysctl option with name
8799 +         "timechange_logging" is created.
8800 +
8801 +config GRKERNSEC_PROC_IPADDR
8802 +       bool "/proc/<pid>/ipaddr support"
8803 +       help
8804 +         If you say Y here, a new entry will be added to each /proc/<pid>
8805 +         directory that contains the IP address of the person using the task.
8806 +         The IP is carried across local TCP and AF_UNIX stream sockets.
8807 +         This information can be useful for IDS/IPSes to perform remote response
8808 +         to a local attack.  The entry is readable by only the owner of the
8809 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
8810 +         the RBAC system), and thus does not create privacy concerns.
8811 +
8812 +config GRKERNSEC_AUDIT_TEXTREL
8813 +       bool 'ELF text relocations logging (READ HELP)'
8814 +       depends on PAX_MPROTECT
8815 +       help
8816 +         If you say Y here, text relocations will be logged with the filename
8817 +         of the offending library or binary.  The purpose of the feature is
8818 +         to help Linux distribution developers get rid of libraries and
8819 +         binaries that need text relocations which hinder the future progress
8820 +         of PaX.  Only Linux distribution developers should say Y here, and
8821 +         never on a production machine, as this option creates an information
8822 +         leak that could aid an attacker in defeating the randomization of
8823 +         a single memory region.  If the sysctl option is enabled, a sysctl
8824 +         option with name "audit_textrel" is created.
8825 +
8826 +endmenu
8827 +
8828 +menu "Executable Protections"
8829 +depends on GRKERNSEC
8830 +
8831 +config GRKERNSEC_EXECVE
8832 +       bool "Enforce RLIMIT_NPROC on execs"
8833 +       help
8834 +         If you say Y here, users with a resource limit on processes will
8835 +         have the value checked during execve() calls.  The current system
8836 +         only checks the system limit during fork() calls.  If the sysctl option
8837 +         is enabled, a sysctl option with name "execve_limiting" is created.
8838 +
8839 +config GRKERNSEC_SHM
8840 +       bool "Destroy unused shared memory"
8841 +       depends on SYSVIPC
8842 +       help
8843 +         If you say Y here, shared memory will be destroyed when no one is
8844 +         attached to it.  Otherwise, resources involved with the shared
8845 +         memory can be used up and not be associated with any process (as the
8846 +         shared memory still exists, and the creating process has exited).  If
8847 +         the sysctl option is enabled, a sysctl option with name
8848 +         "destroy_unused_shm" is created.
8849 +
8850 +config GRKERNSEC_DMESG
8851 +       bool "Dmesg(8) restriction"
8852 +       help
8853 +         If you say Y here, non-root users will not be able to use dmesg(8)
8854 +         to view up to the last 4kb of messages in the kernel's log buffer.
8855 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
8856 +         created.
8857 +
8858 +config GRKERNSEC_RANDPID
8859 +       bool "Randomized PIDs"
8860 +       help
8861 +         If you say Y here, all PIDs created on the system will be
8862 +         pseudo-randomly generated.  This is extremely effective along
8863 +         with the /proc restrictions to disallow an attacker from guessing
8864 +         pids of daemons, etc.  PIDs are also used in some cases as part
8865 +         of a naming system for temporary files, so this option would keep
8866 +         those filenames from being predicted as well.  We also use code
8867 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
8868 +         option is enabled, a sysctl option with name "rand_pids" is created.
8869 +
8870 +config GRKERNSEC_TPE
8871 +       bool "Trusted Path Execution (TPE)"
8872 +       help
8873 +         If you say Y here, you will be able to choose a gid to add to the
8874 +         supplementary groups of users you want to mark as "untrusted."
8875 +         These users will not be able to execute any files that are not in
8876 +         root-owned directories writable only by root.  If the sysctl option
8877 +         is enabled, a sysctl option with name "tpe" is created.
8878 +
8879 +config GRKERNSEC_TPE_ALL
8880 +       bool "Partially restrict non-root users"
8881 +       depends on GRKERNSEC_TPE
8882 +       help
8883 +         If you say Y here, All non-root users other than the ones in the
8884 +         group specified in the main TPE option will only be allowed to
8885 +         execute files in directories they own that are not group or
8886 +         world-writable, or in directories owned by root and writable only by
8887 +         root.  If the sysctl option is enabled, a sysctl option with name
8888 +         "tpe_restrict_all" is created.
8889 +
8890 +config GRKERNSEC_TPE_GID
8891 +       int "GID for untrusted users"
8892 +       depends on GRKERNSEC_TPE
8893 +       default 1005
8894 +       help
8895 +         Here you can choose the GID to enable trusted path protection for.
8896 +         Remember to add the users you want protection enabled for to the GID
8897 +         specified here.  If the sysctl option is enabled, whatever you choose
8898 +         here won't matter. You'll have to specify the GID in your bootup
8899 +         script by echoing the GID to the proper /proc entry.  View the help
8900 +         on the sysctl option for more information.  If the sysctl option is
8901 +         enabled, a sysctl option with name "tpe_gid" is created.
8902 +
8903 +endmenu
8904 +menu "Network Protections"
8905 +depends on GRKERNSEC
8906 +
8907 +config GRKERNSEC_RANDNET
8908 +       bool "Larger entropy pools"
8909 +       help
8910 +         If you say Y here, the entropy pools used for many features of Linux
8911 +         and grsecurity will be doubled in size.  Since several grsecurity
8912 +         features use additional randomness, it is recommended that you say Y
8913 +         here.  Saying Y here has a similar effect as modifying
8914 +         /proc/sys/kernel/random/poolsize.
8915 +
8916 +config GRKERNSEC_RANDSRC
8917 +       bool "Randomized TCP source ports"
8918 +       default n if GRKERNSEC_LOW || GRKERNSEC_MID
8919 +       default y if GRKERNSEC_HIGH
8920 +       help
8921 +         If you say Y here, situations where a source port is generated on the
8922 +         fly for the TCP protocol (ie. with connect() ) will be altered so that
8923 +         the source port is generated at random, instead of a simple incrementing
8924 +         algorithm.  If the sysctl option is enabled, a sysctl option with name
8925 +         "rand_tcp_src_ports" is created.
8926 +
8927 +config GRKERNSEC_SOCKET
8928 +       bool "Socket restrictions"
8929 +       help
8930 +         If you say Y here, you will be able to choose from several options.
8931 +         If you assign a GID on your system and add it to the supplementary
8932 +         groups of users you want to restrict socket access to, this patch
8933 +         will perform up to three things, based on the option(s) you choose.
8934 +
8935 +config GRKERNSEC_SOCKET_ALL
8936 +       bool "Deny any sockets to group"
8937 +       depends on GRKERNSEC_SOCKET
8938 +       help
8939 +         If you say Y here, you will be able to choose a GID of whose users will
8940 +         be unable to connect to other hosts from your machine or run server
8941 +         applications from your machine.  If the sysctl option is enabled, a
8942 +         sysctl option with name "socket_all" is created.
8943 +
8944 +config GRKERNSEC_SOCKET_ALL_GID
8945 +       int "GID to deny all sockets for"
8946 +       depends on GRKERNSEC_SOCKET_ALL
8947 +       default 1004
8948 +       help
8949 +         Here you can choose the GID to disable socket access for. Remember to
8950 +         add the users you want socket access disabled for to the GID
8951 +         specified here.  If the sysctl option is enabled, whatever you choose
8952 +         here won't matter. You'll have to specify the GID in your bootup
8953 +         script by echoing the GID to the proper /proc entry.  View the help
8954 +         on the sysctl option for more information.  If the sysctl option is
8955 +         enabled, a sysctl option with name "socket_all_gid" is created.
8956 +
8957 +config GRKERNSEC_SOCKET_CLIENT
8958 +       bool "Deny client sockets to group"
8959 +       depends on GRKERNSEC_SOCKET
8960 +       help
8961 +         If you say Y here, you will be able to choose a GID of whose users will
8962 +         be unable to connect to other hosts from your machine, but will be
8963 +         able to run servers.  If this option is enabled, all users in the group
8964 +         you specify will have to use passive mode when initiating ftp transfers
8965 +         from the shell on your machine.  If the sysctl option is enabled, a
8966 +         sysctl option with name "socket_client" is created.
8967 +
8968 +config GRKERNSEC_SOCKET_CLIENT_GID
8969 +       int "GID to deny client sockets for"
8970 +       depends on GRKERNSEC_SOCKET_CLIENT
8971 +       default 1003
8972 +       help
8973 +         Here you can choose the GID to disable client socket access for.
8974 +         Remember to add the users you want client socket access disabled for to
8975 +         the GID specified here.  If the sysctl option is enabled, whatever you
8976 +         choose here won't matter. You'll have to specify the GID in your bootup
8977 +         script by echoing the GID to the proper /proc entry.  View the help
8978 +         on the sysctl option for more information.  If the sysctl option is
8979 +         enabled, a sysctl option with name "socket_client_gid" is created.
8980 +
8981 +config GRKERNSEC_SOCKET_SERVER
8982 +       bool "Deny server sockets to group"
8983 +       depends on GRKERNSEC_SOCKET
8984 +       help
8985 +         If you say Y here, you will be able to choose a GID of whose users will
8986 +         be unable to run server applications from your machine.  If the sysctl
8987 +         option is enabled, a sysctl option with name "socket_server" is created.
8988 +
8989 +config GRKERNSEC_SOCKET_SERVER_GID
8990 +       int "GID to deny server sockets for"
8991 +       depends on GRKERNSEC_SOCKET_SERVER
8992 +       default 1002
8993 +       help
8994 +         Here you can choose the GID to disable server socket access for.
8995 +         Remember to add the users you want server socket access disabled for to
8996 +         the GID specified here.  If the sysctl option is enabled, whatever you
8997 +         choose here won't matter. You'll have to specify the GID in your bootup
8998 +         script by echoing the GID to the proper /proc entry.  View the help
8999 +         on the sysctl option for more information.  If the sysctl option is
9000 +         enabled, a sysctl option with name "socket_server_gid" is created.
9001 +
9002 +endmenu
9003 +menu "Sysctl support"
9004 +depends on GRKERNSEC && SYSCTL
9005 +
9006 +config GRKERNSEC_SYSCTL
9007 +       bool "Sysctl support"
9008 +       help
9009 +         If you say Y here, you will be able to change the options that
9010 +         grsecurity runs with at bootup, without having to recompile your
9011 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
9012 +         to enable (1) or disable (0) various features.  All the sysctl entries
9013 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
9014 +         All features enabled in the kernel configuration are disabled at boot
9015 +         if you do not say Y to the "Turn on features by default" option.
9016 +         All options should be set at startup, and the grsec_lock entry should
9017 +         be set to a non-zero value after all the options are set.
9018 +         *THIS IS EXTREMELY IMPORTANT*
9019 +
9020 +config GRKERNSEC_SYSCTL_ON
9021 +       bool "Turn on features by default"
9022 +       depends on GRKERNSEC_SYSCTL
9023 +       help
9024 +         If you say Y here, instead of having all features enabled in the
9025 +         kernel configuration disabled at boot time, the features will be
9026 +         enabled at boot time.  It is recommended you say Y here unless
9027 +         there is some reason you would want all sysctl-tunable features to
9028 +         be disabled by default.  As mentioned elsewhere, it is important
9029 +         to enable the grsec_lock entry once you have finished modifying
9030 +         the sysctl entries.
9031 +
9032 +endmenu
9033 +menu "Logging Options"
9034 +depends on GRKERNSEC
9035 +
9036 +config GRKERNSEC_FLOODTIME
9037 +       int "Seconds in between log messages (minimum)"
9038 +       default 10
9039 +       help
9040 +         This option allows you to enforce the number of seconds between
9041 +         grsecurity log messages.  The default should be suitable for most
9042 +         people, however, if you choose to change it, choose a value small enough
9043 +         to allow informative logs to be produced, but large enough to
9044 +         prevent flooding.
9045 +
9046 +config GRKERNSEC_FLOODBURST
9047 +       int "Number of messages in a burst (maximum)"
9048 +       default 4
9049 +       help
9050 +         This option allows you to choose the maximum number of messages allowed
9051 +         within the flood time interval you chose in a separate option.  The
9052 +         default should be suitable for most people, however if you find that
9053 +         many of your logs are being interpreted as flooding, you may want to
9054 +         raise this value.
9055 +
9056 +endmenu
9057 +
9058 +endmenu
9059 diff -urNp linux-2.6.11/grsecurity/Makefile linux-2.6.11/grsecurity/Makefile
9060 --- linux-2.6.11/grsecurity/Makefile    1969-12-31 19:00:00.000000000 -0500
9061 +++ linux-2.6.11/grsecurity/Makefile    2005-03-09 11:56:44.000000000 -0500
9062 @@ -0,0 +1,20 @@
9063 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
9064 +# during 2001-2005 it has been completely redesigned by Brad Spengler
9065 +# into an RBAC system
9066 +#
9067 +# All code in this directory and various hooks inserted throughout the kernel
9068 +# are copyright Brad Spengler, and released under the GPL v2 or higher
9069 +
9070 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
9071 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
9072 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
9073 +
9074 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
9075 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
9076 +       gracl_learn.o grsec_log.o
9077 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
9078 +
9079 +ifndef CONFIG_GRKERNSEC
9080 +obj-y += grsec_disabled.o
9081 +endif
9082 +
9083 diff -urNp linux-2.6.11/grsecurity/gracl.c linux-2.6.11/grsecurity/gracl.c
9084 --- linux-2.6.11/grsecurity/gracl.c     1969-12-31 19:00:00.000000000 -0500
9085 +++ linux-2.6.11/grsecurity/gracl.c     2005-03-09 11:56:44.000000000 -0500
9086 @@ -0,0 +1,3550 @@
9087 +#include <linux/kernel.h>
9088 +#include <linux/module.h>
9089 +#include <linux/sched.h>
9090 +#include <linux/mm.h>
9091 +#include <linux/file.h>
9092 +#include <linux/fs.h>
9093 +#include <linux/namei.h>
9094 +#include <linux/mount.h>
9095 +#include <linux/tty.h>
9096 +#include <linux/proc_fs.h>
9097 +#include <linux/smp_lock.h>
9098 +#include <linux/slab.h>
9099 +#include <linux/vmalloc.h>
9100 +#include <linux/types.h>
9101 +#include <linux/capability.h>
9102 +#include <linux/sysctl.h>
9103 +#include <linux/ptrace.h>
9104 +#include <linux/gracl.h>
9105 +#include <linux/gralloc.h>
9106 +#include <linux/grsecurity.h>
9107 +#include <linux/grinternal.h>
9108 +#include <linux/percpu.h>
9109 +
9110 +#include <asm/uaccess.h>
9111 +#include <asm/errno.h>
9112 +#include <asm/mman.h>
9113 +
9114 +static struct acl_role_db acl_role_set;
9115 +static struct acl_role_label *role_list_head;
9116 +static struct name_db name_set;
9117 +static struct name_db inodev_set;
9118 +
9119 +/* for keeping track of userspace pointers used for subjects, so we
9120 +   can share references in the kernel as well
9121 +*/
9122 +
9123 +static struct dentry *real_root;
9124 +static struct vfsmount *real_root_mnt;
9125 +
9126 +static struct acl_subj_map_db subj_map_set;
9127 +
9128 +static struct acl_role_label *default_role;
9129 +
9130 +static u16 acl_sp_role_value;
9131 +
9132 +extern char *gr_shared_page[4];
9133 +static DECLARE_MUTEX(gr_dev_sem);
9134 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
9135 +
9136 +struct gr_arg *gr_usermode;
9137 +
9138 +static unsigned long gr_status = GR_STATUS_INIT;
9139 +
9140 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
9141 +extern void gr_clear_learn_entries(void);
9142 +
9143 +#ifdef CONFIG_GRKERNSEC_RESLOG
9144 +extern void gr_log_resource(const struct task_struct *task,
9145 +                           const int res, const unsigned long wanted, const int gt);
9146 +#endif
9147 +
9148 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
9149 +                        struct dentry *root, struct vfsmount *rootmnt,
9150 +                        char *buffer, int buflen);
9151 +
9152 +unsigned char *gr_system_salt;
9153 +unsigned char *gr_system_sum;
9154 +
9155 +static struct sprole_pw **acl_special_roles = NULL;
9156 +static __u16 num_sprole_pws = 0;
9157 +
9158 +static struct acl_role_label *kernel_role = NULL;
9159 +
9160 +/* The following are used to keep a place held in the hash table when we move
9161 +   entries around.  They can be replaced during insert. */
9162 +
9163 +static struct acl_subject_label *deleted_subject;
9164 +static struct acl_object_label *deleted_object;
9165 +static struct name_entry *deleted_inodev;
9166 +
9167 +/* for keeping track of the last and final allocated subjects, since
9168 +   nested subject parsing is tricky
9169 +*/
9170 +static struct acl_subject_label *s_last = NULL;
9171 +static struct acl_subject_label *s_final = NULL;
9172 +
9173 +static unsigned int gr_auth_attempts = 0;
9174 +static unsigned long gr_auth_expires = 0UL;
9175 +
9176 +extern int gr_init_uidset(void);
9177 +extern void gr_free_uidset(void);
9178 +extern void gr_remove_uid(uid_t uid);
9179 +extern int gr_find_uid(uid_t uid);
9180 +
9181 +__inline__ int
9182 +gr_acl_is_enabled(void)
9183 +{
9184 +       return (gr_status & GR_READY);
9185 +}
9186 +
9187 +char gr_roletype_to_char(void)
9188 +{
9189 +       switch (current->role->roletype &
9190 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
9191 +                GR_ROLE_SPECIAL)) {
9192 +       case GR_ROLE_DEFAULT:
9193 +               return 'D';
9194 +       case GR_ROLE_USER:
9195 +               return 'U';
9196 +       case GR_ROLE_GROUP:
9197 +               return 'G';
9198 +       case GR_ROLE_SPECIAL:
9199 +               return 'S';
9200 +       }
9201 +
9202 +       return 'X';
9203 +}
9204 +
9205 +__inline__ int
9206 +gr_acl_tpe_check(void)
9207 +{
9208 +       if (unlikely(!(gr_status & GR_READY)))
9209 +               return 0;
9210 +       if (current->role->roletype & GR_ROLE_TPE)
9211 +               return 1;
9212 +       else
9213 +               return 0;
9214 +}
9215 +
9216 +int
9217 +gr_handle_rawio(const struct inode *inode)
9218 +{
9219 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
9220 +       if (inode && S_ISBLK(inode->i_mode) &&
9221 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
9222 +           !capable(CAP_SYS_RAWIO))
9223 +               return 1;
9224 +#endif
9225 +       return 0;
9226 +}
9227 +
9228 +static int
9229 +gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
9230 +{
9231 +       int i;
9232 +       unsigned long *l1;
9233 +       unsigned long *l2;
9234 +       unsigned char *c1;
9235 +       unsigned char *c2;
9236 +       int num_longs;
9237 +
9238 +       if (likely(lena != lenb))
9239 +               return 0;
9240 +
9241 +       l1 = (unsigned long *)a;
9242 +       l2 = (unsigned long *)b;
9243 +
9244 +       num_longs = lena / sizeof(unsigned long);
9245 +
9246 +       for (i = num_longs; i--; l1++, l2++) {
9247 +               if (unlikely(*l1 != *l2))
9248 +                       return 0;
9249 +       }
9250 +
9251 +       c1 = (unsigned char *) l1;
9252 +       c2 = (unsigned char *) l2;
9253 +
9254 +       i = lena - (num_longs * sizeof(unsigned long)); 
9255 +
9256 +       for (; i--; c1++, c2++) {
9257 +               if (unlikely(*c1 != *c2))
9258 +                       return 0;
9259 +       }
9260 +
9261 +       return 1;
9262 +}
9263 +               
9264 +static char *
9265 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
9266 +               char *buf, int buflen)
9267 +{
9268 +       char *res;
9269 +       struct dentry *l_dentry = (struct dentry *)dentry;
9270 +
9271 +       /* we can use real_root, real_root_mnt, because this is only called
9272 +          by the RBAC system */
9273 +       res = __d_path(l_dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
9274 +       if (unlikely(IS_ERR(res)))
9275 +               res = strcpy(buf, "<path too long>");
9276 +       else if (!IS_ROOT(l_dentry) && d_unhashed(l_dentry)) {
9277 +               unsigned int len;
9278 +
9279 +               /* strip off (deleted) */
9280 +               len = strlen(res);
9281 +               *(res + len - 10) = '\0';
9282 +       }
9283 +
9284 +       return res;
9285 +}
9286 +
9287 +static char *
9288 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
9289 +           char *buf, int buflen)
9290 +{
9291 +       char *res;
9292 +       struct dentry *l_dentry = (struct dentry *)dentry;
9293 +       struct dentry *root;
9294 +       struct vfsmount *rootmnt;
9295 +
9296 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
9297 +       read_lock(&child_reaper->fs->lock);
9298 +       root = dget(child_reaper->fs->root);
9299 +       rootmnt = mntget(child_reaper->fs->rootmnt);
9300 +       read_unlock(&child_reaper->fs->lock);
9301 +
9302 +       spin_lock(&dcache_lock);
9303 +       res = __d_path(l_dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
9304 +       if (unlikely(IS_ERR(res)))
9305 +               res = strcpy(buf, "<path too long>");
9306 +       else if (!IS_ROOT(l_dentry) && d_unhashed(l_dentry)) {
9307 +               unsigned int len;
9308 +
9309 +               /* strip off (deleted) */
9310 +               len = strlen(res);
9311 +               *(res + len - 10) = '\0';
9312 +       }
9313 +       spin_unlock(&dcache_lock);
9314 +
9315 +       dput(root);
9316 +       mntput(rootmnt);
9317 +       return res;
9318 +}
9319 +
9320 +char *
9321 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
9322 +{
9323 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
9324 +                            PAGE_SIZE);
9325 +}
9326 +
9327 +char *
9328 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
9329 +{
9330 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
9331 +                          PAGE_SIZE);
9332 +}
9333 +
9334 +char *
9335 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
9336 +{
9337 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
9338 +                          PAGE_SIZE);
9339 +}
9340 +
9341 +char *
9342 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
9343 +{
9344 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
9345 +                          PAGE_SIZE);
9346 +}
9347 +
9348 +char *
9349 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
9350 +{
9351 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
9352 +                          PAGE_SIZE);
9353 +}
9354 +
9355 +__inline__ __u32
9356 +to_gr_audit(const __u32 reqmode)
9357 +{
9358 +       /* masks off auditable permission flags, then shifts them to create
9359 +          auditing flags, and adds the special case of append auditing if
9360 +          we're requesting write */
9361 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
9362 +}
9363 +
9364 +struct acl_subject_label *
9365 +lookup_subject_map(const struct acl_subject_label *userp)
9366 +{
9367 +       unsigned long index = shash(userp, subj_map_set.s_size);
9368 +       struct subject_map *match;
9369 +       unsigned int i = 0;
9370 +
9371 +       match = subj_map_set.s_hash[index];
9372 +
9373 +       while (match && match->user != userp) {
9374 +               index = (index + (1 << i)) % subj_map_set.s_size;
9375 +               match = subj_map_set.s_hash[index];
9376 +               i = (i + 1) % 32;
9377 +       }
9378 +
9379 +       if (match != NULL)
9380 +               return match->kernel;
9381 +       else
9382 +               return NULL;
9383 +}
9384 +
9385 +static void
9386 +insert_subj_map_entry(struct subject_map *subjmap)
9387 +{
9388 +       unsigned long index = shash(subjmap->user, subj_map_set.s_size);
9389 +       struct subject_map **curr;
9390 +       unsigned int i = 0;
9391 +
9392 +       curr = &subj_map_set.s_hash[index];
9393 +
9394 +       while (*curr) {
9395 +               index = (index + (1 << i)) % subj_map_set.s_size;
9396 +               curr = &subj_map_set.s_hash[index];
9397 +               i = (i + 1) % 32;
9398 +       }
9399 +
9400 +       *curr = subjmap;
9401 +
9402 +       return;
9403 +}
9404 +
9405 +static struct acl_role_label *
9406 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
9407 +                     const gid_t gid)
9408 +{
9409 +       unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
9410 +       struct acl_role_label *match;
9411 +       struct role_allowed_ip *ipp;
9412 +       int x;
9413 +       unsigned int i = 0;
9414 +
9415 +       match = acl_role_set.r_hash[index];
9416 +
9417 +       while (match) {
9418 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
9419 +                       for (x = 0; x < match->domain_child_num; x++) {
9420 +                               if (match->domain_children[x] == uid)
9421 +                                       goto found;
9422 +                       }
9423 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
9424 +                       break;
9425 +               index = (index + (1 << i)) % acl_role_set.r_size;
9426 +               match = acl_role_set.r_hash[index];
9427 +               i = (i + 1) % 32;
9428 +       }
9429 +found:
9430 +       if (match == NULL) {
9431 +             try_group:
9432 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
9433 +               match = acl_role_set.r_hash[index];
9434 +               i = 0;
9435 +
9436 +               while (match) {
9437 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
9438 +                               for (x = 0; x < match->domain_child_num; x++) {
9439 +                                       if (match->domain_children[x] == gid)
9440 +                                               goto found2;
9441 +                               }
9442 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
9443 +                               break;
9444 +                       index = (index + (1 << i)) % acl_role_set.r_size;
9445 +                       match = acl_role_set.r_hash[index];
9446 +                       i = (i + 1) % 32;
9447 +               }
9448 +found2:
9449 +               if (match == NULL)
9450 +                       match = default_role;
9451 +               if (match->allowed_ips == NULL)
9452 +                       return match;
9453 +               else {
9454 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
9455 +                               if (likely
9456 +                                   ((ntohl(task->curr_ip) & ipp->netmask) ==
9457 +                                    (ntohl(ipp->addr) & ipp->netmask)))
9458 +                                       return match;
9459 +                       }
9460 +                       match = default_role;
9461 +               }
9462 +       } else if (match->allowed_ips == NULL) {
9463 +               return match;
9464 +       } else {
9465 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
9466 +                       if (likely
9467 +                           ((ntohl(task->curr_ip) & ipp->netmask) ==
9468 +                            (ntohl(ipp->addr) & ipp->netmask)))
9469 +                               return match;
9470 +               }
9471 +               goto try_group;
9472 +       }
9473 +
9474 +       return match;
9475 +}
9476 +
9477 +struct acl_subject_label *
9478 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
9479 +                     const struct acl_role_label *role)
9480 +{
9481 +       unsigned long subj_size = role->subj_hash_size;
9482 +       struct acl_subject_label **s_hash = role->subj_hash;
9483 +       unsigned long index = fhash(ino, dev, subj_size);
9484 +       struct acl_subject_label *match;
9485 +       unsigned int i = 0;
9486 +
9487 +       match = s_hash[index];
9488 +
9489 +       while (match && (match->inode != ino || match->device != dev ||
9490 +              (match->mode & GR_DELETED))) {
9491 +               index = (index + (1 << i)) % subj_size;
9492 +               match = s_hash[index];
9493 +               i = (i + 1) % 32;
9494 +       }
9495 +
9496 +       if (match && (match != deleted_subject) && !(match->mode & GR_DELETED))
9497 +               return match;
9498 +       else
9499 +               return NULL;
9500 +}
9501 +
9502 +static struct acl_object_label *
9503 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
9504 +                    const struct acl_subject_label *subj)
9505 +{
9506 +       unsigned long obj_size = subj->obj_hash_size;
9507 +       struct acl_object_label **o_hash = subj->obj_hash;
9508 +       unsigned long index = fhash(ino, dev, obj_size);
9509 +       struct acl_object_label *match;
9510 +       unsigned int i = 0;
9511 +
9512 +       match = o_hash[index];
9513 +
9514 +       while (match && (match->inode != ino || match->device != dev ||
9515 +              (match->mode & GR_DELETED))) {
9516 +               index = (index + (1 << i)) % obj_size;
9517 +               match = o_hash[index];
9518 +               i = (i + 1) % 32;
9519 +       }
9520 +
9521 +       if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
9522 +               return match;
9523 +       else
9524 +               return NULL;
9525 +}
9526 +
9527 +static struct acl_object_label *
9528 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
9529 +                    const struct acl_subject_label *subj)
9530 +{
9531 +       unsigned long obj_size = subj->obj_hash_size;
9532 +       struct acl_object_label **o_hash = subj->obj_hash;
9533 +       unsigned long index = fhash(ino, dev, obj_size);
9534 +       struct acl_object_label *match;
9535 +       unsigned int i = 0;
9536 +
9537 +       match = o_hash[index];
9538 +
9539 +       while (match && (match->inode != ino || match->device != dev ||
9540 +              !(match->mode & GR_DELETED))) {
9541 +               index = (index + (1 << i)) % obj_size;
9542 +               match = o_hash[index];
9543 +               i = (i + 1) % 32;
9544 +       }
9545 +
9546 +       if (match && (match != deleted_object) && (match->mode & GR_DELETED))
9547 +               return match;
9548 +
9549 +       i = 0;
9550 +       index = fhash(ino, dev, obj_size);
9551 +       match = o_hash[index];
9552 +
9553 +       while (match && (match->inode != ino || match->device != dev ||
9554 +              (match->mode & GR_DELETED))) {
9555 +               index = (index + (1 << i)) % obj_size;
9556 +               match = o_hash[index];
9557 +               i = (i + 1) % 32;
9558 +       }
9559 +
9560 +       if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
9561 +               return match;
9562 +       else
9563 +               return NULL;
9564 +}
9565 +
9566 +static struct name_entry *
9567 +lookup_name_entry(const char *name)
9568 +{
9569 +       __u16 len = strlen(name);
9570 +       unsigned long index = nhash(name, len, name_set.n_size);
9571 +       struct name_entry *match;
9572 +       unsigned int i = 0;
9573 +
9574 +       match = name_set.n_hash[index];
9575 +
9576 +       while (match && !gr_streq(match->name, name, match->len, len)) {
9577 +               index = (index + (1 << i)) % name_set.n_size;
9578 +               match = name_set.n_hash[index];
9579 +               i = (i + 1) % 32;
9580 +       }
9581 +
9582 +       return match;
9583 +}
9584 +
9585 +static struct name_entry *
9586 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
9587 +{
9588 +       unsigned long index = fhash(ino, dev, inodev_set.n_size);
9589 +       struct name_entry *match;
9590 +       unsigned int i = 0;
9591 +
9592 +       match = inodev_set.n_hash[index];
9593 +
9594 +       while (match && (match->inode != ino || match->device != dev)) {
9595 +               index = (index + (1 << i)) % inodev_set.n_size;
9596 +               match = inodev_set.n_hash[index];
9597 +               i = (i + 1) % 32;
9598 +       }
9599 +
9600 +       if (match && (match != deleted_inodev))
9601 +               return match;
9602 +       else
9603 +               return NULL;
9604 +}
9605 +
9606 +static void
9607 +insert_inodev_entry(struct name_entry *nentry)
9608 +{
9609 +       unsigned long index = fhash(nentry->inode, nentry->device,
9610 +                                   inodev_set.n_size);
9611 +       struct name_entry **curr;
9612 +       unsigned int i = 0;
9613 +
9614 +       curr = &inodev_set.n_hash[index];
9615 +
9616 +       while (*curr && *curr != deleted_inodev) {
9617 +               index = (index + (1 << i)) % inodev_set.n_size;
9618 +               curr = &inodev_set.n_hash[index];
9619 +               i = (i + 1) % 32;
9620 +       }
9621 +
9622 +       *curr = nentry;
9623 +
9624 +       return;
9625 +}
9626 +
9627 +static void
9628 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
9629 +{
9630 +       unsigned long index =
9631 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
9632 +       struct acl_role_label **curr;
9633 +       unsigned int i = 0;
9634 +
9635 +       curr = &acl_role_set.r_hash[index];
9636 +
9637 +       while (*curr) {
9638 +               index = (index + (1 << i)) % acl_role_set.r_size;
9639 +               curr = &acl_role_set.r_hash[index];
9640 +               i = (i + 1) % 32;
9641 +       }
9642 +
9643 +       *curr = role;
9644 +
9645 +       return;
9646 +}
9647 +
9648 +static void
9649 +insert_acl_role_label(struct acl_role_label *role)
9650 +{
9651 +       int i;
9652 +
9653 +       if (role->roletype & GR_ROLE_DOMAIN) {
9654 +               for (i = 0; i < role->domain_child_num; i++)
9655 +                       __insert_acl_role_label(role, role->domain_children[i]);
9656 +       } else
9657 +               __insert_acl_role_label(role, role->uidgid);
9658 +}
9659 +                                       
9660 +static int
9661 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
9662 +{
9663 +       struct name_entry **curr;
9664 +       unsigned int i = 0;
9665 +       __u16 len = strlen(name);
9666 +       unsigned long index = nhash(name, len, name_set.n_size);
9667 +
9668 +       curr = &name_set.n_hash[index];
9669 +
9670 +       while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
9671 +               index = (index + (1 << i)) % name_set.n_size;
9672 +               curr = &name_set.n_hash[index];
9673 +               i = (i + 1) % 32;
9674 +       }
9675 +
9676 +       if (!(*curr)) {
9677 +               struct name_entry *nentry =
9678 +                   acl_alloc(sizeof (struct name_entry));
9679 +               if (!nentry)
9680 +                       return 0;
9681 +               nentry->name = name;
9682 +               nentry->inode = inode;
9683 +               nentry->device = device;
9684 +               nentry->len = len;
9685 +               *curr = nentry;
9686 +               /* insert us into the table searchable by inode/dev */
9687 +               insert_inodev_entry(nentry);
9688 +       }
9689 +
9690 +       return 1;
9691 +}
9692 +
9693 +static void
9694 +insert_acl_obj_label(struct acl_object_label *obj,
9695 +                    struct acl_subject_label *subj)
9696 +{
9697 +       unsigned long index =
9698 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
9699 +       struct acl_object_label **curr;
9700 +       unsigned int i = 0;
9701 +
9702 +       curr = &subj->obj_hash[index];
9703 +
9704 +       while (*curr && *curr != deleted_object) {
9705 +               index = (index + (1 << i)) % subj->obj_hash_size;
9706 +               curr = &subj->obj_hash[index];
9707 +               i = (i + 1) % 32;
9708 +       }
9709 +
9710 +       *curr = obj;
9711 +
9712 +       return;
9713 +}
9714 +
9715 +static void
9716 +insert_acl_subj_label(struct acl_subject_label *obj,
9717 +                     struct acl_role_label *role)
9718 +{
9719 +       unsigned long subj_size = role->subj_hash_size;
9720 +       struct acl_subject_label **s_hash = role->subj_hash;
9721 +       unsigned long index = fhash(obj->inode, obj->device, subj_size);
9722 +       struct acl_subject_label **curr;
9723 +       unsigned int i = 0;
9724 +
9725 +       curr = &s_hash[index];
9726 +
9727 +       while (*curr && *curr != deleted_subject) {
9728 +               index = (index + (1 << i)) % subj_size;
9729 +               curr = &s_hash[index];
9730 +               i = (i + 1) % 32;
9731 +       }
9732 +
9733 +       *curr = obj;
9734 +
9735 +       return;
9736 +}
9737 +
9738 +static void *
9739 +create_table(__u32 * len, int elementsize)
9740 +{
9741 +       unsigned long table_sizes[] = {
9742 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
9743 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
9744 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
9745 +               268435399, 536870909, 1073741789, 2147483647
9746 +       };
9747 +       void *newtable = NULL;
9748 +       unsigned int pwr = 0;
9749 +
9750 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
9751 +              table_sizes[pwr] <= (2 * (*len)))
9752 +               pwr++;
9753 +
9754 +       if (table_sizes[pwr] <= (2 * (*len)))
9755 +               return newtable;
9756 +
9757 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
9758 +               newtable =
9759 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
9760 +       else
9761 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
9762 +
9763 +       *len = table_sizes[pwr];
9764 +
9765 +       return newtable;
9766 +}
9767 +
9768 +static int
9769 +init_variables(const struct gr_arg *arg)
9770 +{
9771 +       unsigned long stacksize;
9772 +
9773 +       subj_map_set.s_size = arg->role_db.num_subjects;
9774 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
9775 +       name_set.n_size = arg->role_db.num_objects;
9776 +       inodev_set.n_size = arg->role_db.num_objects;
9777 +
9778 +       if (!gr_init_uidset())
9779 +               return 1;
9780 +
9781 +       /* set up the stack that holds allocation info */
9782 +
9783 +       stacksize = arg->role_db.num_pointers + 5;
9784 +
9785 +       if (!acl_alloc_stack_init(stacksize))
9786 +               return 1;
9787 +
9788 +       /* create our empty, fake deleted acls */
9789 +       deleted_subject =
9790 +           (struct acl_subject_label *)
9791 +           acl_alloc(sizeof (struct acl_subject_label));
9792 +       deleted_object =
9793 +           (struct acl_object_label *)
9794 +           acl_alloc(sizeof (struct acl_object_label));
9795 +       deleted_inodev =
9796 +           (struct name_entry *) acl_alloc(sizeof (struct name_entry));
9797 +
9798 +       if (!deleted_subject || !deleted_object || !deleted_inodev)
9799 +               return 1;
9800 +
9801 +       memset(deleted_subject, 0, sizeof (struct acl_subject_label));
9802 +       memset(deleted_object, 0, sizeof (struct acl_object_label));
9803 +       memset(deleted_inodev, 0, sizeof (struct name_entry));
9804 +
9805 +       /* grab reference for the real root dentry and vfsmount */
9806 +       read_lock(&child_reaper->fs->lock);
9807 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
9808 +       real_root = dget(child_reaper->fs->root);
9809 +       read_unlock(&child_reaper->fs->lock);
9810 +       
9811 +
9812 +       /* We only want 50% full tables for now */
9813 +
9814 +       subj_map_set.s_hash =
9815 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
9816 +       acl_role_set.r_hash =
9817 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
9818 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
9819 +       inodev_set.n_hash =
9820 +           (struct name_entry **) create_table(&inodev_set.n_size, sizeof(void *));
9821 +
9822 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
9823 +           !name_set.n_hash || !inodev_set.n_hash)
9824 +               return 1;
9825 +
9826 +       memset(subj_map_set.s_hash, 0,
9827 +              sizeof(struct subject_map *) * subj_map_set.s_size);
9828 +       memset(acl_role_set.r_hash, 0,
9829 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
9830 +       memset(name_set.n_hash, 0,
9831 +              sizeof (struct name_entry *) * name_set.n_size);
9832 +       memset(inodev_set.n_hash, 0,
9833 +              sizeof (struct name_entry *) * inodev_set.n_size);
9834 +
9835 +       return 0;
9836 +}
9837 +
9838 +/* free information not needed after startup
9839 +   currently contains user->kernel pointer mappings for subjects
9840 +*/
9841 +
9842 +static void
9843 +free_init_variables(void)
9844 +{
9845 +       __u32 i;
9846 +
9847 +       if (subj_map_set.s_hash) {
9848 +               for (i = 0; i < subj_map_set.s_size; i++) {
9849 +                       if (subj_map_set.s_hash[i]) {
9850 +                               kfree(subj_map_set.s_hash[i]);
9851 +                               subj_map_set.s_hash[i] = NULL;
9852 +                       }
9853 +               }
9854 +
9855 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
9856 +                   PAGE_SIZE)
9857 +                       kfree(subj_map_set.s_hash);
9858 +               else
9859 +                       vfree(subj_map_set.s_hash);
9860 +       }
9861 +
9862 +       return;
9863 +}
9864 +
9865 +static void
9866 +free_variables(void)
9867 +{
9868 +       struct acl_subject_label *s;
9869 +       struct acl_role_label *r;
9870 +       struct task_struct *task, *task2;
9871 +
9872 +       gr_clear_learn_entries();
9873 +
9874 +       read_lock(&tasklist_lock);
9875 +       do_each_thread(task2, task) {
9876 +               task->acl_sp_role = 0;
9877 +               task->acl_role_id = 0;
9878 +               task->acl = NULL;
9879 +               task->role = NULL;
9880 +       } while_each_thread(task2, task);
9881 +       read_unlock(&tasklist_lock);
9882 +
9883 +       /* release the reference to the real root dentry and vfsmount */
9884 +       if (real_root)
9885 +               dput(real_root);
9886 +       real_root = NULL;
9887 +       if (real_root_mnt)
9888 +               mntput(real_root_mnt);
9889 +       real_root_mnt = NULL;
9890 +
9891 +       /* free all object hash tables */
9892 +
9893 +       if (role_list_head) {
9894 +               for (r = role_list_head; r; r = r->next) {
9895 +                       if (!r->subj_hash)
9896 +                               break;
9897 +                       for (s = r->hash->first; s; s = s->next) {
9898 +                               if (!s->obj_hash)
9899 +                                       break;
9900 +                               if ((s->obj_hash_size *
9901 +                                    sizeof (struct acl_object_label *)) <=
9902 +                                   PAGE_SIZE)
9903 +                                       kfree(s->obj_hash);
9904 +                               else
9905 +                                       vfree(s->obj_hash);
9906 +                       }
9907 +                       if ((r->subj_hash_size *
9908 +                            sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
9909 +                               kfree(r->subj_hash);
9910 +                       else
9911 +                               vfree(r->subj_hash);
9912 +               }
9913 +       }
9914 +
9915 +       acl_free_all();
9916 +
9917 +       if (acl_role_set.r_hash) {
9918 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
9919 +                   PAGE_SIZE)
9920 +                       kfree(acl_role_set.r_hash);
9921 +               else
9922 +                       vfree(acl_role_set.r_hash);
9923 +       }
9924 +       if (name_set.n_hash) {
9925 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
9926 +                   PAGE_SIZE)
9927 +                       kfree(name_set.n_hash);
9928 +               else
9929 +                       vfree(name_set.n_hash);
9930 +       }
9931 +
9932 +       if (inodev_set.n_hash) {
9933 +               if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
9934 +                   PAGE_SIZE)
9935 +                       kfree(inodev_set.n_hash);
9936 +               else
9937 +                       vfree(inodev_set.n_hash);
9938 +       }
9939 +
9940 +       gr_free_uidset();
9941 +
9942 +       memset(&name_set, 0, sizeof (struct name_db));
9943 +       memset(&inodev_set, 0, sizeof (struct name_db));
9944 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
9945 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
9946 +
9947 +       role_list_head = NULL;
9948 +       default_role = NULL;
9949 +
9950 +       return;
9951 +}
9952 +
9953 +static __u32
9954 +count_user_objs(struct acl_object_label *userp)
9955 +{
9956 +       struct acl_object_label o_tmp;
9957 +       __u32 num = 0;
9958 +
9959 +       while (userp) {
9960 +               if (copy_from_user(&o_tmp, userp,
9961 +                                  sizeof (struct acl_object_label)))
9962 +                       break;
9963 +
9964 +               userp = o_tmp.prev;
9965 +               num++;
9966 +       }
9967 +
9968 +       return num;
9969 +}
9970 +
9971 +static struct acl_subject_label *
9972 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
9973 +
9974 +static int
9975 +copy_user_glob(struct acl_object_label *obj)
9976 +{
9977 +       struct acl_object_label **guser, *g_tmp, *glast = NULL;
9978 +       unsigned int len;
9979 +       char *tmp;
9980 +
9981 +       if (obj->globbed == NULL)
9982 +               return 0;
9983 +
9984 +       guser = &obj->globbed;
9985 +       while (*guser) {
9986 +               g_tmp = (struct acl_object_label *)
9987 +                       acl_alloc(sizeof (struct acl_object_label));
9988 +               if (g_tmp == NULL)
9989 +                       return -ENOMEM;
9990 +
9991 +               if (copy_from_user(g_tmp, *guser,
9992 +                                  sizeof (struct acl_object_label)))
9993 +                       return -EFAULT;
9994 +
9995 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
9996 +
9997 +               if (!len || len >= PATH_MAX)
9998 +                       return -EINVAL;
9999 +
10000 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
10001 +                       return -ENOMEM;
10002 +
10003 +               if (copy_from_user(tmp, g_tmp->filename, len))
10004 +                       return -EFAULT;
10005 +
10006 +               g_tmp->filename = tmp;
10007 +
10008 +               if (glast)
10009 +                       glast->next = g_tmp;
10010 +               g_tmp->prev = glast;
10011 +               *guser = g_tmp;
10012 +               glast = g_tmp;
10013 +               guser = &((*guser)->next);
10014 +       }
10015 +
10016 +       return 0;
10017 +}
10018 +
10019 +static int
10020 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
10021 +              struct acl_role_label *role)
10022 +{
10023 +       struct acl_object_label *o_tmp;
10024 +       unsigned int len;
10025 +       int ret;
10026 +       char *tmp;
10027 +
10028 +       while (userp) {
10029 +               if ((o_tmp = (struct acl_object_label *)
10030 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
10031 +                       return -ENOMEM;
10032 +
10033 +               if (copy_from_user(o_tmp, userp,
10034 +                                  sizeof (struct acl_object_label)))
10035 +                       return -EFAULT;
10036 +
10037 +               userp = o_tmp->prev;
10038 +
10039 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
10040 +
10041 +               if (!len || len >= PATH_MAX)
10042 +                       return -EINVAL;
10043 +
10044 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
10045 +                       return -ENOMEM;
10046 +
10047 +               if (copy_from_user(tmp, o_tmp->filename, len))
10048 +                       return -EFAULT;
10049 +
10050 +               o_tmp->filename = tmp;
10051 +
10052 +               insert_acl_obj_label(o_tmp, subj);
10053 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
10054 +                                      o_tmp->device))
10055 +                       return -ENOMEM;
10056 +
10057 +               ret = copy_user_glob(o_tmp);
10058 +               if (ret)
10059 +                       return ret;
10060 +
10061 +               if (o_tmp->nested) {
10062 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
10063 +                       if (IS_ERR(o_tmp->nested))
10064 +                               return PTR_ERR(o_tmp->nested);
10065 +
10066 +                       s_final = o_tmp->nested;
10067 +               }
10068 +       }
10069 +
10070 +       return 0;
10071 +}
10072 +
10073 +static __u32
10074 +count_user_subjs(struct acl_subject_label *userp)
10075 +{
10076 +       struct acl_subject_label s_tmp;
10077 +       __u32 num = 0;
10078 +
10079 +       while (userp) {
10080 +               if (copy_from_user(&s_tmp, userp,
10081 +                                  sizeof (struct acl_subject_label)))
10082 +                       break;
10083 +
10084 +               userp = s_tmp.prev;
10085 +               /* do not count nested subjects against this count, since
10086 +                  they are not included in the hash table, but are
10087 +                  attached to objects.  We have already counted
10088 +                  the subjects in userspace for the allocation 
10089 +                  stack
10090 +               */
10091 +               if (!(s_tmp.mode & GR_NESTED))
10092 +                       num++;
10093 +       }
10094 +
10095 +       return num;
10096 +}
10097 +
10098 +static int
10099 +copy_user_allowedips(struct acl_role_label *rolep)
10100 +{
10101 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
10102 +
10103 +       ruserip = rolep->allowed_ips;
10104 +
10105 +       while (ruserip) {
10106 +               rlast = rtmp;
10107 +
10108 +               if ((rtmp = (struct role_allowed_ip *)
10109 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
10110 +                       return -ENOMEM;
10111 +
10112 +               if (copy_from_user(rtmp, ruserip,
10113 +                                  sizeof (struct role_allowed_ip)))
10114 +                       return -EFAULT;
10115 +
10116 +               ruserip = rtmp->prev;
10117 +
10118 +               if (!rlast) {
10119 +                       rtmp->prev = NULL;
10120 +                       rolep->allowed_ips = rtmp;
10121 +               } else {
10122 +                       rlast->next = rtmp;
10123 +                       rtmp->prev = rlast;
10124 +               }
10125 +
10126 +               if (!ruserip)
10127 +                       rtmp->next = NULL;
10128 +       }
10129 +
10130 +       return 0;
10131 +}
10132 +
10133 +static int
10134 +copy_user_transitions(struct acl_role_label *rolep)
10135 +{
10136 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
10137 +       
10138 +       unsigned int len;
10139 +       char *tmp;
10140 +
10141 +       rusertp = rolep->transitions;
10142 +
10143 +       while (rusertp) {
10144 +               rlast = rtmp;
10145 +
10146 +               if ((rtmp = (struct role_transition *)
10147 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
10148 +                       return -ENOMEM;
10149 +
10150 +               if (copy_from_user(rtmp, rusertp,
10151 +                                  sizeof (struct role_transition)))
10152 +                       return -EFAULT;
10153 +
10154 +               rusertp = rtmp->prev;
10155 +
10156 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
10157 +
10158 +               if (!len || len >= GR_SPROLE_LEN)
10159 +                       return -EINVAL;
10160 +
10161 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
10162 +                       return -ENOMEM;
10163 +
10164 +               if (copy_from_user(tmp, rtmp->rolename, len))
10165 +                       return -EFAULT;
10166 +
10167 +               rtmp->rolename = tmp;
10168 +
10169 +               if (!rlast) {
10170 +                       rtmp->prev = NULL;
10171 +                       rolep->transitions = rtmp;
10172 +               } else {
10173 +                       rlast->next = rtmp;
10174 +                       rtmp->prev = rlast;
10175 +               }
10176 +
10177 +               if (!rusertp)
10178 +                       rtmp->next = NULL;
10179 +       }
10180 +
10181 +       return 0;
10182 +}
10183 +
10184 +static struct acl_subject_label *
10185 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
10186 +{
10187 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
10188 +       unsigned int len;
10189 +       char *tmp;
10190 +       __u32 num_objs;
10191 +       struct acl_ip_label **i_tmp, *i_utmp2;
10192 +       struct gr_hash_struct ghash;
10193 +       struct subject_map *subjmap;
10194 +       unsigned long i_num;
10195 +       int err;
10196 +
10197 +       s_tmp = lookup_subject_map(userp);
10198 +
10199 +       /* we've already copied this subject into the kernel, just return
10200 +          the reference to it, and don't copy it over again
10201 +       */
10202 +       if (s_tmp)
10203 +               return(s_tmp);
10204 +
10205 +       if ((s_tmp = (struct acl_subject_label *)
10206 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
10207 +               return ERR_PTR(-ENOMEM);
10208 +
10209 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
10210 +       if (subjmap == NULL)
10211 +               return ERR_PTR(-ENOMEM);
10212 +
10213 +       subjmap->user = userp;
10214 +       subjmap->kernel = s_tmp;
10215 +       insert_subj_map_entry(subjmap);
10216 +
10217 +       if (copy_from_user(s_tmp, userp,
10218 +                          sizeof (struct acl_subject_label)))
10219 +               return ERR_PTR(-EFAULT);
10220 +
10221 +       if (!s_last) {
10222 +               s_tmp->prev = NULL;
10223 +               role->hash->first = s_tmp;
10224 +       } else {
10225 +               s_last->next = s_tmp;
10226 +               s_tmp->prev = s_last;
10227 +       }
10228 +
10229 +       s_last = s_tmp;
10230 +
10231 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
10232 +
10233 +       if (!len || len >= PATH_MAX)
10234 +               return ERR_PTR(-EINVAL);
10235 +
10236 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
10237 +               return ERR_PTR(-ENOMEM);
10238 +
10239 +       if (copy_from_user(tmp, s_tmp->filename, len))
10240 +               return ERR_PTR(-EFAULT);
10241 +
10242 +       s_tmp->filename = tmp;
10243 +
10244 +       if (!strcmp(s_tmp->filename, "/"))
10245 +               role->root_label = s_tmp;
10246 +
10247 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
10248 +               return ERR_PTR(-EFAULT);
10249 +
10250 +       /* copy user and group transition tables */
10251 +
10252 +       if (s_tmp->user_trans_num) {
10253 +               uid_t *uidlist;
10254 +
10255 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
10256 +               if (uidlist == NULL)
10257 +                       return ERR_PTR(-ENOMEM);
10258 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
10259 +                       return ERR_PTR(-EFAULT);
10260 +
10261 +               s_tmp->user_transitions = uidlist;
10262 +       }
10263 +
10264 +       if (s_tmp->group_trans_num) {
10265 +               gid_t *gidlist;
10266 +
10267 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
10268 +               if (gidlist == NULL)
10269 +                       return ERR_PTR(-ENOMEM);
10270 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
10271 +                       return ERR_PTR(-EFAULT);
10272 +
10273 +               s_tmp->group_transitions = gidlist;
10274 +       }
10275 +
10276 +       /* set up object hash table */
10277 +       num_objs = count_user_objs(ghash.first);
10278 +
10279 +       s_tmp->obj_hash_size = num_objs;
10280 +       s_tmp->obj_hash =
10281 +           (struct acl_object_label **)
10282 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
10283 +
10284 +       if (!s_tmp->obj_hash)
10285 +               return ERR_PTR(-ENOMEM);
10286 +
10287 +       memset(s_tmp->obj_hash, 0,
10288 +              s_tmp->obj_hash_size *
10289 +              sizeof (struct acl_object_label *));
10290 +
10291 +       /* copy before adding in objects, since a nested
10292 +          acl could be found and be the final subject
10293 +          copied
10294 +       */
10295 +
10296 +       s_final = s_tmp;
10297 +
10298 +       /* add in objects */
10299 +       err = copy_user_objs(ghash.first, s_tmp, role);
10300 +
10301 +       if (err)
10302 +               return ERR_PTR(err);
10303 +
10304 +       /* set pointer for parent subject */
10305 +       if (s_tmp->parent_subject) {
10306 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
10307 +
10308 +               if (IS_ERR(s_tmp2))
10309 +                       return s_tmp2;
10310 +
10311 +               s_tmp->parent_subject = s_tmp2;
10312 +       }
10313 +
10314 +       /* add in ip acls */
10315 +
10316 +       if (!s_tmp->ip_num) {
10317 +               s_tmp->ips = NULL;
10318 +               goto insert;
10319 +       }
10320 +
10321 +       i_tmp =
10322 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
10323 +                                              sizeof (struct
10324 +                                                      acl_ip_label *));
10325 +
10326 +       if (!i_tmp)
10327 +               return ERR_PTR(-ENOMEM);
10328 +
10329 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
10330 +               *(i_tmp + i_num) =
10331 +                   (struct acl_ip_label *)
10332 +                   acl_alloc(sizeof (struct acl_ip_label));
10333 +               if (!*(i_tmp + i_num))
10334 +                       return ERR_PTR(-ENOMEM);
10335 +
10336 +               if (copy_from_user
10337 +                   (&i_utmp2, s_tmp->ips + i_num,
10338 +                    sizeof (struct acl_ip_label *)))
10339 +                       return ERR_PTR(-EFAULT);
10340 +
10341 +               if (copy_from_user
10342 +                   (*(i_tmp + i_num), i_utmp2,
10343 +                    sizeof (struct acl_ip_label)))
10344 +                       return ERR_PTR(-EFAULT);
10345 +       }
10346 +
10347 +       s_tmp->ips = i_tmp;
10348 +
10349 +insert:
10350 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
10351 +                              s_tmp->device))
10352 +               return ERR_PTR(-ENOMEM);
10353 +
10354 +       return s_tmp;
10355 +}
10356 +
10357 +static int
10358 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
10359 +{
10360 +       struct acl_subject_label s_pre;
10361 +       struct acl_subject_label * ret;
10362 +       int err;
10363 +
10364 +       while (userp) {
10365 +               if (copy_from_user(&s_pre, userp,
10366 +                                  sizeof (struct acl_subject_label)))
10367 +                       return -EFAULT;
10368 +               
10369 +               /* do not add nested subjects here, add
10370 +                  while parsing objects
10371 +               */
10372 +
10373 +               if (s_pre.mode & GR_NESTED) {
10374 +                       userp = s_pre.prev;
10375 +                       continue;
10376 +               }
10377 +
10378 +               ret = do_copy_user_subj(userp, role);
10379 +
10380 +               err = PTR_ERR(ret);
10381 +               if (IS_ERR(ret))
10382 +                       return err;
10383 +
10384 +               insert_acl_subj_label(ret, role);
10385 +
10386 +               userp = s_pre.prev;
10387 +       }
10388 +
10389 +       s_final->next = NULL;
10390 +
10391 +       return 0;
10392 +}
10393 +
10394 +static int
10395 +copy_user_acl(struct gr_arg *arg)
10396 +{
10397 +       struct acl_role_label **r_utmp, *r_utmp2, *r_tmp = NULL, *r_last;
10398 +       struct sprole_pw *sptmp;
10399 +       struct gr_hash_struct *ghash;
10400 +       uid_t *domainlist;
10401 +       unsigned long r_num;
10402 +       unsigned int len;
10403 +       char *tmp;
10404 +       int err = 0;
10405 +       __u16 i;
10406 +       __u32 num_subjs;
10407 +
10408 +       /* we need a default and kernel role */
10409 +       if (arg->role_db.num_roles < 2)
10410 +               return -EINVAL;
10411 +
10412 +       /* copy special role authentication info from userspace */
10413 +
10414 +       num_sprole_pws = arg->num_sprole_pws;
10415 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
10416 +
10417 +       if (!acl_special_roles) {
10418 +               err = -ENOMEM;
10419 +               goto cleanup;
10420 +       }
10421 +
10422 +       for (i = 0; i < num_sprole_pws; i++) {
10423 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
10424 +               if (!sptmp) {
10425 +                       err = -ENOMEM;
10426 +                       goto cleanup;
10427 +               }
10428 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
10429 +                                  sizeof (struct sprole_pw))) {
10430 +                       err = -EFAULT;
10431 +                       goto cleanup;
10432 +               }
10433 +
10434 +               len =
10435 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
10436 +
10437 +               if (!len || len >= GR_SPROLE_LEN) {
10438 +                       err = -EINVAL;
10439 +                       goto cleanup;
10440 +               }
10441 +
10442 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
10443 +                       err = -ENOMEM;
10444 +                       goto cleanup;
10445 +               }
10446 +
10447 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
10448 +                       err = -EFAULT;
10449 +                       goto cleanup;
10450 +               }
10451 +
10452 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10453 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
10454 +#endif
10455 +               sptmp->rolename = tmp;
10456 +               acl_special_roles[i] = sptmp;
10457 +       }
10458 +
10459 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
10460 +
10461 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
10462 +               r_last = r_tmp;
10463 +
10464 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
10465 +
10466 +               if (!r_tmp) {
10467 +                       err = -ENOMEM;
10468 +                       goto cleanup;
10469 +               }
10470 +
10471 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
10472 +                                  sizeof (struct acl_role_label *))) {
10473 +                       err = -EFAULT;
10474 +                       goto cleanup;
10475 +               }
10476 +
10477 +               if (copy_from_user(r_tmp, r_utmp2,
10478 +                                  sizeof (struct acl_role_label))) {
10479 +                       err = -EFAULT;
10480 +                       goto cleanup;
10481 +               }
10482 +
10483 +               if (!r_last) {
10484 +                       r_tmp->prev = NULL;
10485 +                       role_list_head = r_tmp;
10486 +               } else {
10487 +                       r_last->next = r_tmp;
10488 +                       r_tmp->prev = r_last;
10489 +               }
10490 +
10491 +               if (r_num == (arg->role_db.num_roles - 1))
10492 +                       r_tmp->next = NULL;
10493 +
10494 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
10495 +
10496 +               if (!len || len >= PATH_MAX) {
10497 +                       err = -EINVAL;
10498 +                       goto cleanup;
10499 +               }
10500 +
10501 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
10502 +                       err = -ENOMEM;
10503 +                       goto cleanup;
10504 +               }
10505 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
10506 +                       err = -EFAULT;
10507 +                       goto cleanup;
10508 +               }
10509 +               r_tmp->rolename = tmp;
10510 +
10511 +               if (!strcmp(r_tmp->rolename, "default")
10512 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
10513 +                       default_role = r_tmp;
10514 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
10515 +                       kernel_role = r_tmp;
10516 +               }
10517 +
10518 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
10519 +                       err = -ENOMEM;
10520 +                       goto cleanup;
10521 +               }
10522 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
10523 +                       err = -EFAULT;
10524 +                       goto cleanup;
10525 +               }
10526 +
10527 +               r_tmp->hash = ghash;
10528 +
10529 +               num_subjs = count_user_subjs(r_tmp->hash->first);
10530 +
10531 +               r_tmp->subj_hash_size = num_subjs;
10532 +               r_tmp->subj_hash =
10533 +                   (struct acl_subject_label **)
10534 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
10535 +
10536 +               if (!r_tmp->subj_hash) {
10537 +                       err = -ENOMEM;
10538 +                       goto cleanup;
10539 +               }
10540 +
10541 +               err = copy_user_allowedips(r_tmp);
10542 +               if (err)
10543 +                       goto cleanup;
10544 +
10545 +               /* copy domain info */
10546 +               if (r_tmp->domain_children != NULL) {
10547 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
10548 +                       if (domainlist == NULL) {
10549 +                               err = -ENOMEM;
10550 +                               goto cleanup;
10551 +                       }
10552 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
10553 +                               err = -EFAULT;
10554 +                               goto cleanup;
10555 +                       }
10556 +                       r_tmp->domain_children = domainlist;
10557 +               }
10558 +
10559 +               err = copy_user_transitions(r_tmp);
10560 +               if (err)
10561 +                       goto cleanup;
10562 +
10563 +               memset(r_tmp->subj_hash, 0,
10564 +                      r_tmp->subj_hash_size *
10565 +                      sizeof (struct acl_subject_label *));
10566 +
10567 +               s_last = NULL;
10568 +
10569 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
10570 +
10571 +               if (err)
10572 +                       goto cleanup;
10573 +
10574 +               insert_acl_role_label(r_tmp);
10575 +       }
10576 +
10577 +       goto return_err;
10578 +      cleanup:
10579 +       free_variables();
10580 +      return_err:
10581 +       return err;
10582 +
10583 +}
10584 +
10585 +static int
10586 +gracl_init(struct gr_arg *args)
10587 +{
10588 +       int error = 0;
10589 +
10590 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
10591 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
10592 +
10593 +       if (init_variables(args)) {
10594 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
10595 +               error = -ENOMEM;
10596 +               free_variables();
10597 +               goto out;
10598 +       }
10599 +
10600 +       error = copy_user_acl(args);
10601 +       free_init_variables();
10602 +       if (error) {
10603 +               free_variables();
10604 +               goto out;
10605 +       }
10606 +
10607 +       if ((error = gr_set_acls(0))) {
10608 +               free_variables();
10609 +               goto out;
10610 +       }
10611 +
10612 +       gr_status |= GR_READY;
10613 +      out:
10614 +       return error;
10615 +}
10616 +
10617 +/* derived from glibc fnmatch() 0: match, 1: no match*/
10618 +
10619 +static int
10620 +glob_match(const char *p, const char *n)
10621 +{
10622 +       char c;
10623 +
10624 +       while ((c = *p++) != '\0') {
10625 +       switch (c) {
10626 +               case '?':
10627 +                       if (*n == '\0')
10628 +                               return 1;
10629 +                       else if (*n == '/')
10630 +                               return 1;
10631 +                       break;
10632 +               case '\\':
10633 +                       if (*n != c)
10634 +                               return 1;
10635 +                       break;
10636 +               case '*':
10637 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
10638 +                               if (*n == '/')
10639 +                                       return 1;
10640 +                               else if (c == '?') {
10641 +                                       if (*n == '\0')
10642 +                                               return 1;
10643 +                                       else
10644 +                                               ++n;
10645 +                               }
10646 +                       }
10647 +                       if (c == '\0') {
10648 +                               return 0;
10649 +                       } else {
10650 +                               const char *endp;
10651 +
10652 +                               if ((endp = strchr(n, '/')) == NULL)
10653 +                                       endp = n + strlen(n);
10654 +
10655 +                               if (c == '[') {
10656 +                                       for (--p; n < endp; ++n)
10657 +                                               if (!glob_match(p, n))
10658 +                                                       return 0;
10659 +                               } else if (c == '/') {
10660 +                                       while (*n != '\0' && *n != '/')
10661 +                                               ++n;
10662 +                                       if (*n == '/' && !glob_match(p, n + 1))
10663 +                                               return 0;
10664 +                               } else {
10665 +                                       for (--p; n < endp; ++n)
10666 +                                               if (*n == c && !glob_match(p, n))
10667 +                                                       return 0;
10668 +                               }
10669 +
10670 +                               return 1;
10671 +                       }
10672 +               case '[':
10673 +                       {
10674 +                       int not;
10675 +                       char cold;
10676 +
10677 +                       if (*n == '\0' || *n == '/')
10678 +                               return 1;
10679 +
10680 +                       not = (*p == '!' || *p == '^');
10681 +                       if (not)
10682 +                               ++p;
10683 +
10684 +                       c = *p++;
10685 +                       for (;;) {
10686 +                               unsigned char fn = (unsigned char)*n;
10687 +
10688 +                               if (c == '\0')
10689 +                                       return 1;
10690 +                               else {
10691 +                                       if (c == fn)
10692 +                                               goto matched;
10693 +                                       cold = c;
10694 +                                       c = *p++;
10695 +
10696 +                                       if (c == '-' && *p != ']') {
10697 +                                               unsigned char cend = *p++;
10698 +
10699 +                                               if (cend == '\0')
10700 +                                                       return 1;
10701 +
10702 +                                               if (cold <= fn && fn <= cend)
10703 +                                                       goto matched;
10704 +
10705 +                                               c = *p++;
10706 +                                       }
10707 +                               }
10708 +
10709 +                               if (c == ']')
10710 +                                       break;
10711 +                       }
10712 +                       if (!not)
10713 +                               return 1;
10714 +                       break;
10715 +               matched:
10716 +                       while (c != ']') {
10717 +                               if (c == '\0')
10718 +                                       return 1;
10719 +
10720 +                               c = *p++;
10721 +                       }
10722 +                       if (not)
10723 +                               return 1;
10724 +               }
10725 +               break;
10726 +       default:
10727 +               if (c != *n)
10728 +                       return 1;
10729 +       }
10730 +
10731 +       ++n;
10732 +       }
10733 +
10734 +       if (*n == '\0')
10735 +               return 0;
10736 +
10737 +       if (*n == '/')
10738 +               return 0;
10739 +
10740 +       return 1;
10741 +}
10742 +
10743 +static struct acl_object_label *
10744 +chk_glob_label(struct acl_object_label *globbed,
10745 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
10746 +{
10747 +       struct acl_object_label *tmp;
10748 +
10749 +       if (*path == NULL)
10750 +               *path = gr_to_filename_nolock(dentry, mnt);
10751 +
10752 +       tmp = globbed;
10753 +
10754 +       while (tmp) {
10755 +               if (!glob_match(tmp->filename, *path))
10756 +                       return tmp;
10757 +               tmp = tmp->next;
10758 +       }
10759 +
10760 +       return NULL;
10761 +}
10762 +
10763 +static struct acl_object_label *
10764 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
10765 +           const ino_t curr_ino, const dev_t curr_dev,
10766 +           const struct acl_subject_label *subj, char **path)
10767 +{
10768 +       struct acl_subject_label *tmpsubj;
10769 +       struct acl_object_label *retval;
10770 +       struct acl_object_label *retval2;
10771 +
10772 +       tmpsubj = (struct acl_subject_label *) subj;
10773 +       read_lock(&gr_inode_lock);
10774 +       do {
10775 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
10776 +               if (retval) {
10777 +                       if (retval->globbed) {
10778 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
10779 +                                               (struct vfsmount *)orig_mnt, path);
10780 +                               if (retval2)
10781 +                                       retval = retval2;
10782 +                       }
10783 +                       break;
10784 +               }
10785 +       } while ((tmpsubj = tmpsubj->parent_subject));
10786 +       read_unlock(&gr_inode_lock);
10787 +
10788 +       return retval;
10789 +}
10790 +
10791 +static __inline__ struct acl_object_label *
10792 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
10793 +           const struct dentry *curr_dentry,
10794 +           const struct acl_subject_label *subj, char **path)
10795 +{
10796 +       return __full_lookup(orig_dentry, orig_mnt,
10797 +                            curr_dentry->d_inode->i_ino, 
10798 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
10799 +}
10800 +
10801 +static struct acl_object_label *
10802 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10803 +             const struct acl_subject_label *subj, char *path)
10804 +{
10805 +       struct dentry *dentry = (struct dentry *) l_dentry;
10806 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
10807 +       struct acl_object_label *retval;
10808 +
10809 +       spin_lock(&dcache_lock);
10810 +
10811 +       for (;;) {
10812 +               if (dentry == real_root && mnt == real_root_mnt)
10813 +                       break;
10814 +
10815 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
10816 +                       if (mnt->mnt_parent == mnt)
10817 +                               break;
10818 +
10819 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10820 +                       if (retval != NULL)
10821 +                               goto out;
10822 +
10823 +                       dentry = mnt->mnt_mountpoint;
10824 +                       mnt = mnt->mnt_parent;
10825 +                       continue;
10826 +               }
10827 +
10828 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10829 +               if (retval != NULL)
10830 +                       goto out;
10831 +
10832 +               dentry = dentry->d_parent;
10833 +       }
10834 +
10835 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10836 +
10837 +       if (retval == NULL)
10838 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
10839 +out:
10840 +       spin_unlock(&dcache_lock);
10841 +       return retval;
10842 +}
10843 +
10844 +static __inline__ struct acl_object_label *
10845 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10846 +             const struct acl_subject_label *subj)
10847 +{
10848 +       char *path = NULL;
10849 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
10850 +}
10851 +
10852 +static __inline__ struct acl_object_label *
10853 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10854 +                    const struct acl_subject_label *subj, char *path)
10855 +{
10856 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
10857 +}
10858 +
10859 +static struct acl_subject_label *
10860 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10861 +              const struct acl_role_label *role)
10862 +{
10863 +       struct dentry *dentry = (struct dentry *) l_dentry;
10864 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
10865 +       struct acl_subject_label *retval;
10866 +
10867 +       spin_lock(&dcache_lock);
10868 +
10869 +       for (;;) {
10870 +               if (dentry == real_root && mnt == real_root_mnt)
10871 +                       break;
10872 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
10873 +                       if (mnt->mnt_parent == mnt)
10874 +                               break;
10875 +
10876 +                       read_lock(&gr_inode_lock);
10877 +                       retval =
10878 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
10879 +                                               dentry->d_inode->i_sb->s_dev, role);
10880 +                       read_unlock(&gr_inode_lock);
10881 +                       if (retval != NULL)
10882 +                               goto out;
10883 +
10884 +                       dentry = mnt->mnt_mountpoint;
10885 +                       mnt = mnt->mnt_parent;
10886 +                       continue;
10887 +               }
10888 +
10889 +               read_lock(&gr_inode_lock);
10890 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
10891 +                                         dentry->d_inode->i_sb->s_dev, role);
10892 +               read_unlock(&gr_inode_lock);
10893 +               if (retval != NULL)
10894 +                       goto out;
10895 +
10896 +               dentry = dentry->d_parent;
10897 +       }
10898 +
10899 +       read_lock(&gr_inode_lock);
10900 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
10901 +                                 dentry->d_inode->i_sb->s_dev, role);
10902 +       read_unlock(&gr_inode_lock);
10903 +
10904 +       if (unlikely(retval == NULL)) {
10905 +               read_lock(&gr_inode_lock);
10906 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
10907 +                                         real_root->d_inode->i_sb->s_dev, role);
10908 +               read_unlock(&gr_inode_lock);
10909 +       }
10910 +out:
10911 +       spin_unlock(&dcache_lock);
10912 +
10913 +       return retval;
10914 +}
10915 +
10916 +static void
10917 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
10918 +{
10919 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
10920 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
10921 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
10922 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->curr_ip));
10923 +
10924 +       return;
10925 +}
10926 +
10927 +static void
10928 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
10929 +                      const unsigned int effective, const unsigned int fs)
10930 +{
10931 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
10932 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
10933 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
10934 +                      type, real, effective, fs, NIPQUAD(task->curr_ip));
10935 +
10936 +       return;
10937 +}
10938 +
10939 +__u32
10940 +gr_check_link(const struct dentry * new_dentry,
10941 +             const struct dentry * parent_dentry,
10942 +             const struct vfsmount * parent_mnt,
10943 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
10944 +{
10945 +       struct acl_object_label *obj;
10946 +       __u32 oldmode, newmode;
10947 +       __u32 needmode;
10948 +
10949 +       if (unlikely(!(gr_status & GR_READY)))
10950 +               return (GR_CREATE | GR_LINK);
10951 +
10952 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
10953 +       oldmode = obj->mode;
10954 +
10955 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
10956 +               oldmode |= (GR_CREATE | GR_LINK);
10957 +
10958 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
10959 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
10960 +               needmode |= GR_SETID | GR_AUDIT_SETID;
10961 +
10962 +       newmode =
10963 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
10964 +                           oldmode | needmode);
10965 +
10966 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
10967 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
10968 +                             GR_INHERIT | GR_AUDIT_INHERIT);
10969 +
10970 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
10971 +               goto bad;
10972 +
10973 +       if ((oldmode & needmode) != needmode)
10974 +               goto bad;
10975 +
10976 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
10977 +       if ((newmode & needmode) != needmode)
10978 +               goto bad;
10979 +
10980 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
10981 +               return newmode;
10982 +bad:
10983 +       needmode = oldmode;
10984 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
10985 +               needmode |= GR_SETID;
10986 +       
10987 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
10988 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
10989 +               return (GR_CREATE | GR_LINK);
10990 +       } else if (newmode & GR_SUPPRESS)
10991 +               return GR_SUPPRESS;
10992 +       else
10993 +               return 0;
10994 +}
10995 +
10996 +__u32
10997 +gr_search_file(const struct dentry * dentry, const __u32 mode,
10998 +              const struct vfsmount * mnt)
10999 +{
11000 +       __u32 retval = mode;
11001 +       struct acl_subject_label *curracl;
11002 +       struct acl_object_label *currobj;
11003 +
11004 +       if (unlikely(!(gr_status & GR_READY)))
11005 +               return (mode & ~GR_AUDITS);
11006 +
11007 +       curracl = current->acl;
11008 +
11009 +       currobj = chk_obj_label(dentry, mnt, curracl);
11010 +       retval = currobj->mode & mode;
11011 +
11012 +       if (unlikely
11013 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
11014 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
11015 +               __u32 new_mode = mode;
11016 +
11017 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
11018 +
11019 +               retval = new_mode;
11020 +
11021 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
11022 +                       new_mode |= GR_INHERIT;
11023 +
11024 +               if (!(mode & GR_NOLEARN))
11025 +                       gr_log_learn(current, dentry, mnt, new_mode);
11026 +       }
11027 +
11028 +       return retval;
11029 +}
11030 +
11031 +__u32
11032 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
11033 +               const struct vfsmount * mnt, const __u32 mode)
11034 +{
11035 +       struct name_entry *match;
11036 +       struct acl_object_label *matchpo;
11037 +       struct acl_subject_label *curracl;
11038 +       char *path;
11039 +       __u32 retval;
11040 +
11041 +       if (unlikely(!(gr_status & GR_READY)))
11042 +               return (mode & ~GR_AUDITS);
11043 +
11044 +       preempt_disable();
11045 +       path = gr_to_filename(new_dentry, mnt);
11046 +       match = lookup_name_entry(path);
11047 +
11048 +       if (!match)
11049 +               goto check_parent;
11050 +
11051 +       curracl = current->acl;
11052 +
11053 +       read_lock(&gr_inode_lock);
11054 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
11055 +       read_unlock(&gr_inode_lock);
11056 +
11057 +       if (matchpo) {
11058 +               if ((matchpo->mode & mode) !=
11059 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
11060 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
11061 +                       __u32 new_mode = mode;
11062 +
11063 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
11064 +
11065 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
11066 +
11067 +                       preempt_enable();
11068 +                       return new_mode;
11069 +               }
11070 +               preempt_enable();
11071 +               return (matchpo->mode & mode);
11072 +       }
11073 +
11074 +      check_parent:
11075 +       curracl = current->acl;
11076 +
11077 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
11078 +       retval = matchpo->mode & mode;
11079 +
11080 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
11081 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
11082 +               __u32 new_mode = mode;
11083 +
11084 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
11085 +
11086 +               gr_log_learn(current, new_dentry, mnt, new_mode);
11087 +               preempt_enable();
11088 +               return new_mode;
11089 +       }
11090 +
11091 +       preempt_enable();
11092 +       return retval;
11093 +}
11094 +
11095 +int
11096 +gr_check_hidden_task(const struct task_struct *task)
11097 +{
11098 +       if (unlikely(!(gr_status & GR_READY)))
11099 +               return 0;
11100 +
11101 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
11102 +               return 1;
11103 +
11104 +       return 0;
11105 +}
11106 +
11107 +int
11108 +gr_check_protected_task(const struct task_struct *task)
11109 +{
11110 +       if (unlikely(!(gr_status & GR_READY) || !task))
11111 +               return 0;
11112 +
11113 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
11114 +           task->acl != current->acl)
11115 +               return 1;
11116 +
11117 +       return 0;
11118 +}
11119 +
11120 +void
11121 +gr_copy_label(struct task_struct *tsk)
11122 +{
11123 +       tsk->used_accept = 0;
11124 +       tsk->acl_sp_role = 0;
11125 +       tsk->acl_role_id = current->acl_role_id;
11126 +       tsk->acl = current->acl;
11127 +       tsk->role = current->role;
11128 +       tsk->curr_ip = current->curr_ip;
11129 +       if (current->exec_file)
11130 +               get_file(current->exec_file);
11131 +       tsk->exec_file = current->exec_file;
11132 +       tsk->is_writable = current->is_writable;
11133 +       if (unlikely(current->used_accept))
11134 +               current->curr_ip = 0;
11135 +
11136 +       return;
11137 +}
11138 +
11139 +static void
11140 +gr_set_proc_res(struct task_struct *task)
11141 +{
11142 +       struct acl_subject_label *proc;
11143 +       unsigned short i;
11144 +
11145 +       proc = task->acl;
11146 +
11147 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
11148 +               return;
11149 +
11150 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
11151 +               if (!(proc->resmask & (1 << i)))
11152 +                       continue;
11153 +
11154 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
11155 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
11156 +       }
11157 +
11158 +       return;
11159 +}
11160 +
11161 +int
11162 +gr_check_user_change(int real, int effective, int fs)
11163 +{
11164 +       unsigned int i;
11165 +       __u16 num;
11166 +       uid_t *uidlist;
11167 +       int curuid;
11168 +       int realok = 0;
11169 +       int effectiveok = 0;
11170 +       int fsok = 0;
11171 +
11172 +       if (unlikely(!(gr_status & GR_READY)))
11173 +               return 0;
11174 +
11175 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
11176 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
11177 +
11178 +       num = current->acl->user_trans_num;
11179 +       uidlist = current->acl->user_transitions;
11180 +
11181 +       if (uidlist == NULL)
11182 +               return 0;
11183 +
11184 +       if (real == -1)
11185 +               realok = 1;
11186 +       if (effective == -1)
11187 +               effectiveok = 1;
11188 +       if (fs == -1)
11189 +               fsok = 1;
11190 +
11191 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
11192 +               for (i = 0; i < num; i++) {
11193 +                       curuid = (int)uidlist[i];
11194 +                       if (real == curuid)
11195 +                               realok = 1;
11196 +                       if (effective == curuid)
11197 +                               effectiveok = 1;
11198 +                       if (fs == curuid)
11199 +                               fsok = 1;
11200 +               }
11201 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
11202 +               for (i = 0; i < num; i++) {
11203 +                       curuid = (int)uidlist[i];
11204 +                       if (real == curuid)
11205 +                               break;
11206 +                       if (effective == curuid)
11207 +                               break;
11208 +                       if (fs == curuid)
11209 +                               break;
11210 +               }
11211 +               /* not in deny list */
11212 +               if (i == num) {
11213 +                       realok = 1;
11214 +                       effectiveok = 1;
11215 +                       fsok = 1;
11216 +               }
11217 +       }
11218 +
11219 +       if (realok && effectiveok && fsok)
11220 +               return 0;
11221 +       else {
11222 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
11223 +               return 1;
11224 +       }
11225 +}
11226 +
11227 +int
11228 +gr_check_group_change(int real, int effective, int fs)
11229 +{
11230 +       unsigned int i;
11231 +       __u16 num;
11232 +       gid_t *gidlist;
11233 +       int curgid;
11234 +       int realok = 0;
11235 +       int effectiveok = 0;
11236 +       int fsok = 0;
11237 +
11238 +       if (unlikely(!(gr_status & GR_READY)))
11239 +               return 0;
11240 +
11241 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
11242 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
11243 +
11244 +       num = current->acl->group_trans_num;
11245 +       gidlist = current->acl->group_transitions;
11246 +
11247 +       if (gidlist == NULL)
11248 +               return 0;
11249 +
11250 +       if (real == -1)
11251 +               realok = 1;
11252 +       if (effective == -1)
11253 +               effectiveok = 1;
11254 +       if (fs == -1)
11255 +               fsok = 1;
11256 +
11257 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
11258 +               for (i = 0; i < num; i++) {
11259 +                       curgid = (int)gidlist[i];
11260 +                       if (real == curgid)
11261 +                               realok = 1;
11262 +                       if (effective == curgid)
11263 +                               effectiveok = 1;
11264 +                       if (fs == curgid)
11265 +                               fsok = 1;
11266 +               }
11267 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
11268 +               for (i = 0; i < num; i++) {
11269 +                       curgid = (int)gidlist[i];
11270 +                       if (real == curgid)
11271 +                               break;
11272 +                       if (effective == curgid)
11273 +                               break;
11274 +                       if (fs == curgid)
11275 +                               break;
11276 +               }
11277 +               /* not in deny list */
11278 +               if (i == num) {
11279 +                       realok = 1;
11280 +                       effectiveok = 1;
11281 +                       fsok = 1;
11282 +               }
11283 +       }
11284 +
11285 +       if (realok && effectiveok && fsok)
11286 +               return 0;
11287 +       else {
11288 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
11289 +               return 1;
11290 +       }
11291 +}
11292 +
11293 +void
11294 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
11295 +{
11296 +       struct acl_role_label *role = task->role;
11297 +       struct acl_subject_label *subj = NULL;
11298 +       struct acl_object_label *obj;
11299 +       struct file *filp;
11300 +
11301 +       if (unlikely(!(gr_status & GR_READY)))
11302 +               return;
11303 +
11304 +       filp = task->exec_file;
11305 +
11306 +       /* kernel process, we'll give them the kernel role */
11307 +       if (unlikely(!filp)) {
11308 +               task->role = kernel_role;
11309 +               task->acl = kernel_role->root_label;
11310 +               return;
11311 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
11312 +               role = lookup_acl_role_label(task, uid, gid);
11313 +
11314 +       /* perform subject lookup in possibly new role
11315 +          we can use this result below in the case where role == task->role
11316 +       */
11317 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
11318 +
11319 +       /* if we changed uid/gid, but result in the same role
11320 +          and are using inheritance, don't lose the inherited subject
11321 +          if current subject is other than what normal lookup
11322 +          would result in, we arrived via inheritance, don't
11323 +          lose subject
11324 +       */
11325 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
11326 +                                  (subj == task->acl)))
11327 +               task->acl = subj;
11328 +
11329 +       task->role = role;
11330 +
11331 +       task->is_writable = 0;
11332 +
11333 +       /* ignore additional mmap checks for processes that are writable 
11334 +          by the default ACL */
11335 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
11336 +       if (unlikely(obj->mode & GR_WRITE))
11337 +               task->is_writable = 1;
11338 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
11339 +       if (unlikely(obj->mode & GR_WRITE))
11340 +               task->is_writable = 1;
11341 +
11342 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11343 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
11344 +#endif
11345 +
11346 +       gr_set_proc_res(task);
11347 +
11348 +       return;
11349 +}
11350 +
11351 +int
11352 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
11353 +{
11354 +       struct task_struct *task = current;
11355 +       struct acl_subject_label *newacl;
11356 +       struct acl_object_label *obj;
11357 +       __u32 retmode;
11358 +
11359 +       if (unlikely(!(gr_status & GR_READY)))
11360 +               return 0;
11361 +
11362 +       newacl = chk_subj_label(dentry, mnt, task->role);
11363 +
11364 +       task_lock(task);
11365 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
11366 +            GR_POVERRIDE) && (task->acl != newacl) &&
11367 +            !(task->role->roletype & GR_ROLE_GOD) &&
11368 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
11369 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
11370 +           (atomic_read(&task->fs->count) > 1 ||
11371 +            atomic_read(&task->files->count) > 1 ||
11372 +            atomic_read(&task->sighand->count) > 1)) {
11373 +                task_unlock(task);
11374 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
11375 +               return -EACCES;
11376 +       }
11377 +       task_unlock(task);
11378 +
11379 +       obj = chk_obj_label(dentry, mnt, task->acl);
11380 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
11381 +
11382 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
11383 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
11384 +               if (obj->nested)
11385 +                       task->acl = obj->nested;
11386 +               else
11387 +                       task->acl = newacl;
11388 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
11389 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
11390 +
11391 +       task->is_writable = 0;
11392 +
11393 +       /* ignore additional mmap checks for processes that are writable 
11394 +          by the default ACL */
11395 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
11396 +       if (unlikely(obj->mode & GR_WRITE))
11397 +               task->is_writable = 1;
11398 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
11399 +       if (unlikely(obj->mode & GR_WRITE))
11400 +               task->is_writable = 1;
11401 +
11402 +       gr_set_proc_res(task);
11403 +
11404 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11405 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
11406 +#endif
11407 +       return 0;
11408 +}
11409 +
11410 +static void
11411 +do_handle_delete(const ino_t ino, const dev_t dev)
11412 +{
11413 +       struct acl_object_label *matchpo;
11414 +       struct acl_subject_label *matchps;
11415 +       struct acl_subject_label *i;
11416 +       struct acl_role_label *role;
11417 +
11418 +       for (role = role_list_head; role; role = role->next) {
11419 +               for (i = role->hash->first; i; i = i->next) {
11420 +                       if (unlikely((i->mode & GR_NESTED) &&
11421 +                                    (i->inode == ino) &&
11422 +                                    (i->device == dev)))
11423 +                               i->mode |= GR_DELETED;
11424 +                       if (unlikely((matchpo =
11425 +                            lookup_acl_obj_label(ino, dev, i)) != NULL))
11426 +                               matchpo->mode |= GR_DELETED;
11427 +               }
11428 +
11429 +               if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
11430 +                       matchps->mode |= GR_DELETED;
11431 +       }
11432 +
11433 +       return;
11434 +}
11435 +
11436 +void
11437 +gr_handle_delete(const ino_t ino, const dev_t dev)
11438 +{
11439 +       if (unlikely(!(gr_status & GR_READY)))
11440 +               return;
11441 +
11442 +       write_lock(&gr_inode_lock);
11443 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
11444 +               do_handle_delete(ino, dev);
11445 +       write_unlock(&gr_inode_lock);
11446 +
11447 +       return;
11448 +}
11449 +
11450 +static void
11451 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
11452 +                    const ino_t newinode, const dev_t newdevice,
11453 +                    struct acl_subject_label *subj)
11454 +{
11455 +       unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
11456 +       struct acl_object_label **match;
11457 +       struct acl_object_label *tmp;
11458 +       unsigned int i = 0;
11459 +
11460 +       match = &subj->obj_hash[index];
11461 +
11462 +       while (*match && ((*match)->inode != oldinode ||
11463 +              (*match)->device != olddevice ||
11464 +              !((*match)->mode & GR_DELETED))) {
11465 +               index = (index + (1 << i)) % subj->obj_hash_size;
11466 +               match = &subj->obj_hash[index];
11467 +               i = (i + 1) % 32;
11468 +       }
11469 +
11470 +       if (*match && ((*match) != deleted_object)
11471 +           && ((*match)->inode == oldinode)
11472 +           && ((*match)->device == olddevice)
11473 +           && ((*match)->mode & GR_DELETED)) {
11474 +               tmp = *match;
11475 +               tmp->inode = newinode;
11476 +               tmp->device = newdevice;
11477 +               tmp->mode &= ~GR_DELETED;
11478 +
11479 +               *match = deleted_object;
11480 +
11481 +               insert_acl_obj_label(tmp, subj);
11482 +       }
11483 +
11484 +       return;
11485 +}
11486 +
11487 +static void
11488 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
11489 +                     const ino_t newinode, const dev_t newdevice,
11490 +                     struct acl_role_label *role)
11491 +{
11492 +       struct acl_subject_label **s_hash = role->subj_hash;
11493 +       unsigned long subj_size = role->subj_hash_size;
11494 +       unsigned long index = fhash(oldinode, olddevice, subj_size);
11495 +       struct acl_subject_label **match;
11496 +       struct acl_subject_label *tmp;
11497 +       unsigned int i = 0;
11498 +
11499 +       match = &s_hash[index];
11500 +
11501 +       while (*match && ((*match)->inode != oldinode ||
11502 +              (*match)->device != olddevice ||
11503 +              !((*match)->mode & GR_DELETED))) {
11504 +               index = (index + (1 << i)) % subj_size;
11505 +               i = (i + 1) % 32;
11506 +               match = &s_hash[index];
11507 +       }
11508 +
11509 +       if (*match && (*match != deleted_subject)
11510 +           && ((*match)->inode == oldinode)
11511 +           && ((*match)->device == olddevice)
11512 +           && ((*match)->mode & GR_DELETED)) {
11513 +               tmp = *match;
11514 +
11515 +               tmp->inode = newinode;
11516 +               tmp->device = newdevice;
11517 +               tmp->mode &= ~GR_DELETED;
11518 +
11519 +               *match = deleted_subject;
11520 +
11521 +               insert_acl_subj_label(tmp, role);
11522 +       }
11523 +
11524 +       return;
11525 +}
11526 +
11527 +static void
11528 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
11529 +                   const ino_t newinode, const dev_t newdevice)
11530 +{
11531 +       unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
11532 +       struct name_entry **match;
11533 +       struct name_entry *tmp;
11534 +       unsigned int i = 0;
11535 +
11536 +       match = &inodev_set.n_hash[index];
11537 +
11538 +       while (*match
11539 +              && ((*match)->inode != oldinode
11540 +                  || (*match)->device != olddevice)) {
11541 +               index = (index + (1 << i)) % inodev_set.n_size;
11542 +               i = (i + 1) % 32;
11543 +               match = &inodev_set.n_hash[index];
11544 +       }
11545 +
11546 +       if (*match && (*match != deleted_inodev)
11547 +           && ((*match)->inode == oldinode)
11548 +           && ((*match)->device == olddevice)) {
11549 +               tmp = *match;
11550 +
11551 +               tmp->inode = newinode;
11552 +               tmp->device = newdevice;
11553 +
11554 +               *match = deleted_inodev;
11555 +
11556 +               insert_inodev_entry(tmp);
11557 +       }
11558 +
11559 +       return;
11560 +}
11561 +
11562 +static void
11563 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
11564 +                const struct vfsmount *mnt)
11565 +{
11566 +       struct acl_subject_label *i;
11567 +       struct acl_role_label *role;
11568 +
11569 +       for (role = role_list_head; role; role = role->next) {
11570 +               update_acl_subj_label(matchn->inode, matchn->device,
11571 +                                     dentry->d_inode->i_ino,
11572 +                                     dentry->d_inode->i_sb->s_dev, role);
11573 +
11574 +               for (i = role->hash->first; i; i = i->next) {
11575 +                       if (unlikely((i->mode & GR_NESTED) &&
11576 +                                    (i->inode == dentry->d_inode->i_ino) &&
11577 +                                    (i->device == dentry->d_inode->i_sb->s_dev))) {
11578 +                               i->inode = dentry->d_inode->i_ino;
11579 +                               i->device = dentry->d_inode->i_sb->s_dev;
11580 +                       }
11581 +                       update_acl_obj_label(matchn->inode, matchn->device,
11582 +                                            dentry->d_inode->i_ino,
11583 +                                            dentry->d_inode->i_sb->s_dev, i);
11584 +               }
11585 +       }
11586 +
11587 +       update_inodev_entry(matchn->inode, matchn->device,
11588 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
11589 +
11590 +       return;
11591 +}
11592 +
11593 +void
11594 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
11595 +{
11596 +       struct name_entry *matchn;
11597 +
11598 +       if (unlikely(!(gr_status & GR_READY)))
11599 +               return;
11600 +
11601 +       preempt_disable();
11602 +       matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
11603 +       preempt_enable();
11604 +
11605 +       if (unlikely((unsigned long)matchn)) {
11606 +               write_lock(&gr_inode_lock);
11607 +               do_handle_create(matchn, dentry, mnt);
11608 +               write_unlock(&gr_inode_lock);
11609 +       }
11610 +
11611 +       return;
11612 +}
11613 +
11614 +void
11615 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
11616 +                struct dentry *old_dentry,
11617 +                struct dentry *new_dentry,
11618 +                struct vfsmount *mnt, const __u8 replace)
11619 +{
11620 +       struct name_entry *matchn;
11621 +
11622 +       if (unlikely(!(gr_status & GR_READY)))
11623 +               return;
11624 +
11625 +       preempt_disable();
11626 +       matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
11627 +       preempt_enable();
11628 +
11629 +       /* we wouldn't have to check d_inode if it weren't for
11630 +          NFS silly-renaming
11631 +        */
11632 +
11633 +       write_lock(&gr_inode_lock);
11634 +       if (unlikely(replace && new_dentry->d_inode)) {
11635 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
11636 +                                       new_dentry->d_inode->i_sb->s_dev) &&
11637 +                   (old_dentry->d_inode->i_nlink <= 1)))
11638 +                       do_handle_delete(new_dentry->d_inode->i_ino,
11639 +                                        new_dentry->d_inode->i_sb->s_dev);
11640 +       }
11641 +
11642 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
11643 +                               old_dentry->d_inode->i_sb->s_dev) &&
11644 +           (old_dentry->d_inode->i_nlink <= 1)))
11645 +               do_handle_delete(old_dentry->d_inode->i_ino,
11646 +                                old_dentry->d_inode->i_sb->s_dev);
11647 +
11648 +       if (unlikely((unsigned long)matchn))
11649 +               do_handle_create(matchn, old_dentry, mnt);
11650 +
11651 +       write_unlock(&gr_inode_lock);
11652 +
11653 +       return;
11654 +}
11655 +
11656 +static int
11657 +lookup_special_role_auth(const char *rolename, unsigned char **salt,
11658 +                        unsigned char **sum)
11659 +{
11660 +       struct acl_role_label *r;
11661 +       struct role_allowed_ip *ipp;
11662 +       struct role_transition *trans;
11663 +       __u16 i;
11664 +       int found = 0;
11665 +
11666 +       /* check transition table */
11667 +
11668 +       for (trans = current->role->transitions; trans; trans = trans->next) {
11669 +               if (!strcmp(rolename, trans->rolename)) {
11670 +                       found = 1;
11671 +                       break;
11672 +               }
11673 +       }
11674 +
11675 +       if (!found)
11676 +               return 0;
11677 +
11678 +       /* handle special roles that do not require authentication
11679 +          and check ip */
11680 +
11681 +       for (r = role_list_head; r; r = r->next) {
11682 +               if (!strcmp(rolename, r->rolename) &&
11683 +                   (r->roletype & GR_ROLE_SPECIAL)) {
11684 +                       found = 0;
11685 +                       if (r->allowed_ips != NULL) {
11686 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
11687 +                                       if ((ntohl(current->curr_ip) & ipp->netmask) ==
11688 +                                            (ntohl(ipp->addr) & ipp->netmask))
11689 +                                               found = 1;
11690 +                               }
11691 +                       } else
11692 +                               found = 2;
11693 +                       if (!found)
11694 +                               return 0;
11695 +
11696 +                       if (r->roletype & GR_ROLE_NOPW) {
11697 +                               *salt = NULL;
11698 +                               *sum = NULL;
11699 +                               return 1;
11700 +                       }
11701 +               }
11702 +       }
11703 +
11704 +       for (i = 0; i < num_sprole_pws; i++) {
11705 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
11706 +                       *salt = acl_special_roles[i]->salt;
11707 +                       *sum = acl_special_roles[i]->sum;
11708 +                       return 1;
11709 +               }
11710 +       }
11711 +
11712 +       return 0;
11713 +}
11714 +
11715 +static void
11716 +assign_special_role(char *rolename)
11717 +{
11718 +       struct acl_object_label *obj;
11719 +       struct acl_role_label *r;
11720 +       struct acl_role_label *assigned = NULL;
11721 +       struct task_struct *tsk;
11722 +       struct file *filp;
11723 +
11724 +       for (r = role_list_head; r; r = r->next)
11725 +               if (!strcmp(rolename, r->rolename) &&
11726 +                   (r->roletype & GR_ROLE_SPECIAL))
11727 +                       assigned = r;
11728 +
11729 +       if (!assigned)
11730 +               return;
11731 +
11732 +       read_lock(&tasklist_lock);
11733 +       read_lock(&grsec_exec_file_lock);
11734 +
11735 +       tsk = current->parent;
11736 +       if (tsk == NULL) {
11737 +               read_unlock(&grsec_exec_file_lock);
11738 +               read_unlock(&tasklist_lock);
11739 +               return;
11740 +       }
11741 +
11742 +       filp = tsk->exec_file;
11743 +       if (filp == NULL) {
11744 +               read_unlock(&grsec_exec_file_lock);
11745 +               read_unlock(&tasklist_lock);
11746 +               return;
11747 +       }
11748 +
11749 +       tsk->is_writable = 0;
11750 +
11751 +       acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
11752 +       tsk->acl_sp_role = 1;
11753 +       tsk->acl_role_id = acl_sp_role_value;
11754 +       tsk->role = assigned;
11755 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
11756 +
11757 +       /* ignore additional mmap checks for processes that are writable 
11758 +          by the default ACL */
11759 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
11760 +       if (unlikely(obj->mode & GR_WRITE))
11761 +               tsk->is_writable = 1;
11762 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
11763 +       if (unlikely(obj->mode & GR_WRITE))
11764 +               tsk->is_writable = 1;
11765 +
11766 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11767 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
11768 +#endif
11769 +
11770 +       read_unlock(&grsec_exec_file_lock);
11771 +       read_unlock(&tasklist_lock);
11772 +       return;
11773 +}
11774 +
11775 +int gr_check_secure_terminal(struct task_struct *task)
11776 +{
11777 +       struct task_struct *p, *p2, *p3;
11778 +       struct files_struct *files;
11779 +       struct file *our_file = NULL, *file;
11780 +       int i;
11781 +
11782 +       if (task->signal->tty == NULL)
11783 +               return 1;
11784 +
11785 +       task_lock(task);
11786 +       files = task->files;
11787 +       if (files != NULL) {
11788 +               spin_lock(&files->file_lock);
11789 +               for (i=0; i < files->max_fds; i++) {
11790 +                       file = fcheck_files(files, i);
11791 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
11792 +                               get_file(file);
11793 +                               our_file = file;
11794 +                       }
11795 +               }
11796 +               spin_unlock(&files->file_lock);
11797 +       }
11798 +       task_unlock(task);
11799 +
11800 +       if (our_file == NULL)
11801 +               return 1;
11802 +
11803 +       read_lock(&tasklist_lock);
11804 +       do_each_thread(p2, p) {
11805 +               task_lock(p);
11806 +               files = p->files;
11807 +               if (files == NULL ||
11808 +                   (p->signal && p->signal->tty == task->signal->tty)) {
11809 +                       task_unlock(p);
11810 +                       continue;
11811 +               }
11812 +               spin_lock(&files->file_lock);
11813 +               for (i=0; i < files->max_fds; i++) {
11814 +                       file = fcheck_files(files, i);
11815 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
11816 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
11817 +                               p3 = task;
11818 +                               while (p3->pid > 0) {
11819 +                                       if (p3 == p)
11820 +                                               break;
11821 +                                       p3 = p3->parent;
11822 +                               }
11823 +                               if (p3 == p)
11824 +                                       break;
11825 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
11826 +                               gr_handle_alertkill(p);
11827 +                               spin_unlock(&files->file_lock);
11828 +                               task_unlock(p);
11829 +                               read_unlock(&tasklist_lock);
11830 +                               fput(our_file);
11831 +                               return 0;
11832 +                       }
11833 +               }
11834 +               spin_unlock(&files->file_lock);
11835 +               task_unlock(p);
11836 +       } while_each_thread(p2, p);
11837 +       read_unlock(&tasklist_lock);
11838 +
11839 +       fput(our_file);
11840 +       return 1;
11841 +}
11842 +
11843 +ssize_t
11844 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
11845 +{
11846 +       struct gr_arg_wrapper uwrap;
11847 +       unsigned char *sprole_salt;
11848 +       unsigned char *sprole_sum;
11849 +       int error = sizeof (struct gr_arg_wrapper);
11850 +       int error2 = 0;
11851 +
11852 +       down(&gr_dev_sem);
11853 +
11854 +       if (count != sizeof (struct gr_arg_wrapper)) {
11855 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
11856 +               error = -EINVAL;
11857 +               goto out;
11858 +       }
11859 +
11860 +       
11861 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
11862 +               gr_auth_expires = 0;
11863 +               gr_auth_attempts = 0;
11864 +       }
11865 +
11866 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
11867 +               error = -EFAULT;
11868 +               goto out;
11869 +       }
11870 +
11871 +       if ((uwrap.version != (GRSECURITY_VERSION | (6 << 16))) || (uwrap.size != sizeof(struct gr_arg))) {
11872 +               error = -EINVAL;
11873 +               goto out;
11874 +       }
11875 +
11876 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
11877 +               error = -EFAULT;
11878 +               goto out;
11879 +       }
11880 +
11881 +       if (gr_usermode->mode != SPROLE && gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
11882 +           time_after(gr_auth_expires, get_seconds())) {
11883 +               error = -EBUSY;
11884 +               goto out;
11885 +       }
11886 +
11887 +       /* if non-root trying to do anything other than use a special role,
11888 +          do not attempt authentication, do not count towards authentication
11889 +          locking
11890 +        */
11891 +
11892 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
11893 +           gr_usermode->mode != UNSPROLE && current->uid) {
11894 +               error = -EPERM;
11895 +               goto out;
11896 +       }
11897 +
11898 +       /* ensure pw and special role name are null terminated */
11899 +
11900 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
11901 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
11902 +
11903 +       /* Okay. 
11904 +        * We have our enough of the argument structure..(we have yet
11905 +        * to copy_from_user the tables themselves) . Copy the tables
11906 +        * only if we need them, i.e. for loading operations. */
11907 +
11908 +       switch (gr_usermode->mode) {
11909 +       case STATUS:
11910 +                       if (gr_status & GR_READY) {
11911 +                               error = 1;
11912 +                               if (!gr_check_secure_terminal(current))
11913 +                                       error = 3;
11914 +                       } else
11915 +                               error = 2;
11916 +                       goto out;
11917 +       case SHUTDOWN:
11918 +               if ((gr_status & GR_READY)
11919 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11920 +                       gr_status &= ~GR_READY;
11921 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
11922 +                       free_variables();
11923 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
11924 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
11925 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
11926 +               } else if (gr_status & GR_READY) {
11927 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
11928 +                       error = -EPERM;
11929 +               } else {
11930 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
11931 +                       error = -EAGAIN;
11932 +               }
11933 +               break;
11934 +       case ENABLE:
11935 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
11936 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
11937 +               else {
11938 +                       if (gr_status & GR_READY)
11939 +                               error = -EAGAIN;
11940 +                       else
11941 +                               error = error2;
11942 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
11943 +               }
11944 +               break;
11945 +       case RELOAD:
11946 +               if (!(gr_status & GR_READY)) {
11947 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
11948 +                       error = -EAGAIN;
11949 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11950 +                       lock_kernel();
11951 +                       gr_status &= ~GR_READY;
11952 +                       free_variables();
11953 +                       if (!(error2 = gracl_init(gr_usermode))) {
11954 +                               unlock_kernel();
11955 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
11956 +                       } else {
11957 +                               unlock_kernel();
11958 +                               error = error2;
11959 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
11960 +                       }
11961 +               } else {
11962 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
11963 +                       error = -EPERM;
11964 +               }
11965 +               break;
11966 +       case SEGVMOD:
11967 +               if (unlikely(!(gr_status & GR_READY))) {
11968 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
11969 +                       error = -EAGAIN;
11970 +                       break;
11971 +               }
11972 +
11973 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11974 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
11975 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
11976 +                               struct acl_subject_label *segvacl;
11977 +                               segvacl =
11978 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
11979 +                                                         gr_usermode->segv_device,
11980 +                                                         current->role);
11981 +                               if (segvacl) {
11982 +                                       segvacl->crashes = 0;
11983 +                                       segvacl->expires = 0;
11984 +                               }
11985 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
11986 +                               gr_remove_uid(gr_usermode->segv_uid);
11987 +                       }
11988 +               } else {
11989 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
11990 +                       error = -EPERM;
11991 +               }
11992 +               break;
11993 +       case SPROLE:
11994 +               if (unlikely(!(gr_status & GR_READY))) {
11995 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
11996 +                       error = -EAGAIN;
11997 +                       break;
11998 +               }
11999 +
12000 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
12001 +                       current->role->expires = 0;
12002 +                       current->role->auth_attempts = 0;
12003 +               }
12004 +
12005 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
12006 +                   time_after(current->role->expires, get_seconds())) {
12007 +                       error = -EBUSY;
12008 +                       goto out;
12009 +               }
12010 +
12011 +               if (lookup_special_role_auth
12012 +                   (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
12013 +                   && ((!sprole_salt && !sprole_sum)
12014 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
12015 +                       char *p = "";
12016 +                       assign_special_role(gr_usermode->sp_role);
12017 +                       read_lock(&tasklist_lock);
12018 +                       if (current->parent)
12019 +                               p = current->parent->role->rolename;
12020 +                       read_unlock(&tasklist_lock);
12021 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
12022 +                                       p, acl_sp_role_value);
12023 +               } else {
12024 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
12025 +                       error = -EPERM;
12026 +                       if(!(current->role->auth_attempts++))
12027 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
12028 +
12029 +                       goto out;
12030 +               }
12031 +               break;
12032 +       case UNSPROLE:
12033 +               if (unlikely(!(gr_status & GR_READY))) {
12034 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
12035 +                       error = -EAGAIN;
12036 +                       break;
12037 +               }
12038 +
12039 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
12040 +                       char *p = "";
12041 +                       int i = 0;
12042 +
12043 +                       read_lock(&tasklist_lock);
12044 +                       if (current->parent) {
12045 +                               p = current->parent->role->rolename;
12046 +                               i = current->parent->acl_role_id;
12047 +                       }
12048 +                       read_unlock(&tasklist_lock);
12049 +
12050 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
12051 +                       gr_set_acls(1);
12052 +               } else {
12053 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
12054 +                       error = -EPERM;
12055 +                       goto out;
12056 +               }
12057 +               break;
12058 +       default:
12059 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
12060 +               error = -EINVAL;
12061 +               break;
12062 +       }
12063 +
12064 +       if (error != -EPERM)
12065 +               goto out;
12066 +
12067 +       if(!(gr_auth_attempts++))
12068 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
12069 +
12070 +      out:
12071 +       up(&gr_dev_sem);
12072 +       return error;
12073 +}
12074 +
12075 +int
12076 +gr_set_acls(const int type)
12077 +{
12078 +       struct acl_object_label *obj;
12079 +       struct task_struct *task, *task2;
12080 +       struct file *filp;
12081 +
12082 +       read_lock(&tasklist_lock);
12083 +       read_lock(&grsec_exec_file_lock);
12084 +       do_each_thread(task2, task) {
12085 +               /* check to see if we're called from the exit handler,
12086 +                  if so, only replace ACLs that have inherited the admin
12087 +                  ACL */
12088 +
12089 +               if (type && (task->role != current->role ||
12090 +                            task->acl_role_id != current->acl_role_id))
12091 +                       continue;
12092 +
12093 +               task->acl_role_id = 0;
12094 +               task->acl_sp_role = 0;
12095 +
12096 +               if ((filp = task->exec_file)) {
12097 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
12098 +
12099 +                       task->acl =
12100 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
12101 +                                          task->role);
12102 +                       if (task->acl) {
12103 +                               struct acl_subject_label *curr;
12104 +                               curr = task->acl;
12105 +
12106 +                               task->is_writable = 0;
12107 +                               /* ignore additional mmap checks for processes that are writable 
12108 +                                  by the default ACL */
12109 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
12110 +                               if (unlikely(obj->mode & GR_WRITE))
12111 +                                       task->is_writable = 1;
12112 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
12113 +                               if (unlikely(obj->mode & GR_WRITE))
12114 +                                       task->is_writable = 1;
12115 +
12116 +                               gr_set_proc_res(task);
12117 +
12118 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
12119 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
12120 +#endif
12121 +                       } else {
12122 +                               read_unlock(&grsec_exec_file_lock);
12123 +                               read_unlock(&tasklist_lock);
12124 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
12125 +                               return 1;
12126 +                       }
12127 +               } else {
12128 +                       // it's a kernel process
12129 +                       task->role = kernel_role;
12130 +                       task->acl = kernel_role->root_label;
12131 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
12132 +                       task->acl->mode &= ~GR_FIND;
12133 +#endif
12134 +               }
12135 +       } while_each_thread(task2, task);
12136 +       read_unlock(&grsec_exec_file_lock);
12137 +       read_unlock(&tasklist_lock);
12138 +       return 0;
12139 +}
12140 +
12141 +void
12142 +gr_learn_resource(const struct task_struct *task,
12143 +                 const int res, const unsigned long wanted, const int gt)
12144 +{
12145 +       struct acl_subject_label *acl;
12146 +
12147 +       if (unlikely((gr_status & GR_READY) &&
12148 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
12149 +               goto skip_reslog;
12150 +
12151 +#ifdef CONFIG_GRKERNSEC_RESLOG
12152 +       gr_log_resource(task, res, wanted, gt);
12153 +#endif
12154 +      skip_reslog:
12155 +
12156 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
12157 +               return;
12158 +
12159 +       acl = task->acl;
12160 +
12161 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
12162 +                  !(acl->resmask & (1 << (unsigned short) res))))
12163 +               return;
12164 +
12165 +       if (wanted >= acl->res[res].rlim_cur) {
12166 +               unsigned long res_add;
12167 +
12168 +               res_add = wanted;
12169 +               switch (res) {
12170 +               case RLIMIT_CPU:
12171 +                       res_add += GR_RLIM_CPU_BUMP;
12172 +                       break;
12173 +               case RLIMIT_FSIZE:
12174 +                       res_add += GR_RLIM_FSIZE_BUMP;
12175 +                       break;
12176 +               case RLIMIT_DATA:
12177 +                       res_add += GR_RLIM_DATA_BUMP;
12178 +                       break;
12179 +               case RLIMIT_STACK:
12180 +                       res_add += GR_RLIM_STACK_BUMP;
12181 +                       break;
12182 +               case RLIMIT_CORE:
12183 +                       res_add += GR_RLIM_CORE_BUMP;
12184 +                       break;
12185 +               case RLIMIT_RSS:
12186 +                       res_add += GR_RLIM_RSS_BUMP;
12187 +                       break;
12188 +               case RLIMIT_NPROC:
12189 +                       res_add += GR_RLIM_NPROC_BUMP;
12190 +                       break;
12191 +               case RLIMIT_NOFILE:
12192 +                       res_add += GR_RLIM_NOFILE_BUMP;
12193 +                       break;
12194 +               case RLIMIT_MEMLOCK:
12195 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
12196 +                       break;
12197 +               case RLIMIT_AS:
12198 +                       res_add += GR_RLIM_AS_BUMP;
12199 +                       break;
12200 +               case RLIMIT_LOCKS:
12201 +                       res_add += GR_RLIM_LOCKS_BUMP;
12202 +                       break;
12203 +               }
12204 +
12205 +               acl->res[res].rlim_cur = res_add;
12206 +
12207 +               if (wanted > acl->res[res].rlim_max)
12208 +                       acl->res[res].rlim_max = res_add;
12209 +
12210 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
12211 +                              task->role->roletype, acl->filename,
12212 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
12213 +                              "", (unsigned long) res);
12214 +       }
12215 +
12216 +       return;
12217 +}
12218 +
12219 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
12220 +void
12221 +pax_set_initial_flags(struct linux_binprm *bprm)
12222 +{
12223 +       struct task_struct *task = current;
12224 +        struct acl_subject_label *proc;
12225 +       unsigned long flags;
12226 +
12227 +        if (unlikely(!(gr_status & GR_READY)))
12228 +                return;
12229 +
12230 +       flags = pax_get_flags(task);
12231 +
12232 +        proc = task->acl;
12233 +
12234 +        if (proc->mode & GR_PAXPAGE)
12235 +                flags &= ~MF_PAX_PAGEEXEC;
12236 +        if (proc->mode & GR_PAXSEGM)
12237 +                flags &= ~MF_PAX_SEGMEXEC;
12238 +        if (proc->mode & GR_PAXGCC)
12239 +                flags |= MF_PAX_EMUTRAMP;
12240 +        if (proc->mode & GR_PAXMPROTECT)
12241 +                flags &= ~MF_PAX_MPROTECT;
12242 +        if (proc->mode & GR_PAXRANDMMAP)
12243 +                flags &= ~MF_PAX_RANDMMAP;
12244 +
12245 +       pax_set_flags(task, flags);
12246 +
12247 +        return;
12248 +}
12249 +#endif
12250 +
12251 +#ifdef CONFIG_SYSCTL
12252 +extern struct proc_dir_entry *proc_sys_root;
12253 +
12254 +/* the following function is called under the BKL */
12255 +
12256 +__u32
12257 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
12258 +                const void *newval)
12259 +{
12260 +       struct proc_dir_entry *tmp;
12261 +       struct nameidata nd;
12262 +       const char *proc_sys = "/proc/sys";
12263 +       char *path;
12264 +       struct acl_object_label *obj;
12265 +       unsigned short len = 0, pos = 0, depth = 0, i;
12266 +       __u32 err = 0;
12267 +       __u32 mode = 0;
12268 +
12269 +       if (unlikely(!(gr_status & GR_READY)))
12270 +               return 1;
12271 +
12272 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
12273 +
12274 +       if (oldval)
12275 +               mode |= GR_READ;
12276 +       if (newval)
12277 +               mode |= GR_WRITE;
12278 +
12279 +       /* convert the requested sysctl entry into a pathname */
12280 +
12281 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
12282 +               len += strlen(tmp->name);
12283 +               len++;
12284 +               depth++;
12285 +       }
12286 +
12287 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
12288 +               return 0;       /* deny */
12289 +
12290 +       memset(path, 0, PAGE_SIZE);
12291 +
12292 +       memcpy(path, proc_sys, strlen(proc_sys));
12293 +
12294 +       pos += strlen(proc_sys);
12295 +
12296 +       for (; depth > 0; depth--) {
12297 +               path[pos] = '/';
12298 +               pos++;
12299 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
12300 +                    tmp = tmp->parent) {
12301 +                       if (depth == i) {
12302 +                               memcpy(path + pos, tmp->name,
12303 +                                      strlen(tmp->name));
12304 +                               pos += strlen(tmp->name);
12305 +                       }
12306 +                       i++;
12307 +               }
12308 +       }
12309 +
12310 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
12311 +
12312 +       if (err)
12313 +               goto out;
12314 +
12315 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
12316 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
12317 +
12318 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
12319 +                    ((err & mode) != mode))) {
12320 +               __u32 new_mode = mode;
12321 +
12322 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12323 +
12324 +               err = new_mode;
12325 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
12326 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
12327 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
12328 +                              path, (mode & GR_READ) ? " reading" : "",
12329 +                              (mode & GR_WRITE) ? " writing" : "");
12330 +               err = 0;
12331 +       } else if ((err & mode) != mode) {
12332 +               err = 0;
12333 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
12334 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
12335 +                              path, (mode & GR_READ) ? " reading" : "",
12336 +                              (mode & GR_WRITE) ? " writing" : "");
12337 +       }
12338 +
12339 +       path_release(&nd);
12340 +
12341 +      out:
12342 +       return err;
12343 +}
12344 +#endif
12345 +
12346 +int
12347 +gr_handle_proc_ptrace(struct task_struct *task)
12348 +{
12349 +       struct file *filp;
12350 +       struct task_struct *tmp = task;
12351 +       struct task_struct *curtemp = current;
12352 +       __u32 retmode;
12353 +
12354 +       if (unlikely(!(gr_status & GR_READY)))
12355 +               return 0;
12356 +
12357 +       read_lock(&tasklist_lock);
12358 +       read_lock(&grsec_exec_file_lock);
12359 +       filp = task->exec_file;
12360 +
12361 +       while (tmp->pid > 0) {
12362 +               if (tmp == curtemp)
12363 +                       break;
12364 +               tmp = tmp->parent;
12365 +       }
12366 +
12367 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
12368 +               read_unlock(&grsec_exec_file_lock);
12369 +               read_unlock(&tasklist_lock);
12370 +               return 1;
12371 +       }
12372 +
12373 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
12374 +       read_unlock(&grsec_exec_file_lock);
12375 +       read_unlock(&tasklist_lock);
12376 +
12377 +       if (retmode & GR_NOPTRACE)
12378 +               return 1;
12379 +
12380 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
12381 +           && (current->acl != task->acl || (current->acl != current->role->root_label
12382 +           && current->pid != task->pid)))
12383 +               return 1;
12384 +
12385 +       return 0;
12386 +}
12387 +
12388 +int
12389 +gr_handle_ptrace(struct task_struct *task, const long request)
12390 +{
12391 +       struct task_struct *tmp = task;
12392 +       struct task_struct *curtemp = current;
12393 +       __u32 retmode;
12394 +
12395 +       if (unlikely(!(gr_status & GR_READY)))
12396 +               return 0;
12397 +
12398 +       read_lock(&tasklist_lock);
12399 +       while (tmp->pid > 0) {
12400 +               if (tmp == curtemp)
12401 +                       break;
12402 +               tmp = tmp->parent;
12403 +       }
12404 +
12405 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
12406 +               read_unlock(&tasklist_lock);
12407 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12408 +               return 1;
12409 +       }
12410 +       read_unlock(&tasklist_lock);
12411 +
12412 +       read_lock(&grsec_exec_file_lock);
12413 +       if (unlikely(!task->exec_file)) {
12414 +               read_unlock(&grsec_exec_file_lock);
12415 +               return 0;
12416 +       }
12417 +
12418 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
12419 +       read_unlock(&grsec_exec_file_lock);
12420 +
12421 +       if (retmode & GR_NOPTRACE) {
12422 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12423 +               return 1;
12424 +       }
12425 +               
12426 +       if (retmode & GR_PTRACERD) {
12427 +               switch (request) {
12428 +               case PTRACE_POKETEXT:
12429 +               case PTRACE_POKEDATA:
12430 +               case PTRACE_POKEUSR:
12431 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
12432 +               case PTRACE_SETREGS:
12433 +               case PTRACE_SETFPREGS:
12434 +#endif
12435 +#ifdef CONFIG_X86
12436 +               case PTRACE_SETFPXREGS:
12437 +#endif
12438 +#ifdef CONFIG_ALTIVEC
12439 +               case PTRACE_SETVRREGS:
12440 +#endif
12441 +                       return 1;
12442 +               default:
12443 +                       return 0;
12444 +               }
12445 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
12446 +                  !(current->role->roletype & GR_ROLE_GOD) &&
12447 +                  (current->acl != task->acl)) {
12448 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12449 +               return 1;
12450 +       }
12451 +
12452 +       return 0;
12453 +}
12454 +
12455 +int is_writable_mmap(const struct file *filp)
12456 +{
12457 +       struct task_struct *task = current;
12458 +       struct acl_object_label *obj, *obj2;
12459 +
12460 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
12461 +           !task->is_writable) {
12462 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
12463 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
12464 +                                    task->role->root_label);
12465 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
12466 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
12467 +                       return 1;
12468 +               }
12469 +       }
12470 +       return 0;
12471 +}
12472 +
12473 +int
12474 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
12475 +{
12476 +       __u32 mode;
12477 +
12478 +       if (unlikely(!file || !(prot & PROT_EXEC)))
12479 +               return 1;
12480 +
12481 +       if (is_writable_mmap(file))
12482 +               return 0;
12483 +
12484 +       mode =
12485 +           gr_search_file(file->f_dentry,
12486 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
12487 +                          file->f_vfsmnt);
12488 +
12489 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
12490 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12491 +               return 0;
12492 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
12493 +               return 0;
12494 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
12495 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12496 +               return 1;
12497 +       }
12498 +
12499 +       return 1;
12500 +}
12501 +
12502 +int
12503 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
12504 +{
12505 +       __u32 mode;
12506 +
12507 +       if (unlikely(!file || !(prot & PROT_EXEC)))
12508 +               return 1;
12509 +
12510 +       if (is_writable_mmap(file))
12511 +               return 0;
12512 +
12513 +       mode =
12514 +           gr_search_file(file->f_dentry,
12515 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
12516 +                          file->f_vfsmnt);
12517 +
12518 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
12519 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12520 +               return 0;
12521 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
12522 +               return 0;
12523 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
12524 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12525 +               return 1;
12526 +       }
12527 +
12528 +       return 1;
12529 +}
12530 +
12531 +void
12532 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12533 +{
12534 +       unsigned long runtime;
12535 +       unsigned long cputime;
12536 +       unsigned int wday, cday;
12537 +       __u8 whr, chr;
12538 +       __u8 wmin, cmin;
12539 +       __u8 wsec, csec;
12540 +
12541 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
12542 +                    !(task->acl->mode & GR_PROCACCT)))
12543 +               return;
12544 +
12545 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
12546 +       wday = runtime / (3600 * 24);
12547 +       runtime -= wday * (3600 * 24);
12548 +       whr = runtime / 3600;
12549 +       runtime -= whr * 3600;
12550 +       wmin = runtime / 60;
12551 +       runtime -= wmin * 60;
12552 +       wsec = runtime;
12553 +
12554 +       cputime = (task->utime + task->stime) / HZ;
12555 +       cday = cputime / (3600 * 24);
12556 +       cputime -= cday * (3600 * 24);
12557 +       chr = cputime / 3600;
12558 +       cputime -= chr * 3600;
12559 +       cmin = cputime / 60;
12560 +       cputime -= cmin * 60;
12561 +       csec = cputime;
12562 +
12563 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
12564 +
12565 +       return;
12566 +}
12567 +
12568 +void gr_set_kernel_label(struct task_struct *task)
12569 +{
12570 +       if (gr_status & GR_READY) {
12571 +               task->role = kernel_role;
12572 +               task->acl = kernel_role->root_label;
12573 +       }
12574 +       return;
12575 +}
12576 +
12577 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
12578 +{
12579 +       struct task_struct *task = current;
12580 +       struct dentry *dentry = file->f_dentry;
12581 +       struct vfsmount *mnt = file->f_vfsmnt;
12582 +       struct acl_object_label *obj, *tmp;
12583 +       struct acl_subject_label *subj;
12584 +       unsigned int cnt;
12585 +       char *path;
12586 +
12587 +       if (unlikely(!(gr_status & GR_READY)))
12588 +               return 1;
12589 +
12590 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12591 +               return 1;
12592 +
12593 +       subj = task->acl;
12594 +       do {
12595 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
12596 +               if (obj != NULL)
12597 +                       return (obj->mode & GR_FIND) ? 1 : 0;
12598 +       } while ((subj = subj->parent_subject));
12599 +       
12600 +       obj = chk_obj_label(dentry, mnt, task->acl);
12601 +       if (obj->globbed == NULL)
12602 +               return (obj->mode & GR_FIND) ? 1 : 0;
12603 +
12604 +       preempt_disable();
12605 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
12606 +                          PAGE_SIZE);
12607 +       cnt = strlen(path);
12608 +       if ((cnt + namelen + 2) <= PAGE_SIZE) {
12609 +               *(path + cnt) = '/';
12610 +                       
12611 +               memcpy(path + cnt + 1, name, namelen);
12612 +               *(path + cnt + namelen + 1) = '\0';
12613 +                                       
12614 +               tmp = obj->globbed;
12615 +               while (tmp) {
12616 +                       if (!glob_match(tmp->filename, path)) {
12617 +                               preempt_enable();
12618 +                               return (tmp->mode & GR_FIND) ? 1 : 0;
12619 +                       }
12620 +                       tmp = tmp->next;
12621 +               }
12622 +               preempt_enable();
12623 +               return (obj->mode & GR_FIND) ? 1 : 0;
12624 +       }
12625 +       preempt_enable();
12626 +                               
12627 +       return 1;
12628 +}
12629 +
12630 +EXPORT_SYMBOL(gr_learn_resource);
12631 +EXPORT_SYMBOL(gr_set_kernel_label);
12632 +#ifdef CONFIG_SECURITY
12633 +EXPORT_SYMBOL(gr_check_user_change);
12634 +EXPORT_SYMBOL(gr_check_group_change);
12635 +#endif
12636 +
12637 diff -urNp linux-2.6.11/grsecurity/gracl_alloc.c linux-2.6.11/grsecurity/gracl_alloc.c
12638 --- linux-2.6.11/grsecurity/gracl_alloc.c       1969-12-31 19:00:00.000000000 -0500
12639 +++ linux-2.6.11/grsecurity/gracl_alloc.c       2005-03-09 11:56:44.000000000 -0500
12640 @@ -0,0 +1,91 @@
12641 +#include <linux/kernel.h>
12642 +#include <linux/mm.h>
12643 +#include <linux/slab.h>
12644 +#include <linux/vmalloc.h>
12645 +#include <linux/gracl.h>
12646 +#include <linux/grsecurity.h>
12647 +
12648 +static unsigned long alloc_stack_next = 1;
12649 +static unsigned long alloc_stack_size = 1;
12650 +static void **alloc_stack;
12651 +
12652 +static __inline__ int
12653 +alloc_pop(void)
12654 +{
12655 +       if (alloc_stack_next == 1)
12656 +               return 0;
12657 +
12658 +       kfree(alloc_stack[alloc_stack_next - 2]);
12659 +
12660 +       alloc_stack_next--;
12661 +
12662 +       return 1;
12663 +}
12664 +
12665 +static __inline__ void
12666 +alloc_push(void *buf)
12667 +{
12668 +       if (alloc_stack_next >= alloc_stack_size)
12669 +               BUG();
12670 +
12671 +       alloc_stack[alloc_stack_next - 1] = buf;
12672 +
12673 +       alloc_stack_next++;
12674 +
12675 +       return;
12676 +}
12677 +
12678 +void *
12679 +acl_alloc(unsigned long len)
12680 +{
12681 +       void *ret;
12682 +
12683 +       if (len > PAGE_SIZE)
12684 +               BUG();
12685 +
12686 +       ret = kmalloc(len, GFP_KERNEL);
12687 +
12688 +       if (ret)
12689 +               alloc_push(ret);
12690 +
12691 +       return ret;
12692 +}
12693 +
12694 +void
12695 +acl_free_all(void)
12696 +{
12697 +       if (gr_acl_is_enabled() || !alloc_stack)
12698 +               return;
12699 +
12700 +       while (alloc_pop()) ;
12701 +
12702 +       if (alloc_stack) {
12703 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
12704 +                       kfree(alloc_stack);
12705 +               else
12706 +                       vfree(alloc_stack);
12707 +       }
12708 +
12709 +       alloc_stack = NULL;
12710 +       alloc_stack_size = 1;
12711 +       alloc_stack_next = 1;
12712 +
12713 +       return;
12714 +}
12715 +
12716 +int
12717 +acl_alloc_stack_init(unsigned long size)
12718 +{
12719 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
12720 +               alloc_stack =
12721 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
12722 +       else
12723 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
12724 +
12725 +       alloc_stack_size = size;
12726 +
12727 +       if (!alloc_stack)
12728 +               return 0;
12729 +       else
12730 +               return 1;
12731 +}
12732 diff -urNp linux-2.6.11/grsecurity/gracl_cap.c linux-2.6.11/grsecurity/gracl_cap.c
12733 --- linux-2.6.11/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
12734 +++ linux-2.6.11/grsecurity/gracl_cap.c 2005-03-09 11:56:44.000000000 -0500
12735 @@ -0,0 +1,110 @@
12736 +#include <linux/kernel.h>
12737 +#include <linux/module.h>
12738 +#include <linux/sched.h>
12739 +#include <linux/capability.h>
12740 +#include <linux/gracl.h>
12741 +#include <linux/grsecurity.h>
12742 +#include <linux/grinternal.h>
12743 +
12744 +static const char *captab_log[29] = {
12745 +       "CAP_CHOWN",
12746 +       "CAP_DAC_OVERRIDE",
12747 +       "CAP_DAC_READ_SEARCH",
12748 +       "CAP_FOWNER",
12749 +       "CAP_FSETID",
12750 +       "CAP_KILL",
12751 +       "CAP_SETGID",
12752 +       "CAP_SETUID",
12753 +       "CAP_SETPCAP",
12754 +       "CAP_LINUX_IMMUTABLE",
12755 +       "CAP_NET_BIND_SERVICE",
12756 +       "CAP_NET_BROADCAST",
12757 +       "CAP_NET_ADMIN",
12758 +       "CAP_NET_RAW",
12759 +       "CAP_IPC_LOCK",
12760 +       "CAP_IPC_OWNER",
12761 +       "CAP_SYS_MODULE",
12762 +       "CAP_SYS_RAWIO",
12763 +       "CAP_SYS_CHROOT",
12764 +       "CAP_SYS_PTRACE",
12765 +       "CAP_SYS_PACCT",
12766 +       "CAP_SYS_ADMIN",
12767 +       "CAP_SYS_BOOT",
12768 +       "CAP_SYS_NICE",
12769 +       "CAP_SYS_RESOURCE",
12770 +       "CAP_SYS_TIME",
12771 +       "CAP_SYS_TTY_CONFIG",
12772 +       "CAP_MKNOD",
12773 +       "CAP_LEASE"
12774 +};
12775 +
12776 +EXPORT_SYMBOL(gr_task_is_capable);
12777 +
12778 +int
12779 +gr_task_is_capable(struct task_struct *task, const int cap)
12780 +{
12781 +       struct acl_subject_label *curracl;
12782 +       __u32 cap_drop = 0, cap_mask = 0;
12783 +
12784 +       if (!gr_acl_is_enabled())
12785 +               return 1;
12786 +
12787 +       curracl = task->acl;
12788 +
12789 +       cap_drop = curracl->cap_lower;
12790 +       cap_mask = curracl->cap_mask;
12791 +
12792 +       while ((curracl = curracl->parent_subject)) {
12793 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
12794 +                       cap_drop |= curracl->cap_lower & (1 << cap);
12795 +               cap_mask |= curracl->cap_mask;
12796 +       }
12797 +
12798 +       if (!cap_raised(cap_drop, cap))
12799 +               return 1;
12800 +
12801 +       curracl = task->acl;
12802 +
12803 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
12804 +           && cap_raised(task->cap_effective, cap)) {
12805 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
12806 +                              task->role->roletype, task->uid,
12807 +                              task->gid, task->exec_file ?
12808 +                              gr_to_filename(task->exec_file->f_dentry,
12809 +                              task->exec_file->f_vfsmnt) : curracl->filename,
12810 +                              curracl->filename, 0UL,
12811 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->curr_ip));
12812 +               return 1;
12813 +       }
12814 +
12815 +       if ((cap >= 0) && (cap < 29) && cap_raised(task->cap_effective, cap))
12816 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
12817 +
12818 +       return 0;
12819 +}
12820 +
12821 +int
12822 +gr_is_capable_nolog(const int cap)
12823 +{
12824 +       struct acl_subject_label *curracl;
12825 +       __u32 cap_drop = 0, cap_mask = 0;
12826 +
12827 +       if (!gr_acl_is_enabled())
12828 +               return 1;
12829 +
12830 +       curracl = current->acl;
12831 +
12832 +       cap_drop = curracl->cap_lower;
12833 +       cap_mask = curracl->cap_mask;
12834 +
12835 +       while ((curracl = curracl->parent_subject)) {
12836 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
12837 +               cap_mask |= curracl->cap_mask;
12838 +       }
12839 +
12840 +       if (!cap_raised(cap_drop, cap))
12841 +               return 1;
12842 +
12843 +       return 0;
12844 +}
12845 +
12846 diff -urNp linux-2.6.11/grsecurity/gracl_fs.c linux-2.6.11/grsecurity/gracl_fs.c
12847 --- linux-2.6.11/grsecurity/gracl_fs.c  1969-12-31 19:00:00.000000000 -0500
12848 +++ linux-2.6.11/grsecurity/gracl_fs.c  2005-03-09 11:56:44.000000000 -0500
12849 @@ -0,0 +1,423 @@
12850 +#include <linux/kernel.h>
12851 +#include <linux/sched.h>
12852 +#include <linux/types.h>
12853 +#include <linux/fs.h>
12854 +#include <linux/file.h>
12855 +#include <linux/stat.h>
12856 +#include <linux/grsecurity.h>
12857 +#include <linux/grinternal.h>
12858 +#include <linux/gracl.h>
12859 +
12860 +__u32
12861 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12862 +                         const struct vfsmount * mnt)
12863 +{
12864 +       __u32 mode;
12865 +
12866 +       if (unlikely(!dentry->d_inode))
12867 +               return GR_FIND;
12868 +
12869 +       mode =
12870 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
12871 +
12872 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
12873 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
12874 +               return mode;
12875 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
12876 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
12877 +               return 0;
12878 +       } else if (unlikely(!(mode & GR_FIND)))
12879 +               return 0;
12880 +
12881 +       return GR_FIND;
12882 +}
12883 +
12884 +__u32
12885 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12886 +                  const int fmode)
12887 +{
12888 +       __u32 reqmode = GR_FIND;
12889 +       __u32 mode;
12890 +
12891 +       if (unlikely(!dentry->d_inode))
12892 +               return reqmode;
12893 +
12894 +       if (unlikely(fmode & O_APPEND))
12895 +               reqmode |= GR_APPEND;
12896 +       else if (unlikely(fmode & FMODE_WRITE))
12897 +               reqmode |= GR_WRITE;
12898 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
12899 +               reqmode |= GR_READ;
12900 +
12901 +       mode =
12902 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
12903 +                          mnt);
12904 +
12905 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12906 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
12907 +                              reqmode & GR_READ ? " reading" : "",
12908 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12909 +                              GR_APPEND ? " appending" : "");
12910 +               return reqmode;
12911 +       } else
12912 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12913 +       {
12914 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
12915 +                              reqmode & GR_READ ? " reading" : "",
12916 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12917 +                              GR_APPEND ? " appending" : "");
12918 +               return 0;
12919 +       } else if (unlikely((mode & reqmode) != reqmode))
12920 +               return 0;
12921 +
12922 +       return reqmode;
12923 +}
12924 +
12925 +__u32
12926 +gr_acl_handle_creat(const struct dentry * dentry,
12927 +                   const struct dentry * p_dentry,
12928 +                   const struct vfsmount * p_mnt, const int fmode,
12929 +                   const int imode)
12930 +{
12931 +       __u32 reqmode = GR_WRITE | GR_CREATE;
12932 +       __u32 mode;
12933 +
12934 +       if (unlikely(fmode & O_APPEND))
12935 +               reqmode |= GR_APPEND;
12936 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
12937 +               reqmode |= GR_READ;
12938 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
12939 +               reqmode |= GR_SETID;
12940 +
12941 +       mode =
12942 +           gr_check_create(dentry, p_dentry, p_mnt,
12943 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
12944 +
12945 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12946 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
12947 +                              reqmode & GR_READ ? " reading" : "",
12948 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12949 +                              GR_APPEND ? " appending" : "");
12950 +               return reqmode;
12951 +       } else
12952 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12953 +       {
12954 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
12955 +                              reqmode & GR_READ ? " reading" : "",
12956 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12957 +                              GR_APPEND ? " appending" : "");
12958 +               return 0;
12959 +       } else if (unlikely((mode & reqmode) != reqmode))
12960 +               return 0;
12961 +
12962 +       return reqmode;
12963 +}
12964 +
12965 +__u32
12966 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
12967 +                    const int fmode)
12968 +{
12969 +       __u32 mode, reqmode = GR_FIND;
12970 +
12971 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
12972 +               reqmode |= GR_EXEC;
12973 +       if (fmode & S_IWOTH)
12974 +               reqmode |= GR_WRITE;
12975 +       if (fmode & S_IROTH)
12976 +               reqmode |= GR_READ;
12977 +
12978 +       mode =
12979 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
12980 +                          mnt);
12981 +
12982 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12983 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
12984 +                              reqmode & GR_READ ? " reading" : "",
12985 +                              reqmode & GR_WRITE ? " writing" : "",
12986 +                              reqmode & GR_EXEC ? " executing" : "");
12987 +               return reqmode;
12988 +       } else
12989 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12990 +       {
12991 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
12992 +                              reqmode & GR_READ ? " reading" : "",
12993 +                              reqmode & GR_WRITE ? " writing" : "",
12994 +                              reqmode & GR_EXEC ? " executing" : "");
12995 +               return 0;
12996 +       } else if (unlikely((mode & reqmode) != reqmode))
12997 +               return 0;
12998 +
12999 +       return reqmode;
13000 +}
13001 +
13002 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
13003 +{
13004 +       __u32 mode;
13005 +
13006 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
13007 +
13008 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
13009 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
13010 +               return mode;
13011 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
13012 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
13013 +               return 0;
13014 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
13015 +               return 0;
13016 +
13017 +       return (reqmode);
13018 +}
13019 +
13020 +__u32
13021 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
13022 +{
13023 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
13024 +}
13025 +
13026 +__u32
13027 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
13028 +{
13029 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
13030 +}
13031 +
13032 +__u32
13033 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
13034 +{
13035 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
13036 +}
13037 +
13038 +__u32
13039 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
13040 +{
13041 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
13042 +}
13043 +
13044 +__u32
13045 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
13046 +                    mode_t mode)
13047 +{
13048 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
13049 +               return 1;
13050 +
13051 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
13052 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
13053 +                                  GR_FCHMOD_ACL_MSG);
13054 +       } else {
13055 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
13056 +       }
13057 +}
13058 +
13059 +__u32
13060 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
13061 +                   mode_t mode)
13062 +{
13063 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
13064 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
13065 +                                  GR_CHMOD_ACL_MSG);
13066 +       } else {
13067 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
13068 +       }
13069 +}
13070 +
13071 +__u32
13072 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
13073 +{
13074 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
13075 +}
13076 +
13077 +__u32
13078 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
13079 +{
13080 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
13081 +}
13082 +
13083 +__u32
13084 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
13085 +{
13086 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
13087 +                          GR_UNIXCONNECT_ACL_MSG);
13088 +}
13089 +
13090 +/* hardlinks require at minimum create permission,
13091 +   any additional privilege required is based on the
13092 +   privilege of the file being linked to
13093 +*/
13094 +__u32
13095 +gr_acl_handle_link(const struct dentry * new_dentry,
13096 +                  const struct dentry * parent_dentry,
13097 +                  const struct vfsmount * parent_mnt,
13098 +                  const struct dentry * old_dentry,
13099 +                  const struct vfsmount * old_mnt, const char *to)
13100 +{
13101 +       __u32 mode;
13102 +       __u32 needmode = GR_CREATE | GR_LINK;
13103 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
13104 +
13105 +       mode =
13106 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
13107 +                         old_mnt);
13108 +
13109 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
13110 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
13111 +               return mode;
13112 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
13113 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
13114 +               return 0;
13115 +       } else if (unlikely((mode & needmode) != needmode))
13116 +               return 0;
13117 +
13118 +       return 1;
13119 +}
13120 +
13121 +__u32
13122 +gr_acl_handle_symlink(const struct dentry * new_dentry,
13123 +                     const struct dentry * parent_dentry,
13124 +                     const struct vfsmount * parent_mnt, const char *from)
13125 +{
13126 +       __u32 needmode = GR_WRITE | GR_CREATE;
13127 +       __u32 mode;
13128 +
13129 +       mode =
13130 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
13131 +                           GR_CREATE | GR_AUDIT_CREATE |
13132 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
13133 +
13134 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
13135 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
13136 +               return mode;
13137 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
13138 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
13139 +               return 0;
13140 +       } else if (unlikely((mode & needmode) != needmode))
13141 +               return 0;
13142 +
13143 +       return (GR_WRITE | GR_CREATE);
13144 +}
13145 +
13146 +static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt)
13147 +{
13148 +       __u32 mode;
13149 +
13150 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
13151 +
13152 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
13153 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
13154 +               return mode;
13155 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
13156 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
13157 +               return 0;
13158 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
13159 +               return 0;
13160 +
13161 +       return (reqmode);
13162 +}
13163 +
13164 +__u32
13165 +gr_acl_handle_mknod(const struct dentry * new_dentry,
13166 +                   const struct dentry * parent_dentry,
13167 +                   const struct vfsmount * parent_mnt,
13168 +                   const int mode)
13169 +{
13170 +       __u32 reqmode = GR_WRITE | GR_CREATE;
13171 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
13172 +               reqmode |= GR_SETID;
13173 +
13174 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
13175 +                                 reqmode, GR_MKNOD_ACL_MSG);
13176 +}
13177 +
13178 +__u32
13179 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
13180 +                   const struct dentry *parent_dentry,
13181 +                   const struct vfsmount *parent_mnt)
13182 +{
13183 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
13184 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
13185 +}
13186 +
13187 +#define RENAME_CHECK_SUCCESS(old, new) \
13188 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
13189 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
13190 +
13191 +int
13192 +gr_acl_handle_rename(struct dentry *new_dentry,
13193 +                    struct dentry *parent_dentry,
13194 +                    const struct vfsmount *parent_mnt,
13195 +                    struct dentry *old_dentry,
13196 +                    struct inode *old_parent_inode,
13197 +                    struct vfsmount *old_mnt, const char *newname)
13198 +{
13199 +       __u32 comp1, comp2;
13200 +       int error = 0;
13201 +
13202 +       if (unlikely(!gr_acl_is_enabled()))
13203 +               return 0;
13204 +
13205 +       if (!new_dentry->d_inode) {
13206 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
13207 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
13208 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
13209 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
13210 +                                      GR_DELETE | GR_AUDIT_DELETE |
13211 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
13212 +                                      GR_SUPPRESS, old_mnt);
13213 +       } else {
13214 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
13215 +                                      GR_CREATE | GR_DELETE |
13216 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
13217 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
13218 +                                      GR_SUPPRESS, parent_mnt);
13219 +               comp2 =
13220 +                   gr_search_file(old_dentry,
13221 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
13222 +                                  GR_DELETE | GR_AUDIT_DELETE |
13223 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
13224 +       }
13225 +
13226 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
13227 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
13228 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
13229 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
13230 +                && !(comp2 & GR_SUPPRESS)) {
13231 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
13232 +               error = -EACCES;
13233 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
13234 +               error = -EACCES;
13235 +
13236 +       return error;
13237 +}
13238 +
13239 +void
13240 +gr_acl_handle_exit(void)
13241 +{
13242 +       u16 id;
13243 +       char *rolename;
13244 +       struct file *exec_file;
13245 +
13246 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
13247 +               id = current->acl_role_id;
13248 +               rolename = current->role->rolename;
13249 +               gr_set_acls(1);
13250 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
13251 +       }
13252 +
13253 +       write_lock(&grsec_exec_file_lock);
13254 +       exec_file = current->exec_file;
13255 +       current->exec_file = NULL;
13256 +       write_unlock(&grsec_exec_file_lock);
13257 +
13258 +       if (exec_file)
13259 +               fput(exec_file);
13260 +}
13261 +
13262 +int
13263 +gr_acl_handle_procpidmem(const struct task_struct *task)
13264 +{
13265 +       if (unlikely(!gr_acl_is_enabled()))
13266 +               return 0;
13267 +
13268 +       if (task->acl->mode & GR_PROTPROCFD)
13269 +               return -EACCES;
13270 +
13271 +       return 0;
13272 +}
13273 diff -urNp linux-2.6.11/grsecurity/gracl_ip.c linux-2.6.11/grsecurity/gracl_ip.c
13274 --- linux-2.6.11/grsecurity/gracl_ip.c  1969-12-31 19:00:00.000000000 -0500
13275 +++ linux-2.6.11/grsecurity/gracl_ip.c  2005-03-09 11:56:44.000000000 -0500
13276 @@ -0,0 +1,248 @@
13277 +#include <linux/kernel.h>
13278 +#include <asm/uaccess.h>
13279 +#include <asm/errno.h>
13280 +#include <net/sock.h>
13281 +#include <linux/file.h>
13282 +#include <linux/fs.h>
13283 +#include <linux/net.h>
13284 +#include <linux/in.h>
13285 +#include <linux/skbuff.h>
13286 +#include <linux/ip.h>
13287 +#include <linux/udp.h>
13288 +#include <linux/smp_lock.h>
13289 +#include <linux/types.h>
13290 +#include <linux/sched.h>
13291 +#include <linux/gracl.h>
13292 +#include <linux/grsecurity.h>
13293 +#include <linux/grinternal.h>
13294 +
13295 +#define GR_BIND        0x01
13296 +#define GR_CONNECT     0x02
13297 +
13298 +static const char * gr_protocols[256] = {
13299 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
13300 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
13301 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
13302 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
13303 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
13304 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
13305 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
13306 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
13307 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
13308 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
13309 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
13310 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
13311 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
13312 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
13313 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
13314 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
13315 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
13316 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
13317 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
13318 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
13319 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
13320 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
13321 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
13322 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
13323 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
13324 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
13325 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
13326 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
13327 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
13328 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
13329 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
13330 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
13331 +       };
13332 +
13333 +static const char * gr_socktypes[11] = {
13334 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
13335 +       "unknown:7", "unknown:8", "unknown:9", "packet"
13336 +       };
13337 +
13338 +const char *
13339 +gr_proto_to_name(unsigned char proto)
13340 +{
13341 +       return gr_protocols[proto];
13342 +}
13343 +
13344 +const char *
13345 +gr_socktype_to_name(unsigned char type)
13346 +{
13347 +       return gr_socktypes[type];
13348 +}
13349 +
13350 +int
13351 +gr_search_socket(const int domain, const int type, const int protocol)
13352 +{
13353 +       struct acl_subject_label *curr;
13354 +
13355 +       if (unlikely(!gr_acl_is_enabled()))
13356 +               goto exit;
13357 +
13358 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
13359 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
13360 +               goto exit;      // let the kernel handle it
13361 +
13362 +       curr = current->acl;
13363 +
13364 +       if (!curr->ips)
13365 +               goto exit;
13366 +
13367 +       if ((curr->ip_type & (1 << type)) &&
13368 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
13369 +               goto exit;
13370 +
13371 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
13372 +               /* we don't place acls on raw sockets , and sometimes
13373 +                  dgram/ip sockets are opened for ioctl and not
13374 +                  bind/connect, so we'll fake a bind learn log */
13375 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
13376 +                       __u32 fakeip = 0;
13377 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13378 +                                      current->role->roletype, current->uid,
13379 +                                      current->gid, current->exec_file ?
13380 +                                      gr_to_filename(current->exec_file->f_dentry,
13381 +                                      current->exec_file->f_vfsmnt) :
13382 +                                      curr->filename, curr->filename,
13383 +                                      NIPQUAD(fakeip), 0, type,
13384 +                                      protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
13385 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
13386 +                       __u32 fakeip = 0;
13387 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13388 +                                      current->role->roletype, current->uid,
13389 +                                      current->gid, current->exec_file ?
13390 +                                      gr_to_filename(current->exec_file->f_dentry,
13391 +                                      current->exec_file->f_vfsmnt) :
13392 +                                      curr->filename, curr->filename,
13393 +                                      NIPQUAD(fakeip), 0, type,
13394 +                                      protocol, GR_BIND, NIPQUAD(current->curr_ip));
13395 +               }
13396 +               /* we'll log when they use connect or bind */
13397 +               goto exit;
13398 +       }
13399 +
13400 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
13401 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
13402 +
13403 +       return 0;
13404 +      exit:
13405 +       return 1;
13406 +}
13407 +
13408 +static __inline__ int
13409 +gr_search_connectbind(const int mode, const struct sock *sk,
13410 +                     const struct sockaddr_in *addr, const int type)
13411 +{
13412 +       struct acl_subject_label *curr;
13413 +       struct acl_ip_label *ip;
13414 +       unsigned long i;
13415 +       __u32 ip_addr = 0;
13416 +       __u16 ip_port = 0;
13417 +
13418 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
13419 +               return 1;
13420 +
13421 +       curr = current->acl;
13422 +
13423 +       if (!curr->ips)
13424 +               return 1;
13425 +
13426 +       ip_addr = addr->sin_addr.s_addr;
13427 +       ip_port = ntohs(addr->sin_port);
13428 +
13429 +       for (i = 0; i < curr->ip_num; i++) {
13430 +               ip = *(curr->ips + i);
13431 +               if ((ip->mode & mode) &&
13432 +                   (ip_port >= ip->low) &&
13433 +                   (ip_port <= ip->high) &&
13434 +                   ((ntohl(ip_addr) & ip->netmask) ==
13435 +                    (ntohl(ip->addr) & ip->netmask))
13436 +                   && (ip->
13437 +                       proto[sk->sk_protocol / 32] & (1 << (sk->sk_protocol % 32)))
13438 +                   && (ip->type & (1 << type)))
13439 +                       return 1;
13440 +       }
13441 +
13442 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
13443 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13444 +                              current->role->roletype, current->uid,
13445 +                              current->gid, current->exec_file ?
13446 +                              gr_to_filename(current->exec_file->f_dentry,
13447 +                              current->exec_file->f_vfsmnt) :
13448 +                              curr->filename, curr->filename,
13449 +                              NIPQUAD(ip_addr), ip_port, type,
13450 +                              sk->sk_protocol, mode, NIPQUAD(current->curr_ip));
13451 +               return 1;
13452 +       }
13453 +
13454 +       if (mode == GR_BIND)
13455 +               gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
13456 +       else if (mode == GR_CONNECT)
13457 +               gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
13458 +
13459 +       return 0;
13460 +}
13461 +
13462 +int
13463 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
13464 +{
13465 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
13466 +}
13467 +
13468 +int
13469 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
13470 +{
13471 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
13472 +}
13473 +
13474 +int gr_search_listen(const struct socket *sock)
13475 +{
13476 +       struct sock *sk = sock->sk;
13477 +       struct sockaddr_in addr;
13478 +
13479 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
13480 +       addr.sin_port = inet_sk(sk)->sport;
13481 +
13482 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
13483 +}
13484 +
13485 +int gr_search_accept(const struct socket *sock)
13486 +{
13487 +       struct sock *sk = sock->sk;
13488 +       struct sockaddr_in addr;
13489 +
13490 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
13491 +       addr.sin_port = inet_sk(sk)->sport;
13492 +
13493 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
13494 +}
13495 +
13496 +int
13497 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
13498 +{
13499 +       if (addr)
13500 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
13501 +       else {
13502 +               struct sockaddr_in sin;
13503 +               const struct inet_sock *inet = inet_sk(sk);
13504 +
13505 +               sin.sin_addr.s_addr = inet->daddr;
13506 +               sin.sin_port = inet->dport;
13507 +
13508 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
13509 +       }
13510 +}
13511 +
13512 +int
13513 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
13514 +{
13515 +       struct sockaddr_in sin;
13516 +
13517 +       if (unlikely(skb->len < sizeof (struct udphdr)))
13518 +               return 1;       // skip this packet
13519 +
13520 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
13521 +       sin.sin_port = skb->h.uh->source;
13522 +
13523 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
13524 +}
13525 diff -urNp linux-2.6.11/grsecurity/gracl_learn.c linux-2.6.11/grsecurity/gracl_learn.c
13526 --- linux-2.6.11/grsecurity/gracl_learn.c       1969-12-31 19:00:00.000000000 -0500
13527 +++ linux-2.6.11/grsecurity/gracl_learn.c       2005-03-09 11:56:44.000000000 -0500
13528 @@ -0,0 +1,204 @@
13529 +#include <linux/kernel.h>
13530 +#include <linux/mm.h>
13531 +#include <linux/sched.h>
13532 +#include <linux/poll.h>
13533 +#include <linux/smp_lock.h>
13534 +#include <linux/string.h>
13535 +#include <linux/file.h>
13536 +#include <linux/types.h>
13537 +#include <linux/vmalloc.h>
13538 +#include <linux/grinternal.h>
13539 +
13540 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
13541 +                                  size_t count, loff_t *ppos);
13542 +extern int gr_acl_is_enabled(void);
13543 +
13544 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
13545 +static int gr_learn_attached;
13546 +
13547 +/* use a 512k buffer */
13548 +#define LEARN_BUFFER_SIZE (512 * 1024)
13549 +
13550 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
13551 +static DECLARE_MUTEX(gr_learn_user_sem);
13552 +
13553 +/* we need to maintain two buffers, so that the kernel context of grlearn
13554 +   uses a semaphore around the userspace copying, and the other kernel contexts
13555 +   use a spinlock when copying into the buffer, since they cannot sleep
13556 +*/
13557 +static char *learn_buffer;
13558 +static char *learn_buffer_user;
13559 +static int learn_buffer_len;
13560 +static int learn_buffer_user_len;
13561 +
13562 +static ssize_t
13563 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
13564 +{
13565 +       DECLARE_WAITQUEUE(wait, current);
13566 +       ssize_t retval = 0;
13567 +
13568 +       add_wait_queue(&learn_wait, &wait);
13569 +       set_current_state(TASK_INTERRUPTIBLE);
13570 +       do {
13571 +               down(&gr_learn_user_sem);
13572 +               spin_lock(&gr_learn_lock);
13573 +               if (learn_buffer_len)
13574 +                       break;
13575 +               spin_unlock(&gr_learn_lock);
13576 +               up(&gr_learn_user_sem);
13577 +               if (file->f_flags & O_NONBLOCK) {
13578 +                       retval = -EAGAIN;
13579 +                       goto out;
13580 +               }
13581 +               if (signal_pending(current)) {
13582 +                       retval = -ERESTARTSYS;
13583 +                       goto out;
13584 +               }
13585 +
13586 +               schedule();
13587 +       } while (1);
13588 +
13589 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
13590 +       learn_buffer_user_len = learn_buffer_len;
13591 +       retval = learn_buffer_len;
13592 +       learn_buffer_len = 0;
13593 +
13594 +       spin_unlock(&gr_learn_lock);
13595 +
13596 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
13597 +               retval = -EFAULT;
13598 +
13599 +       up(&gr_learn_user_sem);
13600 +out:
13601 +       set_current_state(TASK_RUNNING);
13602 +       remove_wait_queue(&learn_wait, &wait);
13603 +       return retval;
13604 +}
13605 +
13606 +static unsigned int
13607 +poll_learn(struct file * file, poll_table * wait)
13608 +{
13609 +       poll_wait(file, &learn_wait, wait);
13610 +
13611 +       if (learn_buffer_len)
13612 +               return (POLLIN | POLLRDNORM);
13613 +
13614 +       return 0;
13615 +}
13616 +
13617 +void
13618 +gr_clear_learn_entries(void)
13619 +{
13620 +       char *tmp;
13621 +
13622 +       down(&gr_learn_user_sem);
13623 +       if (learn_buffer != NULL) {
13624 +               spin_lock(&gr_learn_lock);
13625 +               tmp = learn_buffer;
13626 +               learn_buffer = NULL;
13627 +               spin_unlock(&gr_learn_lock);
13628 +               vfree(learn_buffer);
13629 +       }
13630 +       if (learn_buffer_user != NULL) {
13631 +               vfree(learn_buffer_user);
13632 +               learn_buffer_user = NULL;
13633 +       }
13634 +       learn_buffer_len = 0;
13635 +       up(&gr_learn_user_sem);
13636 +
13637 +       return;
13638 +}
13639 +
13640 +void
13641 +gr_add_learn_entry(const char *fmt, ...)
13642 +{
13643 +       va_list args;
13644 +       unsigned int len;
13645 +
13646 +       if (!gr_learn_attached)
13647 +               return;
13648 +
13649 +       spin_lock(&gr_learn_lock);
13650 +
13651 +       /* leave a gap at the end so we know when it's "full" but don't have to
13652 +          compute the exact length of the string we're trying to append
13653 +       */
13654 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
13655 +               spin_unlock(&gr_learn_lock);
13656 +               wake_up_interruptible(&learn_wait);
13657 +               return;
13658 +       }
13659 +       if (learn_buffer == NULL) {
13660 +               spin_unlock(&gr_learn_lock);
13661 +               return;
13662 +       }
13663 +
13664 +       va_start(args, fmt);
13665 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
13666 +       va_end(args);
13667 +
13668 +       learn_buffer_len += len + 1;
13669 +
13670 +       spin_unlock(&gr_learn_lock);
13671 +       wake_up_interruptible(&learn_wait);
13672 +
13673 +       return;
13674 +}
13675 +
13676 +static int
13677 +open_learn(struct inode *inode, struct file *file)
13678 +{
13679 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
13680 +               return -EBUSY;
13681 +       if (file->f_mode & FMODE_READ) {
13682 +               down(&gr_learn_user_sem);
13683 +               if (learn_buffer == NULL)
13684 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
13685 +               if (learn_buffer_user == NULL)
13686 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
13687 +               if (learn_buffer == NULL)
13688 +                       return -ENOMEM;
13689 +               if (learn_buffer_user == NULL)
13690 +                       return -ENOMEM;
13691 +               learn_buffer_len = 0;
13692 +               learn_buffer_user_len = 0;
13693 +               gr_learn_attached = 1;
13694 +               up(&gr_learn_user_sem);
13695 +       }
13696 +       return 0;
13697 +}
13698 +
13699 +static int
13700 +close_learn(struct inode *inode, struct file *file)
13701 +{
13702 +       char *tmp;
13703 +
13704 +       if (file->f_mode & FMODE_READ) {
13705 +               down(&gr_learn_user_sem);
13706 +               if (learn_buffer != NULL) {
13707 +                       spin_lock(&gr_learn_lock);
13708 +                       tmp = learn_buffer;
13709 +                       learn_buffer = NULL;
13710 +                       spin_unlock(&gr_learn_lock);
13711 +                       vfree(tmp);
13712 +               }
13713 +               if (learn_buffer_user != NULL) {
13714 +                       vfree(learn_buffer_user);
13715 +                       learn_buffer_user = NULL;
13716 +               }
13717 +               learn_buffer_len = 0;
13718 +               learn_buffer_user_len = 0;
13719 +               gr_learn_attached = 0;
13720 +               up(&gr_learn_user_sem);
13721 +       }
13722 +
13723 +       return 0;
13724 +}
13725 +               
13726 +struct file_operations grsec_fops = {
13727 +       .read           = read_learn,
13728 +       .write          = write_grsec_handler,
13729 +       .open           = open_learn,
13730 +       .release        = close_learn,
13731 +       .poll           = poll_learn,
13732 +};
13733 diff -urNp linux-2.6.11/grsecurity/gracl_res.c linux-2.6.11/grsecurity/gracl_res.c
13734 --- linux-2.6.11/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
13735 +++ linux-2.6.11/grsecurity/gracl_res.c 2005-03-09 11:56:44.000000000 -0500
13736 @@ -0,0 +1,42 @@
13737 +#include <linux/kernel.h>
13738 +#include <linux/sched.h>
13739 +#include <linux/gracl.h>
13740 +#include <linux/grinternal.h>
13741 +
13742 +static const char *restab_log[11] = {
13743 +       "RLIMIT_CPU",
13744 +       "RLIMIT_FSIZE",
13745 +       "RLIMIT_DATA",
13746 +       "RLIMIT_STACK",
13747 +       "RLIMIT_CORE",
13748 +       "RLIMIT_RSS",
13749 +       "RLIMIT_NPROC",
13750 +       "RLIMIT_NOFILE",
13751 +       "RLIMIT_MEMLOCK",
13752 +       "RLIMIT_AS",
13753 +       "RLIMIT_LOCKS"
13754 +};
13755 +
13756 +void
13757 +gr_log_resource(const struct task_struct *task,
13758 +               const int res, const unsigned long wanted, const int gt)
13759 +{
13760 +       if (res == RLIMIT_NPROC && 
13761 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
13762 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
13763 +               return;
13764 +       else if (res == RLIMIT_MEMLOCK &&
13765 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
13766 +               return;
13767 +
13768 +       preempt_disable();
13769 +
13770 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
13771 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
13772 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
13773 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
13774 +
13775 +       preempt_enable_no_resched();
13776 +
13777 +       return;
13778 +}
13779 diff -urNp linux-2.6.11/grsecurity/gracl_segv.c linux-2.6.11/grsecurity/gracl_segv.c
13780 --- linux-2.6.11/grsecurity/gracl_segv.c        1969-12-31 19:00:00.000000000 -0500
13781 +++ linux-2.6.11/grsecurity/gracl_segv.c        2005-03-09 11:56:44.000000000 -0500
13782 @@ -0,0 +1,297 @@
13783 +#include <linux/kernel.h>
13784 +#include <linux/mm.h>
13785 +#include <asm/uaccess.h>
13786 +#include <asm/errno.h>
13787 +#include <asm/mman.h>
13788 +#include <net/sock.h>
13789 +#include <linux/file.h>
13790 +#include <linux/fs.h>
13791 +#include <linux/net.h>
13792 +#include <linux/in.h>
13793 +#include <linux/smp_lock.h>
13794 +#include <linux/slab.h>
13795 +#include <linux/types.h>
13796 +#include <linux/sched.h>
13797 +#include <linux/timer.h>
13798 +#include <linux/gracl.h>
13799 +#include <linux/grsecurity.h>
13800 +#include <linux/grinternal.h>
13801 +
13802 +static struct crash_uid *uid_set;
13803 +static unsigned short uid_used;
13804 +static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
13805 +extern rwlock_t gr_inode_lock;
13806 +extern struct acl_subject_label *
13807 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
13808 +                             struct acl_role_label *role);
13809 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
13810 +
13811 +int
13812 +gr_init_uidset(void)
13813 +{
13814 +       uid_set =
13815 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
13816 +       uid_used = 0;
13817 +
13818 +       return uid_set ? 1 : 0;
13819 +}
13820 +
13821 +void
13822 +gr_free_uidset(void)
13823 +{
13824 +       if (uid_set)
13825 +               kfree(uid_set);
13826 +
13827 +       return;
13828 +}
13829 +
13830 +int
13831 +gr_find_uid(const uid_t uid)
13832 +{
13833 +       struct crash_uid *tmp = uid_set;
13834 +       uid_t buid;
13835 +       int low = 0, high = uid_used - 1, mid;
13836 +
13837 +       while (high >= low) {
13838 +               mid = (low + high) >> 1;
13839 +               buid = tmp[mid].uid;
13840 +               if (buid == uid)
13841 +                       return mid;
13842 +               if (buid > uid)
13843 +                       high = mid - 1;
13844 +               if (buid < uid)
13845 +                       low = mid + 1;
13846 +       }
13847 +
13848 +       return -1;
13849 +}
13850 +
13851 +static __inline__ void
13852 +gr_insertsort(void)
13853 +{
13854 +       unsigned short i, j;
13855 +       struct crash_uid index;
13856 +
13857 +       for (i = 1; i < uid_used; i++) {
13858 +               index = uid_set[i];
13859 +               j = i;
13860 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
13861 +                       uid_set[j] = uid_set[j - 1];
13862 +                       j--;
13863 +               }
13864 +               uid_set[j] = index;
13865 +       }
13866 +
13867 +       return;
13868 +}
13869 +
13870 +static __inline__ void
13871 +gr_insert_uid(const uid_t uid, const unsigned long expires)
13872 +{
13873 +       int loc;
13874 +
13875 +       if (uid_used == GR_UIDTABLE_MAX)
13876 +               return;
13877 +
13878 +       loc = gr_find_uid(uid);
13879 +
13880 +       if (loc >= 0) {
13881 +               uid_set[loc].expires = expires;
13882 +               return;
13883 +       }
13884 +
13885 +       uid_set[uid_used].uid = uid;
13886 +       uid_set[uid_used].expires = expires;
13887 +       uid_used++;
13888 +
13889 +       gr_insertsort();
13890 +
13891 +       return;
13892 +}
13893 +
13894 +void
13895 +gr_remove_uid(const unsigned short loc)
13896 +{
13897 +       unsigned short i;
13898 +
13899 +       for (i = loc + 1; i < uid_used; i++)
13900 +               uid_set[i - i] = uid_set[i];
13901 +
13902 +       uid_used--;
13903 +
13904 +       return;
13905 +}
13906 +
13907 +int
13908 +gr_check_crash_uid(const uid_t uid)
13909 +{
13910 +       int loc;
13911 +
13912 +       if (unlikely(!gr_acl_is_enabled()))
13913 +               return 0;
13914 +
13915 +       read_lock(&gr_uid_lock);
13916 +       loc = gr_find_uid(uid);
13917 +       read_unlock(&gr_uid_lock);
13918 +
13919 +       if (loc < 0)
13920 +               return 0;
13921 +
13922 +       write_lock(&gr_uid_lock);
13923 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
13924 +               gr_remove_uid(loc);
13925 +       else {
13926 +               write_unlock(&gr_uid_lock);
13927 +               return 1;
13928 +       }
13929 +
13930 +       write_unlock(&gr_uid_lock);
13931 +       return 0;
13932 +}
13933 +
13934 +static __inline__ int
13935 +proc_is_setxid(const struct task_struct *task)
13936 +{
13937 +       if (task->uid != task->euid || task->uid != task->suid ||
13938 +           task->uid != task->fsuid)
13939 +               return 1;
13940 +       if (task->gid != task->egid || task->gid != task->sgid ||
13941 +           task->gid != task->fsgid)
13942 +               return 1;
13943 +
13944 +       return 0;
13945 +}
13946 +static __inline__ int
13947 +gr_fake_force_sig(int sig, struct task_struct *t)
13948 +{
13949 +       unsigned long int flags;
13950 +       int ret;
13951 +
13952 +       spin_lock_irqsave(&t->sighand->siglock, flags);
13953 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
13954 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
13955 +               sigdelset(&t->blocked, sig);
13956 +               recalc_sigpending_tsk(t);
13957 +       }
13958 +       ret = specific_send_sig_info(sig, (void*)1L, t);
13959 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
13960 +
13961 +       return ret;
13962 +}
13963 +
13964 +void
13965 +gr_handle_crash(struct task_struct *task, const int sig)
13966 +{
13967 +       struct acl_subject_label *curr;
13968 +       struct acl_subject_label *curr2;
13969 +       struct task_struct *tsk, *tsk2;
13970 +
13971 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
13972 +               return;
13973 +
13974 +       if (unlikely(!gr_acl_is_enabled()))
13975 +               return;
13976 +
13977 +       curr = task->acl;
13978 +
13979 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
13980 +               return;
13981 +
13982 +       if (time_before_eq(curr->expires, get_seconds())) {
13983 +               curr->expires = 0;
13984 +               curr->crashes = 0;
13985 +       }
13986 +
13987 +       curr->crashes++;
13988 +
13989 +       if (!curr->expires)
13990 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
13991 +
13992 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
13993 +           time_after(curr->expires, get_seconds())) {
13994 +               if (task->uid && proc_is_setxid(task)) {
13995 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
13996 +                       write_lock(&gr_uid_lock);
13997 +                       gr_insert_uid(task->uid, curr->expires);
13998 +                       write_unlock(&gr_uid_lock);
13999 +                       curr->expires = 0;
14000 +                       curr->crashes = 0;
14001 +                       read_lock(&tasklist_lock);
14002 +                       do_each_thread(tsk2, tsk) {
14003 +                               if (tsk != task && tsk->uid == task->uid)
14004 +                                       gr_fake_force_sig(SIGKILL, tsk);
14005 +                       } while_each_thread(tsk2, tsk);
14006 +                       read_unlock(&tasklist_lock);
14007 +               } else {
14008 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
14009 +                       read_lock(&tasklist_lock);
14010 +                       do_each_thread(tsk2, tsk) {
14011 +                               if (likely(tsk != task)) {
14012 +                                       curr2 = tsk->acl;
14013 +
14014 +                                       if (curr2->device == curr->device &&
14015 +                                           curr2->inode == curr->inode)
14016 +                                               gr_fake_force_sig(SIGKILL, tsk);
14017 +                               }
14018 +                       } while_each_thread(tsk2, tsk);
14019 +                       read_unlock(&tasklist_lock);
14020 +               }
14021 +       }
14022 +
14023 +       return;
14024 +}
14025 +
14026 +int
14027 +gr_check_crash_exec(const struct file *filp)
14028 +{
14029 +       struct acl_subject_label *curr;
14030 +
14031 +       if (unlikely(!gr_acl_is_enabled()))
14032 +               return 0;
14033 +
14034 +       read_lock(&gr_inode_lock);
14035 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
14036 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
14037 +                                    current->role);
14038 +       read_unlock(&gr_inode_lock);
14039 +
14040 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
14041 +           (!curr->crashes && !curr->expires))
14042 +               return 0;
14043 +
14044 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
14045 +           time_after(curr->expires, get_seconds()))
14046 +               return 1;
14047 +       else if (time_before_eq(curr->expires, get_seconds())) {
14048 +               curr->crashes = 0;
14049 +               curr->expires = 0;
14050 +       }
14051 +
14052 +       return 0;
14053 +}
14054 +
14055 +void
14056 +gr_handle_alertkill(struct task_struct *task)
14057 +{
14058 +       struct acl_subject_label *curracl;
14059 +       __u32 curr_ip;
14060 +       struct task_struct *p, *p2;
14061 +
14062 +       if (unlikely(!gr_acl_is_enabled()))
14063 +               return;
14064 +
14065 +       curracl = task->acl;
14066 +       curr_ip = task->curr_ip;
14067 +
14068 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
14069 +               read_lock(&tasklist_lock);
14070 +               do_each_thread(p2, p) {
14071 +                       if (p->curr_ip == curr_ip)
14072 +                               gr_fake_force_sig(SIGKILL, p);
14073 +               } while_each_thread(p2, p);
14074 +               read_unlock(&tasklist_lock);
14075 +       } else if (curracl->mode & GR_KILLPROC)
14076 +               gr_fake_force_sig(SIGKILL, task);
14077 +
14078 +       return;
14079 +}
14080 diff -urNp linux-2.6.11/grsecurity/gracl_shm.c linux-2.6.11/grsecurity/gracl_shm.c
14081 --- linux-2.6.11/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
14082 +++ linux-2.6.11/grsecurity/gracl_shm.c 2005-03-09 11:56:44.000000000 -0500
14083 @@ -0,0 +1,33 @@
14084 +#include <linux/kernel.h>
14085 +#include <linux/mm.h>
14086 +#include <linux/sched.h>
14087 +#include <linux/file.h>
14088 +#include <linux/ipc.h>
14089 +#include <linux/gracl.h>
14090 +#include <linux/grsecurity.h>
14091 +#include <linux/grinternal.h>
14092 +
14093 +int
14094 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
14095 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
14096 +{
14097 +       struct task_struct *task;
14098 +
14099 +       if (!gr_acl_is_enabled())
14100 +               return 1;
14101 +
14102 +       task = find_task_by_pid(shm_cprid);
14103 +
14104 +       if (unlikely(!task))
14105 +               task = find_task_by_pid(shm_lapid);
14106 +
14107 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
14108 +                             (task->pid == shm_lapid)) &&
14109 +                    (task->acl->mode & GR_PROTSHM) &&
14110 +                    (task->acl != current->acl))) {
14111 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
14112 +               return 0;
14113 +       }
14114 +
14115 +       return 1;
14116 +}
14117 diff -urNp linux-2.6.11/grsecurity/grsec_chdir.c linux-2.6.11/grsecurity/grsec_chdir.c
14118 --- linux-2.6.11/grsecurity/grsec_chdir.c       1969-12-31 19:00:00.000000000 -0500
14119 +++ linux-2.6.11/grsecurity/grsec_chdir.c       2005-03-09 11:56:44.000000000 -0500
14120 @@ -0,0 +1,19 @@
14121 +#include <linux/kernel.h>
14122 +#include <linux/sched.h>
14123 +#include <linux/fs.h>
14124 +#include <linux/file.h>
14125 +#include <linux/grsecurity.h>
14126 +#include <linux/grinternal.h>
14127 +
14128 +void
14129 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
14130 +{
14131 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
14132 +       if ((grsec_enable_chdir && grsec_enable_group &&
14133 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
14134 +                                             !grsec_enable_group)) {
14135 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
14136 +       }
14137 +#endif
14138 +       return;
14139 +}
14140 diff -urNp linux-2.6.11/grsecurity/grsec_chroot.c linux-2.6.11/grsecurity/grsec_chroot.c
14141 --- linux-2.6.11/grsecurity/grsec_chroot.c      1969-12-31 19:00:00.000000000 -0500
14142 +++ linux-2.6.11/grsecurity/grsec_chroot.c      2005-03-09 11:56:44.000000000 -0500
14143 @@ -0,0 +1,335 @@
14144 +#include <linux/kernel.h>
14145 +#include <linux/module.h>
14146 +#include <linux/sched.h>
14147 +#include <linux/file.h>
14148 +#include <linux/fs.h>
14149 +#include <linux/mount.h>
14150 +#include <linux/types.h>
14151 +#include <linux/grinternal.h>
14152 +
14153 +int
14154 +gr_handle_chroot_unix(const pid_t pid)
14155 +{
14156 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
14157 +       struct pid *spid = NULL;
14158 +
14159 +       if (unlikely(!grsec_enable_chroot_unix))
14160 +               return 1;
14161 +
14162 +       if (likely(!proc_is_chrooted(current)))
14163 +               return 1;
14164 +
14165 +       read_lock(&tasklist_lock);
14166 +
14167 +       spid = find_pid(PIDTYPE_PID, pid);
14168 +       if (spid) {
14169 +               struct task_struct *p;
14170 +               p = pid_task(&spid->pid_list, PIDTYPE_PID);
14171 +               task_lock(p);
14172 +               if (unlikely(!have_same_root(current, p))) {
14173 +                       task_unlock(p);
14174 +                       read_unlock(&tasklist_lock);
14175 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
14176 +                       return 0;
14177 +               }
14178 +               task_unlock(p);
14179 +       }
14180 +       read_unlock(&tasklist_lock);
14181 +#endif
14182 +       return 1;
14183 +}
14184 +
14185 +int
14186 +gr_handle_chroot_nice(void)
14187 +{
14188 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
14189 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
14190 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
14191 +               return -EPERM;
14192 +       }
14193 +#endif
14194 +       return 0;
14195 +}
14196 +
14197 +int
14198 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
14199 +{
14200 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
14201 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
14202 +                       && proc_is_chrooted(current)) {
14203 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
14204 +               return -EACCES;
14205 +       }
14206 +#endif
14207 +       return 0;
14208 +}
14209 +
14210 +int
14211 +gr_handle_chroot_rawio(const struct inode *inode)
14212 +{
14213 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14214 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
14215 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
14216 +               return 1;
14217 +#endif
14218 +       return 0;
14219 +}
14220 +
14221 +int
14222 +gr_pid_is_chrooted(struct task_struct *p)
14223 +{
14224 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
14225 +       if (!grsec_enable_chroot_findtask || !current->fs || 
14226 +           !proc_is_chrooted(current) || !p)
14227 +               return 0;
14228 +
14229 +       task_lock(p);
14230 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
14231 +           (p->fs && !have_same_root(current, p))) {
14232 +               task_unlock(p);
14233 +               return 1;
14234 +       }
14235 +       task_unlock(p);
14236 +#endif
14237 +       return 0;
14238 +}
14239 +
14240 +EXPORT_SYMBOL(gr_pid_is_chrooted);
14241 +
14242 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
14243 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
14244 +{
14245 +       struct dentry *dentry = (struct dentry *)u_dentry;
14246 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
14247 +       struct dentry *realroot;
14248 +       struct vfsmount *realrootmnt;
14249 +       struct dentry *currentroot;
14250 +       struct vfsmount *currentmnt;
14251 +
14252 +       read_lock(&child_reaper->fs->lock);
14253 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
14254 +       realroot = dget(child_reaper->fs->root);
14255 +       read_unlock(&child_reaper->fs->lock);
14256 +
14257 +       read_lock(&current->fs->lock);
14258 +       currentmnt = mntget(current->fs->rootmnt);
14259 +       currentroot = dget(current->fs->root);
14260 +       read_unlock(&current->fs->lock);
14261 +
14262 +       spin_lock(&dcache_lock);
14263 +       for (;;) {
14264 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
14265 +                    || (dentry == currentroot && mnt == currentmnt)))
14266 +                       break;
14267 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
14268 +                       if (mnt->mnt_parent == mnt)
14269 +                               break;
14270 +                       dentry = mnt->mnt_mountpoint;
14271 +                       mnt = mnt->mnt_parent;
14272 +                       continue;
14273 +               }
14274 +               dentry = dentry->d_parent;
14275 +       }
14276 +       spin_unlock(&dcache_lock);
14277 +
14278 +       dput(currentroot);
14279 +       mntput(currentmnt);
14280 +
14281 +       if (dentry == realroot && mnt == realrootmnt) {
14282 +               /* access is outside of chroot */
14283 +               dput(realroot);
14284 +               mntput(realrootmnt);
14285 +               return 0;
14286 +       }
14287 +
14288 +       dput(realroot);
14289 +       mntput(realrootmnt);
14290 +       return 1;
14291 +}
14292 +#endif
14293 +
14294 +int
14295 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
14296 +{
14297 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
14298 +       if (!grsec_enable_chroot_fchdir)
14299 +               return 1;
14300 +
14301 +       if (!proc_is_chrooted(current))
14302 +               return 1;
14303 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
14304 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
14305 +               return 0;
14306 +       }
14307 +#endif
14308 +       return 1;
14309 +}
14310 +
14311 +int
14312 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
14313 +               const time_t shm_createtime)
14314 +{
14315 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
14316 +       struct pid *pid = NULL;
14317 +       time_t starttime;
14318 +
14319 +       if (unlikely(!grsec_enable_chroot_shmat))
14320 +               return 1;
14321 +
14322 +       if (likely(!proc_is_chrooted(current)))
14323 +               return 1;
14324 +
14325 +       read_lock(&tasklist_lock);
14326 +
14327 +       pid = find_pid(PIDTYPE_PID, shm_cprid);
14328 +       if (pid) {
14329 +               struct task_struct *p;
14330 +               p = pid_task(&pid->pid_list, PIDTYPE_PID);
14331 +               task_lock(p);
14332 +               starttime = p->start_time.tv_sec;
14333 +               if (unlikely(!have_same_root(current, p) &&
14334 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
14335 +                       task_unlock(p);
14336 +                       read_unlock(&tasklist_lock);
14337 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
14338 +                       return 0;
14339 +               }
14340 +               task_unlock(p);
14341 +       } else {
14342 +               pid = find_pid(PIDTYPE_PID, shm_lapid);
14343 +               if (pid) {
14344 +                       struct task_struct *p;
14345 +                       p = pid_task(&pid->pid_list, PIDTYPE_PID);
14346 +                       task_lock(p);
14347 +                       if (unlikely(!have_same_root(current, p))) {
14348 +                               task_unlock(p);
14349 +                               read_unlock(&tasklist_lock);
14350 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
14351 +                               return 0;
14352 +                       }
14353 +                       task_unlock(p);
14354 +               }
14355 +       }
14356 +
14357 +       read_unlock(&tasklist_lock);
14358 +#endif
14359 +       return 1;
14360 +}
14361 +
14362 +void
14363 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
14364 +{
14365 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
14366 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
14367 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
14368 +#endif
14369 +       return;
14370 +}
14371 +
14372 +int
14373 +gr_handle_chroot_mknod(const struct dentry *dentry,
14374 +                      const struct vfsmount *mnt, const int mode)
14375 +{
14376 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
14377 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
14378 +           proc_is_chrooted(current)) {
14379 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
14380 +               return -EPERM;
14381 +       }
14382 +#endif
14383 +       return 0;
14384 +}
14385 +
14386 +int
14387 +gr_handle_chroot_mount(const struct dentry *dentry,
14388 +                      const struct vfsmount *mnt, const char *dev_name)
14389 +{
14390 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
14391 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
14392 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
14393 +               return -EPERM;
14394 +       }
14395 +#endif
14396 +       return 0;
14397 +}
14398 +
14399 +int
14400 +gr_handle_chroot_pivot(void)
14401 +{
14402 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
14403 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
14404 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
14405 +               return -EPERM;
14406 +       }
14407 +#endif
14408 +       return 0;
14409 +}
14410 +
14411 +int
14412 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
14413 +{
14414 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
14415 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
14416 +           !gr_is_outside_chroot(dentry, mnt)) {
14417 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
14418 +               return -EPERM;
14419 +       }
14420 +#endif
14421 +       return 0;
14422 +}
14423 +
14424 +void
14425 +gr_handle_chroot_caps(struct task_struct *task)
14426 +{
14427 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14428 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
14429 +               task->cap_permitted =
14430 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
14431 +               task->cap_inheritable =
14432 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
14433 +               task->cap_effective =
14434 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
14435 +       }
14436 +#endif
14437 +       return;
14438 +}
14439 +
14440 +int
14441 +gr_handle_chroot_sysctl(const int op)
14442 +{
14443 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
14444 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
14445 +           && (op & 002))
14446 +               return -EACCES;
14447 +#endif
14448 +       return 0;
14449 +}
14450 +
14451 +void
14452 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
14453 +{
14454 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
14455 +       if (grsec_enable_chroot_chdir)
14456 +               set_fs_pwd(current->fs, mnt, dentry);
14457 +#endif
14458 +       return;
14459 +}
14460 +
14461 +int
14462 +gr_handle_chroot_chmod(const struct dentry *dentry,
14463 +                      const struct vfsmount *mnt, const int mode)
14464 +{
14465 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
14466 +       if (grsec_enable_chroot_chmod &&
14467 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
14468 +           proc_is_chrooted(current)) {
14469 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
14470 +               return -EPERM;
14471 +       }
14472 +#endif
14473 +       return 0;
14474 +}
14475 +
14476 +#ifdef CONFIG_SECURITY
14477 +EXPORT_SYMBOL(gr_handle_chroot_caps);
14478 +#endif
14479 diff -urNp linux-2.6.11/grsecurity/grsec_disabled.c linux-2.6.11/grsecurity/grsec_disabled.c
14480 --- linux-2.6.11/grsecurity/grsec_disabled.c    1969-12-31 19:00:00.000000000 -0500
14481 +++ linux-2.6.11/grsecurity/grsec_disabled.c    2005-03-09 11:56:44.000000000 -0500
14482 @@ -0,0 +1,418 @@
14483 +#include <linux/kernel.h>
14484 +#include <linux/module.h>
14485 +#include <linux/config.h>
14486 +#include <linux/sched.h>
14487 +#include <linux/file.h>
14488 +#include <linux/fs.h>
14489 +#include <linux/kdev_t.h>
14490 +#include <linux/net.h>
14491 +#include <linux/in.h>
14492 +#include <linux/ip.h>
14493 +#include <linux/skbuff.h>
14494 +#include <linux/sysctl.h>
14495 +
14496 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14497 +void
14498 +pax_set_initial_flags(struct linux_binprm *bprm)
14499 +{
14500 +       return;
14501 +}
14502 +#endif
14503 +
14504 +#ifdef CONFIG_SYSCTL
14505 +__u32
14506 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
14507 +{
14508 +       return mode;
14509 +}
14510 +#endif
14511 +
14512 +int
14513 +gr_acl_is_enabled(void)
14514 +{
14515 +       return 0;
14516 +}
14517 +
14518 +int
14519 +gr_handle_rawio(const struct inode *inode)
14520 +{
14521 +       return 0;
14522 +}
14523 +
14524 +void
14525 +gr_acl_handle_psacct(struct task_struct *task, const long code)
14526 +{
14527 +       return;
14528 +}
14529 +
14530 +int
14531 +gr_handle_ptrace(struct task_struct *task, const long request)
14532 +{
14533 +       return 0;
14534 +}
14535 +
14536 +int
14537 +gr_handle_proc_ptrace(struct task_struct *task)
14538 +{
14539 +       return 0;
14540 +}
14541 +
14542 +void
14543 +gr_learn_resource(const struct task_struct *task,
14544 +                 const int res, const unsigned long wanted, const int gt)
14545 +{
14546 +       return;
14547 +}
14548 +
14549 +int
14550 +gr_set_acls(const int type)
14551 +{
14552 +       return 0;
14553 +}
14554 +
14555 +int
14556 +gr_check_hidden_task(const struct task_struct *tsk)
14557 +{
14558 +       return 0;
14559 +}
14560 +
14561 +int
14562 +gr_check_protected_task(const struct task_struct *task)
14563 +{
14564 +       return 0;
14565 +}
14566 +
14567 +void
14568 +gr_copy_label(struct task_struct *tsk)
14569 +{
14570 +       return;
14571 +}
14572 +
14573 +void
14574 +gr_set_pax_flags(struct task_struct *task)
14575 +{
14576 +       return;
14577 +}
14578 +
14579 +int
14580 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
14581 +{
14582 +       return 0;
14583 +}
14584 +
14585 +void
14586 +gr_handle_delete(const ino_t ino, const dev_t dev)
14587 +{
14588 +       return;
14589 +}
14590 +
14591 +void
14592 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
14593 +{
14594 +       return;
14595 +}
14596 +
14597 +void
14598 +gr_handle_crash(struct task_struct *task, const int sig)
14599 +{
14600 +       return;
14601 +}
14602 +
14603 +int
14604 +gr_check_crash_exec(const struct file *filp)
14605 +{
14606 +       return 0;
14607 +}
14608 +
14609 +int
14610 +gr_check_crash_uid(const uid_t uid)
14611 +{
14612 +       return 0;
14613 +}
14614 +
14615 +void
14616 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14617 +                struct dentry *old_dentry,
14618 +                struct dentry *new_dentry,
14619 +                struct vfsmount *mnt, const __u8 replace)
14620 +{
14621 +       return;
14622 +}
14623 +
14624 +int
14625 +gr_search_socket(const int family, const int type, const int protocol)
14626 +{
14627 +       return 1;
14628 +}
14629 +
14630 +int
14631 +gr_search_connectbind(const int mode, const struct socket *sock,
14632 +                     const struct sockaddr_in *addr)
14633 +{
14634 +       return 1;
14635 +}
14636 +
14637 +int
14638 +gr_task_is_capable(struct task_struct *task, const int cap)
14639 +{
14640 +       return 1;
14641 +}
14642 +
14643 +int
14644 +gr_is_capable_nolog(const int cap)
14645 +{
14646 +       return 1;
14647 +}
14648 +
14649 +void
14650 +gr_handle_alertkill(struct task_struct *task)
14651 +{
14652 +       return;
14653 +}
14654 +
14655 +__u32
14656 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
14657 +{
14658 +       return 1;
14659 +}
14660 +
14661 +__u32
14662 +gr_acl_handle_hidden_file(const struct dentry * dentry,
14663 +                         const struct vfsmount * mnt)
14664 +{
14665 +       return 1;
14666 +}
14667 +
14668 +__u32
14669 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
14670 +                  const int fmode)
14671 +{
14672 +       return 1;
14673 +}
14674 +
14675 +__u32
14676 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
14677 +{
14678 +       return 1;
14679 +}
14680 +
14681 +__u32
14682 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
14683 +{
14684 +       return 1;
14685 +}
14686 +
14687 +int
14688 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
14689 +                  unsigned int *vm_flags)
14690 +{
14691 +       return 1;
14692 +}
14693 +
14694 +__u32
14695 +gr_acl_handle_truncate(const struct dentry * dentry,
14696 +                      const struct vfsmount * mnt)
14697 +{
14698 +       return 1;
14699 +}
14700 +
14701 +__u32
14702 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
14703 +{
14704 +       return 1;
14705 +}
14706 +
14707 +__u32
14708 +gr_acl_handle_access(const struct dentry * dentry,
14709 +                    const struct vfsmount * mnt, const int fmode)
14710 +{
14711 +       return 1;
14712 +}
14713 +
14714 +__u32
14715 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
14716 +                    mode_t mode)
14717 +{
14718 +       return 1;
14719 +}
14720 +
14721 +__u32
14722 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
14723 +                   mode_t mode)
14724 +{
14725 +       return 1;
14726 +}
14727 +
14728 +__u32
14729 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
14730 +{
14731 +       return 1;
14732 +}
14733 +
14734 +void
14735 +grsecurity_init(void)
14736 +{
14737 +       return;
14738 +}
14739 +
14740 +__u32
14741 +gr_acl_handle_mknod(const struct dentry * new_dentry,
14742 +                   const struct dentry * parent_dentry,
14743 +                   const struct vfsmount * parent_mnt,
14744 +                   const int mode)
14745 +{
14746 +       return 1;
14747 +}
14748 +
14749 +__u32
14750 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
14751 +                   const struct dentry * parent_dentry,
14752 +                   const struct vfsmount * parent_mnt)
14753 +{
14754 +       return 1;
14755 +}
14756 +
14757 +__u32
14758 +gr_acl_handle_symlink(const struct dentry * new_dentry,
14759 +                     const struct dentry * parent_dentry,
14760 +                     const struct vfsmount * parent_mnt, const char *from)
14761 +{
14762 +       return 1;
14763 +}
14764 +
14765 +__u32
14766 +gr_acl_handle_link(const struct dentry * new_dentry,
14767 +                  const struct dentry * parent_dentry,
14768 +                  const struct vfsmount * parent_mnt,
14769 +                  const struct dentry * old_dentry,
14770 +                  const struct vfsmount * old_mnt, const char *to)
14771 +{
14772 +       return 1;
14773 +}
14774 +
14775 +int
14776 +gr_acl_handle_rename(const struct dentry *new_dentry,
14777 +                    const struct dentry *parent_dentry,
14778 +                    const struct vfsmount *parent_mnt,
14779 +                    const struct dentry *old_dentry,
14780 +                    const struct inode *old_parent_inode,
14781 +                    const struct vfsmount *old_mnt, const char *newname)
14782 +{
14783 +       return 0;
14784 +}
14785 +
14786 +int
14787 +gr_acl_handle_filldir(const struct file *file, const char *name,
14788 +                     const int namelen, const ino_t ino)
14789 +{
14790 +       return 1;
14791 +}
14792 +
14793 +int
14794 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
14795 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
14796 +{
14797 +       return 1;
14798 +}
14799 +
14800 +int
14801 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
14802 +{
14803 +       return 1;
14804 +}
14805 +
14806 +int
14807 +gr_search_accept(const struct socket *sock)
14808 +{
14809 +       return 1;
14810 +}
14811 +
14812 +int
14813 +gr_search_listen(const struct socket *sock)
14814 +{
14815 +       return 1;
14816 +}
14817 +
14818 +int
14819 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
14820 +{
14821 +       return 1;
14822 +}
14823 +
14824 +__u32
14825 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
14826 +{
14827 +       return 1;
14828 +}
14829 +
14830 +__u32
14831 +gr_acl_handle_creat(const struct dentry * dentry,
14832 +                   const struct dentry * p_dentry,
14833 +                   const struct vfsmount * p_mnt, const int fmode,
14834 +                   const int imode)
14835 +{
14836 +       return 1;
14837 +}
14838 +
14839 +void
14840 +gr_acl_handle_exit(void)
14841 +{
14842 +       return;
14843 +}
14844 +
14845 +int
14846 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
14847 +{
14848 +       return 1;
14849 +}
14850 +
14851 +void
14852 +gr_set_role_label(const uid_t uid, const gid_t gid)
14853 +{
14854 +       return;
14855 +}
14856 +
14857 +int
14858 +gr_acl_handle_procpidmem(const struct task_struct *task)
14859 +{
14860 +       return 0;
14861 +}
14862 +
14863 +int
14864 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
14865 +{
14866 +       return 1;
14867 +}
14868 +
14869 +int
14870 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
14871 +{
14872 +       return 1;
14873 +}
14874 +
14875 +void
14876 +gr_set_kernel_label(struct task_struct *task)
14877 +{
14878 +       return;
14879 +}
14880 +
14881 +int
14882 +gr_check_user_change(int real, int effective, int fs)
14883 +{
14884 +       return 0;
14885 +}
14886 +
14887 +int
14888 +gr_check_group_change(int real, int effective, int fs)
14889 +{
14890 +       return 0;
14891 +}
14892 +
14893 +
14894 +EXPORT_SYMBOL(gr_task_is_capable);
14895 +EXPORT_SYMBOL(gr_learn_resource);
14896 +EXPORT_SYMBOL(gr_set_kernel_label);
14897 +#ifdef CONFIG_SECURITY
14898 +EXPORT_SYMBOL(gr_check_user_change);
14899 +EXPORT_SYMBOL(gr_check_group_change);
14900 +#endif
14901 diff -urNp linux-2.6.11/grsecurity/grsec_exec.c linux-2.6.11/grsecurity/grsec_exec.c
14902 --- linux-2.6.11/grsecurity/grsec_exec.c        1969-12-31 19:00:00.000000000 -0500
14903 +++ linux-2.6.11/grsecurity/grsec_exec.c        2005-03-09 11:56:44.000000000 -0500
14904 @@ -0,0 +1,88 @@
14905 +#include <linux/kernel.h>
14906 +#include <linux/sched.h>
14907 +#include <linux/file.h>
14908 +#include <linux/binfmts.h>
14909 +#include <linux/smp_lock.h>
14910 +#include <linux/fs.h>
14911 +#include <linux/types.h>
14912 +#include <linux/grdefs.h>
14913 +#include <linux/grinternal.h>
14914 +#include <linux/capability.h>
14915 +
14916 +#include <asm/uaccess.h>
14917 +
14918 +#ifdef CONFIG_GRKERNSEC_EXECLOG
14919 +static char gr_exec_arg_buf[132];
14920 +static DECLARE_MUTEX(gr_exec_arg_sem);
14921 +#endif
14922 +
14923 +int
14924 +gr_handle_nproc(void)
14925 +{
14926 +#ifdef CONFIG_GRKERNSEC_EXECVE
14927 +       if (grsec_enable_execve && current->user &&
14928 +           (atomic_read(&current->user->processes) >
14929 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
14930 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
14931 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
14932 +               return -EAGAIN;
14933 +       }
14934 +#endif
14935 +       return 0;
14936 +}
14937 +
14938 +void
14939 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
14940 +{
14941 +#ifdef CONFIG_GRKERNSEC_EXECLOG
14942 +       char *grarg = gr_exec_arg_buf;
14943 +       unsigned int i, x, execlen = 0;
14944 +       char c;
14945 +
14946 +       if (!((grsec_enable_execlog && grsec_enable_group &&
14947 +              in_group_p(grsec_audit_gid))
14948 +             || (grsec_enable_execlog && !grsec_enable_group)))
14949 +               return;
14950 +
14951 +       down(&gr_exec_arg_sem);
14952 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
14953 +
14954 +       if (unlikely(argv == NULL))
14955 +               goto log;
14956 +
14957 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
14958 +               const char __user *p;
14959 +               unsigned int len;
14960 +
14961 +               if (copy_from_user(&p, argv + i, sizeof(p)))
14962 +                       goto log;
14963 +               if (!p)
14964 +                       goto log;
14965 +               len = strnlen_user(p, 128 - execlen);
14966 +               if (len > 128 - execlen)
14967 +                       len = 128 - execlen;
14968 +               else if (len > 0)
14969 +                       len--;
14970 +               if (copy_from_user(grarg + execlen, p, len))
14971 +                       goto log;
14972 +
14973 +               /* rewrite unprintable characters */
14974 +               for (x = 0; x < len; x++) {
14975 +                       c = *(grarg + execlen + x);
14976 +                       if (c < 32 || c > 126)
14977 +                               *(grarg + execlen + x) = ' ';
14978 +               }
14979 +
14980 +               execlen += len;
14981 +               *(grarg + execlen) = ' ';
14982 +               *(grarg + execlen + 1) = '\0';
14983 +               execlen++;
14984 +       }
14985 +
14986 +      log:
14987 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
14988 +                       bprm->file->f_vfsmnt, grarg);
14989 +       up(&gr_exec_arg_sem);
14990 +#endif
14991 +       return;
14992 +}
14993 diff -urNp linux-2.6.11/grsecurity/grsec_fifo.c linux-2.6.11/grsecurity/grsec_fifo.c
14994 --- linux-2.6.11/grsecurity/grsec_fifo.c        1969-12-31 19:00:00.000000000 -0500
14995 +++ linux-2.6.11/grsecurity/grsec_fifo.c        2005-03-09 11:56:44.000000000 -0500
14996 @@ -0,0 +1,22 @@
14997 +#include <linux/kernel.h>
14998 +#include <linux/sched.h>
14999 +#include <linux/fs.h>
15000 +#include <linux/file.h>
15001 +#include <linux/grinternal.h>
15002 +
15003 +int
15004 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
15005 +              const struct dentry *dir, const int flag, const int acc_mode)
15006 +{
15007 +#ifdef CONFIG_GRKERNSEC_FIFO
15008 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
15009 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
15010 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
15011 +           (current->fsuid != dentry->d_inode->i_uid)) {
15012 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
15013 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
15014 +               return -EACCES;
15015 +       }
15016 +#endif
15017 +       return 0;
15018 +}
15019 diff -urNp linux-2.6.11/grsecurity/grsec_fork.c linux-2.6.11/grsecurity/grsec_fork.c
15020 --- linux-2.6.11/grsecurity/grsec_fork.c        1969-12-31 19:00:00.000000000 -0500
15021 +++ linux-2.6.11/grsecurity/grsec_fork.c        2005-03-09 11:56:44.000000000 -0500
15022 @@ -0,0 +1,14 @@
15023 +#include <linux/kernel.h>
15024 +#include <linux/sched.h>
15025 +#include <linux/grsecurity.h>
15026 +#include <linux/grinternal.h>
15027 +
15028 +void
15029 +gr_log_forkfail(const int retval)
15030 +{
15031 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
15032 +       if (grsec_enable_forkfail)
15033 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
15034 +#endif
15035 +       return;
15036 +}
15037 diff -urNp linux-2.6.11/grsecurity/grsec_init.c linux-2.6.11/grsecurity/grsec_init.c
15038 --- linux-2.6.11/grsecurity/grsec_init.c        1969-12-31 19:00:00.000000000 -0500
15039 +++ linux-2.6.11/grsecurity/grsec_init.c        2005-03-09 11:56:44.000000000 -0500
15040 @@ -0,0 +1,236 @@
15041 +#include <linux/kernel.h>
15042 +#include <linux/sched.h>
15043 +#include <linux/mm.h>
15044 +#include <linux/smp_lock.h>
15045 +#include <linux/gracl.h>
15046 +#include <linux/slab.h>
15047 +#include <linux/vmalloc.h>
15048 +#include <linux/percpu.h>
15049 +
15050 +int grsec_enable_shm;
15051 +int grsec_enable_link;
15052 +int grsec_enable_dmesg;
15053 +int grsec_enable_fifo;
15054 +int grsec_enable_execve;
15055 +int grsec_enable_execlog;
15056 +int grsec_enable_signal;
15057 +int grsec_enable_forkfail;
15058 +int grsec_enable_time;
15059 +int grsec_enable_audit_textrel;
15060 +int grsec_enable_group;
15061 +int grsec_audit_gid;
15062 +int grsec_enable_chdir;
15063 +int grsec_enable_audit_ipc;
15064 +int grsec_enable_mount;
15065 +int grsec_enable_chroot_findtask;
15066 +int grsec_enable_chroot_mount;
15067 +int grsec_enable_chroot_shmat;
15068 +int grsec_enable_chroot_fchdir;
15069 +int grsec_enable_chroot_double;
15070 +int grsec_enable_chroot_pivot;
15071 +int grsec_enable_chroot_chdir;
15072 +int grsec_enable_chroot_chmod;
15073 +int grsec_enable_chroot_mknod;
15074 +int grsec_enable_chroot_nice;
15075 +int grsec_enable_chroot_execlog;
15076 +int grsec_enable_chroot_caps;
15077 +int grsec_enable_chroot_sysctl;
15078 +int grsec_enable_chroot_unix;
15079 +int grsec_enable_tpe;
15080 +int grsec_tpe_gid;
15081 +int grsec_enable_tpe_all;
15082 +int grsec_enable_randpid;
15083 +int grsec_enable_randsrc;
15084 +int grsec_enable_socket_all;
15085 +int grsec_socket_all_gid;
15086 +int grsec_enable_socket_client;
15087 +int grsec_socket_client_gid;
15088 +int grsec_enable_socket_server;
15089 +int grsec_socket_server_gid;
15090 +int grsec_lock;
15091 +
15092 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
15093 +unsigned long grsec_alert_wtime = 0;
15094 +unsigned long grsec_alert_fyet = 0;
15095 +
15096 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
15097 +
15098 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
15099 +
15100 +char *gr_shared_page[4];
15101 +
15102 +char *gr_alert_log_fmt;
15103 +char *gr_audit_log_fmt;
15104 +char *gr_alert_log_buf;
15105 +char *gr_audit_log_buf;
15106 +
15107 +extern struct gr_arg *gr_usermode;
15108 +extern unsigned char *gr_system_salt;
15109 +extern unsigned char *gr_system_sum;
15110 +
15111 +void
15112 +grsecurity_init(void)
15113 +{
15114 +       int j;
15115 +       /* create the per-cpu shared pages */
15116 +
15117 +       preempt_disable();
15118 +       for (j = 0; j < 4; j++) {
15119 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(char *));
15120 +               if (gr_shared_page[j] == NULL) {
15121 +                       panic("Unable to allocate grsecurity shared page");
15122 +                       return;
15123 +               }
15124 +       }
15125 +       preempt_enable();
15126 +
15127 +       /* allocate log buffers */
15128 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
15129 +       if (!gr_alert_log_fmt) {
15130 +               panic("Unable to allocate grsecurity alert log format buffer");
15131 +               return;
15132 +       }
15133 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
15134 +       if (!gr_audit_log_fmt) {
15135 +               panic("Unable to allocate grsecurity audit log format buffer");
15136 +               return;
15137 +       }
15138 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
15139 +       if (!gr_alert_log_buf) {
15140 +               panic("Unable to allocate grsecurity alert log buffer");
15141 +               return;
15142 +       }
15143 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
15144 +       if (!gr_audit_log_buf) {
15145 +               panic("Unable to allocate grsecurity audit log buffer");
15146 +               return;
15147 +       }
15148 +
15149 +       /* allocate memory for authentication structure */
15150 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
15151 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
15152 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
15153 +
15154 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
15155 +               panic("Unable to allocate grsecurity authentication structure");
15156 +               return;
15157 +       }
15158 +
15159 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
15160 +#ifndef CONFIG_GRKERNSEC_SYSCTL
15161 +       grsec_lock = 1;
15162 +#endif
15163 +#ifdef CONFIG_GRKERNSEC_SHM
15164 +       grsec_enable_shm = 1;
15165 +#endif
15166 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
15167 +       grsec_enable_audit_textrel = 1;
15168 +#endif
15169 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
15170 +       grsec_enable_group = 1;
15171 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
15172 +#endif
15173 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
15174 +       grsec_enable_chdir = 1;
15175 +#endif
15176 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15177 +       grsec_enable_audit_ipc = 1;
15178 +#endif
15179 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15180 +       grsec_enable_mount = 1;
15181 +#endif
15182 +#ifdef CONFIG_GRKERNSEC_LINK
15183 +       grsec_enable_link = 1;
15184 +#endif
15185 +#ifdef CONFIG_GRKERNSEC_DMESG
15186 +       grsec_enable_dmesg = 1;
15187 +#endif
15188 +#ifdef CONFIG_GRKERNSEC_FIFO
15189 +       grsec_enable_fifo = 1;
15190 +#endif
15191 +#ifdef CONFIG_GRKERNSEC_EXECVE
15192 +       grsec_enable_execve = 1;
15193 +#endif
15194 +#ifdef CONFIG_GRKERNSEC_EXECLOG
15195 +       grsec_enable_execlog = 1;
15196 +#endif
15197 +#ifdef CONFIG_GRKERNSEC_SIGNAL
15198 +       grsec_enable_signal = 1;
15199 +#endif
15200 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
15201 +       grsec_enable_forkfail = 1;
15202 +#endif
15203 +#ifdef CONFIG_GRKERNSEC_TIME
15204 +       grsec_enable_time = 1;
15205 +#endif
15206 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
15207 +       grsec_enable_chroot_findtask = 1;
15208 +#endif
15209 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
15210 +       grsec_enable_chroot_unix = 1;
15211 +#endif
15212 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
15213 +       grsec_enable_chroot_mount = 1;
15214 +#endif
15215 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
15216 +       grsec_enable_chroot_fchdir = 1;
15217 +#endif
15218 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
15219 +       grsec_enable_chroot_shmat = 1;
15220 +#endif
15221 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
15222 +       grsec_enable_chroot_double = 1;
15223 +#endif
15224 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
15225 +       grsec_enable_chroot_pivot = 1;
15226 +#endif
15227 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
15228 +       grsec_enable_chroot_chdir = 1;
15229 +#endif
15230 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
15231 +       grsec_enable_chroot_chmod = 1;
15232 +#endif
15233 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
15234 +       grsec_enable_chroot_mknod = 1;
15235 +#endif
15236 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
15237 +       grsec_enable_chroot_nice = 1;
15238 +#endif
15239 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
15240 +       grsec_enable_chroot_execlog = 1;
15241 +#endif
15242 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
15243 +       grsec_enable_chroot_caps = 1;
15244 +#endif
15245 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
15246 +       grsec_enable_chroot_sysctl = 1;
15247 +#endif
15248 +#ifdef CONFIG_GRKERNSEC_TPE
15249 +       grsec_enable_tpe = 1;
15250 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
15251 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
15252 +       grsec_enable_tpe_all = 1;
15253 +#endif
15254 +#endif
15255 +#ifdef CONFIG_GRKERNSEC_RANDPID
15256 +       grsec_enable_randpid = 1;
15257 +#endif
15258 +#ifdef CONFIG_GRKERNSEC_RANDSRC
15259 +       grsec_enable_randsrc = 1;
15260 +#endif
15261 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
15262 +       grsec_enable_socket_all = 1;
15263 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
15264 +#endif
15265 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
15266 +       grsec_enable_socket_client = 1;
15267 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
15268 +#endif
15269 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
15270 +       grsec_enable_socket_server = 1;
15271 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
15272 +#endif
15273 +#endif
15274 +
15275 +       return;
15276 +}
15277 diff -urNp linux-2.6.11/grsecurity/grsec_ipc.c linux-2.6.11/grsecurity/grsec_ipc.c
15278 --- linux-2.6.11/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
15279 +++ linux-2.6.11/grsecurity/grsec_ipc.c 2005-03-09 11:56:44.000000000 -0500
15280 @@ -0,0 +1,81 @@
15281 +#include <linux/kernel.h>
15282 +#include <linux/sched.h>
15283 +#include <linux/types.h>
15284 +#include <linux/ipc.h>
15285 +#include <linux/grsecurity.h>
15286 +#include <linux/grinternal.h>
15287 +
15288 +void
15289 +gr_log_msgget(const int ret, const int msgflg)
15290 +{
15291 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15292 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15293 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15294 +                                         !grsec_enable_group)) && (ret >= 0)
15295 +           && (msgflg & IPC_CREAT))
15296 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
15297 +#endif
15298 +       return;
15299 +}
15300 +
15301 +void
15302 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
15303 +{
15304 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15305 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15306 +            grsec_enable_audit_ipc) ||
15307 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15308 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
15309 +#endif
15310 +       return;
15311 +}
15312 +
15313 +void
15314 +gr_log_semget(const int err, const int semflg)
15315 +{
15316 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15317 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15318 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15319 +                                         !grsec_enable_group)) && (err >= 0)
15320 +           && (semflg & IPC_CREAT))
15321 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
15322 +#endif
15323 +       return;
15324 +}
15325 +
15326 +void
15327 +gr_log_semrm(const uid_t uid, const uid_t cuid)
15328 +{
15329 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15330 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15331 +            grsec_enable_audit_ipc) ||
15332 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15333 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
15334 +#endif
15335 +       return;
15336 +}
15337 +
15338 +void
15339 +gr_log_shmget(const int err, const int shmflg, const size_t size)
15340 +{
15341 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15342 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15343 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15344 +                                         !grsec_enable_group)) && (err >= 0)
15345 +           && (shmflg & IPC_CREAT))
15346 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
15347 +#endif
15348 +       return;
15349 +}
15350 +
15351 +void
15352 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
15353 +{
15354 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15355 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15356 +            grsec_enable_audit_ipc) ||
15357 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15358 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
15359 +#endif
15360 +       return;
15361 +}
15362 diff -urNp linux-2.6.11/grsecurity/grsec_link.c linux-2.6.11/grsecurity/grsec_link.c
15363 --- linux-2.6.11/grsecurity/grsec_link.c        1969-12-31 19:00:00.000000000 -0500
15364 +++ linux-2.6.11/grsecurity/grsec_link.c        2005-03-09 11:56:44.000000000 -0500
15365 @@ -0,0 +1,39 @@
15366 +#include <linux/kernel.h>
15367 +#include <linux/sched.h>
15368 +#include <linux/fs.h>
15369 +#include <linux/file.h>
15370 +#include <linux/grinternal.h>
15371 +
15372 +int
15373 +gr_handle_follow_link(const struct inode *parent,
15374 +                     const struct inode *inode,
15375 +                     const struct dentry *dentry, const struct vfsmount *mnt)
15376 +{
15377 +#ifdef CONFIG_GRKERNSEC_LINK
15378 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
15379 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
15380 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
15381 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
15382 +               return -EACCES;
15383 +       }
15384 +#endif
15385 +       return 0;
15386 +}
15387 +
15388 +int
15389 +gr_handle_hardlink(const struct dentry *dentry,
15390 +                  const struct vfsmount *mnt,
15391 +                  struct inode *inode, const int mode, const char *to)
15392 +{
15393 +#ifdef CONFIG_GRKERNSEC_LINK
15394 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
15395 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
15396 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
15397 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
15398 +           !capable(CAP_FOWNER) && current->uid) {
15399 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
15400 +               return -EPERM;
15401 +       }
15402 +#endif
15403 +       return 0;
15404 +}
15405 diff -urNp linux-2.6.11/grsecurity/grsec_log.c linux-2.6.11/grsecurity/grsec_log.c
15406 --- linux-2.6.11/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
15407 +++ linux-2.6.11/grsecurity/grsec_log.c 2005-03-09 11:56:44.000000000 -0500
15408 @@ -0,0 +1,265 @@
15409 +#include <linux/kernel.h>
15410 +#include <linux/sched.h>
15411 +#include <linux/file.h>
15412 +#include <linux/tty.h>
15413 +#include <linux/fs.h>
15414 +#include <linux/grinternal.h>
15415 +
15416 +#define BEGIN_LOCKS(x) \
15417 +       read_lock(&tasklist_lock); \
15418 +       read_lock(&grsec_exec_file_lock); \
15419 +       if (x != GR_DO_AUDIT) \
15420 +               spin_lock(&grsec_alert_lock); \
15421 +       else \
15422 +               spin_lock(&grsec_audit_lock)
15423 +
15424 +#define END_LOCKS(x) \
15425 +       if (x != GR_DO_AUDIT) \
15426 +               spin_unlock(&grsec_alert_lock); \
15427 +       else \
15428 +               spin_unlock(&grsec_audit_lock); \
15429 +       read_unlock(&grsec_exec_file_lock); \
15430 +       read_unlock(&tasklist_lock); \
15431 +       if (x == GR_DONT_AUDIT) \
15432 +               gr_handle_alertkill(current)
15433 +
15434 +enum {
15435 +       FLOODING,
15436 +       NO_FLOODING
15437 +};
15438 +
15439 +extern char *gr_alert_log_fmt;
15440 +extern char *gr_audit_log_fmt;
15441 +extern char *gr_alert_log_buf;
15442 +extern char *gr_audit_log_buf;
15443 +
15444 +static int gr_log_start(int audit)
15445 +{
15446 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
15447 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
15448 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15449 +
15450 +       if (audit == GR_DO_AUDIT)
15451 +               goto set_fmt;
15452 +
15453 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
15454 +               grsec_alert_wtime = jiffies;
15455 +               grsec_alert_fyet = 0;
15456 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
15457 +               grsec_alert_fyet++;
15458 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
15459 +               grsec_alert_wtime = jiffies;
15460 +               grsec_alert_fyet++;
15461 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
15462 +               return FLOODING;
15463 +       } else return FLOODING;
15464 +
15465 +set_fmt:
15466 +       memset(buf, 0, PAGE_SIZE);
15467 +       if (current->curr_ip && gr_acl_is_enabled()) {
15468 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
15469 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
15470 +       } else if (current->curr_ip) {
15471 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
15472 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->curr_ip));
15473 +       } else if (gr_acl_is_enabled()) {
15474 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
15475 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
15476 +       } else {
15477 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
15478 +               strcpy(buf, fmt);
15479 +       }
15480 +
15481 +       return NO_FLOODING;
15482 +}
15483 +
15484 +static void gr_log_middle(int audit, const char *msg, va_list ap)
15485 +{
15486 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15487 +       unsigned int len = strlen(buf);
15488 +
15489 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
15490 +
15491 +       return;
15492 +}
15493 +
15494 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
15495 +{
15496 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15497 +       unsigned int len = strlen(buf);
15498 +       va_list ap;
15499 +
15500 +       va_start(ap, msg);
15501 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
15502 +       va_end(ap);
15503 +
15504 +       return;
15505 +}
15506 +
15507 +static void gr_log_end(int audit)
15508 +{
15509 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15510 +       unsigned int len = strlen(buf);
15511 +
15512 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
15513 +       printk("%s\n", buf);
15514 +
15515 +       return;
15516 +}
15517 +
15518 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
15519 +{
15520 +       int logtype;
15521 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
15522 +       char *str1, *str2, *str3;
15523 +       int num1, num2;
15524 +       unsigned long ulong1, ulong2;
15525 +       struct dentry *dentry;
15526 +       struct vfsmount *mnt;
15527 +       struct file *file;
15528 +       struct task_struct *task;
15529 +       va_list ap;
15530 +
15531 +       BEGIN_LOCKS(audit);
15532 +       logtype = gr_log_start(audit);
15533 +       if (logtype == FLOODING) {
15534 +               END_LOCKS(audit);
15535 +               return;
15536 +       }
15537 +       va_start(ap, argtypes);
15538 +       switch (argtypes) {
15539 +       case GR_TTYSNIFF:
15540 +               task = va_arg(ap, struct task_struct *);
15541 +               gr_log_middle_varargs(audit, msg, NIPQUAD(task->curr_ip), gr_task_fullpath0(task), task->comm, task->pid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid);
15542 +               break;
15543 +       case GR_RBAC:
15544 +               dentry = va_arg(ap, struct dentry *);
15545 +               mnt = va_arg(ap, struct vfsmount *);
15546 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
15547 +               break;
15548 +       case GR_RBAC_STR:
15549 +               dentry = va_arg(ap, struct dentry *);
15550 +               mnt = va_arg(ap, struct vfsmount *);
15551 +               str1 = va_arg(ap, char *);
15552 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
15553 +               break;
15554 +       case GR_STR_RBAC:
15555 +               str1 = va_arg(ap, char *);
15556 +               dentry = va_arg(ap, struct dentry *);
15557 +               mnt = va_arg(ap, struct vfsmount *);
15558 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
15559 +               break;
15560 +       case GR_RBAC_MODE2:
15561 +               dentry = va_arg(ap, struct dentry *);
15562 +               mnt = va_arg(ap, struct vfsmount *);
15563 +               str1 = va_arg(ap, char *);
15564 +               str2 = va_arg(ap, char *);
15565 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
15566 +               break;
15567 +       case GR_RBAC_MODE3:
15568 +               dentry = va_arg(ap, struct dentry *);
15569 +               mnt = va_arg(ap, struct vfsmount *);
15570 +               str1 = va_arg(ap, char *);
15571 +               str2 = va_arg(ap, char *);
15572 +               str3 = va_arg(ap, char *);
15573 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
15574 +               break;
15575 +       case GR_FILENAME:
15576 +               dentry = va_arg(ap, struct dentry *);
15577 +               mnt = va_arg(ap, struct vfsmount *);
15578 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
15579 +               break;
15580 +       case GR_STR_FILENAME:
15581 +               str1 = va_arg(ap, char *);
15582 +               dentry = va_arg(ap, struct dentry *);
15583 +               mnt = va_arg(ap, struct vfsmount *);
15584 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
15585 +               break;
15586 +       case GR_FILENAME_STR:
15587 +               dentry = va_arg(ap, struct dentry *);
15588 +               mnt = va_arg(ap, struct vfsmount *);
15589 +               str1 = va_arg(ap, char *);
15590 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
15591 +               break;
15592 +       case GR_FILENAME_TWO_INT:
15593 +               dentry = va_arg(ap, struct dentry *);
15594 +               mnt = va_arg(ap, struct vfsmount *);
15595 +               num1 = va_arg(ap, int);
15596 +               num2 = va_arg(ap, int);
15597 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
15598 +               break;
15599 +       case GR_FILENAME_TWO_INT_STR:
15600 +               dentry = va_arg(ap, struct dentry *);
15601 +               mnt = va_arg(ap, struct vfsmount *);
15602 +               num1 = va_arg(ap, int);
15603 +               num2 = va_arg(ap, int);
15604 +               str1 = va_arg(ap, char *);
15605 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
15606 +               break;
15607 +       case GR_TEXTREL:
15608 +               file = va_arg(ap, struct file *);
15609 +               ulong1 = va_arg(ap, unsigned long);
15610 +               ulong2 = va_arg(ap, unsigned long);
15611 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
15612 +               break;
15613 +       case GR_PTRACE:
15614 +               task = va_arg(ap, struct task_struct *);
15615 +               gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
15616 +               break;
15617 +       case GR_RESOURCE:
15618 +               task = va_arg(ap, struct task_struct *);
15619 +               ulong1 = va_arg(ap, unsigned long);
15620 +               str1 = va_arg(ap, char *);
15621 +               ulong2 = va_arg(ap, unsigned long);
15622 +               gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
15623 +               break;
15624 +       case GR_CAP:
15625 +               task = va_arg(ap, struct task_struct *);
15626 +               str1 = va_arg(ap, char *);
15627 +               gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
15628 +               break;
15629 +       case GR_SIG:
15630 +               task = va_arg(ap, struct task_struct *);
15631 +               num1 = va_arg(ap, int);
15632 +               gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
15633 +               break;
15634 +       case GR_CRASH1:
15635 +               task = va_arg(ap, struct task_struct *);
15636 +               ulong1 = va_arg(ap, unsigned long);
15637 +               gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, task->uid, ulong1);
15638 +               break;
15639 +       case GR_CRASH2:
15640 +               task = va_arg(ap, struct task_struct *);
15641 +               ulong1 = va_arg(ap, unsigned long);
15642 +               gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, ulong1);
15643 +               break;
15644 +       case GR_PSACCT:
15645 +               {
15646 +                       unsigned int wday, cday;
15647 +                       __u8 whr, chr;
15648 +                       __u8 wmin, cmin;
15649 +                       __u8 wsec, csec;
15650 +                       char cur_tty[64] = { 0 };
15651 +                       char parent_tty[64] = { 0 };
15652 +
15653 +                       task = va_arg(ap, struct task_struct *);
15654 +                       wday = va_arg(ap, unsigned int);
15655 +                       cday = va_arg(ap, unsigned int);
15656 +                       whr = va_arg(ap, int);
15657 +                       chr = va_arg(ap, int);
15658 +                       wmin = va_arg(ap, int);
15659 +                       cmin = va_arg(ap, int);
15660 +                       wsec = va_arg(ap, int);
15661 +                       csec = va_arg(ap, int);
15662 +                       ulong1 = va_arg(ap, unsigned long);
15663 +
15664 +                       gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, NIPQUAD(task->curr_ip), tty_name(task->signal->tty, cur_tty), task->uid, task->euid, task->gid, task->egid, wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, NIPQUAD(task->parent->curr_ip), tty_name(task->parent->signal->tty, parent_tty), task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
15665 +               }
15666 +               break;
15667 +       default:
15668 +               gr_log_middle(audit, msg, ap);
15669 +       }
15670 +       va_end(ap);
15671 +       gr_log_end(audit);
15672 +       END_LOCKS(audit);
15673 +}
15674 diff -urNp linux-2.6.11/grsecurity/grsec_mem.c linux-2.6.11/grsecurity/grsec_mem.c
15675 --- linux-2.6.11/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
15676 +++ linux-2.6.11/grsecurity/grsec_mem.c 2005-03-09 11:56:44.000000000 -0500
15677 @@ -0,0 +1,62 @@
15678 +#include <linux/kernel.h>
15679 +#include <linux/sched.h>
15680 +#include <linux/mm.h>
15681 +#include <linux/mman.h>
15682 +#include <linux/grinternal.h>
15683 +
15684 +void
15685 +gr_handle_ioperm(void)
15686 +{
15687 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
15688 +       return;
15689 +}
15690 +
15691 +void
15692 +gr_handle_iopl(void)
15693 +{
15694 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
15695 +       return;
15696 +}
15697 +
15698 +void
15699 +gr_handle_mem_write(void)
15700 +{
15701 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
15702 +       return;
15703 +}
15704 +
15705 +void
15706 +gr_handle_kmem_write(void)
15707 +{
15708 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
15709 +       return;
15710 +}
15711 +
15712 +void
15713 +gr_handle_open_port(void)
15714 +{
15715 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
15716 +       return;
15717 +}
15718 +
15719 +int
15720 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
15721 +{
15722 +       if (offset + vma->vm_end - vma->vm_start <= offset) {
15723 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
15724 +               return -EPERM;
15725 +       }
15726 +
15727 +       if (offset < __pa(high_memory) && (vma->vm_flags & VM_WRITE)
15728 +#ifdef CONFIG_X86
15729 +           && !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000))
15730 +           && !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))
15731 +#endif
15732 +          ) {
15733 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
15734 +               return -EPERM;
15735 +       } else if (offset < __pa(high_memory))
15736 +               vma->vm_flags &= ~VM_MAYWRITE;
15737 +
15738 +       return 0;
15739 +}
15740 diff -urNp linux-2.6.11/grsecurity/grsec_mount.c linux-2.6.11/grsecurity/grsec_mount.c
15741 --- linux-2.6.11/grsecurity/grsec_mount.c       1969-12-31 19:00:00.000000000 -0500
15742 +++ linux-2.6.11/grsecurity/grsec_mount.c       2005-03-09 11:56:44.000000000 -0500
15743 @@ -0,0 +1,34 @@
15744 +#include <linux/kernel.h>
15745 +#include <linux/sched.h>
15746 +#include <linux/grsecurity.h>
15747 +#include <linux/grinternal.h>
15748 +
15749 +void
15750 +gr_log_remount(const char *devname, const int retval)
15751 +{
15752 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15753 +       if (grsec_enable_mount && (retval >= 0))
15754 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
15755 +#endif
15756 +       return;
15757 +}
15758 +
15759 +void
15760 +gr_log_unmount(const char *devname, const int retval)
15761 +{
15762 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15763 +       if (grsec_enable_mount && (retval >= 0))
15764 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
15765 +#endif
15766 +       return;
15767 +}
15768 +
15769 +void
15770 +gr_log_mount(const char *from, const char *to, const int retval)
15771 +{
15772 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15773 +       if (grsec_enable_mount && (retval >= 0))
15774 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
15775 +#endif
15776 +       return;
15777 +}
15778 diff -urNp linux-2.6.11/grsecurity/grsec_rand.c linux-2.6.11/grsecurity/grsec_rand.c
15779 --- linux-2.6.11/grsecurity/grsec_rand.c        1969-12-31 19:00:00.000000000 -0500
15780 +++ linux-2.6.11/grsecurity/grsec_rand.c        2005-03-09 11:56:44.000000000 -0500
15781 @@ -0,0 +1,26 @@
15782 +#include <linux/kernel.h>
15783 +#include <linux/sched.h>
15784 +#include <linux/smp_lock.h>
15785 +#include <linux/grsecurity.h>
15786 +#include <linux/grinternal.h>
15787 +
15788 +extern int pid_max;
15789 +
15790 +int
15791 +gr_random_pid(void)
15792 +{
15793 +#ifdef CONFIG_GRKERNSEC_RANDPID
15794 +       int pid;
15795 +
15796 +       if (grsec_enable_randpid && current->fs->root) {
15797 +               /* return a pid in the range 1 ... pid_max - 1
15798 +                  optimize this so we don't have to do a real division
15799 +               */
15800 +               pid = 1 + (get_random_long() % pid_max);
15801 +               if (pid == pid_max)
15802 +                       pid = pid_max - 1;
15803 +               return pid;
15804 +       }
15805 +#endif
15806 +       return 0;
15807 +}
15808 diff -urNp linux-2.6.11/grsecurity/grsec_sig.c linux-2.6.11/grsecurity/grsec_sig.c
15809 --- linux-2.6.11/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
15810 +++ linux-2.6.11/grsecurity/grsec_sig.c 2005-03-09 11:56:44.000000000 -0500
15811 @@ -0,0 +1,59 @@
15812 +#include <linux/kernel.h>
15813 +#include <linux/sched.h>
15814 +#include <linux/grsecurity.h>
15815 +#include <linux/grinternal.h>
15816 +
15817 +void
15818 +gr_log_signal(const int sig, const struct task_struct *t)
15819 +{
15820 +#ifdef CONFIG_GRKERNSEC_SIGNAL
15821 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
15822 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
15823 +               if (t->pid == current->pid) {
15824 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
15825 +               } else {
15826 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
15827 +               }
15828 +       }
15829 +#endif
15830 +       return;
15831 +}
15832 +
15833 +int
15834 +gr_handle_signal(const struct task_struct *p, const int sig)
15835 +{
15836 +#ifdef CONFIG_GRKERNSEC
15837 +       if (current->pid > 1 && gr_check_protected_task(p)) {
15838 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
15839 +               return -EPERM;
15840 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
15841 +               return -EPERM;
15842 +       }
15843 +#endif
15844 +       return 0;
15845 +}
15846 +
15847 +void gr_handle_brute_attach(struct task_struct *p)
15848 +{
15849 +#ifdef CONFIG_GRKERNSEC_BRUTE
15850 +       read_lock(&tasklist_lock);
15851 +       read_lock(&grsec_exec_file_lock);
15852 +       if (p->parent && p->parent->exec_file == p->exec_file)
15853 +               p->parent->brute = 1;
15854 +       read_unlock(&grsec_exec_file_lock);
15855 +       read_unlock(&tasklist_lock);
15856 +#endif
15857 +       return;
15858 +}
15859 +
15860 +void gr_handle_brute_check(void)
15861 +{
15862 +#ifdef CONFIG_GRKERNSEC_BRUTE
15863 +       if (current->brute) {
15864 +               set_current_state(TASK_UNINTERRUPTIBLE);
15865 +               schedule_timeout(30 * HZ);
15866 +       }
15867 +#endif
15868 +       return;
15869 +}
15870 +
15871 diff -urNp linux-2.6.11/grsecurity/grsec_sock.c linux-2.6.11/grsecurity/grsec_sock.c
15872 --- linux-2.6.11/grsecurity/grsec_sock.c        1969-12-31 19:00:00.000000000 -0500
15873 +++ linux-2.6.11/grsecurity/grsec_sock.c        2005-03-09 11:56:44.000000000 -0500
15874 @@ -0,0 +1,259 @@
15875 +#include <linux/kernel.h>
15876 +#include <linux/module.h>
15877 +#include <linux/sched.h>
15878 +#include <linux/file.h>
15879 +#include <linux/net.h>
15880 +#include <linux/in.h>
15881 +#include <linux/ip.h>
15882 +#include <net/sock.h>
15883 +#include <linux/grsecurity.h>
15884 +#include <linux/grinternal.h>
15885 +#include <linux/gracl.h>
15886 +
15887 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
15888 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
15889 +EXPORT_SYMBOL(udp_v4_lookup);
15890 +#endif
15891 +
15892 +#ifdef CONFIG_GRKERNSEC_RANDSRC
15893 +EXPORT_SYMBOL(pax_get_random_long);
15894 +EXPORT_SYMBOL(grsec_enable_randsrc);
15895 +#endif
15896 +
15897 +EXPORT_SYMBOL(gr_cap_rtnetlink);
15898 +
15899 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
15900 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
15901 +
15902 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
15903 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
15904 +
15905 +#ifdef CONFIG_UNIX_MODULE
15906 +EXPORT_SYMBOL(gr_acl_handle_unix);
15907 +EXPORT_SYMBOL(gr_acl_handle_mknod);
15908 +EXPORT_SYMBOL(gr_handle_chroot_unix);
15909 +EXPORT_SYMBOL(gr_handle_create);
15910 +#endif
15911 +
15912 +#ifdef CONFIG_GRKERNSEC
15913 +#define gr_conn_table_size 65521
15914 +struct task_struct *gr_conn_table[gr_conn_table_size];
15915 +struct task_struct *deleted_conn = (struct task_struct *)~0;
15916 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
15917 +
15918 +extern const char * gr_socktype_to_name(unsigned char type);
15919 +extern const char * gr_proto_to_name(unsigned char proto);
15920 +
15921 +static __inline__ int 
15922 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
15923 +{
15924 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
15925 +}
15926 +
15927 +static __inline__ int
15928 +conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr, 
15929 +          __u16 sport, __u16 dport)
15930 +{
15931 +       if (unlikely(task != deleted_conn && task->gr_saddr == saddr && 
15932 +                    task->gr_daddr == daddr && task->gr_sport == sport &&
15933 +                    task->gr_dport == dport))
15934 +               return 1;
15935 +       else
15936 +               return 0;
15937 +}
15938 +
15939 +void gr_add_to_task_ip_table(struct task_struct *task)
15940 +{
15941 +       unsigned int index;
15942 +
15943 +       if (unlikely(gr_conn_table == NULL))
15944 +               return;
15945 +
15946 +       if (!thread_group_leader(task))
15947 +               task = task->group_leader;
15948 +
15949 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
15950 +                         task->gr_sport, task->gr_dport, 
15951 +                         gr_conn_table_size);
15952 +
15953 +       spin_lock(&gr_conn_table_lock);
15954 +
15955 +       while (gr_conn_table[index] && gr_conn_table[index] != deleted_conn) {
15956 +               index = (index + 1) % gr_conn_table_size;
15957 +       }
15958 +
15959 +       gr_conn_table[index] = task;
15960 +
15961 +       spin_unlock(&gr_conn_table_lock);
15962 +
15963 +       return;
15964 +}
15965 +
15966 +void gr_del_task_from_ip_table_nolock(struct task_struct *task)
15967 +{
15968 +       unsigned int index;
15969 +
15970 +       if (unlikely(gr_conn_table == NULL))
15971 +               return;
15972 +
15973 +       if (!thread_group_leader(task))
15974 +               task = task->group_leader;
15975 +
15976 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
15977 +                         task->gr_sport, task->gr_dport, 
15978 +                         gr_conn_table_size);
15979 +
15980 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
15981 +               task->gr_saddr, task->gr_daddr, task->gr_sport, 
15982 +               task->gr_dport)) {
15983 +               index = (index + 1) % gr_conn_table_size;
15984 +       }
15985 +
15986 +       if (gr_conn_table[index]) {
15987 +               if (gr_conn_table[(index + 1) % gr_conn_table_size])
15988 +                       gr_conn_table[index] = deleted_conn;
15989 +               else
15990 +                       gr_conn_table[index] = NULL;
15991 +       }
15992 +
15993 +       return;
15994 +}
15995 +
15996 +struct task_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
15997 +                                            __u16 sport, __u16 dport)
15998 +{
15999 +       unsigned int index;
16000 +
16001 +       if (unlikely(gr_conn_table == NULL))
16002 +               return NULL;
16003 +
16004 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
16005 +
16006 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
16007 +               saddr, daddr, sport, dport)) {
16008 +               index = (index + 1) % gr_conn_table_size;
16009 +       }
16010 +
16011 +       return gr_conn_table[index];
16012 +}
16013 +
16014 +#endif
16015 +
16016 +void gr_del_task_from_ip_table(struct task_struct *task)
16017 +{
16018 +#ifdef CONFIG_GRKERNSEC
16019 +       spin_lock(&gr_conn_table_lock);
16020 +       if (!thread_group_leader(task))
16021 +               gr_del_task_from_ip_table_nolock(task->group_leader);
16022 +       else
16023 +               gr_del_task_from_ip_table_nolock(task);
16024 +       spin_unlock(&gr_conn_table_lock);
16025 +#endif
16026 +       return;
16027 +}
16028 +
16029 +void
16030 +gr_attach_curr_ip(const struct sock *sk)
16031 +{
16032 +#ifdef CONFIG_GRKERNSEC
16033 +       struct task_struct *p;
16034 +       struct task_struct *set;
16035 +       const struct inet_sock *inet = inet_sk(sk);     
16036 +
16037 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
16038 +               return;
16039 +
16040 +       set = current;
16041 +       if (!thread_group_leader(set))
16042 +               set = set->group_leader;
16043 +
16044 +       spin_lock(&gr_conn_table_lock);
16045 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
16046 +                                   inet->dport, inet->sport);
16047 +       if (unlikely(p != NULL)) {
16048 +               set->curr_ip = p->curr_ip;
16049 +               set->used_accept = 1;
16050 +               gr_del_task_from_ip_table_nolock(p);
16051 +               spin_unlock(&gr_conn_table_lock);
16052 +               return;
16053 +       }
16054 +       spin_unlock(&gr_conn_table_lock);
16055 +
16056 +       set->curr_ip = inet->daddr;
16057 +       set->used_accept = 1;
16058 +#endif
16059 +       return;
16060 +}
16061 +
16062 +int
16063 +gr_handle_sock_all(const int family, const int type, const int protocol)
16064 +{
16065 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
16066 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
16067 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
16068 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
16069 +               return -EACCES;
16070 +       }
16071 +#endif
16072 +       return 0;
16073 +}
16074 +
16075 +int
16076 +gr_handle_sock_server(const struct sockaddr *sck)
16077 +{
16078 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16079 +       if (grsec_enable_socket_server &&
16080 +           in_group_p(grsec_socket_server_gid) &&
16081 +           sck && (sck->sa_family != AF_UNIX) &&
16082 +           (sck->sa_family != AF_LOCAL)) {
16083 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
16084 +               return -EACCES;
16085 +       }
16086 +#endif
16087 +       return 0;
16088 +}
16089 +
16090 +int
16091 +gr_handle_sock_server_other(const struct sock *sck)
16092 +{
16093 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16094 +       if (grsec_enable_socket_server &&
16095 +           in_group_p(grsec_socket_server_gid) &&
16096 +           sck && (sck->sk_family != AF_UNIX) &&
16097 +           (sck->sk_family != AF_LOCAL)) {
16098 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
16099 +               return -EACCES;
16100 +       }
16101 +#endif
16102 +       return 0;
16103 +}
16104 +
16105 +int
16106 +gr_handle_sock_client(const struct sockaddr *sck)
16107 +{
16108 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16109 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
16110 +           sck && (sck->sa_family != AF_UNIX) &&
16111 +           (sck->sa_family != AF_LOCAL)) {
16112 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
16113 +               return -EACCES;
16114 +       }
16115 +#endif
16116 +       return 0;
16117 +}
16118 +
16119 +__u32
16120 +gr_cap_rtnetlink(void)
16121 +{
16122 +#ifdef CONFIG_GRKERNSEC
16123 +       if (!gr_acl_is_enabled())
16124 +               return current->cap_effective;
16125 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
16126 +                gr_task_is_capable(current, CAP_NET_ADMIN))
16127 +               return current->cap_effective;
16128 +       else
16129 +               return 0;
16130 +#else
16131 +       return current->cap_effective;
16132 +#endif
16133 +}
16134 diff -urNp linux-2.6.11/grsecurity/grsec_sysctl.c linux-2.6.11/grsecurity/grsec_sysctl.c
16135 --- linux-2.6.11/grsecurity/grsec_sysctl.c      1969-12-31 19:00:00.000000000 -0500
16136 +++ linux-2.6.11/grsecurity/grsec_sysctl.c      2005-03-09 11:56:44.000000000 -0500
16137 @@ -0,0 +1,432 @@
16138 +#include <linux/kernel.h>
16139 +#include <linux/sched.h>
16140 +#include <linux/sysctl.h>
16141 +#include <linux/grsecurity.h>
16142 +#include <linux/grinternal.h>
16143 +
16144 +int
16145 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
16146 +{
16147 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16148 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
16149 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
16150 +               return -EACCES;
16151 +       }
16152 +#endif
16153 +       return 0;
16154 +}
16155 +
16156 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16157 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
16158 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
16159 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
16160 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
16161 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
16162 +GS_RANDPID, GS_RANDSRC, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
16163 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
16164 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
16165 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK};
16166 +
16167 +
16168 +ctl_table grsecurity_table[] = {
16169 +#ifdef CONFIG_GRKERNSEC_LINK
16170 +       {
16171 +               .ctl_name       = GS_LINK,
16172 +               .procname       = "linking_restrictions",
16173 +               .data           = &grsec_enable_link,
16174 +               .maxlen         = sizeof(int),
16175 +               .mode           = 0600,
16176 +               .proc_handler   = &proc_dointvec,
16177 +       },
16178 +#endif
16179 +#ifdef CONFIG_GRKERNSEC_FIFO
16180 +       {
16181 +               .ctl_name       = GS_FIFO,
16182 +               .procname       = "fifo_restrictions",
16183 +               .data           = &grsec_enable_fifo,
16184 +               .maxlen         = sizeof(int),
16185 +               .mode           = 0600,
16186 +               .proc_handler   = &proc_dointvec,
16187 +       },
16188 +#endif
16189 +#ifdef CONFIG_GRKERNSEC_EXECVE
16190 +       {
16191 +               .ctl_name       = GS_EXECVE,
16192 +               .procname       = "execve_limiting",
16193 +               .data           = &grsec_enable_execve,
16194 +               .maxlen         = sizeof(int),
16195 +               .mode           = 0600,
16196 +               .proc_handler   = &proc_dointvec,
16197 +       },
16198 +#endif
16199 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16200 +       {
16201 +               .ctl_name       = GS_EXECLOG,
16202 +               .procname       = "exec_logging",
16203 +               .data           = &grsec_enable_execlog,
16204 +               .maxlen         = sizeof(int),
16205 +               .mode           = 0600,
16206 +               .proc_handler   = &proc_dointvec,
16207 +       },
16208 +#endif
16209 +#ifdef CONFIG_GRKERNSEC_SIGNAL
16210 +       {
16211 +               .ctl_name       = GS_SIGNAL,
16212 +               .procname       = "signal_logging",
16213 +               .data           = &grsec_enable_signal,
16214 +               .maxlen         = sizeof(int),
16215 +               .mode           = 0600,
16216 +               .proc_handler   = &proc_dointvec,
16217 +       },
16218 +#endif
16219 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16220 +       {
16221 +               .ctl_name       = GS_FORKFAIL,
16222 +               .procname       = "forkfail_logging",
16223 +               .data           = &grsec_enable_forkfail,
16224 +               .maxlen         = sizeof(int),
16225 +               .mode           = 0600,
16226 +               .proc_handler   = &proc_dointvec,
16227 +       },
16228 +#endif
16229 +#ifdef CONFIG_GRKERNSEC_TIME
16230 +       {
16231 +               .ctl_name       = GS_TIME,
16232 +               .procname       = "timechange_logging",
16233 +               .data           = &grsec_enable_time,
16234 +               .maxlen         = sizeof(int),
16235 +               .mode           = 0600,
16236 +               .proc_handler   = &proc_dointvec,
16237 +       },
16238 +#endif
16239 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16240 +       {
16241 +               .ctl_name       = GS_CHROOT_SHMAT,
16242 +               .procname       = "chroot_deny_shmat",
16243 +               .data           = &grsec_enable_chroot_shmat,
16244 +               .maxlen         = sizeof(int),
16245 +               .mode           = 0600,
16246 +               .proc_handler   = &proc_dointvec,
16247 +       },
16248 +#endif
16249 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16250 +       {
16251 +               .ctl_name       = GS_CHROOT_UNIX,
16252 +               .procname       = "chroot_deny_unix",
16253 +               .data           = &grsec_enable_chroot_unix,
16254 +               .maxlen         = sizeof(int),
16255 +               .mode           = 0600,
16256 +               .proc_handler   = &proc_dointvec,
16257 +       },
16258 +#endif
16259 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16260 +       {
16261 +               .ctl_name       = GS_CHROOT_MNT,
16262 +               .procname       = "chroot_deny_mount",
16263 +               .data           = &grsec_enable_chroot_mount,
16264 +               .maxlen         = sizeof(int),
16265 +               .mode           = 0600,
16266 +               .proc_handler   = &proc_dointvec,
16267 +       },
16268 +#endif
16269 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16270 +       {
16271 +               .ctl_name       = GS_CHROOT_FCHDIR,
16272 +               .procname       = "chroot_deny_fchdir",
16273 +               .data           = &grsec_enable_chroot_fchdir,
16274 +               .maxlen         = sizeof(int),
16275 +               .mode           = 0600,
16276 +               .proc_handler   = &proc_dointvec,
16277 +       },
16278 +#endif
16279 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16280 +       {
16281 +               .ctl_name       = GS_CHROOT_DBL,
16282 +               .procname       = "chroot_deny_chroot",
16283 +               .data           = &grsec_enable_chroot_double,
16284 +               .maxlen         = sizeof(int),
16285 +               .mode           = 0600,
16286 +               .proc_handler   = &proc_dointvec,
16287 +       },
16288 +#endif
16289 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16290 +       {
16291 +               .ctl_name       = GS_CHROOT_PVT,
16292 +               .procname       = "chroot_deny_pivot",
16293 +               .data           = &grsec_enable_chroot_pivot,
16294 +               .maxlen         = sizeof(int),
16295 +               .mode           = 0600,
16296 +               .proc_handler   = &proc_dointvec,
16297 +       },
16298 +#endif
16299 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16300 +       {
16301 +               .ctl_name       = GS_CHROOT_CD,
16302 +               .procname       = "chroot_enforce_chdir",
16303 +               .data           = &grsec_enable_chroot_chdir,
16304 +               .maxlen         = sizeof(int),
16305 +               .mode           = 0600,
16306 +               .proc_handler   = &proc_dointvec,
16307 +       },
16308 +#endif
16309 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16310 +       {
16311 +               .ctl_name       = GS_CHROOT_CM,
16312 +               .procname       = "chroot_deny_chmod",
16313 +               .data           = &grsec_enable_chroot_chmod,
16314 +               .maxlen         = sizeof(int),
16315 +               .mode           = 0600,
16316 +               .proc_handler   = &proc_dointvec,
16317 +       },
16318 +#endif
16319 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16320 +       {
16321 +               .ctl_name       = GS_CHROOT_MK,
16322 +               .procname       = "chroot_deny_mknod",
16323 +               .data           = &grsec_enable_chroot_mknod,
16324 +               .maxlen         = sizeof(int),
16325 +               .mode           = 0600,
16326 +               .proc_handler   = &proc_dointvec,
16327 +       },
16328 +#endif
16329 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16330 +       {
16331 +               .ctl_name       = GS_CHROOT_NI,
16332 +               .procname       = "chroot_restrict_nice",
16333 +               .data           = &grsec_enable_chroot_nice,
16334 +               .maxlen         = sizeof(int),
16335 +               .mode           = 0600,
16336 +               .proc_handler   = &proc_dointvec,
16337 +       },
16338 +#endif
16339 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16340 +       {
16341 +               .ctl_name       = GS_CHROOT_EXECLOG,
16342 +               .procname       = "chroot_execlog",
16343 +               .data           = &grsec_enable_chroot_execlog,
16344 +               .maxlen         = sizeof(int),
16345 +               .mode           = 0600,
16346 +               .proc_handler   = &proc_dointvec,
16347 +       },
16348 +#endif
16349 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16350 +       {
16351 +               .ctl_name       = GS_CHROOT_CAPS,
16352 +               .procname       = "chroot_caps",
16353 +               .data           = &grsec_enable_chroot_caps,
16354 +               .maxlen         = sizeof(int),
16355 +               .mode           = 0600,
16356 +               .proc_handler   = &proc_dointvec,
16357 +       },
16358 +#endif
16359 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16360 +       {
16361 +               .ctl_name       = GS_CHROOT_SYSCTL,
16362 +               .procname       = "chroot_deny_sysctl",
16363 +               .data           = &grsec_enable_chroot_sysctl,
16364 +               .maxlen         = sizeof(int),
16365 +               .mode           = 0600,
16366 +               .proc_handler   = &proc_dointvec,
16367 +       },
16368 +#endif
16369 +#ifdef CONFIG_GRKERNSEC_TPE
16370 +       {
16371 +               .ctl_name       = GS_TPE,
16372 +               .procname       = "tpe",
16373 +               .data           = &grsec_enable_tpe,
16374 +               .maxlen         = sizeof(int),
16375 +               .mode           = 0600,
16376 +               .proc_handler   = &proc_dointvec,
16377 +       },
16378 +       {
16379 +               .ctl_name       = GS_TPE_GID,
16380 +               .procname       = "tpe_gid",
16381 +               .data           = &grsec_tpe_gid,
16382 +               .maxlen         = sizeof(int),
16383 +               .mode           = 0600,
16384 +               .proc_handler   = &proc_dointvec,
16385 +       },
16386 +#endif
16387 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16388 +       {
16389 +               .ctl_name       = GS_TPE_ALL,
16390 +               .procname       = "tpe_restrict_all",
16391 +               .data           = &grsec_enable_tpe_all,
16392 +               .maxlen         = sizeof(int),
16393 +               .mode           = 0600,
16394 +               .proc_handler   = &proc_dointvec,
16395 +       },
16396 +#endif
16397 +#ifdef CONFIG_GRKERNSEC_RANDPID
16398 +       {
16399 +               .ctl_name       = GS_RANDPID,
16400 +               .procname       = "rand_pids",
16401 +               .data           = &grsec_enable_randpid,
16402 +               .maxlen         = sizeof(int),
16403 +               .mode           = 0600,
16404 +               .proc_handler   = &proc_dointvec,
16405 +       },
16406 +#endif
16407 +#ifdef CONFIG_GRKERNSEC_RANDSRC
16408 +       {
16409 +               .ctl_name       = GS_RANDSRC,
16410 +               .procname       = "rand_tcp_src_ports",
16411 +               .data           = &grsec_enable_randsrc,
16412 +               .maxlen         = sizeof(int),
16413 +               .mode           = 0600,
16414 +               .proc_handler   = &proc_dointvec,
16415 +       },
16416 +#endif
16417 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
16418 +       {
16419 +               .ctl_name       = GS_SOCKET_ALL,
16420 +               .procname       = "socket_all",
16421 +               .data           = &grsec_enable_socket_all,
16422 +               .maxlen         = sizeof(int),
16423 +               .mode           = 0600,
16424 +               .proc_handler   = &proc_dointvec,
16425 +       },
16426 +       {
16427 +               .ctl_name       = GS_SOCKET_ALL_GID,
16428 +               .procname       = "socket_all_gid",
16429 +               .data           = &grsec_socket_all_gid,
16430 +               .maxlen         = sizeof(int),
16431 +               .mode           = 0600,
16432 +               .proc_handler   = &proc_dointvec,
16433 +       },
16434 +#endif
16435 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16436 +       {
16437 +               .ctl_name       = GS_SOCKET_CLIENT,
16438 +               .procname       = "socket_client",
16439 +               .data           = &grsec_enable_socket_client,
16440 +               .maxlen         = sizeof(int),
16441 +               .mode           = 0600,
16442 +               .proc_handler   = &proc_dointvec,
16443 +       },
16444 +       {
16445 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
16446 +               .procname       = "socket_client_gid",
16447 +               .data           = &grsec_socket_client_gid,
16448 +               .maxlen         = sizeof(int),
16449 +               .mode           = 0600,
16450 +               .proc_handler   = &proc_dointvec,
16451 +       },
16452 +#endif
16453 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16454 +       {
16455 +               .ctl_name       = GS_SOCKET_SERVER,
16456 +               .procname       = "socket_server",
16457 +               .data           = &grsec_enable_socket_server,
16458 +               .maxlen         = sizeof(int),
16459 +               .mode           = 0600,
16460 +               .proc_handler   = &proc_dointvec,
16461 +       },
16462 +       {
16463 +               .ctl_name       = GS_SOCKET_SERVER_GID,
16464 +               .procname       = "socket_server_gid",
16465 +               .data           = &grsec_socket_server_gid,
16466 +               .maxlen         = sizeof(int),
16467 +               .mode           = 0600,
16468 +               .proc_handler   = &proc_dointvec,
16469 +       },
16470 +#endif
16471 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
16472 +       {
16473 +               .ctl_name       = GS_GROUP,
16474 +               .procname       = "audit_group",
16475 +               .data           = &grsec_enable_group,
16476 +               .maxlen         = sizeof(int),
16477 +               .mode           = 0600,
16478 +               .proc_handler   = &proc_dointvec,
16479 +       },
16480 +       {
16481 +               .ctl_name       = GS_GID,
16482 +               .procname       = "audit_gid",
16483 +               .data           = &grsec_audit_gid,
16484 +               .maxlen         = sizeof(int),
16485 +               .mode           = 0600,
16486 +               .proc_handler   = &proc_dointvec,
16487 +       },
16488 +#endif
16489 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16490 +       {
16491 +               .ctl_name       = GS_ACHDIR,
16492 +               .procname       = "audit_chdir",
16493 +               .data           = &grsec_enable_chdir,
16494 +               .maxlen         = sizeof(int),
16495 +               .mode           = 0600,
16496 +               .proc_handler   = &proc_dointvec,
16497 +       },
16498 +#endif
16499 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16500 +       {
16501 +               .ctl_name       = GS_AMOUNT,
16502 +               .procname       = "audit_mount",
16503 +               .data           = &grsec_enable_mount,
16504 +               .maxlen         = sizeof(int),
16505 +               .mode           = 0600,
16506 +               .proc_handler   = &proc_dointvec,
16507 +       },
16508 +#endif
16509 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16510 +       {
16511 +               .ctl_name       = GS_AIPC,
16512 +               .procname       = "audit_ipc",
16513 +               .data           = &grsec_enable_audit_ipc,
16514 +               .maxlen         = sizeof(int),
16515 +               .mode           = 0600,
16516 +               .proc_handler   = &proc_dointvec,
16517 +       },
16518 +#endif
16519 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
16520 +       {
16521 +               .ctl_name       = GS_TEXTREL,
16522 +               .procname       = "audit_textrel",
16523 +               .data           = &grsec_enable_audit_textrel,
16524 +               .maxlen         = sizeof(int),
16525 +               .mode           = 0600,
16526 +               .proc_handler   = &proc_dointvec,
16527 +       },
16528 +#endif
16529 +#ifdef CONFIG_GRKERNSEC_DMESG
16530 +       {
16531 +               .ctl_name       = GS_DMSG,
16532 +               .procname       = "dmesg",
16533 +               .data           = &grsec_enable_dmesg,
16534 +               .maxlen         = sizeof(int),
16535 +               .mode           = 0600,
16536 +               .proc_handler   = &proc_dointvec,
16537 +       },
16538 +#endif
16539 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16540 +       {
16541 +               .ctl_name       = GS_FINDTASK,
16542 +               .procname       = "chroot_findtask",
16543 +               .data           = &grsec_enable_chroot_findtask,
16544 +               .maxlen         = sizeof(int),
16545 +               .mode           = 0600,
16546 +               .proc_handler   = &proc_dointvec,
16547 +       },
16548 +#endif
16549 +#ifdef CONFIG_GRKERNSEC_SHM
16550 +       {
16551 +               .ctl_name       = GS_SHM,
16552 +               .procname       = "destroy_unused_shm",
16553 +               .data           = &grsec_enable_shm,
16554 +               .maxlen         = sizeof(int),
16555 +               .mode           = 0600,
16556 +               .proc_handler   = &proc_dointvec,
16557 +       },
16558 +#endif
16559 +       {
16560 +               .ctl_name       = GS_LOCK,
16561 +               .procname       = "grsec_lock",
16562 +               .data           = &grsec_lock,
16563 +               .maxlen         = sizeof(int),
16564 +               .mode           = 0600,
16565 +               .proc_handler   = &proc_dointvec,
16566 +       },
16567 +       { .ctl_name = 0 }
16568 +};
16569 +#endif
16570 diff -urNp linux-2.6.11/grsecurity/grsec_textrel.c linux-2.6.11/grsecurity/grsec_textrel.c
16571 --- linux-2.6.11/grsecurity/grsec_textrel.c     1969-12-31 19:00:00.000000000 -0500
16572 +++ linux-2.6.11/grsecurity/grsec_textrel.c     2005-03-09 11:56:44.000000000 -0500
16573 @@ -0,0 +1,16 @@
16574 +#include <linux/kernel.h>
16575 +#include <linux/sched.h>
16576 +#include <linux/mm.h>
16577 +#include <linux/file.h>
16578 +#include <linux/grinternal.h>
16579 +#include <linux/grsecurity.h>
16580 +
16581 +void
16582 +gr_log_textrel(struct vm_area_struct * vma)
16583 +{
16584 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
16585 +       if (grsec_enable_audit_textrel)
16586 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
16587 +#endif
16588 +       return;
16589 +}
16590 diff -urNp linux-2.6.11/grsecurity/grsec_time.c linux-2.6.11/grsecurity/grsec_time.c
16591 --- linux-2.6.11/grsecurity/grsec_time.c        1969-12-31 19:00:00.000000000 -0500
16592 +++ linux-2.6.11/grsecurity/grsec_time.c        2005-03-09 11:56:44.000000000 -0500
16593 @@ -0,0 +1,13 @@
16594 +#include <linux/kernel.h>
16595 +#include <linux/sched.h>
16596 +#include <linux/grinternal.h>
16597 +
16598 +void
16599 +gr_log_timechange(void)
16600 +{
16601 +#ifdef CONFIG_GRKERNSEC_TIME
16602 +       if (grsec_enable_time)
16603 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
16604 +#endif
16605 +       return;
16606 +}
16607 diff -urNp linux-2.6.11/grsecurity/grsec_tpe.c linux-2.6.11/grsecurity/grsec_tpe.c
16608 --- linux-2.6.11/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
16609 +++ linux-2.6.11/grsecurity/grsec_tpe.c 2005-03-09 11:56:44.000000000 -0500
16610 @@ -0,0 +1,31 @@
16611 +#include <linux/kernel.h>
16612 +#include <linux/sched.h>
16613 +#include <linux/file.h>
16614 +#include <linux/fs.h>
16615 +#include <linux/grinternal.h>
16616 +
16617 +extern int gr_acl_tpe_check(void);
16618 +
16619 +int
16620 +gr_tpe_allow(const struct file *file)
16621 +{
16622 +#ifdef CONFIG_GRKERNSEC
16623 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
16624 +
16625 +       if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
16626 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
16627 +                                               (inode->i_mode & S_IWOTH))))) {
16628 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
16629 +               return 0;
16630 +       }
16631 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16632 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
16633 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
16634 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
16635 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
16636 +               return 0;
16637 +       }
16638 +#endif
16639 +#endif
16640 +       return 1;
16641 +}
16642 diff -urNp linux-2.6.11/grsecurity/grsum.c linux-2.6.11/grsecurity/grsum.c
16643 --- linux-2.6.11/grsecurity/grsum.c     1969-12-31 19:00:00.000000000 -0500
16644 +++ linux-2.6.11/grsecurity/grsum.c     2005-03-09 11:56:44.000000000 -0500
16645 @@ -0,0 +1,59 @@
16646 +#include <linux/kernel.h>
16647 +#include <linux/sched.h>
16648 +#include <linux/mm.h>
16649 +#include <asm/scatterlist.h>
16650 +#include <linux/crypto.h>
16651 +#include <linux/gracl.h>
16652 +
16653 +
16654 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
16655 +#error "crypto and sha256 must be built into the kernel"
16656 +#endif
16657 +
16658 +int
16659 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
16660 +{
16661 +       char *p;
16662 +       struct crypto_tfm *tfm;
16663 +       unsigned char temp_sum[GR_SHA_LEN];
16664 +       struct scatterlist sg[2];
16665 +       volatile int retval = 0;
16666 +       volatile int dummy = 0;
16667 +       unsigned int i;
16668 +
16669 +       tfm = crypto_alloc_tfm("sha256", 0);
16670 +       if (tfm == NULL) {
16671 +               /* should never happen, since sha256 should be built in */
16672 +               return 1;
16673 +       }
16674 +
16675 +       crypto_digest_init(tfm);
16676 +
16677 +       p = salt;
16678 +       sg[0].page = virt_to_page(p);
16679 +       sg[0].offset = ((long) p & ~PAGE_MASK);
16680 +       sg[0].length = GR_SALT_LEN;
16681 +       
16682 +       crypto_digest_update(tfm, sg, 1);
16683 +
16684 +       p = entry->pw;
16685 +       sg[0].page = virt_to_page(p);
16686 +       sg[0].offset = ((long) p & ~PAGE_MASK);
16687 +       sg[0].length = strlen(entry->pw);
16688 +
16689 +       crypto_digest_update(tfm, sg, 1);
16690 +
16691 +       crypto_digest_final(tfm, temp_sum);
16692 +
16693 +       memset(entry->pw, 0, GR_PW_LEN);
16694 +
16695 +       for (i = 0; i < GR_SHA_LEN; i++)
16696 +               if (sum[i] != temp_sum[i])
16697 +                       retval = 1;
16698 +               else
16699 +                       dummy = 1;      // waste a cycle
16700 +
16701 +       crypto_free_tfm(tfm);
16702 +
16703 +       return retval;
16704 +}
16705 diff -urNp linux-2.6.11/include/asm-alpha/a.out.h linux-2.6.11/include/asm-alpha/a.out.h
16706 --- linux-2.6.11/include/asm-alpha/a.out.h      2005-03-02 02:38:17.000000000 -0500
16707 +++ linux-2.6.11/include/asm-alpha/a.out.h      2005-03-09 11:56:44.000000000 -0500
16708 @@ -98,7 +98,7 @@ struct exec
16709         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
16710                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
16711  
16712 -#define STACK_TOP \
16713 +#define __STACK_TOP \
16714    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
16715  
16716  #endif
16717 diff -urNp linux-2.6.11/include/asm-alpha/elf.h linux-2.6.11/include/asm-alpha/elf.h
16718 --- linux-2.6.11/include/asm-alpha/elf.h        2005-03-02 02:38:09.000000000 -0500
16719 +++ linux-2.6.11/include/asm-alpha/elf.h        2005-03-09 11:56:44.000000000 -0500
16720 @@ -89,6 +89,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
16721  
16722  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
16723  
16724 +#ifdef CONFIG_PAX_ASLR
16725 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
16726 +
16727 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
16728 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
16729 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
16730 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
16731 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
16732 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
16733 +#endif
16734 +
16735  /* $0 is set by ld.so to a pointer to a function which might be 
16736     registered using atexit.  This provides a mean for the dynamic
16737     linker to call DT_FINI functions for shared libraries that have
16738 diff -urNp linux-2.6.11/include/asm-alpha/mman.h linux-2.6.11/include/asm-alpha/mman.h
16739 --- linux-2.6.11/include/asm-alpha/mman.h       2005-03-02 02:37:31.000000000 -0500
16740 +++ linux-2.6.11/include/asm-alpha/mman.h       2005-03-09 11:56:44.000000000 -0500
16741 @@ -29,6 +29,10 @@
16742  #define MAP_POPULATE   0x20000         /* populate (prefault) pagetables */
16743  #define MAP_NONBLOCK   0x40000         /* do not block on IO */
16744  
16745 +#ifdef CONFIG_PAX_RANDEXEC
16746 +#define MAP_MIRROR     0x20000
16747 +#endif
16748 +
16749  #define MS_ASYNC       1               /* sync memory asynchronously */
16750  #define MS_SYNC                2               /* synchronous memory sync */
16751  #define MS_INVALIDATE  4               /* invalidate the caches */
16752 diff -urNp linux-2.6.11/include/asm-alpha/page.h linux-2.6.11/include/asm-alpha/page.h
16753 --- linux-2.6.11/include/asm-alpha/page.h       2005-03-02 02:38:17.000000000 -0500
16754 +++ linux-2.6.11/include/asm-alpha/page.h       2005-03-09 11:56:44.000000000 -0500
16755 @@ -110,6 +110,15 @@ extern __inline__ int get_order(unsigned
16756  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
16757                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16758  
16759 +#ifdef CONFIG_PAX_PAGEEXEC
16760 +#ifdef CONFIG_PAX_MPROTECT
16761 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16762 +                         ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
16763 +#else
16764 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
16765 +#endif
16766 +#endif
16767 +
16768  #endif /* __KERNEL__ */
16769  
16770  #endif /* _ALPHA_PAGE_H */
16771 diff -urNp linux-2.6.11/include/asm-alpha/pgtable.h linux-2.6.11/include/asm-alpha/pgtable.h
16772 --- linux-2.6.11/include/asm-alpha/pgtable.h    2005-03-02 02:37:52.000000000 -0500
16773 +++ linux-2.6.11/include/asm-alpha/pgtable.h    2005-03-09 11:56:44.000000000 -0500
16774 @@ -98,6 +98,17 @@
16775  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
16776  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
16777  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
16778 +
16779 +#ifdef CONFIG_PAX_PAGEEXEC
16780 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
16781 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16782 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16783 +#else
16784 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
16785 +# define PAGE_COPY_NOEXEC      PAGE_COPY
16786 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
16787 +#endif
16788 +
16789  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
16790  
16791  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
16792 diff -urNp linux-2.6.11/include/asm-arm/a.out.h linux-2.6.11/include/asm-arm/a.out.h
16793 --- linux-2.6.11/include/asm-arm/a.out.h        2005-03-02 02:37:46.000000000 -0500
16794 +++ linux-2.6.11/include/asm-arm/a.out.h        2005-03-09 11:56:44.000000000 -0500
16795 @@ -28,7 +28,7 @@ struct exec
16796  #define M_ARM 103
16797  
16798  #ifdef __KERNEL__
16799 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
16800 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
16801                          TASK_SIZE : TASK_SIZE_26)
16802  #endif
16803  
16804 diff -urNp linux-2.6.11/include/asm-arm/elf.h linux-2.6.11/include/asm-arm/elf.h
16805 --- linux-2.6.11/include/asm-arm/elf.h  2005-03-02 02:38:25.000000000 -0500
16806 +++ linux-2.6.11/include/asm-arm/elf.h  2005-03-09 11:56:44.000000000 -0500
16807 @@ -54,6 +54,17 @@ typedef struct user_fp elf_fpregset_t;
16808  
16809  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
16810  
16811 +#ifdef CONFIG_PAX_ASLR
16812 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
16813 +
16814 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
16815 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
16816 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
16817 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
16818 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
16819 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
16820 +#endif
16821 +
16822  /* When the program starts, a1 contains a pointer to a function to be 
16823     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
16824     have no such handler.  */
16825 diff -urNp linux-2.6.11/include/asm-generic/pgtable-nopud.h linux-2.6.11/include/asm-generic/pgtable-nopud.h
16826 --- linux-2.6.11/include/asm-generic/pgtable-nopud.h    2005-03-02 02:38:12.000000000 -0500
16827 +++ linux-2.6.11/include/asm-generic/pgtable-nopud.h    2005-03-09 11:56:44.000000000 -0500
16828 @@ -22,7 +22,7 @@ typedef struct { pgd_t pgd; } pud_t;
16829   */
16830  static inline int pgd_none(pgd_t pgd)          { return 0; }
16831  static inline int pgd_bad(pgd_t pgd)           { return 0; }
16832 -static inline int pgd_present(pgd_t pgd)       { return 1; }
16833 +#define pgd_present(x)                 (pgd_val(x) & _PAGE_PRESENT)
16834  static inline void pgd_clear(pgd_t *pgd)       { }
16835  #define pud_ERROR(pud)                         (pgd_ERROR((pud).pgd))
16836  
16837 diff -urNp linux-2.6.11/include/asm-i386/a.out.h linux-2.6.11/include/asm-i386/a.out.h
16838 --- linux-2.6.11/include/asm-i386/a.out.h       2005-03-02 02:38:07.000000000 -0500
16839 +++ linux-2.6.11/include/asm-i386/a.out.h       2005-03-09 11:56:44.000000000 -0500
16840 @@ -19,7 +19,11 @@ struct exec
16841  
16842  #ifdef __KERNEL__
16843  
16844 -#define STACK_TOP      TASK_SIZE
16845 +#ifdef CONFIG_PAX_SEGMEXEC
16846 +#define __STACK_TOP ((current->mm->flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
16847 +#else
16848 +#define __STACK_TOP TASK_SIZE
16849 +#endif
16850  
16851  #endif
16852  
16853 diff -urNp linux-2.6.11/include/asm-i386/desc.h linux-2.6.11/include/asm-i386/desc.h
16854 --- linux-2.6.11/include/asm-i386/desc.h        2005-03-02 02:37:30.000000000 -0500
16855 +++ linux-2.6.11/include/asm-i386/desc.h        2005-03-09 11:56:44.000000000 -0500
16856 @@ -8,12 +8,70 @@
16857  
16858  #include <linux/preempt.h>
16859  #include <linux/smp.h>
16860 -#include <linux/percpu.h>
16861 +#include <linux/sched.h>
16862  
16863  #include <asm/mmu.h>
16864 +#include <asm/pgtable.h>
16865 +#include <asm/tlbflush.h>
16866  
16867 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
16868 -DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
16869 +extern struct desc_struct cpu_gdt_table[NR_CPUS][GDT_ENTRIES];
16870 +
16871 +#define pax_open_kernel(flags, cr3)            \
16872 +do {                                           \
16873 +       typecheck(unsigned long,flags);         \
16874 +       typecheck(unsigned long,cr3);           \
16875 +       local_irq_save(flags);                  \
16876 +       asm("movl %%cr3,%0":"=r" (cr3));        \
16877 +       load_cr3(kernexec_pg_dir);              \
16878 +} while(0)
16879 +
16880 +#define pax_close_kernel(flags, cr3)           \
16881 +do {                                           \
16882 +       typecheck(unsigned long,flags);         \
16883 +       typecheck(unsigned long,cr3);           \
16884 +       asm("movl %0,%%cr3": :"r" (cr3));       \
16885 +       local_irq_restore(flags);               \
16886 +} while(0)
16887 +
16888 +#define pax_open_kernel_noirq(cr3)             \
16889 +do {                                           \
16890 +       typecheck(unsigned long,cr3);           \
16891 +       asm("movl %%cr3,%0":"=r" (cr3));        \
16892 +       load_cr3(kernexec_pg_dir);              \
16893 +} while(0)
16894 +
16895 +#define pax_close_kernel_noirq(cr3)            \
16896 +do {                                           \
16897 +       typecheck(unsigned long,cr3);           \
16898 +       asm("movl %0,%%cr3": :"r" (cr3));       \
16899 +} while(0)
16900 +
16901 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
16902 +{
16903 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16904 +       unsigned long base = mm->context.user_cs_base;
16905 +       unsigned long limit = mm->context.user_cs_limit;
16906 +
16907 +#ifdef CONFIG_PAX_KERNEXEC
16908 +       unsigned long flags, cr3;
16909 +
16910 +       pax_open_kernel(flags, cr3);
16911 +#endif
16912 +
16913 +       if (limit) {
16914 +               limit -= 1UL;
16915 +               limit >>= 12;
16916 +       }
16917 +
16918 +       cpu_gdt_table[cpu][GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
16919 +       cpu_gdt_table[cpu][GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
16920 +
16921 +#ifdef CONFIG_PAX_KERNEXEC
16922 +       pax_close_kernel(flags, cr3);
16923 +#endif
16924 +
16925 +#endif
16926 +}
16927  
16928  struct Xgt_desc_struct {
16929         unsigned short size;
16930 @@ -30,7 +88,7 @@ extern struct Xgt_desc_struct idt_descr,
16931   * This is the ldt that every process will get unless we need
16932   * something other than this.
16933   */
16934 -extern struct desc_struct default_ldt[];
16935 +extern const struct desc_struct default_ldt[];
16936  extern void set_intr_gate(unsigned int irq, void * addr);
16937  
16938  #define _set_tssldt_desc(n,addr,limit,type) \
16939 @@ -44,17 +102,34 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
16940         "rorl $16,%%eax" \
16941         : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
16942  
16943 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
16944 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
16945  {
16946 -       _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
16947 +       _set_tssldt_desc(&cpu_gdt_table[cpu][entry], (int)addr,
16948                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
16949  }
16950  
16951  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
16952  
16953 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
16954 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
16955  {
16956 -       _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
16957 +       _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
16958 +}
16959 +
16960 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
16961 +{
16962 +
16963 +#ifdef CONFIG_PAX_KERNEXEC
16964 +       unsigned long flags, cr3;
16965 +
16966 +       pax_open_kernel(flags, cr3);
16967 +#endif
16968 +
16969 +       _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
16970 +
16971 +#ifdef CONFIG_PAX_KERNEXEC
16972 +       pax_close_kernel(flags, cr3);
16973 +#endif
16974 +
16975  }
16976  
16977  #define LDT_entry_a(info) \
16978 @@ -70,7 +145,7 @@ static inline void set_ldt_desc(unsigned
16979         ((info)->seg_32bit << 22) | \
16980         ((info)->limit_in_pages << 23) | \
16981         ((info)->useable << 20) | \
16982 -       0x7000)
16983 +       0x7100)
16984  
16985  #define LDT_empty(info) (\
16986         (info)->base_addr       == 0    && \
16987 @@ -88,7 +163,7 @@ static inline void set_ldt_desc(unsigned
16988  
16989  static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
16990  {
16991 -#define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
16992 +#define C(i) cpu_gdt_table[cpu][GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
16993         C(0); C(1); C(2);
16994  #undef C
16995  }
16996 @@ -107,7 +182,7 @@ static inline void clear_LDT(void)
16997   */
16998  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
16999  {
17000 -       void *segments = pc->ldt;
17001 +       const void *segments = pc->ldt;
17002         int count = pc->size;
17003  
17004         if (likely(!count)) {
17005 @@ -135,6 +210,22 @@ static inline unsigned long get_desc_bas
17006         return base;
17007  }
17008  
17009 +static inline void _load_LDT(mm_context_t *pc)
17010 +{
17011 +       int cpu = get_cpu();
17012 +       const void *segments = pc->ldt;
17013 +       int count = pc->size;
17014 +
17015 +       if (likely(!count)) {
17016 +               segments = &default_ldt[0];
17017 +               count = 5;
17018 +       }
17019 +               
17020 +       __set_ldt_desc(cpu, segments, count);
17021 +       load_LDT_desc();
17022 +       put_cpu();
17023 +}
17024 +
17025  #endif /* !__ASSEMBLY__ */
17026  
17027  #endif
17028 diff -urNp linux-2.6.11/include/asm-i386/elf.h linux-2.6.11/include/asm-i386/elf.h
17029 --- linux-2.6.11/include/asm-i386/elf.h 2005-03-02 02:38:13.000000000 -0500
17030 +++ linux-2.6.11/include/asm-i386/elf.h 2005-03-09 11:56:44.000000000 -0500
17031 @@ -72,6 +72,17 @@ typedef struct user_fxsr_struct elf_fpxr
17032  
17033  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
17034  
17035 +#ifdef CONFIG_PAX_ASLR
17036 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
17037 +
17038 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17039 +#define PAX_DELTA_MMAP_LEN(tsk)                15
17040 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17041 +#define PAX_DELTA_EXEC_LEN(tsk)                15
17042 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17043 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->flags & MF_PAX_SEGMEXEC ? 15 : 16)
17044 +#endif
17045 +
17046  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
17047     now struct_user_regs, they are different) */
17048  
17049 @@ -113,8 +124,11 @@ typedef struct user_fxsr_struct elf_fpxr
17050   * Architecture-neutral AT_ values in 0-17, leave some room
17051   * for more of them, start the x86-specific ones at 32.
17052   */
17053 +
17054 +#ifndef CONFIG_PAX_NOVSYSCALL
17055  #define AT_SYSINFO             32
17056  #define AT_SYSINFO_EHDR                33
17057 +#endif
17058  
17059  #ifdef __KERNEL__
17060  #define SET_PERSONALITY(ex, ibcs2) do { } while (0)
17061 @@ -135,7 +149,14 @@ extern int dump_task_extended_fpu (struc
17062  
17063  #define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
17064  #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
17065 +
17066 +#ifndef CONFIG_PAX_NOVSYSCALL
17067 +#ifdef CONFIG_PAX_SEGMEXEC
17068 +#define VSYSCALL_ENTRY ((current->mm->flags & MF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
17069 +#else
17070  #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
17071 +#endif
17072 +
17073  extern void __kernel_vsyscall;
17074  
17075  #define ARCH_DLINFO                                            \
17076 @@ -191,3 +212,5 @@ do {                                                                              \
17077  #endif
17078  
17079  #endif
17080 +
17081 +#endif
17082 diff -urNp linux-2.6.11/include/asm-i386/mach-default/apm.h linux-2.6.11/include/asm-i386/mach-default/apm.h
17083 --- linux-2.6.11/include/asm-i386/mach-default/apm.h    2005-03-02 02:37:49.000000000 -0500
17084 +++ linux-2.6.11/include/asm-i386/mach-default/apm.h    2005-03-09 11:56:44.000000000 -0500
17085 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
17086         __asm__ __volatile__(APM_DO_ZERO_SEGS
17087                 "pushl %%edi\n\t"
17088                 "pushl %%ebp\n\t"
17089 -               "lcall *%%cs:apm_bios_entry\n\t"
17090 +               "lcall *%%ss:apm_bios_entry\n\t"
17091                 "setc %%al\n\t"
17092                 "popl %%ebp\n\t"
17093                 "popl %%edi\n\t"
17094 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
17095         __asm__ __volatile__(APM_DO_ZERO_SEGS
17096                 "pushl %%edi\n\t"
17097                 "pushl %%ebp\n\t"
17098 -               "lcall *%%cs:apm_bios_entry\n\t"
17099 +               "lcall *%%ss:apm_bios_entry\n\t"
17100                 "setc %%bl\n\t"
17101                 "popl %%ebp\n\t"
17102                 "popl %%edi\n\t"
17103 diff -urNp linux-2.6.11/include/asm-i386/mman.h linux-2.6.11/include/asm-i386/mman.h
17104 --- linux-2.6.11/include/asm-i386/mman.h        2005-03-02 02:37:49.000000000 -0500
17105 +++ linux-2.6.11/include/asm-i386/mman.h        2005-03-09 11:56:44.000000000 -0500
17106 @@ -23,6 +23,10 @@
17107  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
17108  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
17109  
17110 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
17111 +#define MAP_MIRROR     0x20000
17112 +#endif
17113 +
17114  #define MS_ASYNC       1               /* sync memory asynchronously */
17115  #define MS_INVALIDATE  2               /* invalidate the caches */
17116  #define MS_SYNC                4               /* synchronous memory sync */
17117 diff -urNp linux-2.6.11/include/asm-i386/mmu.h linux-2.6.11/include/asm-i386/mmu.h
17118 --- linux-2.6.11/include/asm-i386/mmu.h 2005-03-02 02:38:12.000000000 -0500
17119 +++ linux-2.6.11/include/asm-i386/mmu.h 2005-03-09 11:56:44.000000000 -0500
17120 @@ -12,6 +12,17 @@ typedef struct { 
17121         int size;
17122         struct semaphore sem;
17123         void *ldt;
17124 +
17125 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17126 +       unsigned long user_cs_base;
17127 +       unsigned long user_cs_limit;
17128 +
17129 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17130 +       cpumask_t cpu_user_cs_mask;
17131 +#endif
17132 +
17133 +#endif
17134 +
17135  } mm_context_t;
17136  
17137  #endif
17138 diff -urNp linux-2.6.11/include/asm-i386/mmu_context.h linux-2.6.11/include/asm-i386/mmu_context.h
17139 --- linux-2.6.11/include/asm-i386/mmu_context.h 2005-03-02 02:38:34.000000000 -0500
17140 +++ linux-2.6.11/include/asm-i386/mmu_context.h 2005-03-09 11:56:44.000000000 -0500
17141 @@ -46,6 +46,13 @@ static inline void switch_mm(struct mm_s
17142                  */
17143                 if (unlikely(prev->context.ldt != next->context.ldt))
17144                         load_LDT_nolock(&next->context, cpu);
17145 +
17146 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17147 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
17148 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
17149 +#endif
17150 +
17151 +               set_user_cs(next, cpu);
17152         }
17153  #ifdef CONFIG_SMP
17154         else {
17155 @@ -58,6 +65,12 @@ static inline void switch_mm(struct mm_s
17156                          */
17157                         load_cr3(next->pgd);
17158                         load_LDT_nolock(&next->context, cpu);
17159 +
17160 +#ifdef CONFIG_PAX_PAGEEXEC
17161 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
17162 +#endif
17163 +
17164 +                       set_user_cs(next, cpu);
17165                 }
17166         }
17167  #endif
17168 diff -urNp linux-2.6.11/include/asm-i386/module.h linux-2.6.11/include/asm-i386/module.h
17169 --- linux-2.6.11/include/asm-i386/module.h      2005-03-02 02:37:48.000000000 -0500
17170 +++ linux-2.6.11/include/asm-i386/module.h      2005-03-09 11:56:44.000000000 -0500
17171 @@ -68,6 +68,12 @@ struct mod_arch_specific
17172  #define MODULE_STACKSIZE ""
17173  #endif
17174  
17175 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
17176 +#ifdef CONFIG_GRKERNSEC
17177 +#define MODULE_GRSEC "GRSECURITY "
17178 +#else
17179 +#define MODULE_GRSEC ""
17180 +#endif
17181 +
17182 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
17183  
17184  #endif /* _ASM_I386_MODULE_H */
17185 diff -urNp linux-2.6.11/include/asm-i386/page.h linux-2.6.11/include/asm-i386/page.h
17186 --- linux-2.6.11/include/asm-i386/page.h        2005-03-02 02:37:49.000000000 -0500
17187 +++ linux-2.6.11/include/asm-i386/page.h        2005-03-09 11:56:44.000000000 -0500
17188 @@ -9,11 +9,11 @@
17189  #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
17190  #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
17191  
17192 +#include <linux/config.h>
17193 +
17194  #ifdef __KERNEL__
17195  #ifndef __ASSEMBLY__
17196  
17197 -#include <linux/config.h>
17198 -
17199  #ifdef CONFIG_X86_USE_3DNOW
17200  
17201  #include <asm/mmx.h>
17202 @@ -127,6 +127,23 @@ extern int sysctl_legacy_va_layout;
17203  #define __PAGE_OFFSET          (0xC0000000UL)
17204  #endif
17205  
17206 +#endif /* __KERNEL__ */
17207 +
17208 +#ifdef CONFIG_PAX_KERNEXEC
17209 +#ifdef __ASSEMBLY__
17210 +#define __KERNEL_TEXT_OFFSET   (0xC0400000)
17211 +#else
17212 +#define __KERNEL_TEXT_OFFSET   (0xC0400000UL)
17213 +#endif
17214 +#else
17215 +#ifdef __ASSEMBLY__
17216 +#define __KERNEL_TEXT_OFFSET   (0)
17217 +#else
17218 +#define __KERNEL_TEXT_OFFSET   (0x0UL)
17219 +#endif
17220 +#endif
17221 +
17222 +#ifdef __KERNEL__
17223  
17224  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
17225  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
17226 @@ -148,6 +165,19 @@ extern int sysctl_legacy_va_layout;
17227         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
17228                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17229  
17230 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17231 +#ifdef CONFIG_PAX_MPROTECT
17232 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17233 +                         ((current->mm->flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
17234 +#else
17235 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
17236 +#endif
17237 +#endif
17238 +
17239 +#ifdef CONFIG_PAX_PAGEEXEC
17240 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
17241 +#endif
17242 +
17243  #endif /* __KERNEL__ */
17244  
17245  #endif /* _I386_PAGE_H */
17246 diff -urNp linux-2.6.11/include/asm-i386/pgalloc.h linux-2.6.11/include/asm-i386/pgalloc.h
17247 --- linux-2.6.11/include/asm-i386/pgalloc.h     2005-03-02 02:37:47.000000000 -0500
17248 +++ linux-2.6.11/include/asm-i386/pgalloc.h     2005-03-09 11:56:44.000000000 -0500
17249 @@ -8,7 +8,7 @@
17250  #include <linux/mm.h>          /* for struct page */
17251  
17252  #define pmd_populate_kernel(mm, pmd, pte) \
17253 -               set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
17254 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
17255  
17256  #define pmd_populate(mm, pmd, pte)                             \
17257         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
17258 diff -urNp linux-2.6.11/include/asm-i386/pgtable.h linux-2.6.11/include/asm-i386/pgtable.h
17259 --- linux-2.6.11/include/asm-i386/pgtable.h     2005-03-02 02:38:38.000000000 -0500
17260 +++ linux-2.6.11/include/asm-i386/pgtable.h     2005-03-09 11:56:44.000000000 -0500
17261 @@ -31,7 +31,6 @@
17262   */
17263  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
17264  extern unsigned long empty_zero_page[1024];
17265 -extern pgd_t swapper_pg_dir[1024];
17266  extern kmem_cache_t *pgd_cache;
17267  extern kmem_cache_t *pmd_cache;
17268  extern spinlock_t pgd_lock;
17269 @@ -42,6 +41,7 @@ void pgd_ctor(void *, kmem_cache_t *, un
17270  void pgd_dtor(void *, kmem_cache_t *, unsigned long);
17271  void pgtable_cache_init(void);
17272  void paging_init(void);
17273 +#endif /* !__ASSEMBLY__ */
17274  
17275  /*
17276   * The Linux x86 paging architecture is 'compile-time dual-mode', it
17277 @@ -56,6 +56,23 @@ void paging_init(void);
17278  # include <asm/pgtable-2level-defs.h>
17279  #endif
17280  
17281 +#ifndef __ASSEMBLY__
17282 +#ifdef CONFIG_X86_PAE
17283 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
17284 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
17285 +
17286 +#ifdef CONFIG_PAX_KERNEXEC
17287 +extern pgd_t kernexec_pg_dir[PTRS_PER_PGD];
17288 +extern pmd_t kernexec_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
17289 +#endif
17290 +#else
17291 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
17292 +
17293 +#ifdef CONFIG_PAX_KERNEXEC
17294 +extern pgd_t kernexec_pg_dir[PTRS_PER_PGD];
17295 +#endif
17296 +#endif
17297 +
17298  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
17299  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
17300  
17301 @@ -138,17 +155,26 @@ void paging_init(void);
17302  
17303  #define PAGE_SHARED_EXEC \
17304         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
17305 -#define PAGE_COPY_NOEXEC \
17306 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
17307  #define PAGE_COPY_EXEC \
17308         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
17309 -#define PAGE_COPY \
17310 -       PAGE_COPY_NOEXEC
17311  #define PAGE_READONLY \
17312         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
17313  #define PAGE_READONLY_EXEC \
17314         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
17315  
17316 +#ifdef CONFIG_PAX_PAGEEXEC
17317 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
17318 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
17319 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
17320 +#else
17321 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17322 +# define PAGE_COPY_NOEXEC \
17323 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
17324 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17325 +#endif
17326 +
17327 +#define PAGE_COPY \
17328 +       PAGE_COPY_NOEXEC
17329  #define _PAGE_KERNEL \
17330         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
17331  #define _PAGE_KERNEL_EXEC \
17332 @@ -173,18 +199,18 @@ extern unsigned long long __PAGE_KERNEL,
17333   * This is the closest we can get..
17334   */
17335  #define __P000 PAGE_NONE
17336 -#define __P001 PAGE_READONLY
17337 -#define __P010 PAGE_COPY
17338 -#define __P011 PAGE_COPY
17339 +#define __P001 PAGE_READONLY_NOEXEC
17340 +#define __P010 PAGE_COPY_NOEXEC
17341 +#define __P011 PAGE_COPY_NOEXEC
17342  #define __P100 PAGE_READONLY_EXEC
17343  #define __P101 PAGE_READONLY_EXEC
17344  #define __P110 PAGE_COPY_EXEC
17345  #define __P111 PAGE_COPY_EXEC
17346  
17347  #define __S000 PAGE_NONE
17348 -#define __S001 PAGE_READONLY
17349 -#define __S010 PAGE_SHARED
17350 -#define __S011 PAGE_SHARED
17351 +#define __S001 PAGE_READONLY_NOEXEC
17352 +#define __S010 PAGE_SHARED_NOEXEC
17353 +#define __S011 PAGE_SHARED_NOEXEC
17354  #define __S100 PAGE_READONLY_EXEC
17355  #define __S101 PAGE_READONLY_EXEC
17356  #define __S110 PAGE_SHARED_EXEC
17357 @@ -396,6 +422,9 @@ extern void noexec_setup(const char *str
17358  
17359  #endif /* !__ASSEMBLY__ */
17360  
17361 +#define HAVE_ARCH_UNMAPPED_AREA
17362 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
17363 +
17364  #ifndef CONFIG_DISCONTIGMEM
17365  #define kern_addr_valid(addr)  (1)
17366  #endif /* !CONFIG_DISCONTIGMEM */
17367 diff -urNp linux-2.6.11/include/asm-i386/processor.h linux-2.6.11/include/asm-i386/processor.h
17368 --- linux-2.6.11/include/asm-i386/processor.h   2005-03-02 02:37:47.000000000 -0500
17369 +++ linux-2.6.11/include/asm-i386/processor.h   2005-03-09 11:56:44.000000000 -0500
17370 @@ -19,7 +19,6 @@
17371  #include <linux/cache.h>
17372  #include <linux/config.h>
17373  #include <linux/threads.h>
17374 -#include <asm/percpu.h>
17375  
17376  /* flag for disabling the tsc */
17377  extern int tsc_disable;
17378 @@ -29,7 +28,7 @@ struct desc_struct {
17379  };
17380  
17381  #define desc_empty(desc) \
17382 -               (!((desc)->a + (desc)->b))
17383 +               (!((desc)->a | (desc)->b))
17384  
17385  #define desc_equal(desc1, desc2) \
17386                 (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
17387 @@ -87,7 +86,10 @@ struct cpuinfo_x86 {
17388  extern struct cpuinfo_x86 boot_cpu_data;
17389  extern struct cpuinfo_x86 new_cpu_data;
17390  extern struct tss_struct doublefault_tss;
17391 +#if 0
17392  DECLARE_PER_CPU(struct tss_struct, init_tss);
17393 +#endif
17394 +extern struct tss_struct init_tss[NR_CPUS];
17395  
17396  #ifdef CONFIG_SMP
17397  extern struct cpuinfo_x86 cpu_data[];
17398 @@ -301,10 +303,23 @@ extern int bootloader_type;
17399   */
17400  #define TASK_SIZE      (PAGE_OFFSET)
17401  
17402 +#ifdef CONFIG_PAX_SEGMEXEC
17403 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
17404 +#endif
17405 +
17406  /* This decides where the kernel will search for a free chunk of vm
17407   * space during mmap's.
17408   */
17409 +
17410 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
17411 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->flags & MF_PAX_PAGEEXEC)? 0x00110000UL : (current->mm->flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
17412 +#elif defined(CONFIG_PAX_PAGEEXEC)
17413 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->flags & MF_PAX_PAGEEXEC)? 0x00110000UL : TASK_SIZE/3))
17414 +#elif defined(CONFIG_PAX_SEGMEXEC)
17415 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
17416 +#else
17417  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
17418 +#endif
17419  
17420  #define HAVE_ARCH_PICK_MMAP_LAYOUT
17421  
17422 @@ -509,16 +524,12 @@ void show_trace(struct task_struct *task
17423  unsigned long get_wchan(struct task_struct *p);
17424  
17425  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
17426 -#define KSTK_TOP(info)                                                 \
17427 -({                                                                     \
17428 -       unsigned long *__ptr = (unsigned long *)(info);                 \
17429 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
17430 -})
17431 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
17432  
17433  #define task_pt_regs(task)                                             \
17434  ({                                                                     \
17435         struct pt_regs *__regs__;                                       \
17436 -       __regs__ = (struct pt_regs *)KSTK_TOP((task)->thread_info);     \
17437 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
17438         __regs__ - 1;                                                   \
17439  })
17440  
17441 @@ -642,7 +653,7 @@ static inline void rep_nop(void)
17442  extern inline void prefetch(const void *x)
17443  {
17444         alternative_input(ASM_NOP4,
17445 -                         "prefetchnta (%1)",
17446 +                         "prefetchnta (%2)",
17447                           X86_FEATURE_XMM,
17448                           "r" (x));
17449  }
17450 @@ -656,7 +667,7 @@ extern inline void prefetch(const void *
17451  extern inline void prefetchw(const void *x)
17452  {
17453         alternative_input(ASM_NOP4,
17454 -                         "prefetchw (%1)",
17455 +                         "prefetchw (%2)",
17456                           X86_FEATURE_3DNOW,
17457                           "r" (x));
17458  }
17459 diff -urNp linux-2.6.11/include/asm-i386/system.h linux-2.6.11/include/asm-i386/system.h
17460 --- linux-2.6.11/include/asm-i386/system.h      2005-03-02 02:37:30.000000000 -0500
17461 +++ linux-2.6.11/include/asm-i386/system.h      2005-03-09 11:56:44.000000000 -0500
17462 @@ -5,6 +5,7 @@
17463  #include <linux/kernel.h>
17464  #include <asm/segment.h>
17465  #include <asm/cpufeature.h>
17466 +#include <asm/page.h>
17467  #include <linux/bitops.h> /* for LOCK_PREFIX */
17468  
17469  #ifdef __KERNEL__
17470 @@ -301,7 +302,7 @@ struct alt_instr { 
17471         asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
17472                       ".section .altinstructions,\"a\"\n"            \
17473                       "  .align 4\n"                                   \
17474 -                     "  .long 661b\n"            /* label */          \
17475 +                     "  .long 661b + %c1\n"       /* label */          \
17476                       "  .long 663f\n"            /* new instruction */         \
17477                       "  .byte %c0\n"             /* feature bit */    \
17478                       "  .byte 662b-661b\n"       /* sourcelen */      \
17479 @@ -309,7 +310,7 @@ struct alt_instr { 
17480                       ".previous\n"                                             \
17481                       ".section .altinstr_replacement,\"ax\"\n"                 \
17482                       "663:\n\t" newinstr "\n664:\n"   /* replacement */    \
17483 -                     ".previous" :: "i" (feature) : "memory")  
17484 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET) : "memory")  
17485  
17486  /*
17487   * Alternative inline assembly with input.
17488 @@ -325,7 +326,7 @@ struct alt_instr { 
17489         asm volatile ("661:\n\t" oldinstr "\n662:\n"                            \
17490                       ".section .altinstructions,\"a\"\n"                       \
17491                       "  .align 4\n"                                            \
17492 -                     "  .long 661b\n"            /* label */                   \
17493 +                     "  .long 661b + %c1\n"      /* label */                   \
17494                       "  .long 663f\n"            /* new instruction */         \
17495                       "  .byte %c0\n"             /* feature bit */             \
17496                       "  .byte 662b-661b\n"       /* sourcelen */               \
17497 @@ -333,7 +334,7 @@ struct alt_instr { 
17498                       ".previous\n"                                             \
17499                       ".section .altinstr_replacement,\"ax\"\n"                 \
17500                       "663:\n\t" newinstr "\n664:\n"   /* replacement */        \
17501 -                     ".previous" :: "i" (feature), ##input)
17502 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET), ##input)
17503  
17504  /*
17505   * Force strict CPU ordering.
17506 diff -urNp linux-2.6.11/include/asm-ia64/elf.h linux-2.6.11/include/asm-ia64/elf.h
17507 --- linux-2.6.11/include/asm-ia64/elf.h 2005-03-02 02:38:13.000000000 -0500
17508 +++ linux-2.6.11/include/asm-ia64/elf.h 2005-03-09 11:56:44.000000000 -0500
17509 @@ -162,6 +162,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
17510  typedef struct ia64_fpreg elf_fpreg_t;
17511  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
17512  
17513 +#ifdef CONFIG_PAX_ASLR
17514 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
17515 +
17516 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17517 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
17518 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17519 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
17520 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17521 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
17522 +#endif
17523  
17524  
17525  struct pt_regs;        /* forward declaration... */
17526 diff -urNp linux-2.6.11/include/asm-ia64/mman.h linux-2.6.11/include/asm-ia64/mman.h
17527 --- linux-2.6.11/include/asm-ia64/mman.h        2005-03-02 02:38:09.000000000 -0500
17528 +++ linux-2.6.11/include/asm-ia64/mman.h        2005-03-09 11:56:44.000000000 -0500
17529 @@ -31,6 +31,10 @@
17530  #define MAP_POPULATE   0x08000         /* populate (prefault) pagetables */
17531  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
17532  
17533 +#ifdef CONFIG_PAX_RANDEXEC
17534 +#define MAP_MIRROR     0x40000
17535 +#endif
17536 +
17537  #define MS_ASYNC       1               /* sync memory asynchronously */
17538  #define MS_INVALIDATE  2               /* invalidate the caches */
17539  #define MS_SYNC                4               /* synchronous memory sync */
17540 diff -urNp linux-2.6.11/include/asm-ia64/page.h linux-2.6.11/include/asm-ia64/page.h
17541 --- linux-2.6.11/include/asm-ia64/page.h        2005-03-02 02:37:48.000000000 -0500
17542 +++ linux-2.6.11/include/asm-ia64/page.h        2005-03-09 11:56:44.000000000 -0500
17543 @@ -204,4 +204,13 @@ get_order (unsigned long size)
17544                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
17545                                           ? VM_EXEC : 0))
17546  
17547 +#ifdef CONFIG_PAX_PAGEEXEC
17548 +#ifdef CONFIG_PAX_MPROTECT
17549 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17550 +                         ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17551 +#else
17552 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17553 +#endif
17554 +#endif
17555 +
17556  #endif /* _ASM_IA64_PAGE_H */
17557 diff -urNp linux-2.6.11/include/asm-ia64/pgtable.h linux-2.6.11/include/asm-ia64/pgtable.h
17558 --- linux-2.6.11/include/asm-ia64/pgtable.h     2005-03-02 02:37:53.000000000 -0500
17559 +++ linux-2.6.11/include/asm-ia64/pgtable.h     2005-03-09 11:56:44.000000000 -0500
17560 @@ -121,6 +121,17 @@
17561  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17562  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17563  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
17564 +
17565 +#ifdef CONFIG_PAX_PAGEEXEC
17566 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
17567 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17568 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17569 +#else
17570 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17571 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17572 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17573 +#endif
17574 +
17575  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
17576  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
17577  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
17578 diff -urNp linux-2.6.11/include/asm-ia64/processor.h linux-2.6.11/include/asm-ia64/processor.h
17579 --- linux-2.6.11/include/asm-ia64/processor.h   2005-03-02 02:37:58.000000000 -0500
17580 +++ linux-2.6.11/include/asm-ia64/processor.h   2005-03-09 11:56:44.000000000 -0500
17581 @@ -291,7 +291,7 @@ struct thread_struct {
17582         .on_ustack =    0,                                      \
17583         .ksp =          0,                                      \
17584         .map_base =     DEFAULT_MAP_BASE,                       \
17585 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
17586 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
17587         .task_size =    DEFAULT_TASK_SIZE,                      \
17588         .last_fph_cpu =  -1,                                    \
17589         INIT_THREAD_IA32                                        \
17590 diff -urNp linux-2.6.11/include/asm-ia64/ustack.h linux-2.6.11/include/asm-ia64/ustack.h
17591 --- linux-2.6.11/include/asm-ia64/ustack.h      2005-03-02 02:38:32.000000000 -0500
17592 +++ linux-2.6.11/include/asm-ia64/ustack.h      2005-03-09 11:56:44.000000000 -0500
17593 @@ -11,6 +11,6 @@
17594  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
17595  /* Make a default stack size of 2GB */
17596  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
17597 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
17598 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
17599  
17600  #endif /* _ASM_IA64_USTACK_H */
17601 diff -urNp linux-2.6.11/include/asm-mips/a.out.h linux-2.6.11/include/asm-mips/a.out.h
17602 --- linux-2.6.11/include/asm-mips/a.out.h       2005-03-02 02:38:00.000000000 -0500
17603 +++ linux-2.6.11/include/asm-mips/a.out.h       2005-03-09 11:56:44.000000000 -0500
17604 @@ -36,10 +36,10 @@ struct exec
17605  #ifdef __KERNEL__
17606  
17607  #ifdef CONFIG_MIPS32
17608 -#define STACK_TOP      TASK_SIZE
17609 +#define __STACK_TOP    TASK_SIZE
17610  #endif
17611  #ifdef CONFIG_MIPS64
17612 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
17613 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
17614  #endif
17615  
17616  #endif
17617 diff -urNp linux-2.6.11/include/asm-mips/elf.h linux-2.6.11/include/asm-mips/elf.h
17618 --- linux-2.6.11/include/asm-mips/elf.h 2005-03-02 02:38:07.000000000 -0500
17619 +++ linux-2.6.11/include/asm-mips/elf.h 2005-03-09 11:56:44.000000000 -0500
17620 @@ -279,4 +279,15 @@ extern int dump_task_fpu(struct task_str
17621  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
17622  #endif
17623  
17624 +#ifdef CONFIG_PAX_ASLR
17625 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
17626 +
17627 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17628 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
17629 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17630 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
17631 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17632 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
17633 +#endif
17634 +
17635  #endif /* _ASM_ELF_H */
17636 diff -urNp linux-2.6.11/include/asm-mips/page.h linux-2.6.11/include/asm-mips/page.h
17637 --- linux-2.6.11/include/asm-mips/page.h        2005-03-02 02:38:01.000000000 -0500
17638 +++ linux-2.6.11/include/asm-mips/page.h        2005-03-09 11:56:44.000000000 -0500
17639 @@ -139,6 +139,15 @@ static __inline__ int get_order(unsigned
17640  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17641                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17642  
17643 +#ifdef CONFIG_PAX_PAGEEXEC
17644 +#ifdef CONFIG_PAX_MPROTECT
17645 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17646 +                         ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17647 +#else
17648 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17649 +#endif
17650 +#endif
17651 +
17652  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
17653  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
17654  
17655 diff -urNp linux-2.6.11/include/asm-parisc/a.out.h linux-2.6.11/include/asm-parisc/a.out.h
17656 --- linux-2.6.11/include/asm-parisc/a.out.h     2005-03-02 02:38:26.000000000 -0500
17657 +++ linux-2.6.11/include/asm-parisc/a.out.h     2005-03-09 11:56:44.000000000 -0500
17658 @@ -22,7 +22,7 @@ struct exec
17659  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
17660   * prumpf */
17661  
17662 -#define STACK_TOP      TASK_SIZE
17663 +#define __STACK_TOP    TASK_SIZE
17664  
17665  #endif
17666  
17667 diff -urNp linux-2.6.11/include/asm-parisc/elf.h linux-2.6.11/include/asm-parisc/elf.h
17668 --- linux-2.6.11/include/asm-parisc/elf.h       2005-03-02 02:38:17.000000000 -0500
17669 +++ linux-2.6.11/include/asm-parisc/elf.h       2005-03-09 11:56:44.000000000 -0500
17670 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
17671  
17672  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
17673  
17674 +#ifdef CONFIG_PAX_ASLR
17675 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
17676 +
17677 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17678 +#define PAX_DELTA_MMAP_LEN(tsk)                16
17679 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT 
17680 +#define PAX_DELTA_EXEC_LEN(tsk)                16
17681 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17682 +#define PAX_DELTA_STACK_LEN(tsk)       16
17683 +#endif
17684 +
17685  /* This yields a mask that user programs can use to figure out what
17686     instruction set this CPU supports.  This could be done in user space,
17687     but it's not easy, and we've already done it here.  */
17688 diff -urNp linux-2.6.11/include/asm-parisc/mman.h linux-2.6.11/include/asm-parisc/mman.h
17689 --- linux-2.6.11/include/asm-parisc/mman.h      2005-03-02 02:38:12.000000000 -0500
17690 +++ linux-2.6.11/include/asm-parisc/mman.h      2005-03-09 11:56:44.000000000 -0500
17691 @@ -23,6 +23,10 @@
17692  #define MAP_POPULATE   0x10000         /* populate (prefault) pagetables */
17693  #define MAP_NONBLOCK   0x20000         /* do not block on IO */
17694  
17695 +#ifdef CONFIG_PAX_RANDEXEC
17696 +#define MAP_MIRROR     0x0400
17697 +#endif
17698 +
17699  #define MS_SYNC                1               /* synchronous memory sync */
17700  #define MS_ASYNC       2               /* sync memory asynchronously */
17701  #define MS_INVALIDATE  4               /* invalidate the caches */
17702 diff -urNp linux-2.6.11/include/asm-parisc/page.h linux-2.6.11/include/asm-parisc/page.h
17703 --- linux-2.6.11/include/asm-parisc/page.h      2005-03-02 02:37:50.000000000 -0500
17704 +++ linux-2.6.11/include/asm-parisc/page.h      2005-03-09 11:56:44.000000000 -0500
17705 @@ -157,6 +157,15 @@ extern int npmem_ranges;
17706  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17707                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17708  
17709 +#ifdef CONFIG_PAX_PAGEEXEC
17710 +#ifdef CONFIG_PAX_MPROTECT
17711 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17712 +                         ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17713 +#else
17714 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17715 +#endif
17716 +#endif
17717 +
17718  #endif /* __KERNEL__ */
17719  
17720  #endif /* _PARISC_PAGE_H */
17721 diff -urNp linux-2.6.11/include/asm-parisc/pgtable.h linux-2.6.11/include/asm-parisc/pgtable.h
17722 --- linux-2.6.11/include/asm-parisc/pgtable.h   2005-03-02 02:38:25.000000000 -0500
17723 +++ linux-2.6.11/include/asm-parisc/pgtable.h   2005-03-09 11:56:44.000000000 -0500
17724 @@ -210,6 +210,17 @@ extern  void *vmalloc_start;
17725  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
17726  #define PAGE_COPY       PAGE_EXECREAD
17727  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
17728 +
17729 +#ifdef CONFIG_PAX_PAGEEXEC
17730 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
17731 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
17732 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
17733 +#else
17734 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17735 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17736 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17737 +#endif
17738 +
17739  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
17740  #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
17741  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
17742 diff -urNp linux-2.6.11/include/asm-ppc/a.out.h linux-2.6.11/include/asm-ppc/a.out.h
17743 --- linux-2.6.11/include/asm-ppc/a.out.h        2005-03-02 02:38:09.000000000 -0500
17744 +++ linux-2.6.11/include/asm-ppc/a.out.h        2005-03-09 11:56:44.000000000 -0500
17745 @@ -2,7 +2,7 @@
17746  #define __PPC_A_OUT_H__
17747  
17748  /* grabbed from the intel stuff  */
17749 -#define STACK_TOP TASK_SIZE
17750 +#define __STACK_TOP TASK_SIZE
17751  
17752  
17753  struct exec
17754 diff -urNp linux-2.6.11/include/asm-ppc/elf.h linux-2.6.11/include/asm-ppc/elf.h
17755 --- linux-2.6.11/include/asm-ppc/elf.h  2005-03-02 02:37:30.000000000 -0500
17756 +++ linux-2.6.11/include/asm-ppc/elf.h  2005-03-09 11:56:44.000000000 -0500
17757 @@ -90,6 +90,17 @@ struct task_struct;
17758  
17759  #define ELF_ET_DYN_BASE         (0x08000000)
17760  
17761 +#ifdef CONFIG_PAX_ASLR
17762 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
17763 +
17764 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17765 +#define PAX_DELTA_MMAP_LEN(tsk)                15
17766 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17767 +#define PAX_DELTA_EXEC_LEN(tsk)                15
17768 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17769 +#define PAX_DELTA_STACK_LEN(tsk)       15
17770 +#endif
17771 +
17772  #define USE_ELF_CORE_DUMP
17773  #define ELF_EXEC_PAGESIZE      4096
17774  
17775 diff -urNp linux-2.6.11/include/asm-ppc/mman.h linux-2.6.11/include/asm-ppc/mman.h
17776 --- linux-2.6.11/include/asm-ppc/mman.h 2005-03-02 02:38:34.000000000 -0500
17777 +++ linux-2.6.11/include/asm-ppc/mman.h 2005-03-09 11:56:44.000000000 -0500
17778 @@ -24,6 +24,10 @@
17779  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
17780  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
17781  
17782 +#ifdef CONFIG_PAX_RANDEXEC
17783 +#define MAP_MIRROR     0x0200
17784 +#endif
17785 +
17786  #define MS_ASYNC       1               /* sync memory asynchronously */
17787  #define MS_INVALIDATE  2               /* invalidate the caches */
17788  #define MS_SYNC                4               /* synchronous memory sync */
17789 diff -urNp linux-2.6.11/include/asm-ppc/page.h linux-2.6.11/include/asm-ppc/page.h
17790 --- linux-2.6.11/include/asm-ppc/page.h 2005-03-02 02:37:51.000000000 -0500
17791 +++ linux-2.6.11/include/asm-ppc/page.h 2005-03-09 11:56:44.000000000 -0500
17792 @@ -163,5 +163,14 @@ extern __inline__ int get_order(unsigned
17793  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17794                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17795  
17796 +#ifdef CONFIG_PAX_PAGEEXEC
17797 +#ifdef CONFIG_PAX_MPROTECT
17798 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17799 +                         ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17800 +#else
17801 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17802 +#endif
17803 +#endif
17804 +
17805  #endif /* __KERNEL__ */
17806  #endif /* _PPC_PAGE_H */
17807 diff -urNp linux-2.6.11/include/asm-ppc/pgtable.h linux-2.6.11/include/asm-ppc/pgtable.h
17808 --- linux-2.6.11/include/asm-ppc/pgtable.h      2005-03-02 02:38:37.000000000 -0500
17809 +++ linux-2.6.11/include/asm-ppc/pgtable.h      2005-03-09 11:56:44.000000000 -0500
17810 @@ -389,11 +389,21 @@ extern unsigned long ioremap_bot, iorema
17811  
17812  #define PAGE_NONE      __pgprot(_PAGE_BASE)
17813  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
17814 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17815 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
17816  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
17817 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
17818 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
17819  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
17820 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17821 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
17822 +
17823 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
17824 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
17825 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17826 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17827 +#else
17828 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17829 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17830 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17831 +#endif
17832  
17833  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
17834  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
17835 @@ -405,21 +415,21 @@ extern unsigned long ioremap_bot, iorema
17836   * This is the closest we can get..
17837   */
17838  #define __P000 PAGE_NONE
17839 -#define __P001 PAGE_READONLY_X
17840 -#define __P010 PAGE_COPY
17841 -#define __P011 PAGE_COPY_X
17842 -#define __P100 PAGE_READONLY
17843 +#define __P001 PAGE_READONLY_NOEXEC
17844 +#define __P010 PAGE_COPY_NOEXEC
17845 +#define __P011 PAGE_COPY_NOEXEC
17846 +#define __P100 PAGE_READONLY_X
17847  #define __P101 PAGE_READONLY_X
17848 -#define __P110 PAGE_COPY
17849 +#define __P110 PAGE_COPY_X
17850  #define __P111 PAGE_COPY_X
17851  
17852  #define __S000 PAGE_NONE
17853 -#define __S001 PAGE_READONLY_X
17854 -#define __S010 PAGE_SHARED
17855 -#define __S011 PAGE_SHARED_X
17856 -#define __S100 PAGE_READONLY
17857 +#define __S001 PAGE_READONLY_NOEXEC
17858 +#define __S010 PAGE_SHARED_NOEXEC
17859 +#define __S011 PAGE_SHARED_NOEXEC
17860 +#define __S100 PAGE_READONLY_X
17861  #define __S101 PAGE_READONLY_X
17862 -#define __S110 PAGE_SHARED
17863 +#define __S110 PAGE_SHARED_X
17864  #define __S111 PAGE_SHARED_X
17865  
17866  #ifndef __ASSEMBLY__
17867 diff -urNp linux-2.6.11/include/asm-ppc64/a.out.h linux-2.6.11/include/asm-ppc64/a.out.h
17868 --- linux-2.6.11/include/asm-ppc64/a.out.h      2005-03-02 02:37:31.000000000 -0500
17869 +++ linux-2.6.11/include/asm-ppc64/a.out.h      2005-03-09 11:56:44.000000000 -0500
17870 @@ -35,7 +35,7 @@ struct exec
17871  /* Give 32-bit user space a full 4G address space to live in. */
17872  #define STACK_TOP_USER32 (TASK_SIZE_USER32)
17873  
17874 -#define STACK_TOP ((test_thread_flag(TIF_32BIT) || \
17875 +#define __STACK_TOP ((test_thread_flag(TIF_32BIT) || \
17876                 (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \
17877                 STACK_TOP_USER32 : STACK_TOP_USER64)
17878  
17879 diff -urNp linux-2.6.11/include/asm-ppc64/elf.h linux-2.6.11/include/asm-ppc64/elf.h
17880 --- linux-2.6.11/include/asm-ppc64/elf.h        2005-03-02 02:38:17.000000000 -0500
17881 +++ linux-2.6.11/include/asm-ppc64/elf.h        2005-03-09 11:56:44.000000000 -0500
17882 @@ -154,6 +154,17 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
17883  
17884  #define ELF_ET_DYN_BASE         (0x08000000)
17885  
17886 +#ifdef CONFIG_PAX_ASLR
17887 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
17888 +
17889 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17890 +#define PAX_DELTA_MMAP_LEN(tsk)                ((test_thread_flag(TIF_32BIT) || (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? 16 : 24)
17891 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17892 +#define PAX_DELTA_EXEC_LEN(tsk)                ((test_thread_flag(TIF_32BIT) || (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? 16 : 24)
17893 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17894 +#define PAX_DELTA_STACK_LEN(tsk)       ((test_thread_flag(TIF_32BIT) || (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? 16 : 24)
17895 +#endif
17896 +
17897  #ifdef __KERNEL__
17898  
17899  /* Common routine for both 32-bit and 64-bit processes */
17900 diff -urNp linux-2.6.11/include/asm-ppc64/mman.h linux-2.6.11/include/asm-ppc64/mman.h
17901 --- linux-2.6.11/include/asm-ppc64/mman.h       2005-03-02 02:38:07.000000000 -0500
17902 +++ linux-2.6.11/include/asm-ppc64/mman.h       2005-03-09 11:56:44.000000000 -0500
17903 @@ -29,6 +29,10 @@
17904  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
17905  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
17906  
17907 +#ifdef CONFIG_PAX_RANDEXEC
17908 +#define MAP_MIRROR     0x0200
17909 +#endif
17910 +
17911  #define MS_ASYNC       1               /* sync memory asynchronously */
17912  #define MS_INVALIDATE  2               /* invalidate the caches */
17913  #define MS_SYNC                4               /* synchronous memory sync */
17914 diff -urNp linux-2.6.11/include/asm-ppc64/page.h linux-2.6.11/include/asm-ppc64/page.h
17915 --- linux-2.6.11/include/asm-ppc64/page.h       2005-03-02 02:37:30.000000000 -0500
17916 +++ linux-2.6.11/include/asm-ppc64/page.h       2005-03-09 11:56:44.000000000 -0500
17917 @@ -235,5 +235,14 @@ extern u64 ppc64_pft_size;         /* Log 2 of 
17918  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17919                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17920  
17921 +#ifdef CONFIG_PAX_PAGEEXEC
17922 +#ifdef CONFIG_PAX_MPROTECT
17923 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17924 +                        ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17925 +#else
17926 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17927 +#endif
17928 +#endif
17929 +
17930  #endif /* __KERNEL__ */
17931  #endif /* _PPC64_PAGE_H */
17932 diff -urNp linux-2.6.11/include/asm-ppc64/pgtable.h linux-2.6.11/include/asm-ppc64/pgtable.h
17933 --- linux-2.6.11/include/asm-ppc64/pgtable.h    2005-03-02 02:38:26.000000000 -0500
17934 +++ linux-2.6.11/include/asm-ppc64/pgtable.h    2005-03-09 11:56:44.000000000 -0500
17935 @@ -115,6 +115,17 @@
17936  #define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17937  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
17938  #define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17939 +
17940 +#ifdef CONFIG_PAX_PAGEEXEC
17941 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_GUARDED)
17942 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17943 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17944 +#else
17945 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17946 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17947 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17948 +#endif
17949 +
17950  #define PAGE_KERNEL    __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
17951  #define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
17952                                _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
17953 @@ -126,21 +137,21 @@
17954   * This is the closest we can get..
17955   */
17956  #define __P000 PAGE_NONE
17957 -#define __P001 PAGE_READONLY_X
17958 -#define __P010 PAGE_COPY
17959 -#define __P011 PAGE_COPY_X
17960 -#define __P100 PAGE_READONLY
17961 +#define __P001 PAGE_READONLY_NOEXEC
17962 +#define __P010 PAGE_COPY_NOEXEC
17963 +#define __P011 PAGE_COPY_NOEXEC
17964 +#define __P100 PAGE_READONLY_X
17965  #define __P101 PAGE_READONLY_X
17966 -#define __P110 PAGE_COPY
17967 +#define __P110 PAGE_COPY_X
17968  #define __P111 PAGE_COPY_X
17969  
17970  #define __S000 PAGE_NONE
17971 -#define __S001 PAGE_READONLY_X
17972 -#define __S010 PAGE_SHARED
17973 -#define __S011 PAGE_SHARED_X
17974 -#define __S100 PAGE_READONLY
17975 +#define __S001 PAGE_READONLY_NOEXEC
17976 +#define __S010 PAGE_SHARED_NOEXEC
17977 +#define __S011 PAGE_SHARED_NOEXEC
17978 +#define __S100 PAGE_READONLY_X
17979  #define __S101 PAGE_READONLY_X
17980 -#define __S110 PAGE_SHARED
17981 +#define __S110 PAGE_SHARED_X
17982  #define __S111 PAGE_SHARED_X
17983  
17984  #ifndef __ASSEMBLY__
17985 diff -urNp linux-2.6.11/include/asm-sparc/a.out.h linux-2.6.11/include/asm-sparc/a.out.h
17986 --- linux-2.6.11/include/asm-sparc/a.out.h      2005-03-02 02:37:47.000000000 -0500
17987 +++ linux-2.6.11/include/asm-sparc/a.out.h      2005-03-09 11:56:44.000000000 -0500
17988 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
17989  
17990  #include <asm/page.h>
17991  
17992 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
17993 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
17994  
17995  #endif /* __KERNEL__ */
17996  
17997 diff -urNp linux-2.6.11/include/asm-sparc/elf.h linux-2.6.11/include/asm-sparc/elf.h
17998 --- linux-2.6.11/include/asm-sparc/elf.h        2005-03-02 02:38:18.000000000 -0500
17999 +++ linux-2.6.11/include/asm-sparc/elf.h        2005-03-09 11:56:44.000000000 -0500
18000 @@ -145,6 +145,17 @@ typedef struct {
18001  
18002  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
18003  
18004 +#ifdef CONFIG_PAX_ASLR
18005 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
18006 +
18007 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18008 +#define PAX_DELTA_MMAP_LEN(tsk)                16
18009 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18010 +#define PAX_DELTA_EXEC_LEN(tsk)                16
18011 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18012 +#define PAX_DELTA_STACK_LEN(tsk)       16
18013 +#endif
18014 +
18015  /* This yields a mask that user programs can use to figure out what
18016     instruction set this cpu supports.  This can NOT be done in userspace
18017     on Sparc.  */
18018 diff -urNp linux-2.6.11/include/asm-sparc/mman.h linux-2.6.11/include/asm-sparc/mman.h
18019 --- linux-2.6.11/include/asm-sparc/mman.h       2005-03-02 02:38:26.000000000 -0500
18020 +++ linux-2.6.11/include/asm-sparc/mman.h       2005-03-09 11:56:44.000000000 -0500
18021 @@ -27,6 +27,10 @@
18022  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
18023  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
18024  
18025 +#ifdef CONFIG_PAX_RANDEXEC
18026 +#define MAP_MIRROR     0x0400
18027 +#endif
18028 +
18029  #define MS_ASYNC       1               /* sync memory asynchronously */
18030  #define MS_INVALIDATE  2               /* invalidate the caches */
18031  #define MS_SYNC                4               /* synchronous memory sync */
18032 diff -urNp linux-2.6.11/include/asm-sparc/page.h linux-2.6.11/include/asm-sparc/page.h
18033 --- linux-2.6.11/include/asm-sparc/page.h       2005-03-02 02:37:51.000000000 -0500
18034 +++ linux-2.6.11/include/asm-sparc/page.h       2005-03-09 11:56:44.000000000 -0500
18035 @@ -176,6 +176,15 @@ extern unsigned long pfn_base;
18036  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18037                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18038  
18039 +#ifdef CONFIG_PAX_PAGEEXEC
18040 +#ifdef CONFIG_PAX_MPROTECT
18041 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18042 +                        ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18043 +#else
18044 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18045 +#endif
18046 +#endif
18047 +
18048  #endif /* __KERNEL__ */
18049  
18050  #endif /* _SPARC_PAGE_H */
18051 diff -urNp linux-2.6.11/include/asm-sparc/pgtable.h linux-2.6.11/include/asm-sparc/pgtable.h
18052 --- linux-2.6.11/include/asm-sparc/pgtable.h    2005-03-02 02:38:10.000000000 -0500
18053 +++ linux-2.6.11/include/asm-sparc/pgtable.h    2005-03-09 11:56:44.000000000 -0500
18054 @@ -50,6 +50,13 @@ BTFIXUPDEF_INT(page_none)
18055  BTFIXUPDEF_INT(page_shared)
18056  BTFIXUPDEF_INT(page_copy)
18057  BTFIXUPDEF_INT(page_readonly)
18058 +
18059 +#ifdef CONFIG_PAX_PAGEEXEC
18060 +BTFIXUPDEF_INT(page_shared_noexec)
18061 +BTFIXUPDEF_INT(page_copy_noexec)
18062 +BTFIXUPDEF_INT(page_readonly_noexec)
18063 +#endif
18064 +
18065  BTFIXUPDEF_INT(page_kernel)
18066  
18067  #define PMD_SHIFT              SUN4C_PMD_SHIFT
18068 @@ -71,6 +78,16 @@ BTFIXUPDEF_INT(page_kernel)
18069  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
18070  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
18071  
18072 +#ifdef CONFIG_PAX_PAGEEXEC
18073 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
18074 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
18075 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
18076 +#else
18077 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18078 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18079 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18080 +#endif
18081 +
18082  extern unsigned long page_kernel;
18083  
18084  #ifdef MODULE
18085 diff -urNp linux-2.6.11/include/asm-sparc/pgtsrmmu.h linux-2.6.11/include/asm-sparc/pgtsrmmu.h
18086 --- linux-2.6.11/include/asm-sparc/pgtsrmmu.h   2005-03-02 02:37:54.000000000 -0500
18087 +++ linux-2.6.11/include/asm-sparc/pgtsrmmu.h   2005-03-09 11:56:44.000000000 -0500
18088 @@ -115,6 +115,16 @@
18089                                     SRMMU_EXEC | SRMMU_REF)
18090  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18091                                     SRMMU_EXEC | SRMMU_REF)
18092 +
18093 +#ifdef CONFIG_PAX_PAGEEXEC
18094 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18095 +                                          SRMMU_WRITE | SRMMU_REF)
18096 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18097 +                                          SRMMU_REF)
18098 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18099 +                                          SRMMU_REF)
18100 +#endif
18101 +
18102  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
18103                                     SRMMU_DIRTY | SRMMU_REF)
18104  
18105 diff -urNp linux-2.6.11/include/asm-sparc/uaccess.h linux-2.6.11/include/asm-sparc/uaccess.h
18106 --- linux-2.6.11/include/asm-sparc/uaccess.h    2005-03-02 02:38:25.000000000 -0500
18107 +++ linux-2.6.11/include/asm-sparc/uaccess.h    2005-03-09 11:56:44.000000000 -0500
18108 @@ -41,7 +41,7 @@
18109   * No one can read/write anything from userland in the kernel space by setting
18110   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
18111   */
18112 -#define __user_ok(addr,size) ((addr) < STACK_TOP)
18113 +#define __user_ok(addr,size) ((addr) < __STACK_TOP)
18114  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
18115  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
18116  #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
18117 diff -urNp linux-2.6.11/include/asm-sparc64/a.out.h linux-2.6.11/include/asm-sparc64/a.out.h
18118 --- linux-2.6.11/include/asm-sparc64/a.out.h    2005-03-02 02:38:13.000000000 -0500
18119 +++ linux-2.6.11/include/asm-sparc64/a.out.h    2005-03-09 11:56:44.000000000 -0500
18120 @@ -95,7 +95,7 @@ struct relocation_info /* used when head
18121  
18122  #ifdef __KERNEL__
18123  
18124 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
18125 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
18126  
18127  #endif
18128  
18129 diff -urNp linux-2.6.11/include/asm-sparc64/elf.h linux-2.6.11/include/asm-sparc64/elf.h
18130 --- linux-2.6.11/include/asm-sparc64/elf.h      2005-03-02 02:37:54.000000000 -0500
18131 +++ linux-2.6.11/include/asm-sparc64/elf.h      2005-03-09 11:56:44.000000000 -0500
18132 @@ -140,6 +140,16 @@ typedef struct {
18133  #define ELF_ET_DYN_BASE         0x0000010000000000UL
18134  #endif
18135  
18136 +#ifdef CONFIG_PAX_ASLR
18137 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
18138 +
18139 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
18140 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
18141 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
18142 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
18143 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18144 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
18145 +#endif
18146  
18147  /* This yields a mask that user programs can use to figure out what
18148     instruction set this cpu supports.  */
18149 diff -urNp linux-2.6.11/include/asm-sparc64/mman.h linux-2.6.11/include/asm-sparc64/mman.h
18150 --- linux-2.6.11/include/asm-sparc64/mman.h     2005-03-02 02:38:09.000000000 -0500
18151 +++ linux-2.6.11/include/asm-sparc64/mman.h     2005-03-09 11:56:44.000000000 -0500
18152 @@ -27,6 +27,10 @@
18153  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
18154  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
18155  
18156 +#ifdef CONFIG_PAX_RANDEXEC
18157 +#define MAP_MIRROR     0x0400
18158 +#endif
18159 +
18160  #define MS_ASYNC       1               /* sync memory asynchronously */
18161  #define MS_INVALIDATE  2               /* invalidate the caches */
18162  #define MS_SYNC                4               /* synchronous memory sync */
18163 diff -urNp linux-2.6.11/include/asm-sparc64/page.h linux-2.6.11/include/asm-sparc64/page.h
18164 --- linux-2.6.11/include/asm-sparc64/page.h     2005-03-02 02:38:07.000000000 -0500
18165 +++ linux-2.6.11/include/asm-sparc64/page.h     2005-03-09 11:56:44.000000000 -0500
18166 @@ -156,6 +156,15 @@ static __inline__ int get_order(unsigned
18167  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18168                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18169  
18170 +#ifdef CONFIG_PAX_PAGEEXEC
18171 +#ifdef CONFIG_PAX_MPROTECT
18172 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18173 +                         ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18174 +#else
18175 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18176 +#endif
18177 +#endif
18178 +
18179  #endif /* !(__KERNEL__) */
18180  
18181  #endif /* !(_SPARC64_PAGE_H) */
18182 diff -urNp linux-2.6.11/include/asm-x86_64/a.out.h linux-2.6.11/include/asm-x86_64/a.out.h
18183 --- linux-2.6.11/include/asm-x86_64/a.out.h     2005-03-02 02:38:07.000000000 -0500
18184 +++ linux-2.6.11/include/asm-x86_64/a.out.h     2005-03-09 11:56:44.000000000 -0500
18185 @@ -21,7 +21,7 @@ struct exec
18186  
18187  #ifdef __KERNEL__
18188  #include <linux/thread_info.h>
18189 -#define STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
18190 +#define __STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
18191  #endif
18192  
18193  #endif /* __A_OUT_GNU_H__ */
18194 diff -urNp linux-2.6.11/include/asm-x86_64/elf.h linux-2.6.11/include/asm-x86_64/elf.h
18195 --- linux-2.6.11/include/asm-x86_64/elf.h       2005-03-02 02:38:19.000000000 -0500
18196 +++ linux-2.6.11/include/asm-x86_64/elf.h       2005-03-09 11:56:44.000000000 -0500
18197 @@ -89,6 +89,17 @@ typedef struct user_i387_struct elf_fpre
18198  
18199  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
18200  
18201 +#ifdef CONFIG_PAX_ASLR
18202 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
18203 +
18204 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18205 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
18206 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18207 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
18208 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18209 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
18210 +#endif
18211 +
18212  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
18213     now struct_user_regs, they are different). Assumes current is the process
18214     getting dumped. */
18215 diff -urNp linux-2.6.11/include/asm-x86_64/mman.h linux-2.6.11/include/asm-x86_64/mman.h
18216 --- linux-2.6.11/include/asm-x86_64/mman.h      2005-03-02 02:38:13.000000000 -0500
18217 +++ linux-2.6.11/include/asm-x86_64/mman.h      2005-03-09 11:56:44.000000000 -0500
18218 @@ -24,6 +24,10 @@
18219  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
18220  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
18221  
18222 +#ifdef CONFIG_PAX_RANDEXEC
18223 +#define MAP_MIRROR     0x8000
18224 +#endif
18225 +
18226  #define MS_ASYNC       1               /* sync memory asynchronously */
18227  #define MS_INVALIDATE  2               /* invalidate the caches */
18228  #define MS_SYNC                4               /* synchronous memory sync */
18229 diff -urNp linux-2.6.11/include/asm-x86_64/page.h linux-2.6.11/include/asm-x86_64/page.h
18230 --- linux-2.6.11/include/asm-x86_64/page.h      2005-03-02 02:37:47.000000000 -0500
18231 +++ linux-2.6.11/include/asm-x86_64/page.h      2005-03-09 11:56:44.000000000 -0500
18232 @@ -136,6 +136,15 @@ extern __inline__ int get_order(unsigned
18233         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
18234          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18235  
18236 +#ifdef CONFIG_PAX_PAGEEXEC
18237 +#ifdef CONFIG_PAX_MPROTECT
18238 +#define __VM_STACK_FLAGS (((current->mm->flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18239 +                         ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18240 +#else
18241 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18242 +#endif
18243 +#endif
18244 +
18245  #define __HAVE_ARCH_GATE_AREA 1        
18246  
18247  #endif /* __KERNEL__ */
18248 diff -urNp linux-2.6.11/include/asm-x86_64/pgalloc.h linux-2.6.11/include/asm-x86_64/pgalloc.h
18249 --- linux-2.6.11/include/asm-x86_64/pgalloc.h   2005-03-02 02:38:09.000000000 -0500
18250 +++ linux-2.6.11/include/asm-x86_64/pgalloc.h   2005-03-09 11:56:44.000000000 -0500
18251 @@ -8,7 +8,7 @@
18252  #include <linux/mm.h>
18253  
18254  #define pmd_populate_kernel(mm, pmd, pte) \
18255 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
18256 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
18257  #define pud_populate(mm, pud, pmd) \
18258                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
18259  #define pgd_populate(mm, pgd, pud) \
18260 diff -urNp linux-2.6.11/include/asm-x86_64/pgtable.h linux-2.6.11/include/asm-x86_64/pgtable.h
18261 --- linux-2.6.11/include/asm-x86_64/pgtable.h   2005-03-02 02:38:17.000000000 -0500
18262 +++ linux-2.6.11/include/asm-x86_64/pgtable.h   2005-03-09 11:56:44.000000000 -0500
18263 @@ -161,6 +161,10 @@ extern inline void pgd_clear (pgd_t * pg
18264  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18265  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18266  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18267 +
18268 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
18269 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
18270 +
18271  #define __PAGE_KERNEL \
18272         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18273  #define __PAGE_KERNEL_EXEC \
18274 diff -urNp linux-2.6.11/include/linux/a.out.h linux-2.6.11/include/linux/a.out.h
18275 --- linux-2.6.11/include/linux/a.out.h  2005-03-02 02:38:12.000000000 -0500
18276 +++ linux-2.6.11/include/linux/a.out.h  2005-03-09 11:56:44.000000000 -0500
18277 @@ -7,6 +7,16 @@
18278  
18279  #include <asm/a.out.h>
18280  
18281 +#ifdef CONFIG_PAX_RANDUSTACK
18282 +#define __DELTA_STACK (current->mm->delta_stack)
18283 +#else
18284 +#define __DELTA_STACK 0UL
18285 +#endif
18286 +
18287 +#ifndef STACK_TOP
18288 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
18289 +#endif
18290 +
18291  #endif /* __STRUCT_EXEC_OVERRIDE__ */
18292  
18293  /* these go in the N_MACHTYPE field */
18294 @@ -37,6 +47,14 @@ enum machine_type {
18295    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
18296  };
18297  
18298 +/* Constants for the N_FLAGS field */
18299 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
18300 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
18301 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
18302 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
18303 +#define F_PAX_RANDEXEC 16      /* Randomize ET_EXEC base */
18304 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
18305 +
18306  #if !defined (N_MAGIC)
18307  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
18308  #endif
18309 diff -urNp linux-2.6.11/include/linux/binfmts.h linux-2.6.11/include/linux/binfmts.h
18310 --- linux-2.6.11/include/linux/binfmts.h        2005-03-02 02:38:09.000000000 -0500
18311 +++ linux-2.6.11/include/linux/binfmts.h        2005-03-09 11:56:44.000000000 -0500
18312 @@ -38,6 +38,7 @@ struct linux_binprm{
18313         unsigned interp_flags;
18314         unsigned interp_data;
18315         unsigned long loader, exec;
18316 +       int misc;
18317  };
18318  
18319  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
18320 @@ -83,5 +84,8 @@ extern void compute_creds(struct linux_b
18321  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
18322  extern int set_binfmt(struct linux_binfmt *new);
18323  
18324 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
18325 +void pax_report_insns(void *pc, void *sp);
18326 +
18327  #endif /* __KERNEL__ */
18328  #endif /* _LINUX_BINFMTS_H */
18329 diff -urNp linux-2.6.11/include/linux/elf.h linux-2.6.11/include/linux/elf.h
18330 --- linux-2.6.11/include/linux/elf.h    2005-03-02 02:37:49.000000000 -0500
18331 +++ linux-2.6.11/include/linux/elf.h    2005-03-09 11:56:44.000000000 -0500
18332 @@ -4,6 +4,10 @@
18333  #include <linux/types.h>
18334  #include <asm/elf.h>
18335  
18336 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18337 +#undef elf_read_implies_exec
18338 +#endif
18339 +
18340  #ifndef elf_read_implies_exec
18341    /* Executables for which elf_read_implies_exec() returns TRUE will
18342       have the READ_IMPLIES_EXEC personality flag set automatically.
18343 @@ -45,6 +49,16 @@ typedef __s64        Elf64_Sxword;
18344  
18345  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
18346  
18347 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
18348 +
18349 +/* Constants for the e_flags field */
18350 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
18351 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
18352 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
18353 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
18354 +#define EF_PAX_RANDEXEC                16      /* Randomize ET_EXEC base */
18355 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
18356 +
18357  /* These constants define the different elf file types */
18358  #define ET_NONE   0
18359  #define ET_REL    1
18360 @@ -137,6 +151,8 @@ typedef __s64       Elf64_Sxword;
18361  #define DT_DEBUG       21
18362  #define DT_TEXTREL     22
18363  #define DT_JMPREL      23
18364 +#define DT_FLAGS       30
18365 +  #define DF_TEXTREL   0x00000004
18366  #define DT_LOPROC      0x70000000
18367  #define DT_HIPROC      0x7fffffff
18368  
18369 @@ -287,6 +303,19 @@ typedef struct elf64_hdr {
18370  #define PF_W           0x2
18371  #define PF_X           0x1
18372  
18373 +#define PF_PAGEEXEC    (1 << 4)        /* Enable  PAGEEXEC */
18374 +#define PF_NOPAGEEXEC  (1 << 5)        /* Disable PAGEEXEC */
18375 +#define PF_SEGMEXEC    (1 << 6)        /* Enable  SEGMEXEC */
18376 +#define PF_NOSEGMEXEC  (1 << 7)        /* Disable SEGMEXEC */
18377 +#define PF_MPROTECT    (1 << 8)        /* Enable  MPROTECT */
18378 +#define PF_NOMPROTECT  (1 << 9)        /* Disable MPROTECT */
18379 +#define PF_RANDEXEC    (1 << 10)       /* Enable  RANDEXEC */
18380 +#define PF_NORANDEXEC  (1 << 11)       /* Disable RANDEXEC */
18381 +#define PF_EMUTRAMP    (1 << 12)       /* Enable  EMUTRAMP */
18382 +#define PF_NOEMUTRAMP  (1 << 13)       /* Disable EMUTRAMP */
18383 +#define PF_RANDMMAP    (1 << 14)       /* Enable  RANDMMAP */
18384 +#define PF_NORANDMMAP  (1 << 15)       /* Disable RANDMMAP */
18385 +
18386  typedef struct elf32_phdr{
18387    Elf32_Word   p_type;
18388    Elf32_Off    p_offset;
18389 @@ -379,6 +408,8 @@ typedef struct elf64_shdr {
18390  #define        EI_OSABI        7
18391  #define        EI_PAD          8
18392  
18393 +#define        EI_PAX          14
18394 +
18395  #define        ELFMAG0         0x7f            /* EI_MAG */
18396  #define        ELFMAG1         'E'
18397  #define        ELFMAG2         'L'
18398 @@ -435,6 +466,7 @@ extern Elf32_Dyn _DYNAMIC [];
18399  #define elfhdr         elf32_hdr
18400  #define elf_phdr       elf32_phdr
18401  #define elf_note       elf32_note
18402 +#define elf_dyn                Elf32_Dyn
18403  
18404  #else
18405  
18406 @@ -442,6 +474,7 @@ extern Elf64_Dyn _DYNAMIC [];
18407  #define elfhdr         elf64_hdr
18408  #define elf_phdr       elf64_phdr
18409  #define elf_note       elf64_note
18410 +#define elf_dyn                Elf64_Dyn
18411  
18412  #endif
18413  
18414 diff -urNp linux-2.6.11/include/linux/fs.h linux-2.6.11/include/linux/fs.h
18415 --- linux-2.6.11/include/linux/fs.h     2005-03-02 02:37:50.000000000 -0500
18416 +++ linux-2.6.11/include/linux/fs.h     2005-03-09 11:56:44.000000000 -0500
18417 @@ -1253,7 +1253,7 @@ static inline int break_lease(struct ino
18418  
18419  /* fs/open.c */
18420  
18421 -extern int do_truncate(struct dentry *, loff_t start);
18422 +extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
18423  extern struct file *filp_open(const char *, int, int);
18424  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
18425  extern int filp_close(struct file *, fl_owner_t id);
18426 diff -urNp linux-2.6.11/include/linux/gracl.h linux-2.6.11/include/linux/gracl.h
18427 --- linux-2.6.11/include/linux/gracl.h  1969-12-31 19:00:00.000000000 -0500
18428 +++ linux-2.6.11/include/linux/gracl.h  2005-03-09 11:56:44.000000000 -0500
18429 @@ -0,0 +1,261 @@
18430 +#ifndef GR_ACL_H
18431 +#define GR_ACL_H
18432 +
18433 +#include <linux/grdefs.h>
18434 +#include <linux/resource.h>
18435 +#include <linux/dcache.h>
18436 +#include <asm/resource.h>
18437 +
18438 +/* Major status information */
18439 +
18440 +#define GR_VERSION  "grsecurity 2.1.3"
18441 +#define GRSECURITY_VERSION 0x213
18442 +
18443 +enum {
18444 +
18445 +       SHUTDOWN = 0,
18446 +       ENABLE = 1,
18447 +       SPROLE = 2,
18448 +       RELOAD = 3,
18449 +       SEGVMOD = 4,
18450 +       STATUS = 5,
18451 +       UNSPROLE = 6
18452 +};
18453 +
18454 +/* Password setup definitions
18455 + * kernel/grhash.c */
18456 +enum {
18457 +       GR_PW_LEN = 128,
18458 +       GR_SALT_LEN = 16,
18459 +       GR_SHA_LEN = 32,
18460 +};
18461 +
18462 +enum {
18463 +       GR_SPROLE_LEN = 64,
18464 +};
18465 +
18466 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
18467 +
18468 +/* Begin Data Structures */
18469 +
18470 +struct sprole_pw {
18471 +       unsigned char *rolename;
18472 +       unsigned char salt[GR_SALT_LEN];
18473 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
18474 +};
18475 +
18476 +struct name_entry {
18477 +       ino_t inode;
18478 +       dev_t device;
18479 +       char *name;
18480 +       __u16 len;
18481 +};
18482 +
18483 +struct acl_role_db {
18484 +       struct acl_role_label **r_hash;
18485 +       __u32 r_size;
18486 +};
18487 +
18488 +struct name_db {
18489 +       struct name_entry **n_hash;
18490 +       __u32 n_size;
18491 +};
18492 +
18493 +struct crash_uid {
18494 +       uid_t uid;
18495 +       unsigned long expires;
18496 +};
18497 +
18498 +struct gr_hash_struct {
18499 +       void **table;
18500 +       void **nametable;
18501 +       void *first;
18502 +       __u32 table_size;
18503 +       __u32 used_size;
18504 +       int type;
18505 +};
18506 +
18507 +/* Userspace Grsecurity ACL data structures */
18508 +
18509 +struct acl_subject_label {
18510 +       char *filename;
18511 +       ino_t inode;
18512 +       dev_t device;
18513 +       __u32 mode;
18514 +       __u32 cap_mask;
18515 +       __u32 cap_lower;
18516 +
18517 +       struct rlimit res[GR_NLIMITS];
18518 +       __u16 resmask;
18519 +
18520 +       __u8 user_trans_type;
18521 +       __u8 group_trans_type;
18522 +       uid_t *user_transitions;
18523 +       gid_t *group_transitions;
18524 +       __u16 user_trans_num;
18525 +       __u16 group_trans_num;
18526 +
18527 +       __u32 ip_proto[8];
18528 +       __u32 ip_type;
18529 +       struct acl_ip_label **ips;
18530 +       __u32 ip_num;
18531 +
18532 +       __u32 crashes;
18533 +       unsigned long expires;
18534 +
18535 +       struct acl_subject_label *parent_subject;
18536 +       struct gr_hash_struct *hash;
18537 +       struct acl_subject_label *prev;
18538 +       struct acl_subject_label *next;
18539 +
18540 +       struct acl_object_label **obj_hash;
18541 +       __u32 obj_hash_size;
18542 +};
18543 +
18544 +struct role_allowed_ip {
18545 +       __u32 addr;
18546 +       __u32 netmask;
18547 +
18548 +       struct role_allowed_ip *prev;
18549 +       struct role_allowed_ip *next;
18550 +};
18551 +
18552 +struct role_transition {
18553 +       char *rolename;
18554 +
18555 +       struct role_transition *prev;
18556 +       struct role_transition *next;
18557 +};
18558 +
18559 +struct acl_role_label {
18560 +       char *rolename;
18561 +       uid_t uidgid;
18562 +       __u16 roletype;
18563 +
18564 +       __u16 auth_attempts;
18565 +       unsigned long expires;
18566 +
18567 +       struct acl_subject_label *root_label;
18568 +       struct gr_hash_struct *hash;
18569 +
18570 +       struct acl_role_label *prev;
18571 +       struct acl_role_label *next;
18572 +
18573 +       struct role_transition *transitions;
18574 +       struct role_allowed_ip *allowed_ips;
18575 +       uid_t *domain_children;
18576 +       __u16 domain_child_num;
18577 +
18578 +       struct acl_subject_label **subj_hash;
18579 +       __u32 subj_hash_size;
18580 +};
18581 +
18582 +struct user_acl_role_db {
18583 +       struct acl_role_label **r_table;
18584 +       __u32 num_pointers;             /* Number of allocations to track */
18585 +       __u32 num_roles;                /* Number of roles */
18586 +       __u32 num_domain_children;      /* Number of domain children */
18587 +       __u32 num_subjects;             /* Number of subjects */
18588 +       __u32 num_objects;              /* Number of objects */
18589 +};
18590 +
18591 +struct acl_object_label {
18592 +       char *filename;
18593 +       ino_t inode;
18594 +       dev_t device;
18595 +       __u32 mode;
18596 +
18597 +       struct acl_subject_label *nested;
18598 +       struct acl_object_label *globbed;
18599 +
18600 +       /* next two structures not used */
18601 +
18602 +       struct acl_object_label *prev;
18603 +       struct acl_object_label *next;
18604 +};
18605 +
18606 +struct acl_ip_label {
18607 +       __u32 addr;
18608 +       __u32 netmask;
18609 +       __u16 low, high;
18610 +       __u8 mode;
18611 +       __u32 type;
18612 +       __u32 proto[8];
18613 +
18614 +       /* next two structures not used */
18615 +
18616 +       struct acl_ip_label *prev;
18617 +       struct acl_ip_label *next;
18618 +};
18619 +
18620 +struct gr_arg {
18621 +       struct user_acl_role_db role_db;
18622 +       unsigned char pw[GR_PW_LEN];
18623 +       unsigned char salt[GR_SALT_LEN];
18624 +       unsigned char sum[GR_SHA_LEN];
18625 +       unsigned char sp_role[GR_SPROLE_LEN];
18626 +       struct sprole_pw *sprole_pws;
18627 +       dev_t segv_device;
18628 +       ino_t segv_inode;
18629 +       uid_t segv_uid;
18630 +       __u16 num_sprole_pws;
18631 +       __u16 mode;
18632 +};
18633 +
18634 +struct gr_arg_wrapper {
18635 +       struct gr_arg *arg;
18636 +       __u32 version;
18637 +       __u32 size;
18638 +};
18639 +
18640 +struct subject_map {
18641 +       struct acl_subject_label *user;
18642 +       struct acl_subject_label *kernel;
18643 +};
18644 +
18645 +struct acl_subj_map_db {
18646 +       struct subject_map **s_hash;
18647 +       __u32 s_size;
18648 +};
18649 +
18650 +/* End Data Structures Section */
18651 +
18652 +/* Hash functions generated by empirical testing by Brad Spengler
18653 +   Makes good use of the low bits of the inode.  Generally 0-1 times
18654 +   in loop for successful match.  0-3 for unsuccessful match.
18655 +   Shift/add algorithm with modulus of table size and an XOR*/
18656 +
18657 +static __inline__ unsigned long
18658 +chash(const void *dentry, const void *mnt, const struct acl_subject_label *subj,
18659 +      const unsigned long sz)
18660 +{
18661 +       return (((const unsigned long)subj + (const unsigned long)mnt +
18662 +               (const unsigned long)dentry) % sz);
18663 +}
18664 +
18665 +static __inline__ unsigned long
18666 +rhash(const uid_t uid, const __u16 type, const unsigned long sz)
18667 +{
18668 +       return (((uid << type) + (uid ^ type)) % sz);
18669 +}
18670 +
18671 + static __inline__ unsigned long
18672 +shash(const struct acl_subject_label *userp, const unsigned long sz)
18673 +{
18674 +       return ((const unsigned long)userp % sz);
18675 +}
18676 +
18677 +static __inline__ unsigned long
18678 +fhash(const ino_t ino, const dev_t dev, const unsigned long sz)
18679 +{
18680 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
18681 +}
18682 +
18683 +static __inline__ unsigned long
18684 +nhash(const char *name, const __u16 len, const unsigned long sz)
18685 +{
18686 +       return full_name_hash(name, len) % sz;
18687 +}
18688 +
18689 +#endif
18690 +
18691 diff -urNp linux-2.6.11/include/linux/gralloc.h linux-2.6.11/include/linux/gralloc.h
18692 --- linux-2.6.11/include/linux/gralloc.h        1969-12-31 19:00:00.000000000 -0500
18693 +++ linux-2.6.11/include/linux/gralloc.h        2005-03-09 11:56:44.000000000 -0500
18694 @@ -0,0 +1,8 @@
18695 +#ifndef __GRALLOC_H
18696 +#define __GRALLOC_H
18697 +
18698 +void acl_free_all(void);
18699 +int acl_alloc_stack_init(unsigned long size);
18700 +void *acl_alloc(unsigned long len);
18701 +
18702 +#endif
18703 diff -urNp linux-2.6.11/include/linux/grdefs.h linux-2.6.11/include/linux/grdefs.h
18704 --- linux-2.6.11/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
18705 +++ linux-2.6.11/include/linux/grdefs.h 2005-03-09 11:56:44.000000000 -0500
18706 @@ -0,0 +1,121 @@
18707 +#ifndef GRDEFS_H
18708 +#define GRDEFS_H
18709 +
18710 +/* Begin grsecurity status declarations */
18711 +
18712 +enum {
18713 +       GR_READY = 0x01,
18714 +       GR_STATUS_INIT = 0x00   // disabled state
18715 +};
18716 +
18717 +/* Begin  ACL declarations */
18718 +
18719 +/* Role flags */
18720 +
18721 +enum {
18722 +       GR_ROLE_USER = 0x0001,
18723 +       GR_ROLE_GROUP = 0x0002,
18724 +       GR_ROLE_DEFAULT = 0x0004,
18725 +       GR_ROLE_SPECIAL = 0x0008,
18726 +       GR_ROLE_AUTH = 0x0010,
18727 +       GR_ROLE_NOPW = 0x0020,
18728 +       GR_ROLE_GOD = 0x0040,
18729 +       GR_ROLE_LEARN = 0x0080,
18730 +       GR_ROLE_TPE = 0x0100,
18731 +       GR_ROLE_DOMAIN = 0x0200
18732 +};
18733 +
18734 +/* ACL Subject and Object mode flags */
18735 +enum {
18736 +       GR_DELETED = 0x80000000
18737 +};
18738 +
18739 +/* ACL Object-only mode flags */
18740 +enum {
18741 +       GR_READ         = 0x00000001,
18742 +       GR_APPEND       = 0x00000002,
18743 +       GR_WRITE        = 0x00000004,
18744 +       GR_EXEC         = 0x00000008,
18745 +       GR_FIND         = 0x00000010,
18746 +       GR_INHERIT      = 0x00000020,
18747 +       GR_SETID        = 0x00000040,
18748 +       GR_CREATE       = 0x00000080,
18749 +       GR_DELETE       = 0x00000100,
18750 +       GR_LINK         = 0x00000200,
18751 +       GR_AUDIT_READ   = 0x00000400,
18752 +       GR_AUDIT_APPEND = 0x00000800,
18753 +       GR_AUDIT_WRITE  = 0x00001000,
18754 +       GR_AUDIT_EXEC   = 0x00002000,
18755 +       GR_AUDIT_FIND   = 0x00004000,
18756 +       GR_AUDIT_INHERIT= 0x00008000,
18757 +       GR_AUDIT_SETID  = 0x00010000,
18758 +       GR_AUDIT_CREATE = 0x00020000,
18759 +       GR_AUDIT_DELETE = 0x00040000,
18760 +       GR_AUDIT_LINK   = 0x00080000,
18761 +       GR_PTRACERD     = 0x00100000,
18762 +       GR_NOPTRACE     = 0x00200000,
18763 +       GR_SUPPRESS     = 0x00400000,
18764 +       GR_NOLEARN      = 0x00800000
18765 +};
18766 +
18767 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
18768 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
18769 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
18770 +
18771 +/* ACL subject-only mode flags */
18772 +enum {
18773 +       GR_KILL         = 0x00000001,
18774 +       GR_VIEW         = 0x00000002,
18775 +       GR_PROTECTED    = 0x00000004,
18776 +       GR_LEARN        = 0x00000008,
18777 +       GR_OVERRIDE     = 0x00000010,
18778 +       /* just a placeholder, this mode is only used in userspace */
18779 +       GR_DUMMY        = 0x00000020,
18780 +       GR_PAXPAGE      = 0x00000040,
18781 +       GR_PAXSEGM      = 0x00000080,
18782 +       GR_PAXGCC       = 0x00000100,
18783 +       GR_PAXRANDMMAP  = 0x00000200,
18784 +       GR_PAXMPROTECT  = 0x00000400,
18785 +       GR_PROTSHM      = 0x00000800,
18786 +       GR_KILLPROC     = 0x00001000,
18787 +       GR_KILLIPPROC   = 0x00002000,
18788 +       /* just a placeholder, this mode is only used in userspace */
18789 +       GR_NOTROJAN     = 0x00004000,
18790 +       GR_PROTPROCFD   = 0x00008000,
18791 +       GR_PROCACCT     = 0x00010000,
18792 +       GR_RELAXPTRACE  = 0x00020000,
18793 +       GR_NESTED       = 0x00040000,
18794 +       GR_INHERITLEARN = 0x00080000,
18795 +       GR_PROCFIND     = 0x00100000,
18796 +       GR_POVERRIDE    = 0x00200000
18797 +};
18798 +
18799 +enum {
18800 +       GR_ID_USER      = 0x01,
18801 +       GR_ID_GROUP     = 0x02,
18802 +};
18803 +
18804 +enum {
18805 +       GR_ID_ALLOW     = 0x01,
18806 +       GR_ID_DENY      = 0x02,
18807 +};
18808 +
18809 +#define GR_CRASH_RES   11
18810 +#define GR_UIDTABLE_MAX 500
18811 +
18812 +/* begin resource learning section */
18813 +enum {
18814 +       GR_RLIM_CPU_BUMP = 60,
18815 +       GR_RLIM_FSIZE_BUMP = 50000,
18816 +       GR_RLIM_DATA_BUMP = 10000,
18817 +       GR_RLIM_STACK_BUMP = 1000,
18818 +       GR_RLIM_CORE_BUMP = 10000,
18819 +       GR_RLIM_RSS_BUMP = 500000,
18820 +       GR_RLIM_NPROC_BUMP = 1,
18821 +       GR_RLIM_NOFILE_BUMP = 5,
18822 +       GR_RLIM_MEMLOCK_BUMP = 50000,
18823 +       GR_RLIM_AS_BUMP = 500000,
18824 +       GR_RLIM_LOCKS_BUMP = 2
18825 +};
18826 +
18827 +#endif
18828 diff -urNp linux-2.6.11/include/linux/grinternal.h linux-2.6.11/include/linux/grinternal.h
18829 --- linux-2.6.11/include/linux/grinternal.h     1969-12-31 19:00:00.000000000 -0500
18830 +++ linux-2.6.11/include/linux/grinternal.h     2005-03-09 11:56:44.000000000 -0500
18831 @@ -0,0 +1,209 @@
18832 +#ifndef __GRINTERNAL_H
18833 +#define __GRINTERNAL_H
18834 +
18835 +#ifdef CONFIG_GRKERNSEC
18836 +
18837 +#include <linux/fs.h>
18838 +#include <linux/gracl.h>
18839 +#include <linux/grdefs.h>
18840 +#include <linux/grmsg.h>
18841 +
18842 +extern void gr_add_learn_entry(const char *fmt, ...);
18843 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
18844 +                           const struct vfsmount *mnt);
18845 +extern __u32 gr_check_create(const struct dentry *new_dentry,
18846 +                            const struct dentry *parent,
18847 +                            const struct vfsmount *mnt, const __u32 mode);
18848 +extern int gr_check_protected_task(const struct task_struct *task);
18849 +extern __u32 to_gr_audit(const __u32 reqmode);
18850 +extern int gr_set_acls(const int type);
18851 +
18852 +extern int gr_acl_is_enabled(void);
18853 +extern char gr_roletype_to_char(void);
18854 +
18855 +extern void gr_handle_alertkill(struct task_struct *task);
18856 +extern char *gr_to_filename(const struct dentry *dentry,
18857 +                           const struct vfsmount *mnt);
18858 +extern char *gr_to_filename1(const struct dentry *dentry,
18859 +                           const struct vfsmount *mnt);
18860 +extern char *gr_to_filename2(const struct dentry *dentry,
18861 +                           const struct vfsmount *mnt);
18862 +extern char *gr_to_filename3(const struct dentry *dentry,
18863 +                           const struct vfsmount *mnt);
18864 +
18865 +extern int grsec_enable_link;
18866 +extern int grsec_enable_fifo;
18867 +extern int grsec_enable_execve;
18868 +extern int grsec_enable_shm;
18869 +extern int grsec_enable_execlog;
18870 +extern int grsec_enable_signal;
18871 +extern int grsec_enable_forkfail;
18872 +extern int grsec_enable_time;
18873 +extern int grsec_enable_chroot_shmat;
18874 +extern int grsec_enable_chroot_findtask;
18875 +extern int grsec_enable_chroot_mount;
18876 +extern int grsec_enable_chroot_double;
18877 +extern int grsec_enable_chroot_pivot;
18878 +extern int grsec_enable_chroot_chdir;
18879 +extern int grsec_enable_chroot_chmod;
18880 +extern int grsec_enable_chroot_mknod;
18881 +extern int grsec_enable_chroot_fchdir;
18882 +extern int grsec_enable_chroot_nice;
18883 +extern int grsec_enable_chroot_execlog;
18884 +extern int grsec_enable_chroot_caps;
18885 +extern int grsec_enable_chroot_sysctl;
18886 +extern int grsec_enable_chroot_unix;
18887 +extern int grsec_enable_tpe;
18888 +extern int grsec_tpe_gid;
18889 +extern int grsec_enable_tpe_all;
18890 +extern int grsec_enable_sidcaps;
18891 +extern int grsec_enable_randpid;
18892 +extern int grsec_enable_socket_all;
18893 +extern int grsec_socket_all_gid;
18894 +extern int grsec_enable_socket_client;
18895 +extern int grsec_socket_client_gid;
18896 +extern int grsec_enable_socket_server;
18897 +extern int grsec_socket_server_gid;
18898 +extern int grsec_audit_gid;
18899 +extern int grsec_enable_group;
18900 +extern int grsec_enable_audit_ipc;
18901 +extern int grsec_enable_audit_textrel;
18902 +extern int grsec_enable_mount;
18903 +extern int grsec_enable_chdir;
18904 +extern int grsec_lock;
18905 +
18906 +extern struct task_struct *child_reaper;
18907 +
18908 +extern spinlock_t grsec_alert_lock;
18909 +extern unsigned long grsec_alert_wtime;
18910 +extern unsigned long grsec_alert_fyet;
18911 +
18912 +extern spinlock_t grsec_audit_lock;
18913 +
18914 +extern rwlock_t grsec_exec_file_lock;
18915 +
18916 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
18917 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
18918 +                       tsk->exec_file->f_vfsmnt) : "/")
18919 +
18920 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
18921 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
18922 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
18923 +
18924 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
18925 +                       gr_to_filename(tsk->exec_file->f_dentry, \
18926 +                       tsk->exec_file->f_vfsmnt) : "/")
18927 +
18928 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
18929 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
18930 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
18931 +
18932 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && \
18933 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
18934 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
18935 +                         (tsk_a->fs->root->d_inode->i_ino != \
18936 +                         child_reaper->fs->root->d_inode->i_ino)))
18937 +
18938 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_sb->s_dev == \
18939 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
18940 +                         (tsk_a->fs->root->d_inode->i_ino == \
18941 +                         tsk_b->fs->root->d_inode->i_ino))
18942 +
18943 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
18944 +                      task->pid, task->uid, \
18945 +                      task->euid, task->gid, task->egid, \
18946 +                      gr_parent_task_fullpath(task), \
18947 +                      task->parent->comm, task->parent->pid, \
18948 +                      task->parent->uid, task->parent->euid, \
18949 +                      task->parent->gid, task->parent->egid
18950 +
18951 +#define GR_CHROOT_CAPS ( \
18952 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
18953 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
18954 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
18955 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
18956 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
18957 +       CAP_TO_MASK(CAP_IPC_OWNER))
18958 +
18959 +#define security_learn(normal_msg,args...) \
18960 +({ \
18961 +       read_lock(&grsec_exec_file_lock); \
18962 +       gr_add_learn_entry(normal_msg "\n", ## args); \
18963 +       read_unlock(&grsec_exec_file_lock); \
18964 +})
18965 +
18966 +enum {
18967 +       GR_DO_AUDIT,
18968 +       GR_DONT_AUDIT,
18969 +       GR_DONT_AUDIT_GOOD
18970 +};
18971 +
18972 +enum {
18973 +       GR_TTYSNIFF,
18974 +       GR_RBAC,
18975 +       GR_RBAC_STR,
18976 +       GR_STR_RBAC,
18977 +       GR_RBAC_MODE2,
18978 +       GR_RBAC_MODE3,
18979 +       GR_FILENAME,
18980 +       GR_NOARGS,
18981 +       GR_ONE_INT,
18982 +       GR_ONE_INT_TWO_STR,
18983 +       GR_ONE_STR,
18984 +       GR_STR_INT,
18985 +       GR_TWO_INT,
18986 +       GR_THREE_INT,
18987 +       GR_FIVE_INT_TWO_STR,
18988 +       GR_TWO_STR,
18989 +       GR_THREE_STR,
18990 +       GR_FOUR_STR,
18991 +       GR_STR_FILENAME,
18992 +       GR_FILENAME_STR,
18993 +       GR_FILENAME_TWO_INT,
18994 +       GR_FILENAME_TWO_INT_STR,
18995 +       GR_TEXTREL,
18996 +       GR_PTRACE,
18997 +       GR_RESOURCE,
18998 +       GR_CAP,
18999 +       GR_SIG,
19000 +       GR_CRASH1,
19001 +       GR_CRASH2,
19002 +       GR_PSACCT
19003 +};
19004 +
19005 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
19006 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
19007 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
19008 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
19009 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
19010 +#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3)
19011 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
19012 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
19013 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
19014 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
19015 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
19016 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
19017 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
19018 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
19019 +#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2)
19020 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
19021 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
19022 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
19023 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
19024 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
19025 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
19026 +#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str)
19027 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
19028 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
19029 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
19030 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
19031 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
19032 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
19033 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
19034 +#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9)
19035 +
19036 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
19037 +
19038 +#endif
19039 +
19040 +#endif
19041 diff -urNp linux-2.6.11/include/linux/grmsg.h linux-2.6.11/include/linux/grmsg.h
19042 --- linux-2.6.11/include/linux/grmsg.h  1969-12-31 19:00:00.000000000 -0500
19043 +++ linux-2.6.11/include/linux/grmsg.h  2005-03-09 11:56:44.000000000 -0500
19044 @@ -0,0 +1,107 @@
19045 +#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"
19046 +#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"
19047 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
19048 +#define GR_IOPERM_MSG "denied use of ioperm() by "
19049 +#define GR_IOPL_MSG "denied use of iopl() by "
19050 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
19051 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
19052 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
19053 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
19054 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
19055 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
19056 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
19057 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
19058 +#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"
19059 +#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%u.%u.%u.%u"
19060 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
19061 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
19062 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
19063 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
19064 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
19065 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
19066 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
19067 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
19068 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
19069 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
19070 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
19071 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
19072 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
19073 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
19074 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
19075 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
19076 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
19077 +#define GR_NPROC_MSG "denied overstep of process limit by "
19078 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
19079 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
19080 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
19081 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
19082 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
19083 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
19084 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
19085 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
19086 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
19087 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
19088 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
19089 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
19090 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
19091 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
19092 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
19093 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
19094 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
19095 +#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"
19096 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
19097 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
19098 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
19099 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
19100 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
19101 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
19102 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
19103 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
19104 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
19105 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
19106 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
19107 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
19108 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
19109 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
19110 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
19111 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
19112 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
19113 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
19114 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
19115 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
19116 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
19117 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
19118 +#define GR_NICE_CHROOT_MSG "denied priority change by "
19119 +#define GR_UNISIGLOG_MSG "signal %d sent to "
19120 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
19121 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
19122 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
19123 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
19124 +#define GR_TIME_MSG "time set by "
19125 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
19126 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
19127 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
19128 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
19129 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
19130 +#define GR_BIND_MSG "denied bind() by "
19131 +#define GR_CONNECT_MSG "denied connect() by "
19132 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
19133 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
19134 +#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"
19135 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
19136 +#define GR_CAP_ACL_MSG "use of %s denied for "
19137 +#define GR_USRCHANGE_ACL_MSG "change to uid %d denied for "
19138 +#define GR_GRPCHANGE_ACL_MSG "change to gid %d denied for "
19139 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
19140 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
19141 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
19142 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
19143 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
19144 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
19145 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by "
19146 +#define GR_SEM_AUDIT_MSG "semaphore created by "
19147 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by "
19148 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
19149 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by "
19150 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
19151 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
19152 diff -urNp linux-2.6.11/include/linux/grsecurity.h linux-2.6.11/include/linux/grsecurity.h
19153 --- linux-2.6.11/include/linux/grsecurity.h     1969-12-31 19:00:00.000000000 -0500
19154 +++ linux-2.6.11/include/linux/grsecurity.h     2005-03-09 11:56:44.000000000 -0500
19155 @@ -0,0 +1,197 @@
19156 +#ifndef GR_SECURITY_H
19157 +#define GR_SECURITY_H
19158 +#include <linux/fs.h>
19159 +#include <linux/binfmts.h>
19160 +#include <linux/gracl.h>
19161 +
19162 +extern void gr_handle_brute_attach(struct task_struct *p);
19163 +extern void gr_handle_brute_check(void);
19164 +
19165 +extern char gr_roletype_to_char(void);
19166 +
19167 +extern int gr_check_user_change(int real, int effective, int fs);
19168 +extern int gr_check_group_change(int real, int effective, int fs);
19169 +
19170 +extern void gr_add_to_task_ip_table(struct task_struct *p);
19171 +extern void gr_del_task_from_ip_table(struct task_struct *p);
19172 +
19173 +extern int gr_pid_is_chrooted(struct task_struct *p);
19174 +extern int gr_handle_chroot_nice(void);
19175 +extern int gr_handle_chroot_sysctl(const int op);
19176 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
19177 +                                       const int niceval);
19178 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
19179 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
19180 +                                  const struct vfsmount *mnt);
19181 +extern void gr_handle_chroot_caps(struct task_struct *task);
19182 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
19183 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
19184 +                                 const struct vfsmount *mnt, const int mode);
19185 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
19186 +                                 const struct vfsmount *mnt, const int mode);
19187 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
19188 +                                 const struct vfsmount *mnt,
19189 +                                 const char *dev_name);
19190 +extern int gr_handle_chroot_pivot(void);
19191 +extern int gr_handle_chroot_unix(const pid_t pid);
19192 +
19193 +extern int gr_handle_rawio(const struct inode *inode);
19194 +extern int gr_handle_nproc(void);
19195 +
19196 +extern void gr_handle_ioperm(void);
19197 +extern void gr_handle_iopl(void);
19198 +
19199 +extern int gr_tpe_allow(const struct file *file);
19200 +
19201 +extern int gr_random_pid(void);
19202 +
19203 +extern void gr_log_forkfail(const int retval);
19204 +extern void gr_log_timechange(void);
19205 +extern void gr_log_signal(const int sig, const struct task_struct *t);
19206 +extern void gr_log_chdir(const struct dentry *dentry,
19207 +                        const struct vfsmount *mnt);
19208 +extern void gr_log_chroot_exec(const struct dentry *dentry,
19209 +                              const struct vfsmount *mnt);
19210 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
19211 +extern void gr_log_remount(const char *devname, const int retval);
19212 +extern void gr_log_unmount(const char *devname, const int retval);
19213 +extern void gr_log_mount(const char *from, const char *to, const int retval);
19214 +extern void gr_log_msgget(const int ret, const int msgflg);
19215 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
19216 +extern void gr_log_semget(const int err, const int semflg);
19217 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
19218 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
19219 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
19220 +extern void gr_log_textrel(struct vm_area_struct *vma);
19221 +
19222 +extern int gr_handle_follow_link(const struct inode *parent,
19223 +                                const struct inode *inode,
19224 +                                const struct dentry *dentry,
19225 +                                const struct vfsmount *mnt);
19226 +extern int gr_handle_fifo(const struct dentry *dentry,
19227 +                         const struct vfsmount *mnt,
19228 +                         const struct dentry *dir, const int flag,
19229 +                         const int acc_mode);
19230 +extern int gr_handle_hardlink(const struct dentry *dentry,
19231 +                             const struct vfsmount *mnt,
19232 +                             struct inode *inode,
19233 +                             const int mode, const char *to);
19234 +
19235 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
19236 +extern int gr_is_capable_nolog(const int cap);
19237 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
19238 +                             const unsigned long wanted, const int gt);
19239 +extern void gr_copy_label(struct task_struct *tsk);
19240 +extern void gr_handle_crash(struct task_struct *task, const int sig);
19241 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
19242 +extern int gr_check_crash_uid(const uid_t uid);
19243 +extern int gr_check_protected_task(const struct task_struct *task);
19244 +extern int gr_acl_handle_mmap(const struct file *file,
19245 +                             const unsigned long prot);
19246 +extern int gr_acl_handle_mprotect(const struct file *file,
19247 +                                 const unsigned long prot);
19248 +extern int gr_check_hidden_task(const struct task_struct *tsk);
19249 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
19250 +                                   const struct vfsmount *mnt);
19251 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
19252 +                                const struct vfsmount *mnt);
19253 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
19254 +                                 const struct vfsmount *mnt, const int fmode);
19255 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
19256 +                                 const struct vfsmount *mnt, mode_t mode);
19257 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
19258 +                                const struct vfsmount *mnt, mode_t mode);
19259 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
19260 +                                const struct vfsmount *mnt);
19261 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
19262 +extern int gr_handle_proc_ptrace(struct task_struct *task);
19263 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
19264 +                                 const struct vfsmount *mnt);
19265 +extern int gr_check_crash_exec(const struct file *filp);
19266 +extern int gr_acl_is_enabled(void);
19267 +extern void gr_set_kernel_label(struct task_struct *task);
19268 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
19269 +                             const gid_t gid);
19270 +extern int gr_set_proc_label(const struct dentry *dentry,
19271 +                             const struct vfsmount *mnt);
19272 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
19273 +                                      const struct vfsmount *mnt);
19274 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
19275 +                               const struct vfsmount *mnt, const int fmode);
19276 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
19277 +                                const struct dentry *p_dentry,
19278 +                                const struct vfsmount *p_mnt, const int fmode,
19279 +                                const int imode);
19280 +extern void gr_handle_create(const struct dentry *dentry,
19281 +                            const struct vfsmount *mnt);
19282 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
19283 +                                const struct dentry *parent_dentry,
19284 +                                const struct vfsmount *parent_mnt,
19285 +                                const int mode);
19286 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
19287 +                                const struct dentry *parent_dentry,
19288 +                                const struct vfsmount *parent_mnt);
19289 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
19290 +                                const struct vfsmount *mnt);
19291 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
19292 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
19293 +                                 const struct vfsmount *mnt);
19294 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
19295 +                                  const struct dentry *parent_dentry,
19296 +                                  const struct vfsmount *parent_mnt,
19297 +                                  const char *from);
19298 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
19299 +                               const struct dentry *parent_dentry,
19300 +                               const struct vfsmount *parent_mnt,
19301 +                               const struct dentry *old_dentry,
19302 +                               const struct vfsmount *old_mnt, const char *to);
19303 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
19304 +                               struct dentry *parent_dentry,
19305 +                               const struct vfsmount *parent_mnt,
19306 +                               struct dentry *old_dentry,
19307 +                               struct inode *old_parent_inode,
19308 +                               struct vfsmount *old_mnt, const char *newname);
19309 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
19310 +                               struct dentry *old_dentry,
19311 +                               struct dentry *new_dentry,
19312 +                               struct vfsmount *mnt, const __u8 replace);
19313 +extern __u32 gr_check_link(const struct dentry *new_dentry,
19314 +                          const struct dentry *parent_dentry,
19315 +                          const struct vfsmount *parent_mnt,
19316 +                          const struct dentry *old_dentry,
19317 +                          const struct vfsmount *old_mnt);
19318 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
19319 +                                const unsigned int namelen, const ino_t ino);
19320 +
19321 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
19322 +                               const struct vfsmount *mnt);
19323 +extern void gr_acl_handle_exit(void);
19324 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
19325 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
19326 +extern __u32 gr_cap_rtnetlink(void);
19327 +
19328 +#ifdef CONFIG_SYSVIPC
19329 +extern void gr_shm_exit(struct task_struct *task);
19330 +#else
19331 +static inline void gr_shm_exit(struct task_struct *task)
19332 +{
19333 +       return;
19334 +}
19335 +#endif
19336 +
19337 +#ifdef CONFIG_GRKERNSEC
19338 +extern void gr_handle_mem_write(void);
19339 +extern void gr_handle_kmem_write(void);
19340 +extern void gr_handle_open_port(void);
19341 +extern int gr_handle_mem_mmap(const unsigned long offset,
19342 +                             struct vm_area_struct *vma);
19343 +
19344 +extern unsigned long pax_get_random_long(void);
19345 +#define get_random_long() pax_get_random_long()
19346 +
19347 +extern int grsec_enable_dmesg;
19348 +extern int grsec_enable_randsrc;
19349 +extern int grsec_enable_shm;
19350 +#endif
19351 +
19352 +#endif
19353 diff -urNp linux-2.6.11/include/linux/mm.h linux-2.6.11/include/linux/mm.h
19354 --- linux-2.6.11/include/linux/mm.h     2005-03-02 02:37:47.000000000 -0500
19355 +++ linux-2.6.11/include/linux/mm.h     2005-03-09 11:56:44.000000000 -0500
19356 @@ -36,6 +36,7 @@ extern int sysctl_legacy_va_layout;
19357  #include <asm/pgtable.h>
19358  #include <asm/processor.h>
19359  #include <asm/atomic.h>
19360 +#include <asm/mman.h>
19361  
19362  #ifndef MM_VM_SIZE
19363  #define MM_VM_SIZE(mm) ((TASK_SIZE + PGDIR_SIZE - 1) & PGDIR_MASK)
19364 @@ -113,8 +114,49 @@ struct vm_area_struct {
19365  #ifdef CONFIG_NUMA
19366         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
19367  #endif
19368 +
19369 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19370 +       unsigned long vm_mirror;        /* PaX: mirror distance */
19371 +#endif
19372 +
19373  };
19374  
19375 +#ifdef CONFIG_PAX_SOFTMODE
19376 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
19377 +extern unsigned int pax_aslr;
19378 +#endif
19379 +
19380 +extern unsigned int pax_softmode;
19381 +#endif
19382 +
19383 +extern int pax_check_flags(unsigned long *);
19384 +
19385 +/* if tsk != current then task_lock must be held on it */
19386 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19387 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
19388 +{
19389 +       if (likely(tsk->mm))
19390 +               return tsk->mm->flags;
19391 +       else
19392 +               return 0UL;
19393 +}
19394 +
19395 +/* if tsk != current then task_lock must be held on it */
19396 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
19397 +{
19398 +       if (likely(tsk->mm)) {
19399 +               tsk->mm->flags = flags;
19400 +               return 0;
19401 +       }
19402 +       return -EINVAL;
19403 +}
19404 +#endif
19405 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
19406 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
19407 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
19408 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
19409 +#endif
19410 +
19411  /*
19412   * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
19413   * disabled, then there's a single shared list of VMAs maintained by the
19414 @@ -165,6 +207,18 @@ extern unsigned int kobjsize(const void 
19415  #define VM_HUGETLB     0x00400000      /* Huge TLB Page VM */
19416  #define VM_NONLINEAR   0x00800000      /* Is non-linear (remap_file_pages) */
19417  
19418 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19419 +#define VM_MIRROR      0x01000000      /* vma is mirroring another */
19420 +#endif
19421 +
19422 +#ifdef CONFIG_PAX_MPROTECT
19423 +#define VM_MAYNOTWRITE 0x02000000      /* vma cannot be granted VM_WRITE any more */
19424 +#endif
19425 +
19426 +#ifdef __VM_STACK_FLAGS
19427 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
19428 +#endif
19429 +
19430  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
19431  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
19432  #endif
19433 @@ -734,6 +788,10 @@ extern unsigned long do_mmap_pgoff(struc
19434         unsigned long len, unsigned long prot,
19435         unsigned long flag, unsigned long pgoff);
19436  
19437 +extern unsigned long __do_mmap_pgoff(struct file *file, unsigned long addr,
19438 +       unsigned long len, unsigned long prot,
19439 +       unsigned long flag, unsigned long pgoff);
19440 +
19441  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
19442         unsigned long len, unsigned long prot,
19443         unsigned long flag, unsigned long offset)
19444 @@ -783,7 +841,7 @@ void handle_ra_miss(struct address_space
19445  unsigned long max_sane_readahead(unsigned long nr);
19446  
19447  /* Do stack extension */
19448 -extern int expand_stack(struct vm_area_struct * vma, unsigned long address);
19449 +extern int expand_stack(struct task_struct *tsk, struct vm_area_struct * vma, unsigned long address);
19450  
19451  /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
19452  extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
19453 @@ -806,7 +864,7 @@ static inline unsigned long vma_pages(st
19454         return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
19455  }
19456  
19457 -extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
19458 +extern struct vm_area_struct *find_extend_vma(struct task_struct *tsk, struct mm_struct * mm, unsigned long addr);
19459  
19460  extern struct page * vmalloc_to_page(void *addr);
19461  extern unsigned long vmalloc_to_pfn(void *addr);
19462 @@ -856,5 +914,11 @@ int in_gate_area_no_task(unsigned long a
19463  #define in_gate_area(task, addr) ({(void)task; in_gate_area_no_task(addr);})
19464  #endif /* __HAVE_ARCH_GATE_AREA */
19465  
19466 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19467 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
19468 +#else
19469 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
19470 +#endif
19471 +
19472  #endif /* __KERNEL__ */
19473  #endif /* _LINUX_MM_H */
19474 diff -urNp linux-2.6.11/include/linux/mman.h linux-2.6.11/include/linux/mman.h
19475 --- linux-2.6.11/include/linux/mman.h   2005-03-02 02:37:48.000000000 -0500
19476 +++ linux-2.6.11/include/linux/mman.h   2005-03-09 11:56:44.000000000 -0500
19477 @@ -59,6 +59,11 @@ static inline unsigned long
19478  calc_vm_flag_bits(unsigned long flags)
19479  {
19480         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
19481 +
19482 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19483 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
19484 +#endif
19485 +
19486                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
19487                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
19488                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
19489 diff -urNp linux-2.6.11/include/linux/random.h linux-2.6.11/include/linux/random.h
19490 --- linux-2.6.11/include/linux/random.h 2005-03-02 02:38:33.000000000 -0500
19491 +++ linux-2.6.11/include/linux/random.h 2005-03-09 11:56:44.000000000 -0500
19492 @@ -66,6 +66,8 @@ extern __u32 check_tcp_syn_cookie(__u32 
19493  extern __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
19494                                           __u16 sport, __u16 dport);
19495  
19496 +extern unsigned long pax_get_random_long(void);
19497 +
19498  #ifndef MODULE
19499  extern struct file_operations random_fops, urandom_fops;
19500  #endif
19501 diff -urNp linux-2.6.11/include/linux/sched.h linux-2.6.11/include/linux/sched.h
19502 --- linux-2.6.11/include/linux/sched.h  2005-03-02 02:37:48.000000000 -0500
19503 +++ linux-2.6.11/include/linux/sched.h  2005-03-09 11:56:44.000000000 -0500
19504 @@ -34,6 +34,7 @@
19505  #include <linux/topology.h>
19506  
19507  struct exec_domain;
19508 +struct linux_binprm;
19509  
19510  /*
19511   * cloning flags:
19512 @@ -256,8 +257,34 @@ struct mm_struct {
19513  
19514         unsigned long hiwater_rss;      /* High-water RSS usage */
19515         unsigned long hiwater_vm;       /* High-water virtual memory usage */
19516 +
19517 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19518 +       unsigned long flags;
19519 +#endif
19520 +
19521 +#ifdef CONFIG_PAX_DLRESOLVE
19522 +       unsigned long call_dl_resolve;
19523 +#endif
19524 +
19525 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
19526 +       unsigned long call_syscall;
19527 +#endif
19528 +
19529 +#ifdef CONFIG_PAX_ASLR
19530 +       unsigned long delta_mmap;               /* randomized offset */
19531 +       unsigned long delta_exec;               /* randomized offset */
19532 +       unsigned long delta_stack;              /* randomized offset */
19533 +#endif
19534 +
19535  };
19536  
19537 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
19538 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
19539 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
19540 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
19541 +#define MF_PAX_RANDEXEC                0x10000000      /* Randomize ET_EXEC base */
19542 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
19543 +
19544  struct sighand_struct {
19545         atomic_t                count;
19546         struct k_sigaction      action[_NSIG];
19547 @@ -685,6 +712,23 @@ struct task_struct {
19548         struct mempolicy *mempolicy;
19549         short il_next;
19550  #endif
19551 +
19552 +#ifdef CONFIG_GRKERNSEC
19553 +       /* grsecurity */
19554 +       struct acl_subject_label *acl;
19555 +       struct acl_role_label *role;
19556 +       struct file *exec_file;
19557 +       u32 curr_ip;
19558 +       u32 gr_saddr;
19559 +       u32 gr_daddr;
19560 +       u16 gr_sport;
19561 +       u16 gr_dport;
19562 +       u16 acl_role_id;
19563 +       u8 acl_sp_role:1;
19564 +       u8 used_accept:1;
19565 +       u8 is_writable:1;
19566 +       u8 brute:1;
19567 +#endif
19568  };
19569  
19570  static inline pid_t process_group(struct task_struct *tsk)
19571 @@ -918,14 +962,29 @@ static inline int sas_ss_flags(unsigned 
19572                 : on_sig_stack(sp) ? SS_ONSTACK : 0);
19573  }
19574  
19575 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
19576 +extern int gr_is_capable_nolog(const int cap);
19577  
19578  #ifdef CONFIG_SECURITY
19579  /* code is in security.c */
19580  extern int capable(int cap);
19581 +static inline int capable_nolog(int cap)
19582 +{
19583 +       return capable(cap);
19584 +}
19585  #else
19586  static inline int capable(int cap)
19587  {
19588 -       if (cap_raised(current->cap_effective, cap)) {
19589 +       if (cap_raised(current->cap_effective, cap) && gr_task_is_capable(current, cap)) {
19590 +               current->flags |= PF_SUPERPRIV;
19591 +               return 1;
19592 +       }
19593 +       return 0;
19594 +}
19595 +
19596 +static inline int capable_nolog(int cap)
19597 +{
19598 +       if (cap_raised(current->cap_effective, cap) && gr_is_capable_nolog(cap)) {
19599                 current->flags |= PF_SUPERPRIV;
19600                 return 1;
19601         }
19602 @@ -1172,6 +1231,12 @@ extern void arch_pick_mmap_layout(struct
19603  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
19604  {
19605         mm->mmap_base = TASK_UNMAPPED_BASE;
19606 +
19607 +#ifdef CONFIG_PAX_RANDMMAP
19608 +       if (mm->flags & MF_PAX_RANDMMAP)
19609 +               mm->mmap_base += mm->delta_mmap;
19610 +#endif
19611 +
19612         mm->get_unmapped_area = arch_get_unmapped_area;
19613         mm->unmap_area = arch_unmap_area;
19614  }
19615 diff -urNp linux-2.6.11/include/linux/shm.h linux-2.6.11/include/linux/shm.h
19616 --- linux-2.6.11/include/linux/shm.h    2005-03-02 02:38:17.000000000 -0500
19617 +++ linux-2.6.11/include/linux/shm.h    2005-03-09 11:56:44.000000000 -0500
19618 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
19619         pid_t                   shm_cprid;
19620         pid_t                   shm_lprid;
19621         struct user_struct      *mlock_user;
19622 +#ifdef CONFIG_GRKERNSEC
19623 +       time_t                  shm_createtime;
19624 +       pid_t                   shm_lapid;
19625 +#endif
19626  };
19627  
19628  /* shm_mode upper byte flags */
19629 diff -urNp linux-2.6.11/include/linux/sysctl.h linux-2.6.11/include/linux/sysctl.h
19630 --- linux-2.6.11/include/linux/sysctl.h 2005-03-02 02:38:10.000000000 -0500
19631 +++ linux-2.6.11/include/linux/sysctl.h 2005-03-09 11:56:44.000000000 -0500
19632 @@ -135,8 +135,20 @@ enum
19633         KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
19634         KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */
19635         KERN_FBSPLASH=68,       /* string: path to fbsplash helper */
19636 +       KERN_GRSECURITY=69,     /* grsecurity */
19637 +
19638 +#ifdef CONFIG_PAX_SOFTMODE
19639 +       KERN_PAX=70,            /* PaX control */
19640 +#endif
19641 +
19642  };
19643  
19644 +#ifdef CONFIG_PAX_SOFTMODE
19645 +enum {
19646 +       PAX_ASLR=1,             /* PaX: disable/enable all randomization features */
19647 +       PAX_SOFTMODE=2          /* PaX: disable/enable soft mode */
19648 +};
19649 +#endif
19650  
19651  /* CTL_VM names: */
19652  enum
19653 diff -urNp linux-2.6.11/init/Kconfig linux-2.6.11/init/Kconfig
19654 --- linux-2.6.11/init/Kconfig   2005-03-02 02:38:19.000000000 -0500
19655 +++ linux-2.6.11/init/Kconfig   2005-03-09 11:56:44.000000000 -0500
19656 @@ -249,6 +249,7 @@ menuconfig EMBEDDED
19657  config KALLSYMS
19658          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
19659          default y
19660 +        depends on !GRKERNSEC_HIDESYM
19661          help
19662            Say Y here to let the kernel print out symbolic crash information and
19663            symbolic stack backtraces. This increases the size of the kernel
19664 diff -urNp linux-2.6.11/init/main.c linux-2.6.11/init/main.c
19665 --- linux-2.6.11/init/main.c    2005-03-02 02:37:49.000000000 -0500
19666 +++ linux-2.6.11/init/main.c    2005-03-09 11:56:44.000000000 -0500
19667 @@ -98,6 +98,7 @@ extern void acpi_early_init(void);
19668  #else
19669  static inline void acpi_early_init(void) { }
19670  #endif
19671 +extern void grsecurity_init(void);
19672  
19673  #ifdef CONFIG_TC
19674  extern void tc_init(void);
19675 @@ -660,6 +661,7 @@ static int init(void * unused)
19676                 execute_command = "/init";
19677         else
19678                 prepare_namespace();
19679 +       grsecurity_init();
19680  
19681         /*
19682          * Ok, we have completed the initial bootup, and
19683 diff -urNp linux-2.6.11/ipc/msg.c linux-2.6.11/ipc/msg.c
19684 --- linux-2.6.11/ipc/msg.c      2005-03-02 02:37:30.000000000 -0500
19685 +++ linux-2.6.11/ipc/msg.c      2005-03-09 11:56:44.000000000 -0500
19686 @@ -25,6 +25,7 @@
19687  #include <linux/security.h>
19688  #include <linux/sched.h>
19689  #include <linux/syscalls.h>
19690 +#include <linux/grsecurity.h>
19691  #include <asm/current.h>
19692  #include <asm/uaccess.h>
19693  #include "util.h"
19694 @@ -229,6 +230,9 @@ asmlinkage long sys_msgget (key_t key, i
19695                 msg_unlock(msq);
19696         }
19697         up(&msg_ids.sem);
19698 +
19699 +       gr_log_msgget(ret, msgflg);
19700 +
19701         return ret;
19702  }
19703  
19704 @@ -478,6 +482,8 @@ asmlinkage long sys_msgctl (int msqid, i
19705                 break;
19706         }
19707         case IPC_RMID:
19708 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
19709 +
19710                 freeque (msq, msqid); 
19711                 break;
19712         }
19713 diff -urNp linux-2.6.11/ipc/sem.c linux-2.6.11/ipc/sem.c
19714 --- linux-2.6.11/ipc/sem.c      2005-03-02 02:38:03.000000000 -0500
19715 +++ linux-2.6.11/ipc/sem.c      2005-03-09 11:56:44.000000000 -0500
19716 @@ -72,6 +72,7 @@
19717  #include <linux/smp_lock.h>
19718  #include <linux/security.h>
19719  #include <linux/syscalls.h>
19720 +#include <linux/grsecurity.h>
19721  #include <asm/uaccess.h>
19722  #include "util.h"
19723  
19724 @@ -239,6 +240,9 @@ asmlinkage long sys_semget (key_t key, i
19725         }
19726  
19727         up(&sem_ids.sem);
19728 +
19729 +       gr_log_semget(err, semflg);
19730 +
19731         return err;
19732  }
19733  
19734 @@ -826,6 +830,8 @@ static int semctl_down(int semid, int se
19735  
19736         switch(cmd){
19737         case IPC_RMID:
19738 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
19739 +
19740                 freeary(sma, semid);
19741                 err = 0;
19742                 break;
19743 diff -urNp linux-2.6.11/ipc/shm.c linux-2.6.11/ipc/shm.c
19744 --- linux-2.6.11/ipc/shm.c      2005-03-02 02:38:09.000000000 -0500
19745 +++ linux-2.6.11/ipc/shm.c      2005-03-09 11:56:44.000000000 -0500
19746 @@ -27,6 +27,7 @@
19747  #include <linux/shmem_fs.h>
19748  #include <linux/security.h>
19749  #include <linux/syscalls.h>
19750 +#include <linux/grsecurity.h>
19751  #include <asm/uaccess.h>
19752  
19753  #include "util.h"
19754 @@ -51,6 +52,14 @@ static void shm_close (struct vm_area_st
19755  static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
19756  #endif
19757  
19758 +#ifdef CONFIG_GRKERNSEC
19759 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19760 +                          const time_t shm_createtime, const uid_t cuid,
19761 +                          const int shmid);
19762 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19763 +                          const time_t shm_createtime);
19764 +#endif
19765 +
19766  size_t shm_ctlmax = SHMMAX;
19767  size_t         shm_ctlall = SHMALL;
19768  int    shm_ctlmni = SHMMNI;
19769 @@ -143,6 +152,17 @@ static void shm_close (struct vm_area_st
19770         shp->shm_lprid = current->tgid;
19771         shp->shm_dtim = get_seconds();
19772         shp->shm_nattch--;
19773 +#ifdef CONFIG_GRKERNSEC_SHM
19774 +       if (grsec_enable_shm) {
19775 +               if (shp->shm_nattch == 0) {
19776 +                       shp->shm_flags |= SHM_DEST;
19777 +                       shm_destroy(shp);
19778 +               } else
19779 +                       shm_unlock(shp);
19780 +               up(&shm_ids.sem);
19781 +               return;
19782 +       }
19783 +#endif
19784         if(shp->shm_nattch == 0 &&
19785            shp->shm_flags & SHM_DEST)
19786                 shm_destroy (shp);
19787 @@ -224,6 +244,9 @@ static int newseg (key_t key, int shmflg
19788         shp->shm_lprid = 0;
19789         shp->shm_atim = shp->shm_dtim = 0;
19790         shp->shm_ctim = get_seconds();
19791 +#ifdef CONFIG_GRKERNSEC
19792 +       shp->shm_createtime = get_seconds();
19793 +#endif
19794         shp->shm_segsz = size;
19795         shp->shm_nattch = 0;
19796         shp->id = shm_buildid(id,shp->shm_perm.seq);
19797 @@ -278,6 +301,8 @@ asmlinkage long sys_shmget (key_t key, s
19798         }
19799         up(&shm_ids.sem);
19800  
19801 +       gr_log_shmget(err, shmflg, size);
19802 +
19803         return err;
19804  }
19805  
19806 @@ -583,6 +608,8 @@ asmlinkage long sys_shmctl (int shmid, i
19807                 if (err)
19808                         goto out_unlock_up;
19809  
19810 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
19811 +
19812                 if (shp->shm_nattch){
19813                         shp->shm_flags |= SHM_DEST;
19814                         /* Do not find it any more */
19815 @@ -725,9 +752,27 @@ long do_shmat(int shmid, char __user *sh
19816                 return err;
19817         }
19818                 
19819 +#ifdef CONFIG_GRKERNSEC
19820 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
19821 +                            shp->shm_perm.cuid, shmid)) {
19822 +               shm_unlock(shp);
19823 +               return -EACCES;
19824 +       }
19825 +
19826 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
19827 +               shm_unlock(shp);
19828 +               return -EACCES;
19829 +       }
19830 +#endif
19831 +
19832         file = shp->shm_file;
19833         size = i_size_read(file->f_dentry->d_inode);
19834         shp->shm_nattch++;
19835 +
19836 +#ifdef CONFIG_GRKERNSEC
19837 +       shp->shm_lapid = current->pid;
19838 +#endif
19839 +
19840         shm_unlock(shp);
19841  
19842         down_write(&current->mm->mmap_sem);
19843 @@ -912,3 +957,24 @@ done:
19844         return len;
19845  }
19846  #endif
19847 +
19848 +void gr_shm_exit(struct task_struct *task)
19849 +{
19850 +#ifdef CONFIG_GRKERNSEC_SHM
19851 +       int i;
19852 +       struct shmid_kernel *shp;
19853 +
19854 +       if (!grsec_enable_shm)
19855 +               return;
19856 +
19857 +       for (i = 0; i <= shm_ids.max_id; i++) {
19858 +               shp = shm_get(i);
19859 +               if (shp && (shp->shm_cprid == task->pid) &&
19860 +                   (shp->shm_nattch <= 0)) {
19861 +                       shp->shm_flags |= SHM_DEST;
19862 +                       shm_destroy(shp);
19863 +               }
19864 +       }
19865 +#endif
19866 +       return;
19867 +}
19868 diff -urNp linux-2.6.11/kernel/capability.c linux-2.6.11/kernel/capability.c
19869 --- linux-2.6.11/kernel/capability.c    2005-03-02 02:38:13.000000000 -0500
19870 +++ linux-2.6.11/kernel/capability.c    2005-03-09 11:56:44.000000000 -0500
19871 @@ -11,6 +11,7 @@
19872  #include <linux/module.h>
19873  #include <linux/security.h>
19874  #include <linux/syscalls.h>
19875 +#include <linux/grsecurity.h>
19876  #include <asm/uaccess.h>
19877  
19878  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
19879 diff -urNp linux-2.6.11/kernel/configs.c linux-2.6.11/kernel/configs.c
19880 --- linux-2.6.11/kernel/configs.c       2005-03-02 02:37:55.000000000 -0500
19881 +++ linux-2.6.11/kernel/configs.c       2005-03-09 11:56:44.000000000 -0500
19882 @@ -89,8 +89,16 @@ static int __init ikconfig_init(void)
19883         struct proc_dir_entry *entry;
19884  
19885         /* create the current config file */
19886 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19887 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19888 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
19889 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
19890 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
19891 +#endif
19892 +#else
19893         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
19894                                   &proc_root);
19895 +#endif
19896         if (!entry)
19897                 return -ENOMEM;
19898  
19899 diff -urNp linux-2.6.11/kernel/exit.c linux-2.6.11/kernel/exit.c
19900 --- linux-2.6.11/kernel/exit.c  2005-03-02 02:38:25.000000000 -0500
19901 +++ linux-2.6.11/kernel/exit.c  2005-03-09 11:56:44.000000000 -0500
19902 @@ -26,6 +26,11 @@
19903  #include <linux/proc_fs.h>
19904  #include <linux/mempolicy.h>
19905  #include <linux/syscalls.h>
19906 +#include <linux/grsecurity.h>
19907 +
19908 +#ifdef CONFIG_GRKERNSEC
19909 +extern rwlock_t grsec_exec_file_lock;
19910 +#endif
19911  
19912  #include <asm/uaccess.h>
19913  #include <asm/unistd.h>
19914 @@ -223,6 +228,15 @@ void reparent_to_init(void)
19915  {
19916         write_lock_irq(&tasklist_lock);
19917  
19918 +#ifdef CONFIG_GRKERNSEC
19919 +       write_lock(&grsec_exec_file_lock);
19920 +       if (current->exec_file) {
19921 +               fput(current->exec_file);
19922 +               current->exec_file = NULL;
19923 +       }
19924 +       write_unlock(&grsec_exec_file_lock);
19925 +#endif
19926 +
19927         ptrace_unlink(current);
19928         /* Reparent to init */
19929         REMOVE_LINKS(current);
19930 @@ -230,6 +244,8 @@ void reparent_to_init(void)
19931         current->real_parent = child_reaper;
19932         SET_LINKS(current);
19933  
19934 +       gr_set_kernel_label(current);
19935 +
19936         /* Set the exit signal to SIGCHLD so we signal init on exit */
19937         current->exit_signal = SIGCHLD;
19938  
19939 @@ -324,6 +340,17 @@ void daemonize(const char *name, ...)
19940         vsnprintf(current->comm, sizeof(current->comm), name, args);
19941         va_end(args);
19942  
19943 +#ifdef CONFIG_GRKERNSEC
19944 +       write_lock(&grsec_exec_file_lock);
19945 +       if (current->exec_file) {
19946 +               fput(current->exec_file);
19947 +               current->exec_file = NULL;
19948 +       }
19949 +       write_unlock(&grsec_exec_file_lock);
19950 +#endif
19951 +
19952 +       gr_set_kernel_label(current);
19953 +
19954         /*
19955          * If we were started as result of loading a module, close all of the
19956          * user space pages.  We don't need them, and if we didn't close them
19957 @@ -811,9 +838,15 @@ fastcall NORET_TYPE void do_exit(long co
19958         group_dead = atomic_dec_and_test(&tsk->signal->live);
19959         if (group_dead)
19960                 acct_process(code);
19961 +
19962 +       gr_acl_handle_psacct(tsk, code);
19963 +       gr_acl_handle_exit();
19964 +       gr_del_task_from_ip_table(tsk);
19965 +
19966         exit_mm(tsk);
19967  
19968         exit_sem(tsk);
19969 +       gr_shm_exit(tsk);
19970         __exit_files(tsk);
19971         __exit_fs(tsk);
19972         exit_namespace(tsk);
19973 diff -urNp linux-2.6.11/kernel/fork.c linux-2.6.11/kernel/fork.c
19974 --- linux-2.6.11/kernel/fork.c  2005-03-02 02:37:48.000000000 -0500
19975 +++ linux-2.6.11/kernel/fork.c  2005-03-09 11:56:44.000000000 -0500
19976 @@ -40,6 +40,7 @@
19977  #include <linux/profile.h>
19978  #include <linux/rmap.h>
19979  #include <linux/acct.h>
19980 +#include <linux/grsecurity.h>
19981  
19982  #include <asm/pgtable.h>
19983  #include <asm/pgalloc.h>
19984 @@ -172,7 +173,7 @@ static inline int dup_mmap(struct mm_str
19985         mm->locked_vm = 0;
19986         mm->mmap = NULL;
19987         mm->mmap_cache = NULL;
19988 -       mm->free_area_cache = oldmm->mmap_base;
19989 +       mm->free_area_cache = oldmm->free_area_cache;
19990         mm->map_count = 0;
19991         mm->rss = 0;
19992         mm->anon_rss = 0;
19993 @@ -300,7 +301,6 @@ static struct mm_struct * mm_init(struct
19994         rwlock_init(&mm->ioctx_list_lock);
19995         mm->ioctx_list = NULL;
19996         mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
19997 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
19998  
19999         if (likely(!mm_alloc_pgd(mm))) {
20000                 mm->def_flags = 0;
20001 @@ -822,6 +822,9 @@ static task_t *copy_process(unsigned lon
20002                 goto fork_out;
20003  
20004         retval = -EAGAIN;
20005 +
20006 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
20007 +
20008         if (atomic_read(&p->user->processes) >=
20009                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
20010                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
20011 @@ -927,6 +930,8 @@ static task_t *copy_process(unsigned lon
20012         if (retval)
20013                 goto bad_fork_cleanup_namespace;
20014  
20015 +       gr_copy_label(p);
20016 +
20017         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
20018         /*
20019          * Clear TID on mm_release()?
20020 @@ -1077,6 +1082,9 @@ bad_fork_cleanup_count:
20021         free_uid(p->user);
20022  bad_fork_free:
20023         free_task(p);
20024 +
20025 +       gr_log_forkfail(retval);
20026 +
20027         goto fork_out;
20028  }
20029  
20030 @@ -1134,6 +1142,9 @@ long do_fork(unsigned long clone_flags,
20031  
20032         if (pid < 0)
20033                 return -EAGAIN;
20034 +
20035 +       gr_handle_brute_check();
20036 +
20037         if (unlikely(current->ptrace)) {
20038                 trace = fork_traceflag (clone_flags);
20039                 if (trace)
20040 diff -urNp linux-2.6.11/kernel/futex.c linux-2.6.11/kernel/futex.c
20041 --- linux-2.6.11/kernel/futex.c 2005-03-02 02:37:50.000000000 -0500
20042 +++ linux-2.6.11/kernel/futex.c 2005-03-09 11:56:44.000000000 -0500
20043 @@ -146,6 +146,11 @@ static int get_futex_key(unsigned long u
20044         struct page *page;
20045         int err;
20046  
20047 +#ifdef CONFIG_PAX_SEGMEXEC
20048 +       if ((mm->flags & MF_PAX_SEGMEXEC) && (uaddr >= SEGMEXEC_TASK_SIZE))
20049 +               return -EFAULT;
20050 +#endif
20051 +
20052         /*
20053          * The futex address must be "naturally" aligned.
20054          */
20055 @@ -158,7 +163,7 @@ static int get_futex_key(unsigned long u
20056          * The futex is hashed differently depending on whether
20057          * it's in a shared or private mapping.  So check vma first.
20058          */
20059 -       vma = find_extend_vma(mm, uaddr);
20060 +       vma = find_extend_vma(current, mm, uaddr);
20061         if (unlikely(!vma))
20062                 return -EFAULT;
20063  
20064 diff -urNp linux-2.6.11/kernel/kallsyms.c linux-2.6.11/kernel/kallsyms.c
20065 --- linux-2.6.11/kernel/kallsyms.c      2005-03-02 02:38:32.000000000 -0500
20066 +++ linux-2.6.11/kernel/kallsyms.c      2005-03-09 11:56:44.000000000 -0500
20067 @@ -388,7 +388,15 @@ int __init kallsyms_init(void)
20068  {
20069         struct proc_dir_entry *entry;
20070  
20071 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20072 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20073 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
20074 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
20075 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
20076 +#endif
20077 +#else
20078         entry = create_proc_entry("kallsyms", 0444, NULL);
20079 +#endif
20080         if (entry)
20081                 entry->proc_fops = &kallsyms_operations;
20082         return 0;
20083 diff -urNp linux-2.6.11/kernel/pid.c linux-2.6.11/kernel/pid.c
20084 --- linux-2.6.11/kernel/pid.c   2005-03-02 02:38:10.000000000 -0500
20085 +++ linux-2.6.11/kernel/pid.c   2005-03-09 11:56:44.000000000 -0500
20086 @@ -26,6 +26,7 @@
20087  #include <linux/init.h>
20088  #include <linux/bootmem.h>
20089  #include <linux/hash.h>
20090 +#include <linux/grsecurity.h>
20091  
20092  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
20093  static struct hlist_head *pid_hash[PIDTYPE_MAX];
20094 @@ -76,7 +77,9 @@ int alloc_pidmap(void)
20095         int i, offset, max_scan, pid, last = last_pid;
20096         pidmap_t *map;
20097  
20098 -       pid = last + 1;
20099 +       pid = gr_random_pid();
20100 +       if (!pid)
20101 +               pid = last_pid + 1;
20102         if (pid >= pid_max)
20103                 pid = RESERVED_PIDS;
20104         offset = pid & BITS_PER_PAGE_MASK;
20105 @@ -207,12 +210,18 @@ void fastcall detach_pid(task_t *task, e
20106  task_t *find_task_by_pid_type(int type, int nr)
20107  {
20108         struct pid *pid;
20109 +       task_t *task = NULL;
20110  
20111         pid = find_pid(type, nr);
20112         if (!pid)
20113                 return NULL;
20114  
20115 -       return pid_task(&pid->pid_list, type);
20116 +       task = pid_task(&pid->pid_list, type);
20117 +
20118 +       if (gr_pid_is_chrooted(task))
20119 +               return NULL;
20120 +
20121 +       return task;
20122  }
20123  
20124  EXPORT_SYMBOL(find_task_by_pid_type);
20125 diff -urNp linux-2.6.11/kernel/printk.c linux-2.6.11/kernel/printk.c
20126 --- linux-2.6.11/kernel/printk.c        2005-03-02 02:38:33.000000000 -0500
20127 +++ linux-2.6.11/kernel/printk.c        2005-03-09 11:56:44.000000000 -0500
20128 @@ -31,6 +31,7 @@
20129  #include <linux/security.h>
20130  #include <linux/bootmem.h>
20131  #include <linux/syscalls.h>
20132 +#include <linux/grsecurity.h>
20133  
20134  #include <asm/uaccess.h>
20135  
20136 @@ -253,6 +254,11 @@ int do_syslog(int type, char __user * bu
20137         char c;
20138         int error = 0;
20139  
20140 +#ifdef CONFIG_GRKERNSEC_DMESG
20141 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
20142 +               return -EPERM;
20143 +#endif
20144 +
20145         error = security_syslog(type);
20146         if (error)
20147                 return error;
20148 diff -urNp linux-2.6.11/kernel/resource.c linux-2.6.11/kernel/resource.c
20149 --- linux-2.6.11/kernel/resource.c      2005-03-02 02:38:13.000000000 -0500
20150 +++ linux-2.6.11/kernel/resource.c      2005-03-09 11:56:44.000000000 -0500
20151 @@ -136,10 +136,27 @@ static int __init ioresources_init(void)
20152  {
20153         struct proc_dir_entry *entry;
20154  
20155 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20156 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20157 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
20158 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
20159 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
20160 +#endif
20161 +#else
20162         entry = create_proc_entry("ioports", 0, NULL);
20163 +#endif
20164         if (entry)
20165                 entry->proc_fops = &proc_ioports_operations;
20166 +
20167 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20168 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20169 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
20170 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
20171 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
20172 +#endif
20173 +#else
20174         entry = create_proc_entry("iomem", 0, NULL);
20175 +#endif
20176         if (entry)
20177                 entry->proc_fops = &proc_iomem_operations;
20178         return 0;
20179 diff -urNp linux-2.6.11/kernel/sched.c linux-2.6.11/kernel/sched.c
20180 --- linux-2.6.11/kernel/sched.c 2005-03-02 02:38:19.000000000 -0500
20181 +++ linux-2.6.11/kernel/sched.c 2005-03-09 11:56:44.000000000 -0500
20182 @@ -45,6 +45,7 @@
20183  #include <linux/seq_file.h>
20184  #include <linux/syscalls.h>
20185  #include <linux/times.h>
20186 +#include <linux/grsecurity.h>
20187  #include <asm/tlb.h>
20188  
20189  #include <asm/unistd.h>
20190 @@ -2309,6 +2310,7 @@ static void check_rlimit(struct task_str
20191  
20192         total = cputime_add(p->utime, p->stime);
20193         secs = cputime_to_secs(total);
20194 +       gr_learn_resource(p, RLIMIT_CPU, secs, 1);
20195         if (unlikely(secs >= p->signal->rlim[RLIMIT_CPU].rlim_cur)) {
20196                 /* Send SIGXCPU every second. */
20197                 tmp = cputime_sub(total, cputime);
20198 @@ -3297,6 +3299,8 @@ asmlinkage long sys_nice(int increment)
20199                         return -EPERM;
20200                 if (increment < -40)
20201                         increment = -40;
20202 +               if (gr_handle_chroot_nice())
20203 +                       return -EPERM;
20204         }
20205         if (increment > 40)
20206                 increment = 40;
20207 diff -urNp linux-2.6.11/kernel/signal.c linux-2.6.11/kernel/signal.c
20208 --- linux-2.6.11/kernel/signal.c        2005-03-02 02:38:07.000000000 -0500
20209 +++ linux-2.6.11/kernel/signal.c        2005-03-09 11:56:44.000000000 -0500
20210 @@ -22,6 +22,7 @@
20211  #include <linux/security.h>
20212  #include <linux/syscalls.h>
20213  #include <linux/ptrace.h>
20214 +#include <linux/grsecurity.h>
20215  #include <asm/param.h>
20216  #include <asm/uaccess.h>
20217  #include <asm/unistd.h>
20218 @@ -642,7 +643,12 @@ static int check_kill_permission(int sig
20219             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
20220             && !capable(CAP_KILL))
20221                 return error;
20222 -       return security_task_kill(t, info, sig);
20223 +       if (gr_handle_signal(t, sig))
20224 +               return error;
20225 +       error = security_task_kill(t, info, sig);
20226 +       if (!error)
20227 +               gr_log_signal(sig, t);
20228 +       return error;
20229  }
20230  
20231  /* forward decl */
20232 @@ -840,7 +846,7 @@ out_set:
20233         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
20234  
20235  
20236 -static int
20237 +int
20238  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
20239  {
20240         int ret = 0;
20241 @@ -892,6 +898,9 @@ force_sig_info(int sig, struct siginfo *
20242         ret = specific_send_sig_info(sig, info, t);
20243         spin_unlock_irqrestore(&t->sighand->siglock, flags);
20244  
20245 +       gr_log_signal(sig, t);
20246 +       gr_handle_crash(t, sig);
20247 +
20248         return ret;
20249  }
20250  
20251 diff -urNp linux-2.6.11/kernel/sys.c linux-2.6.11/kernel/sys.c
20252 --- linux-2.6.11/kernel/sys.c   2005-03-02 02:37:48.000000000 -0500
20253 +++ linux-2.6.11/kernel/sys.c   2005-03-09 11:56:44.000000000 -0500
20254 @@ -24,6 +24,7 @@
20255  #include <linux/dcookies.h>
20256  #include <linux/suspend.h>
20257  #include <linux/tty.h>
20258 +#include <linux/grsecurity.h>
20259  
20260  #include <linux/compat.h>
20261  #include <linux/syscalls.h>
20262 @@ -229,6 +230,12 @@ static int set_one_prio(struct task_stru
20263                 error = -EACCES;
20264                 goto out;
20265         }
20266 +
20267 +       if (gr_handle_chroot_setpriority(p, niceval)) {
20268 +               error = -EACCES;
20269 +               goto out;
20270 +       }
20271 +
20272         no_nice = security_task_setnice(p, niceval);
20273         if (no_nice) {
20274                 error = no_nice;
20275 @@ -528,6 +535,9 @@ asmlinkage long sys_setregid(gid_t rgid,
20276         if (rgid != (gid_t) -1 ||
20277             (egid != (gid_t) -1 && egid != old_rgid))
20278                 current->sgid = new_egid;
20279 +
20280 +       gr_set_role_label(current, current->uid, new_rgid);
20281 +
20282         current->fsgid = new_egid;
20283         current->egid = new_egid;
20284         current->gid = new_rgid;
20285 @@ -556,6 +566,9 @@ asmlinkage long sys_setgid(gid_t gid)
20286                         current->mm->dumpable=0;
20287                         wmb();
20288                 }
20289 +
20290 +               gr_set_role_label(current, current->uid, gid);
20291 +
20292                 current->gid = current->egid = current->sgid = current->fsgid = gid;
20293         }
20294         else if ((gid == current->gid) || (gid == current->sgid))
20295 @@ -596,6 +609,9 @@ static int set_user(uid_t new_ruid, int 
20296                 current->mm->dumpable = 0;
20297                 wmb();
20298         }
20299 +
20300 +       gr_set_role_label(current, new_ruid, current->gid);
20301 +
20302         current->uid = new_ruid;
20303         return 0;
20304  }
20305 @@ -698,6 +714,9 @@ asmlinkage long sys_setuid(uid_t uid)
20306         } else if ((uid != current->uid) && (uid != new_suid))
20307                 return -EPERM;
20308  
20309 +       if (gr_check_crash_uid(uid))
20310 +               return -EPERM;
20311 +
20312         if (old_euid != uid)
20313         {
20314                 current->mm->dumpable = 0;
20315 @@ -801,8 +820,10 @@ asmlinkage long sys_setresgid(gid_t rgid
20316                 current->egid = egid;
20317         }
20318         current->fsgid = current->egid;
20319 -       if (rgid != (gid_t) -1)
20320 +       if (rgid != (gid_t) -1) {
20321 +               gr_set_role_label(current, current->uid, rgid);
20322                 current->gid = rgid;
20323 +       }
20324         if (sgid != (gid_t) -1)
20325                 current->sgid = sgid;
20326  
20327 diff -urNp linux-2.6.11/kernel/sysctl.c linux-2.6.11/kernel/sysctl.c
20328 --- linux-2.6.11/kernel/sysctl.c        2005-03-02 02:37:48.000000000 -0500
20329 +++ linux-2.6.11/kernel/sysctl.c        2005-03-09 11:56:44.000000000 -0500
20330 @@ -50,6 +50,14 @@
20331  #endif
20332  
20333  #if defined(CONFIG_SYSCTL)
20334 +#include <linux/grsecurity.h>
20335 +#include <linux/grinternal.h>
20336 +
20337 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
20338 +                             const void *newval);
20339 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
20340 +                               const int op);
20341 +extern int gr_handle_chroot_sysctl(const int op);
20342  
20343  /* External variables not in a header file. */
20344  extern int C_A_D;
20345 @@ -147,6 +155,32 @@ extern ctl_table pty_table[];
20346  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
20347  int sysctl_legacy_va_layout;
20348  #endif
20349 +extern ctl_table grsecurity_table[];
20350 +
20351 +#ifdef CONFIG_PAX_SOFTMODE
20352 +static ctl_table pax_table[] = {
20353 +
20354 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
20355 +       {
20356 +               .ctl_name       = PAX_ASLR,
20357 +               .procname       = "aslr",
20358 +               .data           = &pax_aslr,
20359 +               .maxlen         = sizeof(unsigned int),
20360 +               .mode           = 0600,
20361 +               .proc_handler   = &proc_dointvec,
20362 +       },
20363 +#endif
20364 +
20365 +       {
20366 +               .ctl_name       = PAX_SOFTMODE,
20367 +               .procname       = "softmode",
20368 +               .data           = &pax_softmode,
20369 +               .maxlen         = sizeof(unsigned int),
20370 +               .mode           = 0600,
20371 +               .proc_handler   = &proc_dointvec,
20372 +       }
20373 +};
20374 +#endif
20375  
20376  /* /proc declarations: */
20377  
20378 @@ -632,6 +666,24 @@ static ctl_table kern_table[] = {
20379                 .proc_handler   = &proc_dointvec,
20380         },
20381  #endif
20382 +#ifdef CONFIG_GRKERNSEC_SYSCTL
20383 +       {
20384 +               .ctl_name       = KERN_GRSECURITY,
20385 +               .procname       = "grsecurity",
20386 +               .mode           = 0500,
20387 +               .child          = grsecurity_table,
20388 +       },
20389 +#endif
20390 +
20391 +#ifdef CONFIG_PAX_SOFTMODE
20392 +       {
20393 +               .ctl_name       = KERN_PAX,
20394 +               .procname       = "pax",
20395 +               .mode           = 0500,
20396 +               .child          = pax_table,
20397 +       },
20398 +#endif
20399 +
20400         { .ctl_name = 0 }
20401  };
20402  
20403 @@ -1023,6 +1075,10 @@ static int test_perm(int mode, int op)
20404  static inline int ctl_perm(ctl_table *table, int op)
20405  {
20406         int error;
20407 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
20408 +               return -EACCES;
20409 +       if (gr_handle_chroot_sysctl(op))
20410 +               return -EACCES;
20411         error = security_sysctl(table, op);
20412         if (error)
20413                 return error;
20414 @@ -1059,6 +1115,10 @@ repeat:
20415                                 table = table->child;
20416                                 goto repeat;
20417                         }
20418 +
20419 +                       if (!gr_handle_sysctl(table, oldval, newval))
20420 +                               return -EACCES;
20421 +
20422                         error = do_sysctl_strategy(table, name, nlen,
20423                                                    oldval, oldlenp,
20424                                                    newval, newlen, context);
20425 diff -urNp linux-2.6.11/kernel/time.c linux-2.6.11/kernel/time.c
20426 --- linux-2.6.11/kernel/time.c  2005-03-02 02:37:50.000000000 -0500
20427 +++ linux-2.6.11/kernel/time.c  2005-03-09 11:56:44.000000000 -0500
20428 @@ -34,6 +34,7 @@
20429  #include <linux/syscalls.h>
20430  #include <linux/security.h>
20431  #include <linux/fs.h>
20432 +#include <linux/grsecurity.h>
20433  
20434  #include <asm/uaccess.h>
20435  #include <asm/unistd.h>
20436 @@ -91,6 +92,9 @@ asmlinkage long sys_stime(time_t __user 
20437                 return err;
20438  
20439         do_settimeofday(&tv);
20440 +
20441 +       gr_log_timechange();
20442 +
20443         return 0;
20444  }
20445  
20446 @@ -194,6 +198,8 @@ asmlinkage long sys_settimeofday(struct 
20447                         return -EFAULT;
20448         }
20449  
20450 +       gr_log_timechange();
20451 +
20452         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
20453  }
20454  
20455 diff -urNp linux-2.6.11/mm/filemap.c linux-2.6.11/mm/filemap.c
20456 --- linux-2.6.11/mm/filemap.c   2005-03-02 02:38:37.000000000 -0500
20457 +++ linux-2.6.11/mm/filemap.c   2005-03-09 11:56:44.000000000 -0500
20458 @@ -28,6 +28,8 @@
20459  #include <linux/blkdev.h>
20460  #include <linux/security.h>
20461  #include <linux/syscalls.h>
20462 +#include <linux/grsecurity.h>
20463 +
20464  /*
20465   * This is needed for the following functions:
20466   *  - try_to_release_page
20467 @@ -1516,6 +1518,12 @@ int generic_file_mmap(struct file * file
20468  
20469         if (!mapping->a_ops->readpage)
20470                 return -ENOEXEC;
20471 +
20472 +#ifdef CONFIG_PAX_PAGEEXEC
20473 +       if (vma->vm_mm->flags & MF_PAX_PAGEEXEC)
20474 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
20475 +#endif
20476 +
20477         file_accessed(file);
20478         vma->vm_ops = &generic_file_vm_ops;
20479         return 0;
20480 @@ -1815,6 +1823,7 @@ inline int generic_write_checks(struct f
20481                          *pos = i_size_read(inode);
20482  
20483                 if (limit != RLIM_INFINITY) {
20484 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
20485                         if (*pos >= limit) {
20486                                 send_sig(SIGXFSZ, current, 0);
20487                                 return -EFBIG;
20488 diff -urNp linux-2.6.11/mm/madvise.c linux-2.6.11/mm/madvise.c
20489 --- linux-2.6.11/mm/madvise.c   2005-03-02 02:37:50.000000000 -0500
20490 +++ linux-2.6.11/mm/madvise.c   2005-03-09 11:56:44.000000000 -0500
20491 @@ -14,8 +14,42 @@
20492   * We can potentially split a vm area into separate
20493   * areas, each area with its own behavior.
20494   */
20495 +
20496 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20497 +static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
20498 +                            unsigned long end, int behavior);
20499 +
20500 +static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
20501 +                            unsigned long end, int behavior)
20502 +{
20503 +       if (vma->vm_flags & VM_MIRROR) {
20504 +               struct vm_area_struct * vma_m, * prev_m;
20505 +               unsigned long start_m, end_m;
20506 +               int error;
20507 +
20508 +               start_m = vma->vm_start + vma->vm_mirror;
20509 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
20510 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
20511 +                       start_m = start + vma->vm_mirror;
20512 +                       end_m = end + vma->vm_mirror;
20513 +                       error = __madvise_behavior(vma_m, start_m, end_m, behavior);
20514 +                       if (error)
20515 +                               return error;
20516 +               } else {
20517 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
20518 +                       return -ENOMEM;
20519 +               }
20520 +       }
20521 +
20522 +       return __madvise_behavior(vma, start, end, behavior);
20523 +}
20524 +
20525 +static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
20526 +                            unsigned long end, int behavior)
20527 +#else
20528  static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
20529                              unsigned long end, int behavior)
20530 +#endif
20531  {
20532         struct mm_struct * mm = vma->vm_mm;
20533         int error = 0;
20534 diff -urNp linux-2.6.11/mm/memory.c linux-2.6.11/mm/memory.c
20535 --- linux-2.6.11/mm/memory.c    2005-03-02 02:38:08.000000000 -0500
20536 +++ linux-2.6.11/mm/memory.c    2005-03-09 11:56:44.000000000 -0500
20537 @@ -49,6 +49,7 @@
20538  #include <linux/acct.h>
20539  #include <linux/module.h>
20540  #include <linux/init.h>
20541 +#include <linux/grsecurity.h>
20542  
20543  #include <asm/pgalloc.h>
20544  #include <asm/uaccess.h>
20545 @@ -873,7 +874,7 @@ int get_user_pages(struct task_struct *t
20546         do {
20547                 struct vm_area_struct * vma;
20548  
20549 -               vma = find_extend_vma(mm, start);
20550 +               vma = find_extend_vma(tsk, mm, start);
20551                 if (!vma && in_gate_area(tsk, start)) {
20552                         unsigned long pg = start & PAGE_MASK;
20553                         struct vm_area_struct *gate_vma = get_gate_vma(tsk);
20554 @@ -1254,6 +1255,85 @@ static inline void break_cow(struct vm_a
20555         update_mmu_cache(vma, address, entry);
20556  }
20557  
20558 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20559 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
20560 + *
20561 + * mm->page_table_lock is held on entry and is not released on exit or inside
20562 + * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
20563 + */
20564 +static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
20565 +       unsigned long address, pte_t *pte)
20566 +{
20567 +       unsigned long address_m;
20568 +       struct vm_area_struct * vma_m = NULL;
20569 +       pte_t * pte_m, entry_m;
20570 +       struct page * page_m;
20571 +
20572 +       address_m = vma->vm_start + vma->vm_mirror;
20573 +       vma_m = find_vma(mm, address_m);
20574 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
20575 +
20576 +       address_m = address + vma->vm_mirror;
20577 +
20578 +       {
20579 +               pgd_t *pgd_m;
20580 +               pud_t *pud_m;
20581 +               pmd_t *pmd_m;
20582 +
20583 +               pgd_m = pgd_offset(mm, address_m);
20584 +               pud_m = pud_offset(pgd_m, address_m);
20585 +               pmd_m = pmd_offset(pud_m, address_m);
20586 +               pte_m = pte_offset_map_nested(pmd_m, address_m);
20587 +       }
20588 +
20589 +       if (pte_present(*pte_m)) {
20590 +               flush_cache_page(vma_m, address_m);
20591 +               flush_icache_page(vma_m, pte_page(*pte_m));
20592 +       }
20593 +       entry_m = ptep_get_and_clear(pte_m);
20594 +       if (pte_present(entry_m))
20595 +               flush_tlb_page(vma_m, address_m);
20596 +
20597 +       if (pte_none(entry_m)) {
20598 +               ++mm->rss;
20599 +       } else if (pte_present(entry_m)) {
20600 +               page_m = pte_page(entry_m);
20601 +               if (PageAnon(page_m))
20602 +                       --mm->anon_rss;
20603 +               if (PageReserved(page_m))
20604 +                       ++mm->rss;
20605 +               else
20606 +                       page_remove_rmap(page_m);
20607 +               page_cache_release(page_m);
20608 +       } else if (!pte_file(entry_m)) {
20609 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
20610 +               ++mm->rss;
20611 +       } else {
20612 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
20613 +                               address, vma->vm_start, address_m, vma_m->vm_start);
20614 +       }
20615 +
20616 +       page_m = pte_page(*pte);
20617 +       entry_m = mk_pte(page_m, vma_m->vm_page_prot);
20618 +       if (pte_write(*pte))
20619 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
20620 +       if (!PageReserved(page_m)) {
20621 +               page_cache_get(page_m);
20622 +               /*
20623 +                * we can test PG_anon without holding page_map_lock because
20624 +                * we hold the page table lock and have a reference to page_m
20625 +                */
20626 +               if (PageAnon(page_m))
20627 +                       page_add_anon_rmap(page_m, vma_m, address_m);
20628 +               else
20629 +                       page_add_file_rmap(page_m);
20630 +       }
20631 +       ptep_establish(vma_m, address_m, pte_m, entry_m);
20632 +       update_mmu_cache(vma_m, address_m, entry_m);
20633 +       pte_unmap_nested(pte_m);
20634 +}
20635 +#endif
20636 +
20637  /*
20638   * This routine handles present pages, when users try to write
20639   * to a shared page. It is done by copying the page to a new address
20640 @@ -1350,6 +1430,12 @@ static int do_wp_page(struct mm_struct *
20641  
20642                 /* Free the old page.. */
20643                 new_page = old_page;
20644 +
20645 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20646 +               if (vma->vm_flags & VM_MIRROR)
20647 +                       pax_mirror_fault(mm, vma, address, page_table);
20648 +#endif
20649 +
20650         }
20651         pte_unmap(page_table);
20652         page_cache_release(new_page);
20653 @@ -1605,6 +1691,7 @@ int vmtruncate(struct inode * inode, lof
20654  
20655  do_expand:
20656         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
20657 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
20658         if (limit != RLIM_INFINITY && offset > limit)
20659                 goto out_sig;
20660         if (offset > inode->i_sb->s_maxbytes)
20661 @@ -1770,6 +1857,12 @@ static int do_swap_page(struct mm_struct
20662  
20663         /* No need to invalidate - it was non-present before */
20664         update_mmu_cache(vma, address, pte);
20665 +
20666 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20667 +       if (vma->vm_flags & VM_MIRROR)
20668 +               pax_mirror_fault(mm, vma, address, page_table);
20669 +#endif
20670 +
20671         pte_unmap(page_table);
20672         spin_unlock(&mm->page_table_lock);
20673  out:
20674 @@ -1825,10 +1918,16 @@ do_anonymous_page(struct mm_struct *mm, 
20675         }
20676  
20677         set_pte(page_table, entry);
20678 -       pte_unmap(page_table);
20679  
20680         /* No need to invalidate - it was non-present before */
20681         update_mmu_cache(vma, addr, entry);
20682 +
20683 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20684 +       if (vma->vm_flags & VM_MIRROR)
20685 +               pax_mirror_fault(mm, vma, addr, page_table);
20686 +#endif
20687 +
20688 +       pte_unmap(page_table);
20689         spin_unlock(&mm->page_table_lock);
20690  out:
20691         return VM_FAULT_MINOR;
20692 @@ -1945,6 +2044,15 @@ retry:
20693                         page_add_anon_rmap(new_page, vma, address);
20694                 } else
20695                         page_add_file_rmap(new_page);
20696 +
20697 +               /* no need to invalidate: a not-present page shouldn't be cached */
20698 +               update_mmu_cache(vma, address, entry);
20699 +
20700 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20701 +               if (vma->vm_flags & VM_MIRROR)
20702 +                       pax_mirror_fault(mm, vma, address, page_table);
20703 +#endif
20704 +
20705                 pte_unmap(page_table);
20706         } else {
20707                 /* One of our sibling threads was faster, back out. */
20708 @@ -1954,8 +2062,6 @@ retry:
20709                 goto out;
20710         }
20711  
20712 -       /* no need to invalidate: a not-present page shouldn't be cached */
20713 -       update_mmu_cache(vma, address, entry);
20714         spin_unlock(&mm->page_table_lock);
20715  out:
20716         return ret;
20717 @@ -2066,6 +2172,11 @@ int handle_mm_fault(struct mm_struct *mm
20718         pmd_t *pmd;
20719         pte_t *pte;
20720  
20721 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20722 +       unsigned long address_m = 0UL;
20723 +       struct vm_area_struct * vma_m = NULL;
20724 +#endif
20725 +
20726         __set_current_state(TASK_RUNNING);
20727  
20728         inc_page_state(pgfault);
20729 @@ -2080,6 +2191,45 @@ int handle_mm_fault(struct mm_struct *mm
20730         pgd = pgd_offset(mm, address);
20731         spin_lock(&mm->page_table_lock);
20732  
20733 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20734 +       if (vma->vm_flags & VM_MIRROR) {
20735 +               pgd_t *pgd_m;
20736 +               pud_t *pud_m;
20737 +               pmd_t *pmd_m = NULL;
20738 +               pte_t *pte_m = NULL;
20739 +
20740 +               address_m = vma->vm_start + vma->vm_mirror;
20741 +               vma_m = find_vma(mm, address_m);
20742 +
20743 +               /* PaX: sanity checks */
20744 +               if (!vma_m) {
20745 +                       spin_unlock(&mm->page_table_lock);
20746 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
20747 +                              address, vma, address_m, vma_m);
20748 +                       return VM_FAULT_SIGBUS;
20749 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
20750 +                       vma_m->vm_start != address_m ||
20751 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
20752 +               {
20753 +                       spin_unlock(&mm->page_table_lock);
20754 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
20755 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
20756 +                       return VM_FAULT_SIGBUS;
20757 +               }
20758 +
20759 +               address_m = address + vma->vm_mirror;
20760 +               pgd_m = pgd_offset(mm, address_m);
20761 +               pud_m = pud_alloc(mm, pgd_m, address_m);
20762 +               if (pud_m)
20763 +                       pmd_m = pmd_alloc(mm, pud_m, address_m);
20764 +               if (pmd_m)
20765 +                       pte_m = pte_alloc_map(mm, pmd_m, address_m);
20766 +               if (!pud_m || !pmd_m || !pte_m)
20767 +                       goto oom;
20768 +               pte_unmap(pte_m);
20769 +       }
20770 +#endif
20771 +
20772         pud = pud_alloc(mm, pgd, address);
20773         if (!pud)
20774                 goto oom;
20775 diff -urNp linux-2.6.11/mm/mempolicy.c linux-2.6.11/mm/mempolicy.c
20776 --- linux-2.6.11/mm/mempolicy.c 2005-03-02 02:38:33.000000000 -0500
20777 +++ linux-2.6.11/mm/mempolicy.c 2005-03-09 11:56:44.000000000 -0500
20778 @@ -293,6 +293,12 @@ check_range(struct mm_struct *mm, unsign
20779                         return ERR_PTR(-EFAULT);
20780                 if (prev && prev->vm_end < vma->vm_start)
20781                         return ERR_PTR(-EFAULT);
20782 +
20783 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20784 +               if (vma-vm_flags & VM_MIRROR)
20785 +                       return ERR_PTR(-EFAULT);
20786 +#endif
20787 +
20788                 if ((flags & MPOL_MF_STRICT) && !is_vm_hugetlb_page(vma)) {
20789                         err = verify_pages(vma->vm_mm,
20790                                            vma->vm_start, vma->vm_end, nodes);
20791 diff -urNp linux-2.6.11/mm/mlock.c linux-2.6.11/mm/mlock.c
20792 --- linux-2.6.11/mm/mlock.c     2005-03-02 02:37:47.000000000 -0500
20793 +++ linux-2.6.11/mm/mlock.c     2005-03-09 11:56:44.000000000 -0500
20794 @@ -8,13 +8,62 @@
20795  #include <linux/mman.h>
20796  #include <linux/mm.h>
20797  #include <linux/syscalls.h>
20798 +#include <linux/grsecurity.h>
20799  
20800 +static int __mlock_fixup1(struct vm_area_struct * vma, 
20801 +       unsigned long start, unsigned long end, unsigned int newflags);
20802 +
20803 +static int __mlock_fixup2(struct vm_area_struct * vma, 
20804 +       unsigned long start, unsigned long end, unsigned int newflags);
20805  
20806  static int mlock_fixup(struct vm_area_struct * vma, 
20807         unsigned long start, unsigned long end, unsigned int newflags)
20808  {
20809 +       int error;
20810 +
20811 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20812 +       struct vm_area_struct * vma_m = NULL;
20813 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
20814 +
20815 +       if (vma->vm_flags & VM_MIRROR) {
20816 +               start_m = vma->vm_start + vma->vm_mirror;
20817 +               vma_m = find_vma(vma->vm_mm, start_m);
20818 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
20819 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
20820 +                       return -ENOMEM;
20821 +               }
20822 +
20823 +               start_m = start + vma->vm_mirror;
20824 +               end_m = end + vma->vm_mirror;
20825 +               if (newflags & VM_LOCKED)
20826 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
20827 +               else
20828 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
20829 +               error = __mlock_fixup1(vma_m, start_m, end_m, newflags_m);
20830 +               if (error)
20831 +                       return error;
20832 +       }
20833 +#endif
20834 +
20835 +       error = __mlock_fixup1(vma, start, end, newflags);
20836 +       if (error)
20837 +               return error;
20838 +
20839 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20840 +       if (vma->vm_flags & VM_MIRROR) {
20841 +               error = __mlock_fixup2(vma_m, start_m, end_m, newflags_m);
20842 +               if (error)
20843 +                       return error;
20844 +       }
20845 +#endif
20846 +
20847 +       return __mlock_fixup2(vma, start, end, newflags);
20848 +}
20849 +
20850 +static int __mlock_fixup1(struct vm_area_struct * vma, 
20851 +       unsigned long start, unsigned long end, unsigned int newflags)
20852 +{
20853         struct mm_struct * mm = vma->vm_mm;
20854 -       int pages;
20855         int ret = 0;
20856  
20857         if (newflags == vma->vm_flags)
20858 @@ -26,11 +75,20 @@ static int mlock_fixup(struct vm_area_st
20859                         goto out;
20860         }
20861  
20862 -       if (end != vma->vm_end) {
20863 +       if (end != vma->vm_end)
20864                 ret = split_vma(mm, vma, end, 0);
20865 -               if (ret)
20866 -                       goto out;
20867 -       }
20868 +
20869 +out:
20870 +       if (ret == -ENOMEM)
20871 +               ret = -EAGAIN;
20872 +       return ret;
20873 +}
20874 +
20875 +static int __mlock_fixup2(struct vm_area_struct * vma, 
20876 +       unsigned long start, unsigned long end, unsigned int newflags)
20877 +{
20878 +       int pages;
20879 +       int ret = 0;
20880  
20881         /*
20882          * vm_flags is protected by the mmap_sem held in write mode.
20883 @@ -48,9 +106,8 @@ static int mlock_fixup(struct vm_area_st
20884                 if (!(newflags & VM_IO))
20885                         ret = make_pages_present(start, end);
20886         }
20887 -
20888         vma->vm_mm->locked_vm -= pages;
20889 -out:
20890 +
20891         if (ret == -ENOMEM)
20892                 ret = -EAGAIN;
20893         return ret;
20894 @@ -68,6 +125,17 @@ static int do_mlock(unsigned long start,
20895                 return -EINVAL;
20896         if (end == start)
20897                 return 0;
20898 +
20899 +#ifdef CONFIG_PAX_SEGMEXEC
20900 +       if (current->mm->flags & MF_PAX_SEGMEXEC) {
20901 +               if (end > SEGMEXEC_TASK_SIZE)
20902 +                       return -EINVAL;
20903 +       } else
20904 +#endif
20905 +
20906 +       if (end > TASK_SIZE)
20907 +               return -EINVAL;
20908 +
20909         vma = find_vma(current->mm, start);
20910         if (!vma || vma->vm_start > start)
20911                 return -ENOMEM;
20912 @@ -121,6 +189,7 @@ asmlinkage long sys_mlock(unsigned long 
20913         lock_limit >>= PAGE_SHIFT;
20914  
20915         /* check against resource limits */
20916 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
20917         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
20918                 error = do_mlock(start, len, 1);
20919         up_write(&current->mm->mmap_sem);
20920 @@ -153,6 +222,16 @@ static int do_mlockall(int flags)
20921         for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
20922                 unsigned int newflags;
20923  
20924 +#ifdef CONFIG_PAX_SEGMEXEC
20925 +               if (current->mm->flags & MF_PAX_SEGMEXEC) {
20926 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
20927 +                               break;
20928 +               } else
20929 +#endif
20930 +
20931 +               if (vma->vm_end > TASK_SIZE)
20932 +                       break;
20933 +
20934                 newflags = vma->vm_flags | VM_LOCKED;
20935                 if (!(flags & MCL_CURRENT))
20936                         newflags &= ~VM_LOCKED;
20937 @@ -182,6 +261,7 @@ asmlinkage long sys_mlockall(int flags)
20938         lock_limit >>= PAGE_SHIFT;
20939  
20940         ret = -ENOMEM;
20941 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
20942         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
20943             capable(CAP_IPC_LOCK))
20944                 ret = do_mlockall(flags);
20945 diff -urNp linux-2.6.11/mm/mmap.c linux-2.6.11/mm/mmap.c
20946 --- linux-2.6.11/mm/mmap.c      2005-03-02 02:38:12.000000000 -0500
20947 +++ linux-2.6.11/mm/mmap.c      2005-03-09 11:56:44.000000000 -0500
20948 @@ -25,6 +25,7 @@
20949  #include <linux/mount.h>
20950  #include <linux/mempolicy.h>
20951  #include <linux/rmap.h>
20952 +#include <linux/grsecurity.h>
20953  
20954  #include <asm/uaccess.h>
20955  #include <asm/cacheflush.h>
20956 @@ -153,6 +154,7 @@ EXPORT_SYMBOL(sysctl_overcommit_ratio);
20957  EXPORT_SYMBOL(sysctl_max_map_count);
20958  EXPORT_SYMBOL(vm_committed_space);
20959  EXPORT_SYMBOL(__vm_enough_memory);
20960 +EXPORT_SYMBOL(protection_map);
20961  
20962  /*
20963   * Requires inode->i_mapping->i_mmap_lock
20964 @@ -227,6 +229,7 @@ asmlinkage unsigned long sys_brk(unsigne
20965  
20966         /* Check against rlimit.. */
20967         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
20968 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
20969         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
20970                 goto out;
20971  
20972 @@ -605,7 +608,11 @@ again:                     remove_next = 1 + (end > next->
20973   * If the vma has a ->close operation then the driver probably needs to release
20974   * per-vma resources, so we don't attempt to merge those.
20975   */
20976 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20977 +#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_MIRROR)
20978 +#else
20979  #define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
20980 +#endif
20981  
20982  static inline int is_mergeable_vma(struct vm_area_struct *vma,
20983                         struct file *file, unsigned long vm_flags)
20984 @@ -865,6 +872,42 @@ unsigned long do_mmap_pgoff(struct file 
20985                         unsigned long len, unsigned long prot,
20986                         unsigned long flags, unsigned long pgoff)
20987  {
20988 +       unsigned long ret = -EINVAL;
20989 +
20990 +#ifdef CONFIG_PAX_SEGMEXEC
20991 +       if ((current->mm->flags & MF_PAX_SEGMEXEC) &&
20992 +           (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
20993 +               return ret;
20994 +#endif
20995 +
20996 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
20997 +
20998 +#ifdef CONFIG_PAX_SEGMEXEC
20999 +       if ((current->mm->flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
21000 +
21001 +#ifdef CONFIG_PAX_MPROTECT
21002 +           && (!(current->mm->flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
21003 +#endif
21004 +
21005 +          )
21006 +       {
21007 +               unsigned long ret_m;
21008 +               prot = prot & PROT_EXEC ? prot : PROT_NONE;
21009 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
21010 +               if (ret_m >= TASK_SIZE) {
21011 +                       do_munmap(current->mm, ret, len);
21012 +                       ret = ret_m;
21013 +               }
21014 +       }
21015 +#endif
21016 +
21017 +       return ret;
21018 +}
21019 +
21020 +unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
21021 +                       unsigned long len, unsigned long prot,
21022 +                       unsigned long flags, unsigned long pgoff)
21023 +{
21024         struct mm_struct * mm = current->mm;
21025         struct vm_area_struct * vma, * prev;
21026         struct inode *inode;
21027 @@ -875,6 +918,28 @@ unsigned long do_mmap_pgoff(struct file 
21028         int accountable = 1;
21029         unsigned long charged = 0;
21030  
21031 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21032 +       struct vm_area_struct * vma_m = NULL;
21033 +
21034 +       if (flags & MAP_MIRROR) {
21035 +               /* PaX: sanity checks, to be removed when proved to be stable */
21036 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
21037 +                       return -EINVAL;
21038 +
21039 +               vma_m = find_vma(mm, pgoff);
21040 +
21041 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
21042 +                   vma_m->vm_start != pgoff ||
21043 +                   (vma_m->vm_flags & VM_MIRROR) ||
21044 +                   (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
21045 +                       return -EINVAL;
21046 +
21047 +               file = vma_m->vm_file;
21048 +               pgoff = vma_m->vm_pgoff;
21049 +               len = vma_m->vm_end - vma_m->vm_start;
21050 +       }
21051 +#endif
21052 +
21053         if (file) {
21054                 if (is_file_hugepages(file))
21055                         accountable = 0;
21056 @@ -915,7 +980,7 @@ unsigned long do_mmap_pgoff(struct file 
21057         /* Obtain the address to map to. we verify (or select) it and ensure
21058          * that it represents a valid section of the address space.
21059          */
21060 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
21061 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
21062         if (addr & ~PAGE_MASK)
21063                 return addr;
21064  
21065 @@ -926,6 +991,30 @@ unsigned long do_mmap_pgoff(struct file 
21066         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
21067                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
21068  
21069 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
21070 +               vm_flags &= ~VM_MAYEXEC;
21071 +
21072 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21073 +       if (mm->flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21074 +
21075 +#ifdef CONFIG_PAX_MPROTECT
21076 +               if (mm->flags & MF_PAX_MPROTECT) {
21077 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
21078 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
21079 +                       else
21080 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
21081 +
21082 +#ifdef CONFIG_PAX_RANDEXEC
21083 +                       if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
21084 +                               vma_m->vm_flags &= ~VM_MAYWRITE;
21085 +#endif
21086 +
21087 +               }
21088 +#endif
21089 +
21090 +       }
21091 +#endif
21092 +
21093         if (flags & MAP_LOCKED) {
21094                 if (!can_do_mlock())
21095                         return -EPERM;
21096 @@ -937,6 +1026,7 @@ unsigned long do_mmap_pgoff(struct file 
21097                 locked = mm->locked_vm << PAGE_SHIFT;
21098                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
21099                 locked += len;
21100 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
21101                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
21102                         return -EAGAIN;
21103         }
21104 @@ -984,6 +1074,11 @@ unsigned long do_mmap_pgoff(struct file 
21105                         /*
21106                          * Set pgoff according to addr for anon_vma.
21107                          */
21108 +
21109 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21110 +                       if (!(flags & MAP_MIRROR))
21111 +#endif
21112 +
21113                         pgoff = addr >> PAGE_SHIFT;
21114                         break;
21115                 default:
21116 @@ -995,17 +1090,21 @@ unsigned long do_mmap_pgoff(struct file 
21117         if (error)
21118                 return error;
21119                 
21120 +       if (!gr_acl_handle_mmap(file, prot))
21121 +               return -EACCES;
21122 +
21123         /* Clear old maps */
21124         error = -ENOMEM;
21125 -munmap_back:
21126         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21127         if (vma && vma->vm_start < addr + len) {
21128                 if (do_munmap(mm, addr, len))
21129                         return -ENOMEM;
21130 -               goto munmap_back;
21131 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21132 +               BUG_ON(vma && vma->vm_start < addr + len);
21133         }
21134  
21135         /* Check against address space limit. */
21136 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
21137         if ((mm->total_vm << PAGE_SHIFT) + len
21138             > current->signal->rlim[RLIMIT_AS].rlim_cur)
21139                 return -ENOMEM;
21140 @@ -1052,6 +1151,13 @@ munmap_back:
21141         vma->vm_start = addr;
21142         vma->vm_end = addr + len;
21143         vma->vm_flags = vm_flags;
21144 +
21145 +#ifdef CONFIG_PAX_PAGEEXEC
21146 +       if ((file || !(mm->flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
21147 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
21148 +       else
21149 +#endif
21150 +
21151         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
21152         vma->vm_pgoff = pgoff;
21153  
21154 @@ -1076,6 +1182,14 @@ munmap_back:
21155                         goto free_vma;
21156         }
21157  
21158 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21159 +       if (flags & MAP_MIRROR) {
21160 +               vma_m->vm_flags |= VM_MIRROR;
21161 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
21162 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
21163 +       }
21164 +#endif
21165 +
21166         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
21167          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
21168          * that memory reservation must be checked; but that reservation
21169 @@ -1111,6 +1225,7 @@ munmap_back:
21170  out:   
21171         mm->total_vm += len >> PAGE_SHIFT;
21172         __vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
21173 +       track_exec_limit(mm, addr, addr + len, vm_flags);
21174         if (vm_flags & VM_LOCKED) {
21175                 mm->locked_vm += len >> PAGE_SHIFT;
21176                 make_pages_present(addr, addr + len);
21177 @@ -1142,6 +1257,7 @@ unacct_error:
21178  }
21179  
21180  EXPORT_SYMBOL(do_mmap_pgoff);
21181 +EXPORT_SYMBOL(__do_mmap_pgoff);
21182  
21183  /* Get an address range which is currently unmapped.
21184   * For shmat() with addr=0.
21185 @@ -1166,6 +1282,10 @@ arch_get_unmapped_area(struct file *filp
21186         if (len > TASK_SIZE)
21187                 return -ENOMEM;
21188  
21189 +#ifdef CONFIG_PAX_RANDMMAP
21190 +       if (!(mm->flags & MF_PAX_RANDMMAP) || !filp)
21191 +#endif
21192 +
21193         if (addr) {
21194                 addr = PAGE_ALIGN(addr);
21195                 vma = find_vma(mm, addr);
21196 @@ -1221,7 +1341,7 @@ arch_get_unmapped_area_topdown(struct fi
21197                           const unsigned long len, const unsigned long pgoff,
21198                           const unsigned long flags)
21199  {
21200 -       struct vm_area_struct *vma, *prev_vma;
21201 +       struct vm_area_struct *vma;
21202         struct mm_struct *mm = current->mm;
21203         unsigned long base = mm->mmap_base, addr = addr0;
21204         int first_time = 1;
21205 @@ -1234,6 +1354,10 @@ arch_get_unmapped_area_topdown(struct fi
21206         if (mm->free_area_cache > base)
21207                 mm->free_area_cache = base;
21208  
21209 +#ifdef CONFIG_PAX_RANDMMAP
21210 +       if (!(mm->flags & MF_PAX_RANDMMAP) || !filp)
21211 +#endif
21212 +
21213         /* requesting a specific address */
21214         if (addr) {
21215                 addr = PAGE_ALIGN(addr);
21216 @@ -1255,15 +1379,14 @@ try_again:
21217                  * Lookup failure means no vma is above this address,
21218                  * i.e. return with success:
21219                  */
21220 -               if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
21221 +               if (!(vma = find_vma(mm, addr)))
21222                         return addr;
21223  
21224                 /*
21225                  * new region fits between prev_vma->vm_end and
21226                  * vma->vm_start, use it:
21227                  */
21228 -               if (addr+len <= vma->vm_start &&
21229 -                               (!prev_vma || (addr >= prev_vma->vm_end)))
21230 +               if (addr+len <= vma->vm_start)
21231                         /* remember the address as a hint for next time */
21232                         return (mm->free_area_cache = addr);
21233                 else
21234 @@ -1428,12 +1551,16 @@ out:
21235   * update accounting. This is shared with both the
21236   * grow-up and grow-down cases.
21237   */
21238 -static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, unsigned long grow)
21239 +static int acct_stack_growth(struct task_struct *tsk, struct vm_area_struct * vma, unsigned long size, unsigned long grow)
21240  {
21241         struct mm_struct *mm = vma->vm_mm;
21242 -       struct rlimit *rlim = current->signal->rlim;
21243 +       struct rlimit *rlim = tsk->signal->rlim;
21244 +
21245 +       BUG_ON(mm != tsk->mm);
21246  
21247         /* address space limit tests */
21248 +       gr_learn_resource(tsk, RLIMIT_AS, (mm->total_vm + grow) << PAGE_SHIFT, 1);
21249 +       gr_learn_resource(tsk, RLIMIT_STACK, size, 1);
21250         if (mm->total_vm + grow > rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT)
21251                 return -ENOMEM;
21252  
21253 @@ -1447,6 +1574,7 @@ static int acct_stack_growth(struct vm_a
21254                 unsigned long limit;
21255                 locked = mm->locked_vm + grow;
21256                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
21257 +               gr_learn_resource(tsk, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
21258                 if (locked > limit && !capable(CAP_IPC_LOCK))
21259                         return -ENOMEM;
21260         }
21261 @@ -1472,7 +1600,7 @@ static int acct_stack_growth(struct vm_a
21262  /*
21263   * vma is the first one with address > vma->vm_end.  Have to extend vma.
21264   */
21265 -int expand_stack(struct vm_area_struct * vma, unsigned long address)
21266 +int expand_stack(struct task_struct *tsk, struct vm_area_struct * vma, unsigned long address)
21267  {
21268         int error;
21269  
21270 @@ -1503,7 +1631,7 @@ int expand_stack(struct vm_area_struct *
21271                 size = address - vma->vm_start;
21272                 grow = (address - vma->vm_end) >> PAGE_SHIFT;
21273  
21274 -               error = acct_stack_growth(vma, size, grow);
21275 +               error = acct_stack_growth(tsk, vma, size, grow);
21276                 if (!error)
21277                         vma->vm_end = address;
21278         }
21279 @@ -1512,7 +1640,7 @@ int expand_stack(struct vm_area_struct *
21280  }
21281  
21282  struct vm_area_struct *
21283 -find_extend_vma(struct mm_struct *mm, unsigned long addr)
21284 +find_extend_vma(struct task_struct *tsk, struct mm_struct * mm, unsigned long addr)
21285  {
21286         struct vm_area_struct *vma, *prev;
21287  
21288 @@ -1520,7 +1648,7 @@ find_extend_vma(struct mm_struct *mm, un
21289         vma = find_vma_prev(mm, addr, &prev);
21290         if (vma && (vma->vm_start <= addr))
21291                 return vma;
21292 -       if (!prev || expand_stack(prev, addr))
21293 +       if (!prev || expand_stack(tsk, prev, addr))
21294                 return NULL;
21295         if (prev->vm_flags & VM_LOCKED) {
21296                 make_pages_present(addr, prev->vm_end);
21297 @@ -1531,7 +1659,7 @@ find_extend_vma(struct mm_struct *mm, un
21298  /*
21299   * vma is the first one with address < vma->vm_start.  Have to extend vma.
21300   */
21301 -int expand_stack(struct vm_area_struct *vma, unsigned long address)
21302 +int expand_stack(struct task_struct *tsk, struct vm_area_struct *vma, unsigned long address)
21303  {
21304         int error;
21305  
21306 @@ -1555,13 +1683,50 @@ int expand_stack(struct vm_area_struct *
21307         if (address < vma->vm_start) {
21308                 unsigned long size, grow;
21309  
21310 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21311 +               struct vm_area_struct *vma_m = NULL;
21312 +               unsigned long address_m = 0UL;
21313 +
21314 +               if (vma->vm_flags & VM_MIRROR) {
21315 +                       address_m = vma->vm_start + vma->vm_mirror;
21316 +                       vma_m = find_vma(vma->vm_mm, address_m);
21317 +                       if (!vma_m || vma_m->vm_start != address_m ||
21318 +                           !(vma_m->vm_flags & VM_MIRROR) ||
21319 +                           vma->vm_end - vma->vm_start !=
21320 +                           vma_m->vm_end - vma_m->vm_start ||
21321 +                           vma->anon_vma != vma_m->anon_vma) {
21322 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
21323 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
21324 +                               anon_vma_unlock(vma);
21325 +                               return -EFAULT;
21326 +                       }
21327 +                       address_m = address + vma->vm_mirror;
21328 +               }
21329 +#endif
21330 +
21331                 size = vma->vm_end - address;
21332                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
21333  
21334 -               error = acct_stack_growth(vma, size, grow);
21335 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21336 +               if (vma_m)
21337 +                       error = acct_stack_growth(tsk, vma, size, 2*grow);
21338 +               else
21339 +#endif
21340 +
21341 +               error = acct_stack_growth(tsk, vma, size, grow);
21342                 if (!error) {
21343                         vma->vm_start = address;
21344                         vma->vm_pgoff -= grow;
21345 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
21346 +
21347 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21348 +                       if (vma_m) {
21349 +                               vma_m->vm_start = address_m;
21350 +                               vma_m->vm_pgoff -= grow;
21351 +                               track_exec_limit(vma_m->vm_mm, vma_m->vm_start, vma_m->vm_end, vma_m->vm_flags);
21352 +                       }
21353 +#endif
21354 +
21355                 }
21356         }
21357         anon_vma_unlock(vma);
21358 @@ -1569,7 +1734,7 @@ int expand_stack(struct vm_area_struct *
21359  }
21360  
21361  struct vm_area_struct *
21362 -find_extend_vma(struct mm_struct * mm, unsigned long addr)
21363 +find_extend_vma(struct task_struct *tsk, struct mm_struct * mm, unsigned long addr)
21364  {
21365         struct vm_area_struct * vma;
21366         unsigned long start;
21367 @@ -1583,7 +1748,7 @@ find_extend_vma(struct mm_struct * mm, u
21368         if (!(vma->vm_flags & VM_GROWSDOWN))
21369                 return NULL;
21370         start = vma->vm_start;
21371 -       if (expand_stack(vma, addr))
21372 +       if (expand_stack(tsk, vma, addr))
21373                 return NULL;
21374         if (vma->vm_flags & VM_LOCKED) {
21375                 make_pages_present(addr, start);
21376 @@ -1606,7 +1771,7 @@ find_extend_vma(struct mm_struct * mm, u
21377   * we just free'd - but there's no telling how much before.
21378   */
21379  static void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *prev,
21380 -       unsigned long start, unsigned long end)
21381 +       struct vm_area_struct *mpnt, unsigned long start, unsigned long end)
21382  {
21383         unsigned long first = start & PGDIR_MASK;
21384         unsigned long last = end + PGDIR_SIZE - 1;
21385 @@ -1641,6 +1806,14 @@ static void free_pgtables(struct mmu_gat
21386                 break;
21387         }
21388  no_mmaps:
21389 +       while (mpnt && first < last) {
21390 +               if ((mpnt->vm_end > first) &&(last > mpnt->vm_start)) {
21391 +                       first = mpnt->vm_end + PGDIR_SIZE - 1;
21392 +                       last = mpnt->vm_start;
21393 +               }
21394 +               mpnt = mpnt->vm_next;
21395 +       }
21396 +
21397         if (last < first)       /* for arches with discontiguous pgd indices */
21398                 return;
21399         if (first < FIRST_USER_PGD_NR * PGDIR_SIZE)
21400 @@ -1663,11 +1836,11 @@ static void unmap_vma(struct mm_struct *
21401  {
21402         size_t len = area->vm_end - area->vm_start;
21403  
21404 -       area->vm_mm->total_vm -= len >> PAGE_SHIFT;
21405 +       mm->total_vm -= len >> PAGE_SHIFT;
21406         if (area->vm_flags & VM_LOCKED)
21407 -               area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
21408 +               mm->locked_vm -= len >> PAGE_SHIFT;
21409         vm_stat_unaccount(area);
21410 -       area->vm_mm->unmap_area(area);
21411 +       mm->unmap_area(area);
21412         remove_vm_struct(area);
21413  }
21414  
21415 @@ -1696,6 +1869,7 @@ static void unmap_vma_list(struct mm_str
21416  static void unmap_region(struct mm_struct *mm,
21417         struct vm_area_struct *vma,
21418         struct vm_area_struct *prev,
21419 +       struct vm_area_struct *mpnt,
21420         unsigned long start,
21421         unsigned long end)
21422  {
21423 @@ -1710,31 +1884,93 @@ static void unmap_region(struct mm_struc
21424         if (is_hugepage_only_range(start, end - start))
21425                 hugetlb_free_pgtables(tlb, prev, start, end);
21426         else
21427 -               free_pgtables(tlb, prev, start, end);
21428 +               free_pgtables(tlb, prev, mpnt, start, end);
21429         tlb_finish_mmu(tlb, start, end);
21430  }
21431  
21432 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21433 +static void unmap_mirror_region(struct mm_struct *mm, struct vm_area_struct *mpnt)
21434 +{
21435 +
21436 +       while (mpnt) {
21437 +               struct vm_area_struct *next;
21438 +
21439 +               next = mpnt->vm_next;
21440 +               mpnt->vm_next = NULL;
21441 +               unmap_region(mm, mpnt, NULL, next, mpnt->vm_start, mpnt->vm_end);
21442 +               mpnt->vm_next = next;
21443 +               mpnt = next;
21444 +       }
21445 +}
21446 +#endif
21447 +
21448  /*
21449   * Create a list of vma's touched by the unmap, removing them from the mm's
21450   * vma list as we go..
21451   */
21452  static void
21453  detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
21454 -       struct vm_area_struct *prev, unsigned long end)
21455 +       struct vm_area_struct *prev, struct vm_area_struct **mpnt_m, unsigned long start, unsigned long end)
21456  {
21457         struct vm_area_struct **insertion_point;
21458         struct vm_area_struct *tail_vma = NULL;
21459  
21460 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21461 +       unsigned long start_m;
21462 +       struct vm_area_struct *vma_m, *head_vma = vma, *mirrors = NULL;
21463 +#endif
21464 +
21465         insertion_point = (prev ? &prev->vm_next : &mm->mmap);
21466         do {
21467                 rb_erase(&vma->vm_rb, &mm->mm_rb);
21468                 mm->map_count--;
21469 +
21470 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21471 +               if ((vma->vm_flags & VM_MIRROR) &&
21472 +                   vma->vm_start + vma->vm_mirror >= start &&
21473 +                   vma->vm_start + vma->vm_mirror < end)
21474 +               {
21475 +                       mm->mmap_cache = NULL;          /* Kill the cache. */
21476 +                       start_m = vma->vm_start + vma->vm_mirror;
21477 +                       vma_m = find_vma(mm, start_m);
21478 +                       if (vma_m && (vma_m->vm_flags & VM_MIRROR) && vma_m->vm_start == start_m) {
21479 +                               vma->vm_flags &= ~VM_MIRROR;
21480 +                               vma_m->vm_flags &= ~VM_MIRROR;
21481 +                       } else
21482 +                               printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, vma->vm_start);
21483 +               }
21484 +#endif
21485 +
21486                 tail_vma = vma;
21487                 vma = vma->vm_next;
21488         } while (vma && vma->vm_start < end);
21489         *insertion_point = vma;
21490         tail_vma->vm_next = NULL;
21491         mm->mmap_cache = NULL;          /* Kill the cache. */
21492 +
21493 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21494 +       for (; head_vma; head_vma = head_vma->vm_next) {
21495 +               struct vm_area_struct *prev_m;
21496 +
21497 +               if (!(head_vma->vm_flags & VM_MIRROR))
21498 +                       continue;
21499 +
21500 +               start_m = head_vma->vm_start + head_vma->vm_mirror;
21501 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
21502 +               rb_erase(&vma_m->vm_rb, &mm->mm_rb);
21503 +               mm->map_count--;
21504 +               insertion_point = prev_m ? &prev_m->vm_next : &mm->mmap;
21505 +               *insertion_point = vma_m->vm_next;
21506 +               if (*mpnt_m) {
21507 +                       mirrors->vm_next = vma_m;
21508 +                       mirrors = vma_m;
21509 +               } else
21510 +                       *mpnt_m = mirrors = vma_m;
21511 +               mirrors->vm_next = NULL;
21512 +               mm->mmap_cache = NULL;          /* Kill the cache. */
21513 +       }
21514 +#endif
21515 +
21516  }
21517  
21518  /*
21519 @@ -1797,7 +2033,11 @@ int split_vma(struct mm_struct * mm, str
21520  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
21521  {
21522         unsigned long end;
21523 -       struct vm_area_struct *mpnt, *prev, *last;
21524 +       struct vm_area_struct *mpnt, *prev, *last, *mpnt_m = NULL;
21525 +
21526 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21527 +       struct vm_area_struct *last_m;
21528 +#endif
21529  
21530         if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
21531                 return -EINVAL;
21532 @@ -1824,7 +2064,23 @@ int do_munmap(struct mm_struct *mm, unsi
21533          * places tmp vma above, and higher split_vma places tmp vma below.
21534          */
21535         if (start > mpnt->vm_start) {
21536 -               int error = split_vma(mm, mpnt, start, 0);
21537 +               int error;
21538 +
21539 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21540 +               if (mpnt->vm_flags & VM_MIRROR) {
21541 +                       unsigned long start_m = mpnt->vm_start + mpnt->vm_mirror;
21542 +
21543 +                       mpnt_m = find_vma(mm, start_m);
21544 +                       if (!mpnt_m || (!mpnt_m->vm_flags & VM_MIRROR) || mpnt_m->vm_start != start_m)
21545 +                               return -EINVAL;
21546 +                       start_m = start + mpnt->vm_mirror;
21547 +                       error = split_vma(mm, mpnt_m, start_m, 0);
21548 +                       if (error)
21549 +                               return error;
21550 +               }
21551 +#endif
21552 +
21553 +               error = split_vma(mm, mpnt, start, 0);
21554                 if (error)
21555                         return error;
21556                 prev = mpnt;
21557 @@ -1833,7 +2089,22 @@ int do_munmap(struct mm_struct *mm, unsi
21558         /* Does it split the last one? */
21559         last = find_vma(mm, end);
21560         if (last && end > last->vm_start) {
21561 -               int error = split_vma(mm, last, end, 1);
21562 +               int error;
21563 +
21564 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21565 +               if (last->vm_flags & VM_MIRROR) {
21566 +                       unsigned long end_m = last->vm_start + last->vm_mirror;
21567 +
21568 +                       last_m = find_vma(mm, end_m);
21569 +                       if (!last_m || (!last_m->vm_flags & VM_MIRROR) || last_m->vm_start != end_m)
21570 +                               return -EINVAL;
21571 +                       end_m = end + last->vm_mirror;
21572 +                       if (split_vma(mm, last_m, end_m, 1))
21573 +                               return -ENOMEM;
21574 +               }
21575 +#endif
21576 +
21577 +               error = split_vma(mm, last, end, 1);
21578                 if (error)
21579                         return error;
21580         }
21581 @@ -1842,14 +2113,28 @@ int do_munmap(struct mm_struct *mm, unsi
21582         /*
21583          * Remove the vma's, and unmap the actual pages
21584          */
21585 -       detach_vmas_to_be_unmapped(mm, mpnt, prev, end);
21586 +
21587 +       mpnt_m = NULL;
21588 +       detach_vmas_to_be_unmapped(mm, mpnt, prev, &mpnt_m, start, end);
21589         spin_lock(&mm->page_table_lock);
21590 -       unmap_region(mm, mpnt, prev, start, end);
21591 +       unmap_region(mm, mpnt, prev, NULL, start, end);
21592 +
21593 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21594 +       unmap_mirror_region(mm, mpnt_m);
21595 +#endif
21596 +
21597         spin_unlock(&mm->page_table_lock);
21598  
21599         /* Fix up all other VM information */
21600         unmap_vma_list(mm, mpnt);
21601  
21602 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21603 +       if (mpnt_m)
21604 +               unmap_vma_list(mm, mpnt_m);
21605 +#endif
21606 +
21607 +       track_exec_limit(mm, start, end, 0UL);
21608 +
21609         return 0;
21610  }
21611  
21612 @@ -1862,6 +2147,12 @@ asmlinkage long sys_munmap(unsigned long
21613  
21614         profile_munmap(addr);
21615  
21616 +#ifdef CONFIG_PAX_SEGMEXEC
21617 +       if ((mm->flags & MF_PAX_SEGMEXEC) &&
21618 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
21619 +               return -EINVAL;
21620 +#endif
21621 +
21622         down_write(&mm->mmap_sem);
21623         ret = do_munmap(mm, addr, len);
21624         up_write(&mm->mmap_sem);
21625 @@ -1883,8 +2174,32 @@ static inline void verify_mm_writelocked
21626   *  anonymous maps.  eventually we may be able to do some
21627   *  brk-specific accounting here.
21628   */
21629 +#ifdef CONFIG_PAX_SEGMEXEC
21630 +unsigned long __do_brk(unsigned long addr, unsigned long len);
21631 +
21632  unsigned long do_brk(unsigned long addr, unsigned long len)
21633  {
21634 +       unsigned long ret;
21635 +
21636 +       ret = __do_brk(addr, len);
21637 +       if (ret == addr && (current->mm->flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
21638 +               unsigned long ret_m;
21639 +
21640 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
21641 +               if (ret_m > TASK_SIZE) {
21642 +                       do_munmap(current->mm, addr, len);
21643 +                       ret = ret_m;
21644 +               }
21645 +       }
21646 +
21647 +       return ret;
21648 +}
21649 +
21650 +unsigned long __do_brk(unsigned long addr, unsigned long len)
21651 +#else
21652 +unsigned long do_brk(unsigned long addr, unsigned long len)
21653 +#endif
21654 +{
21655         struct mm_struct * mm = current->mm;
21656         struct vm_area_struct * vma, * prev;
21657         unsigned long flags;
21658 @@ -1895,6 +2210,13 @@ unsigned long do_brk(unsigned long addr,
21659         if (!len)
21660                 return addr;
21661  
21662 +#ifdef CONFIG_PAX_SEGMEXEC
21663 +       if (mm->flags & MF_PAX_SEGMEXEC) {
21664 +               if ((addr + len) > SEGMEXEC_TASK_SIZE || (addr + len) < addr)
21665 +                       return -EINVAL;
21666 +       } else
21667 +#endif
21668 +
21669         if ((addr + len) > TASK_SIZE || (addr + len) < addr)
21670                 return -EINVAL;
21671  
21672 @@ -1906,6 +2228,7 @@ unsigned long do_brk(unsigned long addr,
21673                 locked = mm->locked_vm << PAGE_SHIFT;
21674                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
21675                 locked += len;
21676 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
21677                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
21678                         return -EAGAIN;
21679         }
21680 @@ -1919,15 +2242,16 @@ unsigned long do_brk(unsigned long addr,
21681         /*
21682          * Clear old maps.  this also does some error checking for us
21683          */
21684 - munmap_back:
21685         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21686         if (vma && vma->vm_start < addr + len) {
21687                 if (do_munmap(mm, addr, len))
21688                         return -ENOMEM;
21689 -               goto munmap_back;
21690 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21691 +               BUG_ON(vma && vma->vm_start < addr + len);
21692         }
21693  
21694         /* Check against address space limits *after* clearing old maps... */
21695 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
21696         if ((mm->total_vm << PAGE_SHIFT) + len
21697             > current->signal->rlim[RLIMIT_AS].rlim_cur)
21698                 return -ENOMEM;
21699 @@ -1940,6 +2264,18 @@ unsigned long do_brk(unsigned long addr,
21700  
21701         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
21702  
21703 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21704 +       if (mm->flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21705 +               flags &= ~VM_EXEC;
21706 +
21707 +#ifdef CONFIG_PAX_MPROTECT
21708 +               if (mm->flags & MF_PAX_MPROTECT)
21709 +                       flags &= ~VM_MAYEXEC;
21710 +#endif
21711 +
21712 +       }
21713 +#endif
21714 +
21715         /* Can we just expand an old private anonymous mapping? */
21716         if (vma_merge(mm, prev, addr, addr + len, flags,
21717                                         NULL, NULL, pgoff, NULL))
21718 @@ -1960,6 +2296,13 @@ unsigned long do_brk(unsigned long addr,
21719         vma->vm_end = addr + len;
21720         vma->vm_pgoff = pgoff;
21721         vma->vm_flags = flags;
21722 +
21723 +#ifdef CONFIG_PAX_PAGEEXEC
21724 +       if (!(mm->flags & MF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
21725 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
21726 +       else
21727 +#endif
21728 +
21729         vma->vm_page_prot = protection_map[flags & 0x0f];
21730         vma_link(mm, vma, prev, rb_link, rb_parent);
21731  out:
21732 @@ -1968,6 +2311,7 @@ out:
21733                 mm->locked_vm += len >> PAGE_SHIFT;
21734                 make_pages_present(addr, addr + len);
21735         }
21736 +       track_exec_limit(mm, addr, addr + len, flags);
21737         acct_update_integrals();
21738         update_mem_hiwater();
21739         return addr;
21740 diff -urNp linux-2.6.11/mm/mprotect.c linux-2.6.11/mm/mprotect.c
21741 --- linux-2.6.11/mm/mprotect.c  2005-03-02 02:38:37.000000000 -0500
21742 +++ linux-2.6.11/mm/mprotect.c  2005-03-09 11:56:44.000000000 -0500
21743 @@ -19,11 +19,18 @@
21744  #include <linux/mempolicy.h>
21745  #include <linux/personality.h>
21746  #include <linux/syscalls.h>
21747 +#include <linux/grsecurity.h>
21748 +
21749 +#ifdef CONFIG_PAX_MPROTECT
21750 +#include <linux/elf.h>
21751 +#include <linux/fs.h>
21752 +#endif
21753  
21754  #include <asm/uaccess.h>
21755  #include <asm/pgtable.h>
21756  #include <asm/cacheflush.h>
21757  #include <asm/tlbflush.h>
21758 +#include <asm/mmu_context.h>
21759  
21760  static inline void
21761  change_pte_range(pmd_t *pmd, unsigned long address,
21762 @@ -138,6 +145,97 @@ change_protection(struct vm_area_struct 
21763         spin_unlock(&mm->page_table_lock);
21764  }
21765  
21766 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
21767 +/* called while holding the mmap semaphor for writing */
21768 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
21769 +{
21770 +       struct vm_area_struct *vma = find_vma(mm, start);
21771 +
21772 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
21773 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
21774 +
21775 +}
21776 +
21777 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
21778 +{
21779 +       unsigned long oldlimit, newlimit = 0UL;
21780 +
21781 +       if (!(mm->flags & MF_PAX_PAGEEXEC))
21782 +               return;
21783 +
21784 +       spin_lock(&mm->page_table_lock);
21785 +       oldlimit = mm->context.user_cs_limit;
21786 +       if ((prot & VM_EXEC) && oldlimit < end)
21787 +               /* USER_CS limit moved up */
21788 +               newlimit = end;
21789 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
21790 +               /* USER_CS limit moved down */
21791 +               newlimit = start;
21792 +
21793 +       if (newlimit) {
21794 +               mm->context.user_cs_limit = newlimit;
21795 +
21796 +#ifdef CONFIG_SMP
21797 +               wmb();
21798 +               cpus_clear(mm->context.cpu_user_cs_mask);
21799 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
21800 +#endif
21801 +
21802 +               set_user_cs(mm, smp_processor_id());
21803 +       }
21804 +       spin_unlock(&mm->page_table_lock);
21805 +       if (newlimit == end)
21806 +               establish_user_cs_limit(mm, oldlimit, end);
21807 +}
21808 +#endif
21809 +
21810 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21811 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21812 +       unsigned long start, unsigned long end, unsigned int newflags);
21813 +
21814 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21815 +       unsigned long start, unsigned long end, unsigned int newflags)
21816 +{
21817 +       if (vma->vm_flags & VM_MIRROR) {
21818 +               struct vm_area_struct * vma_m, * prev_m;
21819 +               unsigned long start_m, end_m;
21820 +               int error;
21821 +
21822 +               start_m = vma->vm_start + vma->vm_mirror;
21823 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
21824 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
21825 +                       start_m = start + vma->vm_mirror;
21826 +                       end_m = end + vma->vm_mirror;
21827 +
21828 +#ifdef CONFIG_PAX_SEGMEXEC
21829 +                       if ((vma->vm_mm->flags & MF_PAX_SEGMEXEC) && (vma_m->vm_start >= SEGMEXEC_TASK_SIZE) && !(newflags & VM_EXEC))
21830 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
21831 +                       else
21832 +#endif
21833 +
21834 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
21835 +                       if (error)
21836 +                               return error;
21837 +               } else {
21838 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
21839 +                       return -ENOMEM;
21840 +               }
21841 +       }
21842 +
21843 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
21844 +}
21845 +
21846 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21847 +       unsigned long start, unsigned long end, unsigned int newflags)
21848 +{
21849 +       struct mm_struct * mm = vma->vm_mm;
21850 +       unsigned long oldflags = vma->vm_flags;
21851 +       long nrpages = (end - start) >> PAGE_SHIFT;
21852 +       unsigned long charged = 0;
21853 +       pgprot_t newprot;
21854 +       pgoff_t pgoff;
21855 +       int error;
21856 +#else
21857  static int
21858  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21859         unsigned long start, unsigned long end, unsigned long newflags)
21860 @@ -154,6 +252,7 @@ mprotect_fixup(struct vm_area_struct *vm
21861                 *pprev = vma;
21862                 return 0;
21863         }
21864 +#endif
21865  
21866         /*
21867          * If we make a private mapping writable we increase our commit;
21868 @@ -172,6 +271,12 @@ mprotect_fixup(struct vm_area_struct *vm
21869                 }
21870         }
21871  
21872 +#ifdef CONFIG_PAX_PAGEEXEC
21873 +       if (!(mm->flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
21874 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
21875 +       else
21876 +#endif
21877 +
21878         newprot = protection_map[newflags & 0xf];
21879  
21880         /*
21881 @@ -219,6 +324,69 @@ fail:
21882         return error;
21883  }
21884  
21885 +#ifdef CONFIG_PAX_MPROTECT
21886 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
21887 + * therefore we'll grant them VM_MAYWRITE once during their life.
21888 + *
21889 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
21890 + * basis because we want to allow the common case and not the special ones.
21891 + */
21892 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
21893 +{
21894 +       struct elfhdr elf_h;
21895 +       struct elf_phdr elf_p, p_dyn;
21896 +       elf_dyn dyn;
21897 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
21898 +
21899 +#ifndef CONFIG_PAX_NOELFRELOCS
21900 +       if ((vma->vm_start != start) ||
21901 +           !vma->vm_file ||
21902 +           !(vma->vm_flags & VM_MAYEXEC) ||
21903 +           (vma->vm_flags & VM_MAYNOTWRITE))
21904 +#endif
21905 +
21906 +               return;
21907 +
21908 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
21909 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
21910 +
21911 +#ifdef CONFIG_PAX_ETEXECRELOCS
21912 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
21913 +#else
21914 +           elf_h.e_type != ET_DYN ||
21915 +#endif
21916 +
21917 +           !elf_check_arch(&elf_h) ||
21918 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
21919 +           elf_h.e_phnum > j)
21920 +               return;
21921 +
21922 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
21923 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
21924 +                       return;
21925 +               if (elf_p.p_type == PT_DYNAMIC) {
21926 +                       p_dyn = elf_p;
21927 +                       j = i;
21928 +               }
21929 +       }
21930 +       if (elf_h.e_phnum <= j)
21931 +               return;
21932 +
21933 +       i = 0UL;
21934 +       do {
21935 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
21936 +                       return;
21937 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
21938 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
21939 +                       gr_log_textrel(vma);
21940 +                       return;
21941 +               }
21942 +               i++;
21943 +       } while (dyn.d_tag != DT_NULL);
21944 +       return;
21945 +}
21946 +#endif
21947 +
21948  asmlinkage long
21949  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
21950  {
21951 @@ -236,6 +404,17 @@ sys_mprotect(unsigned long start, size_t
21952         end = start + len;
21953         if (end < start)
21954                 return -ENOMEM;
21955 +
21956 +#ifdef CONFIG_PAX_SEGMEXEC
21957 +       if (current->mm->flags & MF_PAX_SEGMEXEC) {
21958 +               if (end > SEGMEXEC_TASK_SIZE)
21959 +                       return -EINVAL;
21960 +       } else
21961 +#endif
21962 +
21963 +       if (end > TASK_SIZE)
21964 +               return -EINVAL;
21965 +
21966         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
21967                 return -EINVAL;
21968         if (end == start)
21969 @@ -276,6 +455,16 @@ sys_mprotect(unsigned long start, size_t
21970         if (start > vma->vm_start)
21971                 prev = vma;
21972  
21973 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
21974 +               error = -EACCES;
21975 +               goto out;
21976 +       }
21977 +
21978 +#ifdef CONFIG_PAX_MPROTECT
21979 +       if ((vma->vm_mm->flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
21980 +               pax_handle_maywrite(vma, start);
21981 +#endif
21982 +
21983         for (nstart = start ; ; ) {
21984                 unsigned long newflags;
21985  
21986 @@ -293,6 +482,12 @@ sys_mprotect(unsigned long start, size_t
21987                         goto out;
21988                 }
21989  
21990 +#ifdef CONFIG_PAX_MPROTECT
21991 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
21992 +               if ((vma->vm_mm->flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
21993 +                       newflags &= ~VM_MAYWRITE;
21994 +#endif
21995 +
21996                 error = security_file_mprotect(vma, prot);
21997                 if (error)
21998                         goto out;
21999 @@ -316,6 +511,9 @@ sys_mprotect(unsigned long start, size_t
22000                         goto out;
22001                 }
22002         }
22003 +
22004 +       track_exec_limit(current->mm, start, end, vm_flags);
22005 +
22006  out:
22007         up_write(&current->mm->mmap_sem);
22008         return error;
22009 diff -urNp linux-2.6.11/mm/mremap.c linux-2.6.11/mm/mremap.c
22010 --- linux-2.6.11/mm/mremap.c    2005-03-02 02:38:10.000000000 -0500
22011 +++ linux-2.6.11/mm/mremap.c    2005-03-09 11:56:44.000000000 -0500
22012 @@ -150,6 +150,12 @@ move_one_page(struct vm_area_struct *vma
22013                         if (dst) {
22014                                 pte_t pte;
22015                                 pte = ptep_clear_flush(vma, old_addr, src);
22016 +
22017 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22018 +                               if ((mm->flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
22019 +                                       pte_exprotect(pte);
22020 +#endif
22021 +
22022                                 set_pte(dst, pte);
22023                         } else
22024                                 error = -ENOMEM;
22025 @@ -293,6 +299,18 @@ unsigned long do_mremap(unsigned long ad
22026         if (!new_len)
22027                 goto out;
22028  
22029 +#ifdef CONFIG_PAX_SEGMEXEC
22030 +       if (current->mm->flags & MF_PAX_SEGMEXEC) {
22031 +               if (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
22032 +                   old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)
22033 +                       goto out;
22034 +       } else
22035 +#endif
22036 +
22037 +       if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
22038 +           old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
22039 +               goto out;
22040 +
22041         /* new_addr is only valid if MREMAP_FIXED is specified */
22042         if (flags & MREMAP_FIXED) {
22043                 if (new_addr & ~PAGE_MASK)
22044 @@ -300,6 +318,13 @@ unsigned long do_mremap(unsigned long ad
22045                 if (!(flags & MREMAP_MAYMOVE))
22046                         goto out;
22047  
22048 +#ifdef CONFIG_PAX_SEGMEXEC
22049 +               if (current->mm->flags & MF_PAX_SEGMEXEC) {
22050 +                       if (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)
22051 +                               goto out;
22052 +               } else
22053 +#endif
22054 +
22055                 if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
22056                         goto out;
22057  
22058 @@ -343,6 +368,16 @@ unsigned long do_mremap(unsigned long ad
22059                 ret = -EINVAL;
22060                 goto out;
22061         }
22062 +
22063 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
22064 +       if ((current->mm->flags & (MF_PAX_SEGMEXEC | MF_PAX_RANDEXEC)) &&
22065 +           (vma->vm_flags & VM_MIRROR))
22066 +       {
22067 +               ret = -EINVAL;
22068 +               goto out;
22069 +       }
22070 +#endif
22071 +
22072         /* We can't remap across vm area boundaries */
22073         if (old_len > vma->vm_end - addr)
22074                 goto out;
22075 @@ -397,6 +432,7 @@ unsigned long do_mremap(unsigned long ad
22076                         acct_update_integrals();
22077                         update_mem_hiwater();
22078                         ret = addr;
22079 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
22080                         goto out;
22081                 }
22082         }
22083 @@ -407,8 +443,8 @@ unsigned long do_mremap(unsigned long ad
22084          */
22085         ret = -ENOMEM;
22086         if (flags & MREMAP_MAYMOVE) {
22087 +               unsigned long map_flags = 0;
22088                 if (!(flags & MREMAP_FIXED)) {
22089 -                       unsigned long map_flags = 0;
22090                         if (vma->vm_flags & VM_MAYSHARE)
22091                                 map_flags |= MAP_SHARED;
22092  
22093 @@ -418,7 +454,12 @@ unsigned long do_mremap(unsigned long ad
22094                         if (new_addr & ~PAGE_MASK)
22095                                 goto out;
22096                 }
22097 +               map_flags = vma->vm_flags;
22098                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
22099 +               if (!(ret & ~PAGE_MASK)) {
22100 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
22101 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
22102 +               }
22103         }
22104  out:
22105         if (ret & ~PAGE_MASK)
22106 diff -urNp linux-2.6.11/mm/nommu.c linux-2.6.11/mm/nommu.c
22107 --- linux-2.6.11/mm/nommu.c     2005-03-02 02:38:25.000000000 -0500
22108 +++ linux-2.6.11/mm/nommu.c     2005-03-09 11:56:44.000000000 -0500
22109 @@ -934,7 +934,7 @@ struct page * follow_page(struct mm_stru
22110         return NULL;
22111  }
22112  
22113 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
22114 +struct vm_area_struct *find_extend_vma(struct task_struct *tsk, struct mm_struct * mm, unsigned long addr)
22115  {
22116         return NULL;
22117  }
22118 diff -urNp linux-2.6.11/mm/rmap.c linux-2.6.11/mm/rmap.c
22119 --- linux-2.6.11/mm/rmap.c      2005-03-02 02:38:38.000000000 -0500
22120 +++ linux-2.6.11/mm/rmap.c      2005-03-09 11:56:44.000000000 -0500
22121 @@ -109,6 +109,19 @@ int anon_vma_prepare(struct vm_area_stru
22122                         list_add(&vma->anon_vma_node, &anon_vma->head);
22123                         allocated = NULL;
22124                 }
22125 +
22126 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
22127 +               if (vma->vm_flags & VM_MIRROR) {
22128 +                       struct vm_area_struct *vma_m;
22129 +
22130 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
22131 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
22132 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
22133 +                       vma_m->anon_vma = anon_vma;
22134 +                       __anon_vma_link(vma_m);
22135 +               }
22136 +#endif
22137 +
22138                 spin_unlock(&mm->page_table_lock);
22139  
22140                 if (locked)
22141 diff -urNp linux-2.6.11/net/ipv4/netfilter/Kconfig linux-2.6.11/net/ipv4/netfilter/Kconfig
22142 --- linux-2.6.11/net/ipv4/netfilter/Kconfig     2005-03-02 02:38:20.000000000 -0500
22143 +++ linux-2.6.11/net/ipv4/netfilter/Kconfig     2005-03-09 11:56:44.000000000 -0500
22144 @@ -256,6 +256,21 @@ config IP_NF_MATCH_TCPMSS
22145  
22146           To compile it as a module, choose M here.  If unsure, say N.
22147  
22148 +config IP_NF_MATCH_STEALTH
22149 +       tristate "stealth match support"
22150 +       depends on IP_NF_IPTABLES
22151 +       help
22152 +         Enabling this option will drop all syn packets coming to unserved tcp
22153 +         ports as well as all packets coming to unserved udp ports.  If you
22154 +         are using your system to route any type of packets (ie. via NAT)
22155 +         you should put this module at the end of your ruleset, since it will
22156 +         drop packets that aren't going to ports that are listening on your
22157 +         machine itself, it doesn't take into account that the packet might be
22158 +         destined for someone on your internal network if you're using NAT for
22159 +         instance.
22160 +
22161 +         To compile it as a module, choose M here.  If unsure, say N.
22162 +
22163  config IP_NF_MATCH_HELPER
22164         tristate "Helper match support"
22165         depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
22166 diff -urNp linux-2.6.11/net/ipv4/netfilter/Makefile linux-2.6.11/net/ipv4/netfilter/Makefile
22167 --- linux-2.6.11/net/ipv4/netfilter/Makefile    2005-03-02 02:37:50.000000000 -0500
22168 +++ linux-2.6.11/net/ipv4/netfilter/Makefile    2005-03-09 11:56:44.000000000 -0500
22169 @@ -59,6 +59,7 @@ obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_r
22170  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
22171  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
22172  obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
22173 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
22174  
22175  # targets
22176  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
22177 diff -urNp linux-2.6.11/net/ipv4/netfilter/ipt_stealth.c linux-2.6.11/net/ipv4/netfilter/ipt_stealth.c
22178 --- linux-2.6.11/net/ipv4/netfilter/ipt_stealth.c       1969-12-31 19:00:00.000000000 -0500
22179 +++ linux-2.6.11/net/ipv4/netfilter/ipt_stealth.c       2005-03-09 11:56:44.000000000 -0500
22180 @@ -0,0 +1,113 @@
22181 +/* Kernel module to add stealth support.
22182 + *
22183 + * Copyright (C) 2002 Brad Spengler  <spender@grsecurity.net>
22184 + *
22185 + */
22186 +
22187 +#include <linux/kernel.h>
22188 +#include <linux/module.h>
22189 +#include <linux/skbuff.h>
22190 +#include <linux/net.h>
22191 +#include <linux/sched.h>
22192 +#include <linux/inet.h>
22193 +#include <linux/stddef.h>
22194 +
22195 +#include <net/ip.h>
22196 +#include <net/sock.h>
22197 +#include <net/tcp.h>
22198 +#include <net/udp.h>
22199 +#include <net/route.h>
22200 +#include <net/inet_common.h>
22201 +
22202 +#include <linux/netfilter_ipv4/ip_tables.h>
22203 +
22204 +MODULE_LICENSE("GPL");
22205 +
22206 +extern struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum, int dif);
22207 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
22208 +
22209 +static int
22210 +match(const struct sk_buff *skb,
22211 +      const struct net_device *in,
22212 +      const struct net_device *out,
22213 +      const void *matchinfo,
22214 +      int offset,
22215 +      int *hotdrop)
22216 +{
22217 +       struct iphdr *ip = skb->nh.iph;
22218 +       struct tcphdr th;
22219 +       struct udphdr uh;
22220 +       struct sock *sk = NULL;
22221 +
22222 +       if (!ip || offset) return 0;
22223 +
22224 +       switch(ip->protocol) {
22225 +       case IPPROTO_TCP:
22226 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
22227 +                       *hotdrop = 1;
22228 +                       return 0;
22229 +               }
22230 +               if (!(th.syn && !th.ack)) return 0;
22231 +               sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);     
22232 +               break;
22233 +       case IPPROTO_UDP:
22234 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
22235 +                       *hotdrop = 1;
22236 +                       return 0;
22237 +               }
22238 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
22239 +               break;
22240 +       default:
22241 +               return 0;
22242 +       }
22243 +
22244 +       if(!sk) // port is being listened on, match this
22245 +               return 1;
22246 +       else {
22247 +               sock_put(sk);
22248 +               return 0;
22249 +       }
22250 +}
22251 +
22252 +/* Called when user tries to insert an entry of this type. */
22253 +static int
22254 +checkentry(const char *tablename,
22255 +           const struct ipt_ip *ip,
22256 +           void *matchinfo,
22257 +           unsigned int matchsize,
22258 +           unsigned int hook_mask)
22259 +{
22260 +        if (matchsize != IPT_ALIGN(0))
22261 +                return 0;
22262 +
22263 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
22264 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
22265 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
22266 +                       return 1;
22267 +
22268 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
22269 +
22270 +        return 0;
22271 +}
22272 +
22273 +
22274 +static struct ipt_match stealth_match = {
22275 +       .name = "stealth",
22276 +       .match = &match,
22277 +       .checkentry = &checkentry,
22278 +       .destroy = NULL,
22279 +       .me = THIS_MODULE
22280 +};
22281 +
22282 +static int __init init(void)
22283 +{
22284 +       return ipt_register_match(&stealth_match);
22285 +}
22286 +
22287 +static void __exit fini(void)
22288 +{
22289 +       ipt_unregister_match(&stealth_match);
22290 +}
22291 +
22292 +module_init(init);
22293 +module_exit(fini);
22294 diff -urNp linux-2.6.11/net/ipv4/tcp_ipv4.c linux-2.6.11/net/ipv4/tcp_ipv4.c
22295 --- linux-2.6.11/net/ipv4/tcp_ipv4.c    2005-03-02 02:37:54.000000000 -0500
22296 +++ linux-2.6.11/net/ipv4/tcp_ipv4.c    2005-03-09 11:56:44.000000000 -0500
22297 @@ -62,6 +62,7 @@
22298  #include <linux/jhash.h>
22299  #include <linux/init.h>
22300  #include <linux/times.h>
22301 +#include <linux/grsecurity.h>
22302  
22303  #include <net/icmp.h>
22304  #include <net/tcp.h>
22305 @@ -223,6 +224,10 @@ static int tcp_v4_get_port(struct sock *
22306  
22307                 spin_lock(&tcp_portalloc_lock);
22308                 rover = tcp_port_rover;
22309 +#ifdef CONFIG_GRKERNSEC_RANDSRC
22310 +               if (grsec_enable_randsrc && (high > low))
22311 +                       rover = low + (get_random_long() % remaining);
22312 +#endif
22313                 do {
22314                         rover++;
22315                         if (rover < low || rover > high)
22316 @@ -448,7 +453,7 @@ static struct sock *__tcp_v4_lookup_list
22317  }
22318  
22319  /* Optimize the common listener case. */
22320 -static inline struct sock *tcp_v4_lookup_listener(u32 daddr,
22321 +struct sock *tcp_v4_lookup_listener(u32 daddr,
22322                 unsigned short hnum, int dif)
22323  {
22324         struct sock *sk = NULL;
22325 @@ -474,6 +479,8 @@ sherry_cache:
22326         return sk;
22327  }
22328  
22329 +EXPORT_SYMBOL_GPL(tcp_v4_lookup_listener);
22330 +
22331  /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
22332   * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
22333   *
22334 @@ -665,7 +672,12 @@ static inline int tcp_v4_hash_connect(st
22335                 struct hlist_node *node;
22336                 struct tcp_tw_bucket *tw = NULL;
22337  
22338 -               local_bh_disable();
22339 +#ifdef CONFIG_GRKERNSEC_RANDSRC
22340 +               if (grsec_enable_randsrc)
22341 +                       offset = get_random_long();
22342 +#endif
22343 +
22344 +               local_bh_disable();
22345                 for (i = 1; i <= range; i++) {
22346                         port = low + (i + offset) % range;
22347                         head = &tcp_bhash[tcp_bhashfn(port)];
22348 @@ -714,6 +726,15 @@ ok:
22349                 }
22350                 spin_unlock(&head->lock);
22351  
22352 +#ifdef CONFIG_GRKERNSEC
22353 +               gr_del_task_from_ip_table(current);
22354 +               current->gr_saddr = inet_sk(sk)->rcv_saddr;
22355 +               current->gr_daddr = inet_sk(sk)->daddr;
22356 +               current->gr_sport = inet_sk(sk)->sport;
22357 +               current->gr_dport = inet_sk(sk)->dport;
22358 +               gr_add_to_task_ip_table(current);
22359 +#endif
22360 +
22361                 if (tw) {
22362                         tcp_tw_deschedule(tw);
22363                         tcp_tw_put(tw);
22364 diff -urNp linux-2.6.11/net/ipv4/udp.c linux-2.6.11/net/ipv4/udp.c
22365 --- linux-2.6.11/net/ipv4/udp.c 2005-03-02 02:37:49.000000000 -0500
22366 +++ linux-2.6.11/net/ipv4/udp.c 2005-03-09 11:56:44.000000000 -0500
22367 @@ -100,6 +100,7 @@
22368  #include <linux/skbuff.h>
22369  #include <linux/proc_fs.h>
22370  #include <linux/seq_file.h>
22371 +#include <linux/grsecurity.h>
22372  #include <net/sock.h>
22373  #include <net/udp.h>
22374  #include <net/icmp.h>
22375 @@ -108,6 +109,12 @@
22376  #include <net/checksum.h>
22377  #include <net/xfrm.h>
22378  
22379 +extern int gr_search_udp_recvmsg(const struct sock *sk,
22380 +                                const struct sk_buff *skb);
22381 +extern int gr_search_udp_sendmsg(const struct sock *sk,
22382 +                                const struct sockaddr_in *addr);
22383 +
22384 +
22385  /*
22386   *     Snmp MIB for the UDP layer
22387   */
22388 @@ -264,8 +271,7 @@ static struct sock *udp_v4_lookup_longwa
22389         return result;
22390  }
22391  
22392 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
22393 -                                            u32 daddr, u16 dport, int dif)
22394 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
22395  {
22396         struct sock *sk;
22397  
22398 @@ -540,9 +546,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
22399                 dport = usin->sin_port;
22400                 if (dport == 0)
22401                         return -EINVAL;
22402 +
22403 +               if (!gr_search_udp_sendmsg(sk, usin))
22404 +                       return -EPERM;
22405         } else {
22406                 if (sk->sk_state != TCP_ESTABLISHED)
22407                         return -EDESTADDRREQ;
22408 +
22409 +               if (!gr_search_udp_sendmsg(sk, NULL))
22410 +                       return -EPERM;
22411 +
22412                 daddr = inet->daddr;
22413                 dport = inet->dport;
22414                 /* Open fast path for connected socket.
22415 @@ -795,6 +808,11 @@ try_again:
22416         if (!skb)
22417                 goto out;
22418    
22419 +       if (!gr_search_udp_recvmsg(sk, skb)) {
22420 +               err = -EPERM;
22421 +               goto out_free;
22422 +       }
22423 +
22424         copied = skb->len - sizeof(struct udphdr);
22425         if (copied > len) {
22426                 copied = len;
22427 diff -urNp linux-2.6.11/net/socket.c linux-2.6.11/net/socket.c
22428 --- linux-2.6.11/net/socket.c   2005-03-02 02:37:58.000000000 -0500
22429 +++ linux-2.6.11/net/socket.c   2005-03-09 11:56:44.000000000 -0500
22430 @@ -81,6 +81,7 @@
22431  #include <linux/syscalls.h>
22432  #include <linux/compat.h>
22433  #include <linux/kmod.h>
22434 +#include <linux/in.h>
22435  
22436  #ifdef CONFIG_NET_RADIO
22437  #include <linux/wireless.h>            /* Note : will define WIRELESS_EXT */
22438 @@ -94,6 +95,21 @@
22439  #include <net/sock.h>
22440  #include <linux/netfilter.h>
22441  
22442 +extern void gr_attach_curr_ip(const struct sock *sk);
22443 +extern int gr_handle_sock_all(const int family, const int type,
22444 +                             const int protocol);
22445 +extern int gr_handle_sock_server(const struct sockaddr *sck);
22446 +extern int gr_handle_sock_server_other(const struct socket *sck);
22447 +extern int gr_handle_sock_client(const struct sockaddr *sck);
22448 +extern int gr_search_connect(const struct socket * sock,
22449 +                            const struct sockaddr_in * addr);
22450 +extern int gr_search_bind(const struct socket * sock,
22451 +                          const struct sockaddr_in * addr);
22452 +extern int gr_search_listen(const struct socket * sock);
22453 +extern int gr_search_accept(const struct socket * sock);
22454 +extern int gr_search_socket(const int domain, const int type,
22455 +                           const int protocol);
22456 +
22457  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
22458  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
22459                          size_t size, loff_t pos);
22460 @@ -1184,6 +1200,16 @@ asmlinkage long sys_socket(int family, i
22461         int retval;
22462         struct socket *sock;
22463  
22464 +       if(!gr_search_socket(family, type, protocol)) {
22465 +               retval = -EACCES;
22466 +               goto out;
22467 +       }
22468 +
22469 +       if (gr_handle_sock_all(family, type, protocol)) {
22470 +               retval = -EACCES;
22471 +               goto out;
22472 +       }
22473 +
22474         retval = sock_create(family, type, protocol, &sock);
22475         if (retval < 0)
22476                 goto out;
22477 @@ -1279,11 +1305,23 @@ asmlinkage long sys_bind(int fd, struct 
22478  {
22479         struct socket *sock;
22480         char address[MAX_SOCK_ADDR];
22481 +       struct sockaddr *sck;
22482         int err;
22483  
22484         if((sock = sockfd_lookup(fd,&err))!=NULL)
22485         {
22486                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
22487 +                       sck = (struct sockaddr *)address;
22488 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck)) {
22489 +                               sockfd_put(sock);
22490 +                               return -EACCES;
22491 +                       }
22492 +
22493 +                       if (gr_handle_sock_server(sck)) {
22494 +                               sockfd_put(sock);
22495 +                               return -EACCES;
22496 +                       }
22497 +
22498                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
22499                         if (err) {
22500                                 sockfd_put(sock);
22501 @@ -1320,6 +1358,16 @@ asmlinkage long sys_listen(int fd, int b
22502                         return err;
22503                 }
22504  
22505 +               if (gr_handle_sock_server_other(sock)) {
22506 +                       sockfd_put(sock);
22507 +                       return -EPERM;
22508 +               }
22509 +
22510 +               if(!gr_search_listen(sock)) {
22511 +                       sockfd_put(sock);
22512 +                       return -EPERM;
22513 +               }
22514 +
22515                 err=sock->ops->listen(sock, backlog);
22516                 sockfd_put(sock);
22517         }
22518 @@ -1360,6 +1408,16 @@ asmlinkage long sys_accept(int fd, struc
22519         if (err)
22520                 goto out_release;
22521  
22522 +       if (gr_handle_sock_server_other(sock)) {
22523 +               err = -EPERM;
22524 +               goto out_release;
22525 +       }
22526 +
22527 +       if(!gr_search_accept(sock)) {
22528 +               err = -EPERM;
22529 +               goto out_release;
22530 +       }
22531 +
22532         /*
22533          * We don't need try_module_get here, as the listening socket (sock)
22534          * has the protocol module (sock->ops->owner) held.
22535 @@ -1386,6 +1444,7 @@ asmlinkage long sys_accept(int fd, struc
22536                 goto out_release;
22537  
22538         security_socket_post_accept(sock, newsock);
22539 +       gr_attach_curr_ip(newsock->sk);
22540  
22541  out_put:
22542         sockfd_put(sock);
22543 @@ -1413,6 +1472,7 @@ asmlinkage long sys_connect(int fd, stru
22544  {
22545         struct socket *sock;
22546         char address[MAX_SOCK_ADDR];
22547 +       struct sockaddr *sck;
22548         int err;
22549  
22550         sock = sockfd_lookup(fd, &err);
22551 @@ -1422,6 +1482,18 @@ asmlinkage long sys_connect(int fd, stru
22552         if (err < 0)
22553                 goto out_put;
22554  
22555 +       sck = (struct sockaddr *)address;
22556 +
22557 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck)) {
22558 +               err = -EACCES;
22559 +               goto out_put;
22560 +       }
22561 +
22562 +       if (gr_handle_sock_client(sck)) {
22563 +               err = -EACCES;
22564 +               goto out_put;
22565 +       }
22566 +
22567         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
22568         if (err)
22569                 goto out_put;
22570 @@ -1675,6 +1747,7 @@ asmlinkage long sys_shutdown(int fd, int
22571                 err=sock->ops->shutdown(sock, how);
22572                 sockfd_put(sock);
22573         }
22574 +
22575         return err;
22576  }
22577  
22578 diff -urNp linux-2.6.11/net/sunrpc/xprt.c linux-2.6.11/net/sunrpc/xprt.c
22579 --- linux-2.6.11/net/sunrpc/xprt.c      2005-03-02 02:38:13.000000000 -0500
22580 +++ linux-2.6.11/net/sunrpc/xprt.c      2005-03-09 11:56:44.000000000 -0500
22581 @@ -58,6 +58,7 @@
22582  #include <linux/file.h>
22583  #include <linux/workqueue.h>
22584  #include <linux/random.h>
22585 +#include <linux/grsecurity.h>
22586  
22587  #include <net/sock.h>
22588  #include <net/checksum.h>
22589 diff -urNp linux-2.6.11/net/unix/af_unix.c linux-2.6.11/net/unix/af_unix.c
22590 --- linux-2.6.11/net/unix/af_unix.c     2005-03-02 02:38:12.000000000 -0500
22591 +++ linux-2.6.11/net/unix/af_unix.c     2005-03-09 11:56:44.000000000 -0500
22592 @@ -118,6 +118,7 @@
22593  #include <linux/mount.h>
22594  #include <net/checksum.h>
22595  #include <linux/security.h>
22596 +#include <linux/grsecurity.h>
22597  
22598  int sysctl_unix_max_dgram_qlen = 10;
22599  
22600 @@ -672,6 +673,11 @@ static struct sock *unix_find_other(stru
22601                 if (err)
22602                         goto put_fail;
22603  
22604 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
22605 +                       err = -EACCES;
22606 +                       goto put_fail;
22607 +               }
22608 +
22609                 err = -ECONNREFUSED;
22610                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
22611                         goto put_fail;
22612 @@ -695,6 +701,13 @@ static struct sock *unix_find_other(stru
22613                 if (u) {
22614                         struct dentry *dentry;
22615                         dentry = unix_sk(u)->dentry;
22616 +
22617 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
22618 +                               err = -EPERM;
22619 +                               sock_put(u);
22620 +                               goto fail;
22621 +                       }
22622 +
22623                         if (dentry)
22624                                 touch_atime(unix_sk(u)->mnt, dentry);
22625                 } else
22626 @@ -794,9 +807,18 @@ static int unix_bind(struct socket *sock
22627                  */
22628                 mode = S_IFSOCK |
22629                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
22630 +
22631 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
22632 +                       err = -EACCES;
22633 +                       goto out_mknod_dput;
22634 +               }
22635 +
22636                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
22637                 if (err)
22638                         goto out_mknod_dput;
22639 +
22640 +               gr_handle_create(dentry, nd.mnt);
22641 +
22642                 up(&nd.dentry->d_inode->i_sem);
22643                 dput(nd.dentry);
22644                 nd.dentry = dentry;
22645 @@ -814,6 +836,10 @@ static int unix_bind(struct socket *sock
22646                         goto out_unlock;
22647                 }
22648  
22649 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
22650 +               sk->sk_peercred.pid = current->pid;
22651 +#endif
22652 +
22653                 list = &unix_socket_table[addr->hash];
22654         } else {
22655                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
22656 diff -urNp linux-2.6.11/security/Kconfig linux-2.6.11/security/Kconfig
22657 --- linux-2.6.11/security/Kconfig       2005-03-02 02:38:13.000000000 -0500
22658 +++ linux-2.6.11/security/Kconfig       2005-03-09 11:56:44.000000000 -0500
22659 @@ -4,6 +4,407 @@
22660  
22661  menu "Security options"
22662  
22663 +source grsecurity/Kconfig
22664 +
22665 +menu "PaX"
22666 +
22667 +config PAX
22668 +       bool "Enable various PaX features"
22669 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
22670 +       help
22671 +         This allows you to enable various PaX features.  PaX adds
22672 +         intrusion prevention mechanisms to the kernel that reduce
22673 +         the risks posed by exploitable memory corruption bugs.
22674 +
22675 +menu "PaX Control"
22676 +       depends on PAX
22677 +
22678 +config PAX_SOFTMODE
22679 +       bool 'Support soft mode'
22680 +       help
22681 +         Enabling this option will allow you to run PaX in soft mode, that
22682 +         is, PaX features will not be enforced by default, only on executables
22683 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
22684 +         is the only way to mark executables for soft mode use.
22685 +
22686 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
22687 +         line option on boot.  Furthermore you can control various PaX features
22688 +         at runtime via the entries in /proc/sys/kernel/pax.
22689 +
22690 +config PAX_EI_PAX
22691 +       bool 'Use legacy ELF header marking'
22692 +       help
22693 +         Enabling this option will allow you to control PaX features on
22694 +         a per executable basis via the 'chpax' utility available at
22695 +         http://pax.grsecurity.net/.  The control flags will be read from
22696 +         an otherwise reserved part of the ELF header.  This marking has
22697 +         numerous drawbacks (no support for soft-mode, toolchain does not
22698 +         know about the non-standard use of the ELF header) therefore it
22699 +         has been deprecated in favour of PT_PAX_FLAGS support.
22700 +
22701 +         If you have applications not marked by the PT_PAX_FLAGS ELF
22702 +         program header then you MUST enable this option otherwise they
22703 +         will not get any protection.
22704 +
22705 +         Note that if you enable PT_PAX_FLAGS marking support as well,
22706 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
22707 +
22708 +config PAX_PT_PAX_FLAGS
22709 +       bool 'Use ELF program header marking'
22710 +       help
22711 +         Enabling this option will allow you to control PaX features on
22712 +         a per executable basis via the 'paxctl' utility available at
22713 +         http://pax.grsecurity.net/.  The control flags will be read from
22714 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
22715 +         has the benefits of supporting both soft mode and being fully
22716 +         integrated into the toolchain (the binutils patch is available
22717 +         from http://pax.grsecurity.net).
22718 +
22719 +         If you have applications not marked by the PT_PAX_FLAGS ELF
22720 +         program header then you MUST enable the EI_PAX marking support
22721 +         otherwise they will not get any protection.
22722 +
22723 +         Note that if you enable the legacy EI_PAX marking support as well,
22724 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
22725 +
22726 +choice
22727 +       prompt 'MAC system integration'
22728 +       default PAX_HAVE_ACL_FLAGS
22729 +       help
22730 +         Mandatory Access Control systems have the option of controlling
22731 +         PaX flags on a per executable basis, choose the method supported
22732 +         by your particular system.
22733 +
22734 +         - "none": if your MAC system does not interact with PaX,
22735 +         - "direct": if your MAC system defines pax_set_flags() itself,
22736 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
22737 +
22738 +         NOTE: this option is for developers/integrators only.
22739 +
22740 +config PAX_NO_ACL_FLAGS
22741 +       bool 'none'
22742 +
22743 +config PAX_HAVE_ACL_FLAGS
22744 +       bool 'direct'
22745 +
22746 +config PAX_HOOK_ACL_FLAGS
22747 +       bool 'hook'
22748 +endchoice
22749 +
22750 +endmenu
22751 +
22752 +menu "Non-executable pages"
22753 +       depends on PAX
22754 +
22755 +config PAX_NOEXEC
22756 +       bool "Enforce non-executable pages"
22757 +       depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
22758 +       help
22759 +         By design some architectures do not allow for protecting memory
22760 +         pages against execution or even if they do, Linux does not make
22761 +         use of this feature.  In practice this means that if a page is
22762 +         readable (such as the stack or heap) it is also executable.
22763 +
22764 +         There is a well known exploit technique that makes use of this
22765 +         fact and a common programming mistake where an attacker can
22766 +         introduce code of his choice somewhere in the attacked program's
22767 +         memory (typically the stack or the heap) and then execute it.
22768 +
22769 +         If the attacked program was running with different (typically
22770 +         higher) privileges than that of the attacker, then he can elevate
22771 +         his own privilege level (e.g. get a root shell, write to files for
22772 +         which he does not have write access to, etc).
22773 +
22774 +         Enabling this option will let you choose from various features
22775 +         that prevent the injection and execution of 'foreign' code in
22776 +         a program.
22777 +
22778 +         This will also break programs that rely on the old behaviour and
22779 +         expect that dynamically allocated memory via the malloc() family
22780 +         of functions is executable (which it is not).  Notable examples
22781 +         are the XFree86 4.x server, the java runtime and wine.
22782 +
22783 +config PAX_PAGEEXEC
22784 +       bool "Paging based non-executable pages"
22785 +       depends on PAX_NOEXEC && (!X86 || X86_64 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8)
22786 +       select PAX_NOVSYSCALL if X86 && !X86_64
22787 +       help
22788 +         This implementation is based on the paging feature of the CPU.
22789 +         On i386 and ppc there is a variable but usually low performance
22790 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
22791 +         and x86_64 there is no performance impact.
22792 +
22793 +config PAX_SEGMEXEC
22794 +       bool "Segmentation based non-executable pages"
22795 +       depends on PAX_NOEXEC && X86 && !X86_64
22796 +       help
22797 +         This implementation is based on the segmentation feature of the
22798 +         CPU and has little performance impact, however applications will
22799 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
22800 +
22801 +choice
22802 +       prompt "Default non-executable page method"
22803 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
22804 +       default PAX_DEFAULT_SEGMEXEC
22805 +       help
22806 +         Select the default non-executable page method applied to applications
22807 +         that do not select one themselves.
22808 +
22809 +config PAX_DEFAULT_PAGEEXEC
22810 +       bool "PAGEEXEC"
22811 +
22812 +config PAX_DEFAULT_SEGMEXEC
22813 +       bool "SEGMEXEC"
22814 +endchoice
22815 +
22816 +config PAX_EMUTRAMP
22817 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86) && !X86_64
22818 +       default y if PARISC || PPC32
22819 +       help
22820 +         There are some programs and libraries that for one reason or
22821 +         another attempt to execute special small code snippets from
22822 +         non-executable memory pages.  Most notable examples are the
22823 +         signal handler return code generated by the kernel itself and
22824 +         the GCC trampolines.
22825 +
22826 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
22827 +         such programs will no longer work under your kernel.
22828 +
22829 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
22830 +         utilities to enable trampoline emulation for the affected programs
22831 +         yet still have the protection provided by the non-executable pages.
22832 +
22833 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
22834 +         well, otherwise your system will not even boot.
22835 +
22836 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
22837 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
22838 +         for the affected files.
22839 +
22840 +         NOTE: enabling this feature *may* open up a loophole in the
22841 +         protection provided by non-executable pages that an attacker
22842 +         could abuse.  Therefore the best solution is to not have any
22843 +         files on your system that would require this option.  This can
22844 +         be achieved by not using libc5 (which relies on the kernel
22845 +         signal handler return code) and not using or rewriting programs
22846 +         that make use of the nested function implementation of GCC.
22847 +         Skilled users can just fix GCC itself so that it implements
22848 +         nested function calls in a way that does not interfere with PaX.
22849 +
22850 +config PAX_EMUSIGRT
22851 +       bool "Automatically emulate sigreturn trampolines"
22852 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
22853 +       default y
22854 +       help
22855 +         Enabling this option will have the kernel automatically detect
22856 +         and emulate signal return trampolines executing on the stack
22857 +         that would otherwise lead to task termination.
22858 +
22859 +         This solution is intended as a temporary one for users with
22860 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
22861 +         Modula-3 runtime, etc) or executables linked to such, basically
22862 +         everything that does not specify its own SA_RESTORER function in
22863 +         normal executable memory like glibc 2.1+ does.
22864 +
22865 +         On parisc and ppc you MUST enable this option, otherwise your
22866 +         system will not even boot.
22867 +
22868 +         NOTE: this feature cannot be disabled on a per executable basis
22869 +         and since it *does* open up a loophole in the protection provided
22870 +         by non-executable pages, the best solution is to not have any
22871 +         files on your system that would require this option.
22872 +
22873 +config PAX_MPROTECT
22874 +       bool "Restrict mprotect()"
22875 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
22876 +       help
22877 +         Enabling this option will prevent programs from
22878 +          - changing the executable status of memory pages that were
22879 +            not originally created as executable,
22880 +          - making read-only executable pages writable again,
22881 +          - creating executable pages from anonymous memory.
22882 +
22883 +         You should say Y here to complete the protection provided by
22884 +         the enforcement of non-executable pages.
22885 +
22886 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
22887 +         this feature on a per file basis.
22888 +
22889 +config PAX_NOELFRELOCS
22890 +       bool "Disallow ELF text relocations"
22891 +       depends on PAX_MPROTECT && (IA64 || X86 || X86_64)
22892 +       help
22893 +         Non-executable pages and mprotect() restrictions are effective
22894 +         in preventing the introduction of new executable code into an
22895 +         attacked task's address space.  There remain only two venues
22896 +         for this kind of attack: if the attacker can execute already
22897 +         existing code in the attacked task then he can either have it
22898 +         create and mmap() a file containing his code or have it mmap()
22899 +         an already existing ELF library that does not have position
22900 +         independent code in it and use mprotect() on it to make it
22901 +         writable and copy his code there.  While protecting against
22902 +         the former approach is beyond PaX, the latter can be prevented
22903 +         by having only PIC ELF libraries on one's system (which do not
22904 +         need to relocate their code).  If you are sure this is your case,
22905 +         then enable this option otherwise be careful as you may not even
22906 +         be able to boot or log on your system (for example, some PAM
22907 +         modules are erroneously compiled as non-PIC by default).
22908 +
22909 +         NOTE: if you are using dynamic ELF executables (as suggested
22910 +         when using ASLR) then you must have made sure that you linked
22911 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
22912 +         referenced there has already been updated to support this).
22913 +
22914 +config PAX_ETEXECRELOCS
22915 +       bool "Allow ELF ET_EXEC text relocations"
22916 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
22917 +       default y
22918 +       help
22919 +         On some architectures there are incorrectly created applications
22920 +         that require text relocations and would not work without enabling
22921 +         this option.  If you are an alpha, ia64 or parisc user, you should
22922 +         enable this option and disable it once you have made sure that
22923 +         none of your applications need it.
22924 +
22925 +config PAX_EMUPLT
22926 +       bool "Automatically emulate ELF PLT"
22927 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
22928 +       default y
22929 +       help
22930 +         Enabling this option will have the kernel automatically detect
22931 +         and emulate the Procedure Linkage Table entries in ELF files.
22932 +         On some architectures such entries are in writable memory, and
22933 +         become non-executable leading to task termination.  Therefore
22934 +         it is mandatory that you enable this option on alpha, parisc, ppc,
22935 +         sparc and sparc64, otherwise your system would not even boot.
22936 +
22937 +         NOTE: this feature *does* open up a loophole in the protection
22938 +         provided by the non-executable pages, therefore the proper
22939 +         solution is to modify the toolchain to produce a PLT that does
22940 +         not need to be writable.
22941 +
22942 +config PAX_DLRESOLVE
22943 +       bool
22944 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
22945 +       default y
22946 +
22947 +config PAX_SYSCALL
22948 +       bool
22949 +       depends on PAX_PAGEEXEC && PPC32
22950 +       default y
22951 +
22952 +config PAX_KERNEXEC
22953 +       bool "Enforce non-executable kernel pages"
22954 +       depends on PAX_NOEXEC && X86 && !X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS
22955 +       help
22956 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
22957 +         that is, enabling this option will make it harder to inject
22958 +         and execute 'foreign' code in kernel memory itself.
22959 +
22960 +endmenu
22961 +
22962 +menu "Address Space Layout Randomization"
22963 +       depends on PAX
22964 +
22965 +config PAX_ASLR
22966 +       bool "Address Space Layout Randomization"
22967 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
22968 +       help
22969 +         Many if not most exploit techniques rely on the knowledge of
22970 +         certain addresses in the attacked program.  The following options
22971 +         will allow the kernel to apply a certain amount of randomization
22972 +         to specific parts of the program thereby forcing an attacker to
22973 +         guess them in most cases.  Any failed guess will most likely crash
22974 +         the attacked program which allows the kernel to detect such attempts
22975 +         and react on them.  PaX itself provides no reaction mechanisms,
22976 +         instead it is strongly encouraged that you make use of Nergal's
22977 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
22978 +         (http://www.grsecurity.net/) built-in crash detection features or
22979 +         develop one yourself.
22980 +
22981 +         By saying Y here you can choose to randomize the following areas:
22982 +          - top of the task's kernel stack
22983 +          - top of the task's userland stack
22984 +          - base address for mmap() requests that do not specify one
22985 +            (this includes all libraries)
22986 +          - base address of the main executable
22987 +
22988 +         It is strongly recommended to say Y here as address space layout
22989 +         randomization has negligible impact on performance yet it provides
22990 +         a very effective protection.
22991 +
22992 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
22993 +         this feature on a per file basis.
22994 +
22995 +config PAX_RANDKSTACK
22996 +       bool "Randomize kernel stack base"
22997 +       depends on PAX_ASLR && X86_TSC && !X86_64
22998 +       help
22999 +         By saying Y here the kernel will randomize every task's kernel
23000 +         stack on every system call.  This will not only force an attacker
23001 +         to guess it but also prevent him from making use of possible
23002 +         leaked information about it.
23003 +
23004 +         Since the kernel stack is a rather scarce resource, randomization
23005 +         may cause unexpected stack overflows, therefore you should very
23006 +         carefully test your system.  Note that once enabled in the kernel
23007 +         configuration, this feature cannot be disabled on a per file basis.
23008 +
23009 +config PAX_RANDUSTACK
23010 +       bool "Randomize user stack base"
23011 +       depends on PAX_ASLR
23012 +       help
23013 +         By saying Y here the kernel will randomize every task's userland
23014 +         stack.  The randomization is done in two steps where the second
23015 +         one may apply a big amount of shift to the top of the stack and
23016 +         cause problems for programs that want to use lots of memory (more
23017 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
23018 +         For this reason the second step can be controlled by 'chpax' or
23019 +         'paxctl' on a per file basis.
23020 +
23021 +config PAX_RANDMMAP
23022 +       bool "Randomize mmap() base"
23023 +       depends on PAX_ASLR
23024 +       help
23025 +         By saying Y here the kernel will use a randomized base address for
23026 +         mmap() requests that do not specify one themselves.  As a result
23027 +         all dynamically loaded libraries will appear at random addresses
23028 +         and therefore be harder to exploit by a technique where an attacker
23029 +         attempts to execute library code for his purposes (e.g. spawn a
23030 +         shell from an exploited program that is running at an elevated
23031 +         privilege level).
23032 +
23033 +         Furthermore, if a program is relinked as a dynamic ELF file, its
23034 +         base address will be randomized as well, completing the full
23035 +         randomization of the address space layout.  Attacking such programs
23036 +         becomes a guess game.  You can find an example of doing this at
23037 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
23038 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
23039 +
23040 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
23041 +         feature on a per file basis.
23042 +
23043 +config PAX_NOVSYSCALL
23044 +       bool "Disable the vsyscall page"
23045 +       depends on PAX_ASLR && X86 && !X86_64
23046 +       help
23047 +         The Linux 2.6 kernel introduced a new feature that speeds up or
23048 +         simplifies certain operations, such as system calls or returns
23049 +         from signal handlers.
23050 +
23051 +         Unfortunately the implementation also gives a powerful instrument
23052 +         into the hands of exploit writers: the so-called vsyscall page exists
23053 +         in every task at the same fixed address and it contains machine code
23054 +         that is very useful in performing the return-to-libc style attack.
23055 +
23056 +         Since this exploit technique cannot in general be protected against
23057 +         via kernel solutions, this option will allow you to disable the use
23058 +         of the vsyscall page and revert back to the old behaviour.
23059 +
23060 +endmenu
23061 +
23062 +endmenu
23063 +
23064  config KEYS
23065         bool "Enable access key retention support"
23066         help
23067 diff -urNp linux-2.6.11/security/commoncap.c linux-2.6.11/security/commoncap.c
23068 --- linux-2.6.11/security/commoncap.c   2005-03-02 02:38:07.000000000 -0500
23069 +++ linux-2.6.11/security/commoncap.c   2005-03-09 11:56:44.000000000 -0500
23070 @@ -23,6 +23,7 @@
23071  #include <linux/ptrace.h>
23072  #include <linux/xattr.h>
23073  #include <linux/hugetlb.h>
23074 +#include <linux/grsecurity.h>
23075  
23076  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
23077  {
23078 @@ -44,7 +45,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
23079  int cap_capable (struct task_struct *tsk, int cap)
23080  {
23081         /* Derived from include/linux/sched.h:capable. */
23082 -       if (cap_raised(tsk->cap_effective, cap))
23083 +       if (cap_raised (tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
23084 +               return 0;
23085 +       return -EPERM;
23086 +}
23087 +
23088 +int cap_capable_nolog (struct task_struct *tsk, int cap)
23089 +{
23090 +       /* Derived from include/linux/sched.h:capable. */
23091 +       if (cap_raised (tsk->cap_effective, cap))
23092                 return 0;
23093         return -EPERM;
23094  }
23095 @@ -60,7 +69,7 @@ int cap_ptrace (struct task_struct *pare
23096  {
23097         /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
23098         if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
23099 -           !capable(CAP_SYS_PTRACE))
23100 +           !capable_nolog(CAP_SYS_PTRACE))
23101                 return -EPERM;
23102         return 0;
23103  }
23104 @@ -163,8 +172,11 @@ void cap_bprm_apply_creds (struct linux_
23105                 }
23106         }
23107  
23108 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
23109 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
23110 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
23111 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
23112 +
23113 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
23114 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
23115  
23116         /* For init, we want to retain the capabilities set
23117          * in the init_task struct. Thus we skip the usual
23118 @@ -175,6 +187,8 @@ void cap_bprm_apply_creds (struct linux_
23119                     cap_intersect (new_permitted, bprm->cap_effective);
23120         }
23121  
23122 +       gr_handle_chroot_caps(current);
23123 +
23124         /* AUD: Audit candidate if current->cap_effective is set */
23125  
23126         current->keep_capabilities = 0;
23127 @@ -320,12 +334,13 @@ int cap_vm_enough_memory(long pages)
23128  {
23129         int cap_sys_admin = 0;
23130  
23131 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
23132 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
23133                 cap_sys_admin = 1;
23134         return __vm_enough_memory(pages, cap_sys_admin);
23135  }
23136  
23137  EXPORT_SYMBOL(cap_capable);
23138 +EXPORT_SYMBOL(cap_capable_nolog);
23139  EXPORT_SYMBOL(cap_settime);
23140  EXPORT_SYMBOL(cap_ptrace);
23141  EXPORT_SYMBOL(cap_capget);
23142 diff -urNp linux-2.6.11/security/dummy.c linux-2.6.11/security/dummy.c
23143 --- linux-2.6.11/security/dummy.c       2005-03-02 02:37:50.000000000 -0500
23144 +++ linux-2.6.11/security/dummy.c       2005-03-09 11:56:44.000000000 -0500
23145 @@ -28,6 +28,7 @@
23146  #include <linux/hugetlb.h>
23147  #include <linux/ptrace.h>
23148  #include <linux/file.h>
23149 +#include <linux/grsecurity.h>
23150  
23151  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
23152  {
23153 @@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru
23154                 }
23155         }
23156  
23157 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
23158 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
23159 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
23160 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
23161 +
23162 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
23163 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
23164  
23165         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
23166  }
23167 diff -urNp linux-2.6.11/security/security.c linux-2.6.11/security/security.c
23168 --- linux-2.6.11/security/security.c    2005-03-02 02:37:30.000000000 -0500
23169 +++ linux-2.6.11/security/security.c    2005-03-09 11:56:44.000000000 -0500
23170 @@ -200,4 +200,5 @@ EXPORT_SYMBOL_GPL(unregister_security);
23171  EXPORT_SYMBOL_GPL(mod_reg_security);
23172  EXPORT_SYMBOL_GPL(mod_unreg_security);
23173  EXPORT_SYMBOL(capable);
23174 +EXPORT_SYMBOL(capable_nolog);
23175  EXPORT_SYMBOL(security_ops);
This page took 2.165784 seconds and 3 git commands to generate.