]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.0-rc3-2.4.22-O1.patch
- added description of djurban's branch
[packages/kernel.git] / grsecurity-2.0-rc3-2.4.22-O1.patch
1 diff -urN linux-2.4.22.org/arch/alpha/config.in linux-2.4.22/arch/alpha/config.in
2 --- linux-2.4.22.org/arch/alpha/config.in       2003-11-22 22:11:56.000000000 +0100
3 +++ linux-2.4.22/arch/alpha/config.in   2003-11-22 22:14:06.000000000 +0100
4 @@ -469,3 +469,12 @@
5  
6  source crypto/Config.in
7  source lib/Config.in
8 +
9 +mainmenu_option next_comment
10 +comment 'Grsecurity'
11 +bool 'Grsecurity' CONFIG_GRKERNSEC
12 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
13 +       source grsecurity/Config.in
14 +fi
15 +endmenu
16 +
17 diff -urN linux-2.4.22.org/arch/alpha/kernel/osf_sys.c linux-2.4.22/arch/alpha/kernel/osf_sys.c
18 --- linux-2.4.22.org/arch/alpha/kernel/osf_sys.c        2003-11-22 22:11:56.000000000 +0100
19 +++ linux-2.4.22/arch/alpha/kernel/osf_sys.c    2003-11-22 22:14:06.000000000 +0100
20 @@ -33,6 +33,7 @@
21  #include <linux/file.h>
22  #include <linux/types.h>
23  #include <linux/ipc.h>
24 +#include <linux/grsecurity.h>
25  
26  #include <asm/fpu.h>
27  #include <asm/io.h>
28 @@ -230,6 +231,11 @@
29         struct file *file = NULL;
30         unsigned long ret = -EBADF;
31  
32 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
33 +       if (flags & MAP_MIRROR)
34 +               return -EINVAL;
35 +#endif
36 +
37  #if 0
38         if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
39                 printk("%s: unimplemented OSF mmap flags %04lx\n", 
40 @@ -240,6 +246,13 @@
41                 if (!file)
42                         goto out;
43         }
44 +
45 +       if(gr_handle_mmap(file, prot)) {
46 +               fput(file);
47 +               ret = -EACCES;
48 +               goto out;
49 +       }
50 +
51         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
52         down_write(&current->mm->mmap_sem);
53         ret = do_mmap(file, addr, len, prot, flags, off);
54 @@ -1357,6 +1370,10 @@
55            merely specific addresses, but regions of memory -- perhaps
56            this feature should be incorporated into all ports?  */
57  
58 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
59 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
60 +#endif
61 +
62         if (addr) {
63                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
64                 if (addr != -ENOMEM)
65 @@ -1364,8 +1381,15 @@
66         }
67  
68         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
69 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
70 -                                        len, limit);
71 +
72 +       addr = TASK_UNMAPPED_BASE;
73 +
74 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
75 +       if (current->flags & PF_PAX_RANDMMAP)
76 +               addr += current->mm->delta_mmap;
77 +#endif
78 +
79 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
80         if (addr != -ENOMEM)
81                 return addr;
82  
83 diff -urN linux-2.4.22.org/arch/alpha/kernel/ptrace.c linux-2.4.22/arch/alpha/kernel/ptrace.c
84 --- linux-2.4.22.org/arch/alpha/kernel/ptrace.c 2003-11-22 22:11:56.000000000 +0100
85 +++ linux-2.4.22/arch/alpha/kernel/ptrace.c     2003-11-22 22:14:06.000000000 +0100
86 @@ -13,6 +13,7 @@
87  #include <linux/ptrace.h>
88  #include <linux/user.h>
89  #include <linux/slab.h>
90 +#include <linux/grsecurity.h>
91  
92  #include <asm/uaccess.h>
93  #include <asm/pgtable.h>
94 @@ -275,6 +276,10 @@
95         read_unlock(&tasklist_lock);
96         if (!child)
97                 goto out_notsk;
98 +
99 +       if(gr_handle_ptrace(child, request))
100 +               goto out;
101 +
102         if (request == PTRACE_ATTACH) {
103                 ret = ptrace_attach(child);
104                 goto out;
105 diff -urN linux-2.4.22.org/arch/alpha/mm/fault.c linux-2.4.22/arch/alpha/mm/fault.c
106 --- linux-2.4.22.org/arch/alpha/mm/fault.c      2003-11-22 22:11:56.000000000 +0100
107 +++ linux-2.4.22/arch/alpha/mm/fault.c  2003-11-22 22:14:06.000000000 +0100
108 @@ -53,6 +53,139 @@
109         __reload_thread(&current->thread);
110  }
111  
112 +/*
113 + * PaX: decide what to do with offenders (regs->pc = fault address)
114 + *
115 + * returns 1 when task should be killed
116 + *         2 when patched PLT trampoline was detected
117 + *         3 when unpatched PLT trampoline was detected
118 + *        4 when legitimate ET_EXEC was detected
119 + */
120 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
121 +static int pax_handle_fetch_fault(struct pt_regs *regs)
122 +{
123 +       int err;
124 +
125 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
126 +       if (current->flags & PF_PAX_RANDEXEC) {
127 +               if (regs->pc >= current->mm->start_code &&
128 +                   regs->pc < current->mm->end_code)
129 +               {
130 +                       if (regs->r26 == regs->pc)
131 +                               return 1;
132 +                       regs->pc += current->mm->delta_exec;
133 +                       return 4;
134 +               }
135 +       }
136 +#endif
137 +
138 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
139 +       do { /* PaX: patched PLT emulation #1 */
140 +               unsigned int ldah, ldq, jmp;
141 +
142 +               err = get_user(ldah, (unsigned int *)regs->pc);
143 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
144 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
145 +
146 +               if (err)
147 +                       break;
148 +
149 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
150 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
151 +                   jmp == 0x6BFB0000U)
152 +               {
153 +                       unsigned long r27, addr;
154 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
155 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
156 +
157 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
158 +                       err = get_user(r27, (unsigned long*)addr);
159 +                       if (err)
160 +                               break;
161 +
162 +                       regs->r27 = r27;
163 +                       regs->pc = r27;
164 +                       return 2;
165 +               }
166 +       } while (0);
167 +
168 +       do { /* PaX: patched PLT emulation #2 */
169 +               unsigned int ldah, lda, br;
170 +
171 +               err = get_user(ldah, (unsigned int *)regs->pc);
172 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
173 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
174 +
175 +               if (err)
176 +                       break;
177 +
178 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
179 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
180 +                   (br & 0xFFE00000U) == 0xC3E00000U)
181 +               {
182 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
183 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
184 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
185 +
186 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
187 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
188 +                       return 2;
189 +               }
190 +       } while (0);
191 +
192 +       do { /* PaX: unpatched PLT emulation */
193 +               unsigned int br;
194 +
195 +               err = get_user(br, (unsigned int *)regs->pc);
196 +
197 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
198 +                       unsigned int br2, ldq, nop, jmp;
199 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
200 +
201 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
202 +                       err = get_user(br2, (unsigned int *)addr);  
203 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
204 +                       err |= get_user(nop, (unsigned int *)(addr+8));
205 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
206 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
207 +
208 +                       if (err)
209 +                               break;
210 +
211 +                       if (br2 == 0xC3600000U &&
212 +                           ldq == 0xA77B000CU &&
213 +                           nop == 0x47FF041FU &&
214 +                           jmp == 0x6B7B0000U)
215 +                       {
216 +                               regs->r28 = regs->pc+4;
217 +                               regs->r27 = addr+16;
218 +                               regs->pc = resolver;
219 +                               return 3;
220 +                       }
221 +               }
222 +       } while (0);
223 +#endif
224 +
225 +       return 1;
226 +}
227 +
228 +void pax_report_insns(void *pc)
229 +{
230 +       unsigned long i;
231 +
232 +       printk(KERN_ERR "PAX: bytes at PC: ");
233 +       for (i = 0; i < 5; i++) {
234 +               unsigned int c;
235 +               if (get_user(c, (unsigned int*)pc+i)) {
236 +                       printk("<invalid address>.");
237 +                       break;
238 +               }
239 +               printk("%08x ", c);
240 +       }
241 +       printk("\n");
242 +}
243 +#endif
244 +
245  
246  /*
247   * This routine handles page faults.  It determines the address,
248 @@ -133,8 +266,32 @@
249  good_area:
250         info.si_code = SEGV_ACCERR;
251         if (cause < 0) {
252 -               if (!(vma->vm_flags & VM_EXEC))
253 +               if (!(vma->vm_flags & VM_EXEC)) {
254 +
255 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
256 +                       if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->pc)
257 +                               goto bad_area;
258 +
259 +                       up_read(&mm->mmap_sem);
260 +                       switch(pax_handle_fetch_fault(regs)) {
261 +
262 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
263 +                       case 2:
264 +                       case 3:
265 +                               return;
266 +#endif
267 +
268 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
269 +                       case 4:
270 +                               return;
271 +#endif
272 +                       }
273 +                       pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
274 +                       do_exit(SIGKILL);
275 +#else
276                         goto bad_area;
277 +#endif
278 +               }
279         } else if (!cause) {
280                 /* Allow reads even for write-only mappings */
281                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
282 diff -urN linux-2.4.22.org/arch/arm/config.in linux-2.4.22/arch/arm/config.in
283 --- linux-2.4.22.org/arch/arm/config.in 2003-11-22 22:12:20.000000000 +0100
284 +++ linux-2.4.22/arch/arm/config.in     2003-11-22 22:14:06.000000000 +0100
285 @@ -737,3 +737,11 @@
286  
287  source crypto/Config.in
288  source lib/Config.in
289 +
290 +mainmenu_option next_comment
291 +comment 'Grsecurity'
292 +bool 'Grsecurity' CONFIG_GRKERNSEC
293 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
294 +       source grsecurity/Config.in
295 +fi
296 +endmenu
297 diff -urN linux-2.4.22.org/arch/cris/config.in linux-2.4.22/arch/cris/config.in
298 --- linux-2.4.22.org/arch/cris/config.in        2003-11-22 22:12:37.000000000 +0100
299 +++ linux-2.4.22/arch/cris/config.in    2003-11-22 22:14:06.000000000 +0100
300 @@ -277,3 +277,12 @@
301  source crypto/Config.in
302  source lib/Config.in
303  endmenu
304 +
305 +mainmenu_option next_comment
306 +comment 'Grsecurity'
307 +bool 'Grsecurity' CONFIG_GRKERNSEC
308 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
309 +    source grsecurity/Config.in
310 +fi
311 +endmenu
312 +
313 diff -urN linux-2.4.22.org/arch/i386/config.in linux-2.4.22/arch/i386/config.in
314 --- linux-2.4.22.org/arch/i386/config.in        2003-11-22 22:11:56.000000000 +0100
315 +++ linux-2.4.22/arch/i386/config.in    2003-11-22 22:14:06.000000000 +0100
316 @@ -503,3 +503,11 @@
317  
318  source crypto/Config.in
319  source lib/Config.in
320 +
321 +mainmenu_option next_comment
322 +comment 'Grsecurity'
323 +bool 'Grsecurity' CONFIG_GRKERNSEC
324 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
325 +       source grsecurity/Config.in
326 +fi
327 +endmenu
328 diff -urN linux-2.4.22.org/arch/i386/kernel/apm.c linux-2.4.22/arch/i386/kernel/apm.c
329 --- linux-2.4.22.org/arch/i386/kernel/apm.c     2003-11-22 22:11:55.000000000 +0100
330 +++ linux-2.4.22/arch/i386/kernel/apm.c 2003-11-22 22:14:06.000000000 +0100
331 @@ -614,7 +614,7 @@
332         __asm__ __volatile__(APM_DO_ZERO_SEGS
333                 "pushl %%edi\n\t"
334                 "pushl %%ebp\n\t"
335 -               "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
336 +               "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
337                 "setc %%al\n\t"
338                 "popl %%ebp\n\t"
339                 "popl %%edi\n\t"
340 @@ -666,7 +666,7 @@
341                 __asm__ __volatile__(APM_DO_ZERO_SEGS
342                         "pushl %%edi\n\t"
343                         "pushl %%ebp\n\t"
344 -                       "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
345 +                       "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
346                         "setc %%bl\n\t"
347                         "popl %%ebp\n\t"
348                         "popl %%edi\n\t"
349 @@ -1985,6 +1985,12 @@
350                  __va((unsigned long)0x40 << 4));
351         _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4));
352  
353 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
354 +       set_base(gdt2[APM_40 >> 3],
355 +               __va((unsigned long)0x40 << 4));
356 +       _set_limit((char *)&gdt2[APM_40 >> 3], 4095 - (0x40 << 4));
357 +#endif
358 +
359         apm_bios_entry.offset = apm_info.bios.offset;
360         apm_bios_entry.segment = APM_CS;
361         set_base(gdt[APM_CS >> 3],
362 @@ -1993,6 +1999,16 @@
363                  __va((unsigned long)apm_info.bios.cseg_16 << 4));
364         set_base(gdt[APM_DS >> 3],
365                  __va((unsigned long)apm_info.bios.dseg << 4));
366 +
367 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
368 +       set_base(gdt2[APM_CS >> 3],
369 +               __va((unsigned long)apm_info.bios.cseg << 4));
370 +       set_base(gdt2[APM_CS_16 >> 3],
371 +               __va((unsigned long)apm_info.bios.cseg_16 << 4));
372 +       set_base(gdt2[APM_DS >> 3],
373 +               __va((unsigned long)apm_info.bios.dseg << 4));
374 +#endif
375 +
376  #ifndef APM_RELAX_SEGMENTS
377         if (apm_info.bios.version == 0x100) {
378  #endif
379 @@ -2002,6 +2018,13 @@
380                 _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
381                 /* For the DEC Hinote Ultra CT475 (and others?) */
382                 _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
383 +
384 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
385 +               _set_limit((char *)&gdt2[APM_CS >> 3], 64 * 1024 - 1);
386 +               _set_limit((char *)&gdt2[APM_CS_16 >> 3], 64 * 1024 - 1);
387 +               _set_limit((char *)&gdt2[APM_DS >> 3], 64 * 1024 - 1);
388 +#endif
389 +
390  #ifndef APM_RELAX_SEGMENTS
391         } else {
392                 _set_limit((char *)&gdt[APM_CS >> 3],
393 @@ -2010,6 +2033,16 @@
394                         (apm_info.bios.cseg_16_len - 1) & 0xffff);
395                 _set_limit((char *)&gdt[APM_DS >> 3],
396                         (apm_info.bios.dseg_len - 1) & 0xffff);
397 +
398 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
399 +               _set_limit((char *)&gdt2[APM_CS >> 3],
400 +                       (apm_info.bios.cseg_len - 1) & 0xffff);
401 +               _set_limit((char *)&gdt2[APM_CS_16 >> 3],
402 +                       (apm_info.bios.cseg_16_len - 1) & 0xffff);
403 +               _set_limit((char *)&gdt2[APM_DS >> 3],
404 +                       (apm_info.bios.dseg_len - 1) & 0xffff);
405 +#endif
406 +
407         }
408  #endif
409  
410 diff -urN linux-2.4.22.org/arch/i386/kernel/entry.S linux-2.4.22/arch/i386/kernel/entry.S
411 --- linux-2.4.22.org/arch/i386/kernel/entry.S   2003-11-22 22:11:55.000000000 +0100
412 +++ linux-2.4.22/arch/i386/kernel/entry.S       2003-11-22 22:14:06.000000000 +0100
413 @@ -211,6 +211,17 @@
414         jae badsys
415         call *SYMBOL_NAME(sys_call_table)(,%eax,4)
416         movl %eax,EAX(%esp)             # save the return value
417 +
418 +#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
419 +       cli                             # need_resched and signals atomic test
420 +       cmpl $0,need_resched(%ebx)
421 +       jne reschedule
422 +       cmpl $0,sigpending(%ebx)
423 +       jne signal_return
424 +       call SYMBOL_NAME(pax_randomize_kstack)
425 +       jmp restore_all
426 +#endif
427 +
428  ENTRY(ret_from_sys_call)
429         cli                             # need_resched and signals atomic test
430         cmpl $0,need_resched(%ebx)
431 @@ -391,8 +402,56 @@
432         jmp error_code
433  
434  ENTRY(page_fault)
435 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
436 +       ALIGN
437 +       pushl $ SYMBOL_NAME(pax_do_page_fault)
438 +#else
439         pushl $ SYMBOL_NAME(do_page_fault)
440 +#endif
441 +
442 +#ifndef CONFIG_GRKERNSEC_PAX_EMUTRAMP
443         jmp error_code
444 +#else
445 +       pushl %ds
446 +       pushl %eax
447 +       xorl %eax,%eax
448 +       pushl %ebp
449 +       pushl %edi
450 +       pushl %esi
451 +       pushl %edx
452 +       decl %eax                       # eax = -1
453 +       pushl %ecx
454 +       pushl %ebx
455 +       cld
456 +       movl %es,%ecx
457 +       movl ORIG_EAX(%esp), %esi       # get the error code
458 +       movl ES(%esp), %edi             # get the function address
459 +       movl %eax, ORIG_EAX(%esp)
460 +       movl %ecx, ES(%esp)
461 +       movl %esp,%edx
462 +       pushl %esi                      # push the error code
463 +       pushl %edx                      # push the pt_regs pointer
464 +       movl $(__KERNEL_DS),%edx
465 +       movl %edx,%ds
466 +       movl %edx,%es
467 +       GET_CURRENT(%ebx)
468 +       call *%edi
469 +       addl $8,%esp
470 +       decl %eax
471 +       jnz ret_from_exception
472 +
473 +       popl %ebx
474 +       popl %ecx
475 +       popl %edx
476 +       popl %esi
477 +       popl %edi
478 +       popl %ebp
479 +       popl %eax
480 +       popl %ds
481 +       popl %es
482 +       addl $4,%esp
483 +       jmp system_call
484 +#endif
485  
486  ENTRY(machine_check)
487         pushl $0
488 @@ -404,7 +463,7 @@
489         pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
490         jmp error_code
491  
492 -.data
493 +.section .rodata, "a"
494  ENTRY(sys_call_table)
495         .long SYMBOL_NAME(sys_ni_syscall)       /* 0  -  old "setup()" system call*/
496         .long SYMBOL_NAME(sys_exit)
497 diff -urN linux-2.4.22.org/arch/i386/kernel/head.S linux-2.4.22/arch/i386/kernel/head.S
498 --- linux-2.4.22.org/arch/i386/kernel/head.S    2003-11-22 22:11:55.000000000 +0100
499 +++ linux-2.4.22/arch/i386/kernel/head.S        2003-11-22 22:14:06.000000000 +0100
500 @@ -41,6 +41,7 @@
501   *
502   * On entry, %esi points to the real-mode code as a 32-bit pointer.
503   */
504 +.global startup_32
505  startup_32:
506  /*
507   * Set segments to known values
508 @@ -86,7 +87,7 @@
509                                    PRESENT+RW+USER */
510  2:     stosl
511         add $0x1000,%eax
512 -       cmp $empty_zero_page-__PAGE_OFFSET,%edi
513 +       cmp $0x00c00007,%eax
514         jne 2b
515  
516  /*
517 @@ -100,9 +101,19 @@
518         movl %eax,%cr0          /* ..and set paging (PG) bit */
519         jmp 1f                  /* flush the prefetch-queue */
520  1:
521 +
522 +#if !defined(CONFIG_GRKERNSEC_PAX_KERNEXEC) || defined(CONFIG_SMP)
523 +
524 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
525 +       orw  %bx,%bx
526 +       jz  1f
527 +#endif
528 +
529         movl $1f,%eax
530         jmp *%eax               /* make sure eip is relocated */
531  1:
532 +#endif
533 +
534         /* Set up the stack pointer */
535         lss stack_start,%esp
536  
537 @@ -121,7 +132,7 @@
538   */
539         xorl %eax,%eax
540         movl $ SYMBOL_NAME(__bss_start),%edi
541 -       movl $ SYMBOL_NAME(_end),%ecx
542 +       movl $ SYMBOL_NAME(__bss_end),%ecx
543         subl %edi,%ecx
544         rep
545         stosb
546 @@ -272,8 +283,6 @@
547         jmp L6                  # main should never return here, but
548                                 # just in case, we know what happens.
549  
550 -ready: .byte 0
551 -
552  /*
553   * We depend on ET to be correct. This checks for 287/387.
554   */
555 @@ -319,13 +328,6 @@
556         jne rp_sidt
557         ret
558  
559 -ENTRY(stack_start)
560 -       .long SYMBOL_NAME(init_task_union)+8192
561 -       .long __KERNEL_DS
562 -
563 -/* This is the default interrupt "handler" :-) */
564 -int_msg:
565 -       .asciz "Unknown interrupt\n"
566         ALIGN
567  ignore_int:
568         cld
569 @@ -347,6 +349,18 @@
570         popl %eax
571         iret
572  
573 +.data
574 +ready: .byte 0
575 +
576 +ENTRY(stack_start)
577 +       .long SYMBOL_NAME(init_task_union)+8192
578 +       .long __KERNEL_DS
579 +
580 +.section .rodata,"a"
581 +/* This is the default interrupt "handler" :-) */
582 +int_msg:
583 +       .asciz "Unknown interrupt\n"
584 +
585  /*
586   * The interrupt descriptor table has room for 256 idt's,
587   * the global descriptor table is dependent on the number
588 @@ -372,41 +386,58 @@
589  SYMBOL_NAME(gdt):
590         .long SYMBOL_NAME(gdt_table)
591  
592 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
593 +.globl SYMBOL_NAME(gdt2)
594 +       .word 0
595 +gdt_descr2:
596 +       .word GDT_ENTRIES*8-1
597 +SYMBOL_NAME(gdt2):
598 +       .long SYMBOL_NAME(gdt_table2)
599 +#endif
600 +
601  /*
602   * This is initialized to create an identity-mapping at 0-8M (for bootup
603   * purposes) and another mapping of the 0-8M area at virtual address
604   * PAGE_OFFSET.
605   */
606 -.org 0x1000
607 +.section .data.swapper_pg_dir,"a"
608  ENTRY(swapper_pg_dir)
609 -       .long 0x00102007
610 -       .long 0x00103007
611 -       .fill BOOT_USER_PGD_PTRS-2,4,0
612 +       .long pg0-__PAGE_OFFSET+7
613 +       .long pg1-__PAGE_OFFSET+7
614 +       .long pg2-__PAGE_OFFSET+7
615 +       .fill BOOT_USER_PGD_PTRS-3,4,0
616         /* default: 766 entries */
617 -       .long 0x00102007
618 -       .long 0x00103007
619 +       .long pg0-__PAGE_OFFSET+7
620 +       .long pg1-__PAGE_OFFSET+7
621 +       .long pg2-__PAGE_OFFSET+7
622         /* default: 254 entries */
623 -       .fill BOOT_KERNEL_PGD_PTRS-2,4,0
624 +       .fill BOOT_KERNEL_PGD_PTRS-3,4,0
625  
626  /*
627   * The page tables are initialized to only 8MB here - the final page
628   * tables are set up later depending on memory size.
629   */
630 -.org 0x2000
631 +.section .data.pg0,"a"
632  ENTRY(pg0)
633 +       .fill 1024,4,0
634  
635 -.org 0x3000
636 +.section .data.pg1,"a"
637  ENTRY(pg1)
638 +       .fill 1024,4,0
639 +
640 +.section .data.pg2,"a"
641 +ENTRY(pg2)
642 +       .fill 1024,4,0
643  
644  /*
645   * empty_zero_page must immediately follow the page tables ! (The
646   * initialization loop counts until empty_zero_page)
647   */
648 -
649 -.org 0x4000
650 +.section .data.empty_zero_page,"a"
651  ENTRY(empty_zero_page)
652 +       .fill 1024,4,0
653  
654 -.org 0x5000
655 +.text
656  
657  /*
658   * Real beginning of normal "text" segment
659 @@ -419,7 +450,7 @@
660   * in the text section because it has alignment requirements
661   * that we cannot fulfill any other way.
662   */
663 -.data
664 +.section .rodata,"a"
665  
666  ALIGN
667  /*
668 @@ -430,19 +461,55 @@
669   */
670  ENTRY(gdt_table)
671         .quad 0x0000000000000000        /* NULL descriptor */
672 -       .quad 0x0000000000000000        /* not used */
673 -       .quad 0x00cf9a000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
674 -       .quad 0x00cf92000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
675 -       .quad 0x00cffa000000ffff        /* 0x23 user   4GB code at 0x00000000 */
676 -       .quad 0x00cff2000000ffff        /* 0x2b user   4GB data at 0x00000000 */
677 +
678 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
679 +       .quad 0x00cf9b000000ffff        /* 0x08 kernel 4GB code at 0x00000000 */
680 +       .quad 0xc0cf9b400000ffff        /* 0x10 kernel 4GB code at 0xc0400000 */
681 +#else
682 +       .quad 0x0000000000000000        /* not used */
683 +       .quad 0x00cf9b000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
684 +#endif
685 +
686 +       .quad 0x00cf93000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
687 +       .quad 0x00cffb000000ffff        /* 0x23 user   4GB code at 0x00000000 */
688 +       .quad 0x00cff3000000ffff        /* 0x2b user   4GB data at 0x00000000 */
689 +       .quad 0x0000000000000000        /* not used */
690 +       .quad 0x0000000000000000        /* not used */
691 +       /*
692 +        * The APM segments have byte granularity and their bases
693 +        * and limits are set at run time.
694 +        */
695 +       .quad 0x0040930000000000        /* 0x40 APM set up for bad BIOS's */
696 +       .quad 0x00409b0000000000        /* 0x48 APM CS    code */
697 +       .quad 0x00009b0000000000        /* 0x50 APM CS 16 code (16 bit) */
698 +       .quad 0x0040930000000000        /* 0x58 APM DS    data */
699 +       .fill NR_CPUS*4,8,0             /* space for TSS's and LDT's */
700 +
701 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
702 +ENTRY(gdt_table2)
703 +       .quad 0x0000000000000000        /* NULL descriptor */
704 +
705 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
706 +       .quad 0x00cf9b000000ffff        /* 0x08 kernel 4GB code at 0x00000000 */
707 +       .quad 0xc0cf9b400000ffff        /* 0x10 kernel 4GB code at 0xc0400000 */
708 +#else
709 +       .quad 0x0000000000000000        /* not used */
710 +       .quad 0x00cf9b000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
711 +#endif
712 +
713 +       .quad 0x00cf93000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
714 +       .quad 0x60c5fb000000ffff        /* 0x23 user 1.5GB code at 0x60000000 */
715 +       .quad 0x00c5f3000000ffff        /* 0x2b user 1.5GB data at 0x00000000 */
716 +
717         .quad 0x0000000000000000        /* not used */
718         .quad 0x0000000000000000        /* not used */
719         /*
720          * The APM segments have byte granularity and their bases
721          * and limits are set at run time.
722          */
723 -       .quad 0x0040920000000000        /* 0x40 APM set up for bad BIOS's */
724 -       .quad 0x00409a0000000000        /* 0x48 APM CS    code */
725 -       .quad 0x00009a0000000000        /* 0x50 APM CS 16 code (16 bit) */
726 -       .quad 0x0040920000000000        /* 0x58 APM DS    data */
727 +       .quad 0x0040930000000000        /* 0x40 APM set up for bad BIOS's */
728 +       .quad 0x00409b0000000000        /* 0x48 APM CS    code */
729 +       .quad 0x00009b0000000000        /* 0x50 APM CS 16 code (16 bit) */
730 +       .quad 0x0040930000000000        /* 0x58 APM DS    data */
731         .fill NR_CPUS*4,8,0             /* space for TSS's and LDT's */
732 +#endif
733 diff -urN linux-2.4.22.org/arch/i386/kernel/i386_ksyms.c linux-2.4.22/arch/i386/kernel/i386_ksyms.c
734 --- linux-2.4.22.org/arch/i386/kernel/i386_ksyms.c      2003-11-22 22:11:55.000000000 +0100
735 +++ linux-2.4.22/arch/i386/kernel/i386_ksyms.c  2003-11-22 22:14:06.000000000 +0100
736 @@ -74,6 +74,9 @@
737  EXPORT_SYMBOL(get_cmos_time);
738  EXPORT_SYMBOL(apm_info);
739  EXPORT_SYMBOL(gdt);
740 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
741 +EXPORT_SYMBOL(gdt2);
742 +#endif
743  EXPORT_SYMBOL(empty_zero_page);
744  
745  #ifdef CONFIG_DEBUG_IOVIRT
746 diff -urN linux-2.4.22.org/arch/i386/kernel/ioport.c linux-2.4.22/arch/i386/kernel/ioport.c
747 --- linux-2.4.22.org/arch/i386/kernel/ioport.c  2003-11-22 22:11:55.000000000 +0100
748 +++ linux-2.4.22/arch/i386/kernel/ioport.c      2003-11-22 22:14:06.000000000 +0100
749 @@ -14,6 +14,7 @@
750  #include <linux/smp.h>
751  #include <linux/smp_lock.h>
752  #include <linux/stddef.h>
753 +#include <linux/grsecurity.h>
754  
755  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
756  static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
757 @@ -59,8 +60,16 @@
758  
759         if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
760                 return -EINVAL;
761 +#ifdef CONFIG_GRKERNSEC_IO
762 +       if (turn_on) {
763 +               gr_handle_ioperm();
764 +#else
765         if (turn_on && !capable(CAP_SYS_RAWIO))
766 +#endif
767                 return -EPERM;
768 +#ifdef CONFIG_GRKERNSEC_IO
769 +       }
770 +#endif
771         /*
772          * If it's the first ioperm() call in this thread's lifetime, set the
773          * IO bitmap up. ioperm() is much less timing critical than clone(),
774 @@ -109,8 +118,13 @@
775                 return -EINVAL;
776         /* Trying to gain more privileges? */
777         if (level > old) {
778 +#ifdef CONFIG_GRKERNSEC_IO
779 +               gr_handle_iopl();
780 +               return -EPERM;
781 +#else
782                 if (!capable(CAP_SYS_RAWIO))
783                         return -EPERM;
784 +#endif
785         }
786         regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
787         return 0;
788 diff -urN linux-2.4.22.org/arch/i386/kernel/ldt.c linux-2.4.22/arch/i386/kernel/ldt.c
789 --- linux-2.4.22.org/arch/i386/kernel/ldt.c     2003-11-22 22:11:55.000000000 +0100
790 +++ linux-2.4.22/arch/i386/kernel/ldt.c 2003-11-22 22:14:06.000000000 +0100
791 @@ -124,6 +124,13 @@
792                 }
793         }
794  
795 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
796 +       if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
797 +               error = -EINVAL;
798 +               goto out_unlock;
799 +       }
800 +#endif
801 +
802         entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
803                   (ldt_info.limit & 0x0ffff);
804         entry_2 = (ldt_info.base_addr & 0xff000000) |
805 diff -urN linux-2.4.22.org/arch/i386/kernel/pci-pc.c linux-2.4.22/arch/i386/kernel/pci-pc.c
806 --- linux-2.4.22.org/arch/i386/kernel/pci-pc.c  2003-11-22 22:11:55.000000000 +0100
807 +++ linux-2.4.22/arch/i386/kernel/pci-pc.c      2003-11-22 22:14:06.000000000 +0100
808 @@ -17,6 +17,7 @@
809  #include <asm/io.h>
810  #include <asm/smp.h>
811  #include <asm/smpboot.h>
812 +#include <asm/desc.h>
813  
814  #include "pci-i386.h"
815  
816 @@ -575,10 +576,16 @@
817   * the array there.
818   */
819  
820 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
821 +#define __FLAT_KERNEL_CS 0x08
822 +#else
823 +#define __FLAT_KERNEL_CS __KERNEL_CS
824 +#endif
825 +
826  static struct {
827         unsigned long address;
828         unsigned short segment;
829 -} bios32_indirect = { 0, __KERNEL_CS };
830 +} bios32_indirect = { 0, __FLAT_KERNEL_CS };
831  
832  /*
833   * Returns the entry point for the given service, NULL on error
834 @@ -619,7 +626,9 @@
835  static struct {
836         unsigned long address;
837         unsigned short segment;
838 -} pci_indirect = { 0, __KERNEL_CS };
839 +} pci_indirect = { 0, __FLAT_KERNEL_CS };
840 +
841 +#undef __FLAT_KERNEL_CS
842  
843  static int pci_bios_present;
844  
845 @@ -1457,6 +1466,7 @@
846         if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
847                 pcibios_sort();
848  #endif
849 +
850  }
851  
852  char * __devinit  pcibios_setup(char *str)
853 diff -urN linux-2.4.22.org/arch/i386/kernel/process.c linux-2.4.22/arch/i386/kernel/process.c
854 --- linux-2.4.22.org/arch/i386/kernel/process.c 2003-11-22 22:11:55.000000000 +0100
855 +++ linux-2.4.22/arch/i386/kernel/process.c     2003-11-22 22:14:06.000000000 +0100
856 @@ -600,7 +600,11 @@
857  {
858         struct pt_regs * childregs;
859  
860 +#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
861 +       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p - sizeof(unsigned long))) - 1;
862 +#else
863         childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
864 +#endif
865         struct_cpy(childregs, regs);
866         childregs->eax = 0;
867         childregs->esp = esp;
868 @@ -661,6 +665,16 @@
869         dump->u_fpvalid = dump_fpu (regs, &dump->i387);
870  }
871  
872 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
873 +void pax_switch_segments(struct task_struct * tsk)
874 +{
875 +       if (tsk->flags & PF_PAX_SEGMEXEC)
876 +               __asm__ __volatile__("lgdt %0": "=m" (gdt_descr2));
877 +       else
878 +               __asm__ __volatile__("lgdt %0": "=m" (gdt_descr));
879 +}
880 +#endif
881 +
882  /*
883   * This special macro can be used to load a debugging register
884   */
885 @@ -700,6 +714,10 @@
886  
887         unlazy_fpu(prev_p);
888  
889 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
890 +       pax_switch_segments(next_p);
891 +#endif
892 +
893         /*
894          * Reload esp0, LDT and the page table pointer:
895          */
896 @@ -842,3 +860,25 @@
897  }
898  #undef last_sched
899  #undef first_sched
900 +
901 +#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
902 +asmlinkage void pax_randomize_kstack(void)
903 +{
904 +       struct tss_struct *tss = init_tss + smp_processor_id();
905 +       unsigned long time;
906 +
907 +       rdtscl(time);
908 +
909 +       /* P4 seems to return a 0 LSB, ignore it */
910 +#ifdef CONFIG_MPENTIUM4
911 +       time &= 0x3EUL;
912 +       time <<= 1;
913 +#else
914 +       time &= 0x1FUL;
915 +       time <<= 2;
916 +#endif
917 +
918 +       current->thread.esp0 ^= time;
919 +       tss->esp0 = current->thread.esp0;
920 +}
921 +#endif
922 diff -urN linux-2.4.22.org/arch/i386/kernel/ptrace.c linux-2.4.22/arch/i386/kernel/ptrace.c
923 --- linux-2.4.22.org/arch/i386/kernel/ptrace.c  2003-11-22 22:11:55.000000000 +0100
924 +++ linux-2.4.22/arch/i386/kernel/ptrace.c      2003-11-22 22:14:06.000000000 +0100
925 @@ -13,6 +13,7 @@
926  #include <linux/errno.h>
927  #include <linux/ptrace.h>
928  #include <linux/user.h>
929 +#include <linux/grsecurity.h>
930  
931  #include <asm/uaccess.h>
932  #include <asm/pgtable.h>
933 @@ -182,6 +183,9 @@
934         if (pid == 1)           /* you may not mess with init */
935                 goto out_tsk;
936  
937 +       if(gr_handle_ptrace(child, request))
938 +               goto out_tsk;
939 +
940         if (request == PTRACE_ATTACH) {
941                 ret = ptrace_attach(child);
942                 goto out_tsk;
943 @@ -261,6 +265,17 @@
944                           if(addr < (long) &dummy->u_debugreg[4] &&
945                              ((unsigned long) data) >= TASK_SIZE-3) break;
946                           
947 +#ifdef CONFIG_GRKERNSEC
948 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
949 +                            addr <= (long) &dummy->u_debugreg[3]){
950 +                                 long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
951 +                                 long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
952 +                                 long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
953 +                                 if((type & 1) && (data & align))
954 +                                       break;
955 +                         }
956 +#endif
957 +
958                           if(addr == (long) &dummy->u_debugreg[7]) {
959                                   data &= ~DR_CONTROL_RESERVED;
960                                   for(i=0; i<4; i++)
961 diff -urN linux-2.4.22.org/arch/i386/kernel/setup.c linux-2.4.22/arch/i386/kernel/setup.c
962 --- linux-2.4.22.org/arch/i386/kernel/setup.c   2003-11-22 22:11:55.000000000 +0100
963 +++ linux-2.4.22/arch/i386/kernel/setup.c       2003-11-22 22:14:06.000000000 +0100
964 @@ -3188,7 +3188,7 @@
965         set_tss_desc(nr,t);
966         gdt_table[__TSS(nr)].b &= 0xfffffdff;
967         load_TR(nr);
968 -       load_LDT(&init_mm);
969 +       _load_LDT(&init_mm);
970  
971         /* Clear %fs and %gs. */
972         asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
973 diff -urN linux-2.4.22.org/arch/i386/kernel/sys_i386.c linux-2.4.22/arch/i386/kernel/sys_i386.c
974 --- linux-2.4.22.org/arch/i386/kernel/sys_i386.c        2003-11-22 22:11:55.000000000 +0100
975 +++ linux-2.4.22/arch/i386/kernel/sys_i386.c    2003-11-22 22:14:06.000000000 +0100
976 @@ -18,6 +18,7 @@
977  #include <linux/mman.h>
978  #include <linux/file.h>
979  #include <linux/utsname.h>
980 +#include <linux/grsecurity.h>
981  
982  #include <asm/uaccess.h>
983  #include <asm/ipc.h>
984 @@ -48,6 +49,11 @@
985         int error = -EBADF;
986         struct file * file = NULL;
987  
988 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
989 +       if (flags & MAP_MIRROR)
990 +               return -EINVAL;
991 +#endif
992 +
993         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
994         if (!(flags & MAP_ANONYMOUS)) {
995                 file = fget(fd);
996 @@ -55,8 +61,14 @@
997                         goto out;
998         }
999  
1000 +       if(gr_handle_mmap(file, prot)) {
1001 +               fput(file);
1002 +               error = -EACCES;
1003 +               goto out;
1004 +       }
1005 +
1006         down_write(&mm->mmap_sem);
1007 -       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
1008 +       error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
1009         up_write(&mm->mmap_sem);
1010  
1011         if (file)
1012 diff -urN linux-2.4.22.org/arch/i386/kernel/trampoline.S linux-2.4.22/arch/i386/kernel/trampoline.S
1013 --- linux-2.4.22.org/arch/i386/kernel/trampoline.S      2003-11-22 22:11:55.000000000 +0100
1014 +++ linux-2.4.22/arch/i386/kernel/trampoline.S  2003-11-22 22:14:06.000000000 +0100
1015 @@ -54,7 +54,7 @@
1016         lmsw    %ax             # into protected mode
1017         jmp     flush_instr
1018  flush_instr:
1019 -       ljmpl   $__KERNEL_CS, $0x00100000
1020 +       ljmpl   $__KERNEL_CS, $SYMBOL_NAME(startup_32)-__PAGE_OFFSET
1021                         # jump to startup_32 in arch/i386/kernel/head.S
1022  
1023  idt_48:
1024 diff -urN linux-2.4.22.org/arch/i386/kernel/traps.c linux-2.4.22/arch/i386/kernel/traps.c
1025 --- linux-2.4.22.org/arch/i386/kernel/traps.c   2003-11-22 22:11:55.000000000 +0100
1026 +++ linux-2.4.22/arch/i386/kernel/traps.c       2003-11-22 22:14:06.000000000 +0100
1027 @@ -228,14 +228,23 @@
1028                 show_stack((unsigned long*)esp);
1029  
1030                 printk("\nCode: ");
1031 +
1032 +#ifndef CONFIG_GRKERNSEC_PAX_KERNEXEC
1033                 if(regs->eip < PAGE_OFFSET)
1034                         goto bad;
1035 +#endif
1036  
1037                 for(i=0;i<20;i++)
1038                 {
1039                         unsigned char c;
1040 +
1041 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1042 +                       if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) {
1043 +#else
1044                         if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
1045  bad:
1046 +#endif
1047 +
1048                                 printk(" Bad EIP value.");
1049                                 break;
1050                         }
1051 @@ -258,8 +267,13 @@
1052  
1053         eip = regs->eip;
1054  
1055 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1056 +       eip += __KERNEL_TEXT_OFFSET;
1057 +#else
1058         if (eip < PAGE_OFFSET)
1059                 goto no_bug;
1060 +#endif
1061 +
1062         if (__get_user(ud2, (unsigned short *)eip))
1063                 goto no_bug;
1064         if (ud2 != 0x0b0f)
1065 @@ -267,7 +281,13 @@
1066         if (__get_user(line, (unsigned short *)(eip + 2)))
1067                 goto bug;
1068         if (__get_user(file, (char **)(eip + 4)) ||
1069 +
1070 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1071 +               __get_user(c, file + __KERNEL_TEXT_OFFSET))
1072 +#else
1073                 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
1074 +#endif
1075 +
1076                 file = "<bad filename>";
1077  
1078         printk("kernel BUG at %s:%d!\n", file, line);
1079 @@ -417,6 +437,18 @@
1080  gp_in_kernel:
1081         {
1082                 unsigned long fixup;
1083 +
1084 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1085 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS) {
1086 +                       if (current->curr_ip)
1087 +                               printk(KERN_ERR "PAX: From %u.%u.%u.%u: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n",
1088 +                                               NIPQUAD(current->curr_ip), current->comm, current->pid, current->uid, current->euid, regs->eip);
1089 +                       else
1090 +                               printk(KERN_ERR "PAX: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n",
1091 +                                               current->comm, current->pid, current->uid, current->euid, regs->eip);
1092 +               }
1093 +#endif
1094 +
1095                 fixup = search_exception_table(regs->eip);
1096                 if (fixup) {
1097                         regs->eip = fixup;
1098 @@ -527,13 +559,12 @@
1099  {
1100         unsigned int condition;
1101         struct task_struct *tsk = current;
1102 -       unsigned long eip = regs->eip;
1103         siginfo_t info;
1104  
1105         __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
1106  
1107         /* If the user set TF, it's simplest to clear it right away. */
1108 -       if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
1109 +       if (!(regs->xcs & 3) && (regs->eflags & TF_MASK) && !(regs->eflags & VM_MASK))
1110                 goto clear_TF;
1111  
1112         /* Mask out spurious debug traps due to lazy DR7 setting */
1113 @@ -855,11 +886,55 @@
1114  void set_tss_desc(unsigned int n, void *addr)
1115  {
1116         _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
1117 +
1118 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1119 +       _set_tssldt_desc(gdt_table2+__TSS(n), (int)addr, 235, 0x89);
1120 +#endif
1121 +
1122 +}
1123 +
1124 +void __set_ldt_desc(unsigned int n, void *addr, unsigned int size)
1125 +{
1126 +       _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1127 +
1128 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1129 +       _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1130 +#endif
1131 +
1132  }
1133  
1134  void set_ldt_desc(unsigned int n, void *addr, unsigned int size)
1135  {
1136 +
1137 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1138 +       unsigned long temp, cr3;
1139 +       pgd_t* pgd;
1140 +       pmd_t* pmd;
1141 +
1142 +       asm("movl %%cr3,%0":"=r" (cr3));
1143 +       for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
1144 +               pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
1145 +               pmd = pmd_offset(pgd, temp);
1146 +               set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_RW));
1147 +       }
1148 +       __flush_tlb_all();
1149 +#endif
1150 +
1151         _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1152 +
1153 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1154 +       _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1155 +#endif
1156 +
1157 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1158 +       for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
1159 +               pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
1160 +               pmd = pmd_offset(pgd, temp);
1161 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1162 +       }
1163 +       flush_tlb_all();
1164 +#endif
1165 +
1166  }
1167  
1168  #ifdef CONFIG_X86_VISWS_APIC
1169 diff -urN linux-2.4.22.org/arch/i386/Makefile linux-2.4.22/arch/i386/Makefile
1170 --- linux-2.4.22.org/arch/i386/Makefile 2003-11-22 22:11:54.000000000 +0100
1171 +++ linux-2.4.22/arch/i386/Makefile     2003-11-22 22:14:06.000000000 +0100
1172 @@ -114,6 +114,9 @@
1173  
1174  MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
1175  
1176 +arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE
1177 +       $(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/linux/config.h -imacros $(HPATH)/asm-i386/segment.h -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds
1178 +
1179  vmlinux: arch/i386/vmlinux.lds
1180  
1181  FORCE: ;
1182 @@ -150,6 +153,7 @@
1183         @$(MAKEBOOT) clean
1184  
1185  archmrproper:
1186 +       rm -f arch/i386/vmlinux.lds
1187  
1188  archdep:
1189         @$(MAKEBOOT) dep
1190 diff -urN linux-2.4.22.org/arch/i386/mm/fault.c linux-2.4.22/arch/i386/mm/fault.c
1191 --- linux-2.4.22.org/arch/i386/mm/fault.c       2003-11-22 22:11:54.000000000 +0100
1192 +++ linux-2.4.22/arch/i386/mm/fault.c   2003-11-22 22:14:06.000000000 +0100
1193 @@ -4,6 +4,7 @@
1194   *  Copyright (C) 1995  Linus Torvalds
1195   */
1196  
1197 +#include <linux/config.h>
1198  #include <linux/signal.h>
1199  #include <linux/sched.h>
1200  #include <linux/kernel.h>
1201 @@ -19,6 +20,8 @@
1202  #include <linux/init.h>
1203  #include <linux/tty.h>
1204  #include <linux/vt_kern.h>             /* For unblank_screen() */
1205 +#include <linux/unistd.h>
1206 +#include <linux/compiler.h>
1207  
1208  #include <asm/system.h>
1209  #include <asm/uaccess.h>
1210 @@ -123,6 +126,10 @@
1211  asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
1212  extern unsigned long idt;
1213  
1214 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
1215 +static int pax_handle_fetch_fault(struct pt_regs *regs);
1216 +#endif
1217 +
1218  /*
1219   * This routine handles page faults.  It determines the address,
1220   * and the problem, and then passes it off to one of the appropriate
1221 @@ -133,23 +140,31 @@
1222   *     bit 1 == 0 means read, 1 means write
1223   *     bit 2 == 0 means kernel, 1 means user-mode
1224   */
1225 -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
1226 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1227 +static int do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
1228 +#else
1229 +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long error_code)
1230 +#endif
1231  {
1232         struct task_struct *tsk;
1233         struct mm_struct *mm;
1234         struct vm_area_struct * vma;
1235 +#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1236         unsigned long address;
1237 +#endif
1238         unsigned long page;
1239         unsigned long fixup;
1240         int write;
1241         siginfo_t info;
1242  
1243 +#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1244         /* get the address */
1245         __asm__("movl %%cr2,%0":"=r" (address));
1246  
1247         /* It's safe to allow irq's after cr2 has been saved */
1248         if (regs->eflags & X86_EFLAGS_IF)
1249                 local_irq_enable();
1250 +#endif
1251  
1252         tsk = current;
1253  
1254 @@ -256,7 +271,7 @@
1255         }
1256         up_read(&mm->mmap_sem);
1257         tsk->in_page_fault = 0;
1258 -       return;
1259 +       return 0;
1260  
1261  /*
1262   * Something tried to access memory that isn't in our memory map..
1263 @@ -268,6 +283,39 @@
1264  
1265         /* User mode accesses just cause a SIGSEGV */
1266         if (error_code & 4) {
1267 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1268 +               if (current->flags & PF_PAX_SEGMEXEC) {
1269 +
1270 +#if defined(CONFIG_GRKERNSEC_PAX_EMUTRAMP) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
1271 +               if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
1272 +                       switch (pax_handle_fetch_fault(regs)) {
1273 +
1274 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1275 +                       case 5:
1276 +                               return 0;
1277 +#endif
1278 +
1279 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1280 +                       case 4:
1281 +                               return 0;
1282 +                       case 3:
1283 +                       case 2:
1284 +                               return 1;
1285 +#endif
1286 +
1287 +                       case 1:
1288 +                       default:
1289 +                       }
1290 +               }
1291 +#endif
1292 +
1293 +                       if (address >= SEGMEXEC_TASK_SIZE) {
1294 +                               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1295 +                               do_exit(SIGKILL);
1296 +                       }
1297 +               }
1298 +#endif
1299 +
1300                 tsk->thread.cr2 = address;
1301                 tsk->thread.error_code = error_code;
1302                 tsk->thread.trap_no = 14;
1303 @@ -276,7 +324,7 @@
1304                 /* info.si_code has been set above */
1305                 info.si_addr = (void *)address;
1306                 force_sig_info(SIGSEGV, &info, tsk);
1307 -               return;
1308 +               return 0;
1309         }
1310  
1311         /*
1312 @@ -289,7 +337,7 @@
1313  
1314                 if (nr == 6) {
1315                         do_invalid_op(regs, 0);
1316 -                       return;
1317 +                       return 0;
1318                 }
1319         }
1320  
1321 @@ -297,7 +345,7 @@
1322         /* Are we prepared to handle this kernel fault?  */
1323         if ((fixup = search_exception_table(regs->eip)) != 0) {
1324                 regs->eip = fixup;
1325 -               return;
1326 +               return 0;
1327         }
1328  
1329  /*
1330 @@ -310,6 +358,18 @@
1331  
1332         if (address < PAGE_SIZE)
1333                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
1334 +
1335 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1336 +       else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET) {
1337 +               if (tsk->curr_ip)
1338 +                       printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1339 +                                        NIPQUAD(tsk->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1340 +               else
1341 +                       printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1342 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1343 +       }
1344 +#endif
1345 +
1346         else
1347                 printk(KERN_ALERT "Unable to handle kernel paging request");
1348         printk(" at virtual address %08lx\n",address);
1349 @@ -364,7 +424,7 @@
1350         /* Kernel mode? Handle exceptions or die */
1351         if (!(error_code & 4))
1352                 goto no_context;
1353 -       return;
1354 +       return 0;
1355  
1356  vmalloc_fault:
1357         {
1358 @@ -397,6 +457,337 @@
1359                 pte_k = pte_offset(pmd_k, address);
1360                 if (!pte_present(*pte_k))
1361                         goto no_context;
1362 -               return;
1363 +               return 0;
1364 +       }
1365 +}
1366 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1367 +/* PaX: called with the page_table_lock spinlock held */
1368 +static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
1369 +{
1370 +       pgd_t *pgd;
1371 +       pmd_t *pmd;
1372 +
1373 +       pgd = pgd_offset(mm, address);
1374 +       if (!pgd || !pgd_present(*pgd))
1375 +               return 0;
1376 +       pmd = pmd_offset(pgd, address);
1377 +       if (!pmd || !pmd_present(*pmd))
1378 +               return 0;
1379 +       return pte_offset(pmd, address);
1380 +}
1381 +#endif
1382 +
1383 +/*
1384 + * PaX: decide what to do with offenders (regs->eip = fault address)
1385 + *
1386 + * returns 1 when task should be killed
1387 + *         2 when sigreturn trampoline was detected
1388 + *         3 when rt_sigreturn trampoline was detected
1389 + *         4 when gcc trampoline was detected
1390 + *        5 when legitimate ET_EXEC was detected
1391 + */
1392 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
1393 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1394 +{
1395 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1396 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
1397 +#endif
1398 +       int err;
1399 +       
1400 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1401 +       if (current->flags & PF_PAX_RANDEXEC) {
1402 +               unsigned long esp_4;
1403 +               if (regs->eip >= current->mm->start_code &&
1404 +                   regs->eip < current->mm->end_code)
1405 +               {
1406 +                       err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
1407 +                       if (err || esp_4 == regs->eip)
1408 +                               return 1;
1409 +                       regs->eip += current->mm->delta_exec;
1410 +                       return 5;
1411 +               }
1412 +       }
1413 +#endif
1414 +
1415 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1416 +
1417 +#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1418 +       if (!(current->flags & PF_PAX_EMUTRAMP))
1419 +               return 1;
1420 +#endif
1421 +
1422 +       do { /* PaX: sigreturn emulation */
1423 +               unsigned char pop, mov;
1424 +               unsigned short sys;
1425 +               unsigned long nr;
1426 +
1427 +               err = get_user(pop, (unsigned char *)(regs->eip));
1428 +               err |= get_user(mov, (unsigned char *)(regs->eip + 1));
1429 +               err |= get_user(nr, (unsigned long *)(regs->eip + 2));
1430 +               err |= get_user(sys, (unsigned short *)(regs->eip + 6));
1431 +
1432 +               if (err)
1433 +                       break;
1434 +
1435 +               if (pop == 0x58 &&
1436 +                   mov == 0xb8 &&
1437 +                   nr == __NR_sigreturn &&
1438 +                   sys == 0x80cd)
1439 +               {
1440 +
1441 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1442 +                       int sig;
1443 +                       struct k_sigaction *ka;
1444 +                       __sighandler_t handler;
1445 +
1446 +                       if (get_user(sig, (int *)regs->esp))
1447 +                               return 1;
1448 +                       if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
1449 +                               return 1;
1450 +                       ka = &current->sig->action[sig-1];
1451 +                       handler = ka->sa.sa_handler;
1452 +                       if (handler == SIG_DFL || handler == SIG_IGN) {
1453 +                               if (!(current->flags & PF_PAX_EMUTRAMP))
1454 +                                       return 1;
1455 +                       } else if (!(ka->sa.sa_flags & SA_SIGINFO))
1456 +                               return 1;
1457 +#endif
1458 +
1459 +                       regs->esp += 4;
1460 +                       regs->eax = nr;
1461 +                       regs->eip += 8;
1462 +                       return 2;
1463 +               }
1464 +       } while (0);
1465 +
1466 +       do { /* PaX: rt_sigreturn emulation */
1467 +               unsigned char mov;
1468 +               unsigned short sys;
1469 +               unsigned long nr;
1470 +
1471 +               err = get_user(mov, (unsigned char *)(regs->eip));
1472 +               err |= get_user(nr, (unsigned long *)(regs->eip + 1));
1473 +               err |= get_user(sys, (unsigned short *)(regs->eip + 5));
1474 +
1475 +               if (err)
1476 +                       break;
1477 +
1478 +               if (mov == 0xb8 &&
1479 +                   nr == __NR_rt_sigreturn &&
1480 +                   sys == 0x80cd)
1481 +               {
1482 +
1483 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1484 +                       int sig;
1485 +                       struct k_sigaction *ka;
1486 +                       __sighandler_t handler;
1487 +
1488 +                       if (get_user(sig, (int *)regs->esp))
1489 +                               return 1;
1490 +                       if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
1491 +                               return 1;
1492 +                       ka = &current->sig->action[sig-1];
1493 +                       handler = ka->sa.sa_handler;
1494 +                       if (handler == SIG_DFL || handler == SIG_IGN) {
1495 +                               if (!(current->flags & PF_PAX_EMUTRAMP))
1496 +                                       return 1;
1497 +                       } else if (ka->sa.sa_flags & SA_SIGINFO)
1498 +                               return 1;
1499 +#endif
1500 +
1501 +                       regs->eax = nr;
1502 +                       regs->eip += 7;
1503 +                       return 3;
1504 +               }
1505 +       } while (0);
1506 +
1507 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1508 +       if (!(current->flags & PF_PAX_EMUTRAMP))
1509 +               return 1;
1510 +#endif
1511 +
1512 +       do { /* PaX: gcc trampoline emulation #1 */
1513 +               unsigned char mov1, mov2;
1514 +               unsigned short jmp;
1515 +               unsigned long addr1, addr2, ret;
1516 +               unsigned short call;
1517 +
1518 +               err = get_user(mov1, (unsigned char *)regs->eip);
1519 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1520 +               err |= get_user(mov2, (unsigned char *)(regs->eip + 5));
1521 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1522 +               err |= get_user(jmp, (unsigned short *)(regs->eip + 10));
1523 +               err |= get_user(ret, (unsigned long *)regs->esp);
1524 +
1525 +               if (err)
1526 +                       break;
1527 +
1528 +               err = get_user(call, (unsigned short *)(ret-2));
1529 +               if (err)
1530 +                       break;
1531 +
1532 +               if ((mov1 & 0xF8) == 0xB8 &&
1533 +                   (mov2 & 0xF8) == 0xB8 &&
1534 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
1535 +                   (jmp & 0xF8FF) == 0xE0FF &&
1536 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
1537 +                   (call & 0xF8FF) == 0xD0FF &&
1538 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1539 +               {
1540 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
1541 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
1542 +                       regs->eip = addr2;
1543 +                       return 4;
1544 +               }
1545 +       } while (0);
1546 +
1547 +       do { /* PaX: gcc trampoline emulation #2 */
1548 +               unsigned char mov, jmp;
1549 +               unsigned long addr1, addr2, ret;
1550 +               unsigned short call;
1551 +
1552 +               err = get_user(mov, (unsigned char *)regs->eip);
1553 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1554 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1555 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1556 +               err |= get_user(ret, (unsigned long *)regs->esp);
1557 +
1558 +               if (err)
1559 +                       break;
1560 +
1561 +               err = get_user(call, (unsigned short *)(ret-2));
1562 +               if (err)
1563 +                       break;
1564 +
1565 +               if ((mov & 0xF8) == 0xB8 &&
1566 +                   jmp == 0xE9 &&
1567 +                   (call & 0xF8FF) == 0xD0FF &&
1568 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1569 +               {
1570 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1571 +                       regs->eip += addr2 + 10;
1572 +                       return 4;
1573 +               }
1574 +       } while (0);
1575 +#endif
1576 +
1577 +       return 1; /* PaX in action */
1578 +}
1579 +
1580 +void pax_report_insns(void *pc)
1581 +{
1582 +       unsigned long i;
1583 +
1584 +       printk(KERN_ERR "PAX: bytes at PC: ");
1585 +       for (i = 0; i < 20; i++) {
1586 +               unsigned char c;
1587 +               if (get_user(c, (unsigned char*)pc+i)) {
1588 +                       printk("<invalid address>.");
1589 +                       break;
1590 +               }
1591 +               printk("%02x ", c);
1592 +       }
1593 +       printk("\n");
1594 +}
1595 +#endif
1596 +
1597 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1598 +/*
1599 + * PaX: handle the extra page faults or pass it down to the original handler
1600 + *
1601 + * returns 0 when nothing special was detected
1602 + *         1 when sigreturn trampoline (syscall) has to be emulated
1603 + */
1604 +asmlinkage int pax_do_page_fault(struct pt_regs *regs, unsigned long error_code)
1605 +{
1606 +       struct mm_struct *mm = current->mm;
1607 +       unsigned long address;
1608 +       pte_t *pte;
1609 +       unsigned char pte_mask;
1610 +       int ret;
1611 +
1612 +       __asm__("movl %%cr2,%0":"=r" (address));
1613 +
1614 +       /* It's safe to allow irq's after cr2 has been saved */
1615 +       if (likely(regs->eflags & X86_EFLAGS_IF))
1616 +               local_irq_enable();
1617 +
1618 +       if (unlikely((error_code & 5) != 5 ||
1619 +                    address >= TASK_SIZE ||
1620 +                    !(current->flags & PF_PAX_PAGEEXEC)))
1621 +               return do_page_fault(regs, error_code, address);
1622 +
1623 +       /* PaX: it's our fault, let's handle it if we can */
1624 +
1625 +       /* PaX: take a look at read faults before acquiring any locks */
1626 +       if (unlikely((error_code == 5) && (regs->eip == address))) { 
1627 +               /* instruction fetch attempt from a protected page in user mode */
1628 +               ret = pax_handle_fetch_fault(regs);
1629 +               switch (ret) {
1630 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1631 +               case 5:
1632 +                       return 0;
1633 +#endif
1634 +
1635 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1636 +               case 4:
1637 +                       return 0;
1638 +               case 3:
1639 +               case 2:
1640 +                       return 1;
1641 +#endif
1642 +               case 1:
1643 +               default:
1644 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1645 +                       do_exit(SIGKILL);
1646 +               }
1647 +       }
1648 +
1649 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
1650 +
1651 +       spin_lock(&mm->page_table_lock);
1652 +       pte = pax_get_pte(mm, address);
1653 +       if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
1654 +               spin_unlock(&mm->page_table_lock);
1655 +               do_page_fault(regs, error_code, address);
1656 +               return 0;
1657         }
1658 +
1659 +       if (unlikely((error_code == 7) && !pte_write(*pte))) {
1660 +               /* write attempt to a protected page in user mode */
1661 +               spin_unlock(&mm->page_table_lock);
1662 +               do_page_fault(regs, error_code, address);
1663 +               return 0;
1664 +       }
1665 +
1666 +       /*
1667 +        * PaX: fill DTLB with user rights and retry
1668 +        */
1669 +       __asm__ __volatile__ (
1670 +               "orb %2,%1\n"
1671 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
1672 +/*   
1673 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's   
1674 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
1675 + * page fault when examined during a TLB load attempt. this is true not only
1676 + * for PTEs holding a non-present entry but also present entries that will
1677 + * raise a page fault (such as those set up by PaX, or the copy-on-write
1678 + * mechanism). in effect it means that we do *not* need to flush the TLBs
1679 + * for our target pages since their PTEs are simply not in the TLBs at all.
1680 + * the best thing in omitting it is that we gain around 15-20% speed in the
1681 + * fast path of the page fault handler and can get rid of tracing since we
1682 + * can no longer flush unintended entries.
1683 + */
1684 +
1685 +               "invlpg %0\n"
1686 +#endif
1687 +
1688 +               "testb $0,%0\n"
1689 +               "xorb %3,%1\n"
1690 +               :
1691 +               : "m" (*(char*)address), "m" (*(char*)pte) , "q" (pte_mask) , "i" (_PAGE_USER)
1692 +               : "memory", "cc");
1693 +       spin_unlock(&mm->page_table_lock);
1694 +       return 0;
1695  }
1696 +#endif
1697 diff -urN linux-2.4.22.org/arch/i386/mm/init.c linux-2.4.22/arch/i386/mm/init.c
1698 --- linux-2.4.22.org/arch/i386/mm/init.c        2003-11-22 22:11:54.000000000 +0100
1699 +++ linux-2.4.22/arch/i386/mm/init.c    2003-11-22 22:14:06.000000000 +0100
1700 @@ -37,6 +37,8 @@
1701  #include <asm/e820.h>
1702  #include <asm/apic.h>
1703  #include <asm/tlb.h>
1704 +#include <asm/page_offset.h>
1705 +#include <asm/desc.h>
1706  
1707  mmu_gather_t mmu_gathers[NR_CPUS];
1708  unsigned long highstart_pfn, highend_pfn;
1709 @@ -122,7 +124,7 @@
1710  
1711  /* References to section boundaries */
1712  
1713 -extern char _text, _etext, _edata, __bss_start, _end;
1714 +extern char _text, _etext, _data, _edata, __bss_start, _end;
1715  extern char __init_begin, __init_end;
1716  
1717  static inline void set_pte_phys (unsigned long vaddr,
1718 @@ -514,7 +516,7 @@
1719         reservedpages = free_pages_init();
1720  
1721         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
1722 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
1723 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
1724         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
1725  
1726         printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
1727 @@ -582,6 +584,42 @@
1728                 totalram_pages++;
1729         }
1730         printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
1731 +
1732 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1733 +       /* PaX: limit KERNEL_CS to actual size */
1734 +       {
1735 +               unsigned long limit;
1736 +
1737 +               limit = (unsigned long)&_etext >> PAGE_SHIFT;
1738 +               gdt_table[2].a = (gdt_table[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1739 +               gdt_table[2].b = (gdt_table[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1740 +
1741 +               /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */
1742 +               gdt_table[1].a = 0UL;
1743 +               gdt_table[1].b = 0UL;
1744 +
1745 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1746 +               gdt_table2[2].a = (gdt_table2[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1747 +               gdt_table2[2].b = (gdt_table2[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1748 +
1749 +               /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */
1750 +               gdt_table2[1].a = 0UL;
1751 +               gdt_table2[1].b = 0UL;
1752 +#endif
1753 +
1754 +       /* PaX: make KERNEL_CS read-only */
1755 +               for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
1756 +                       pgd_t *pgd;
1757 +                       pmd_t *pmd;
1758 +
1759 +                       pgd = pgd_offset_k(addr);
1760 +                       pmd = pmd_offset(pgd, addr);
1761 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1762 +               }
1763 +               flush_tlb_all();
1764 +       }
1765 +#endif
1766 +
1767  }
1768  
1769  #ifdef CONFIG_BLK_DEV_INITRD
1770 diff -urN linux-2.4.22.org/arch/i386/vmlinux.lds linux-2.4.22/arch/i386/vmlinux.lds
1771 --- linux-2.4.22.org/arch/i386/vmlinux.lds      2003-11-22 22:11:55.000000000 +0100
1772 +++ linux-2.4.22/arch/i386/vmlinux.lds  1970-01-01 01:00:00.000000000 +0100
1773 @@ -1,82 +0,0 @@
1774 -/* ld script to make i386 Linux kernel
1775 - * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1776 - */
1777 -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1778 -OUTPUT_ARCH(i386)
1779 -ENTRY(_start)
1780 -SECTIONS
1781 -{
1782 -  . = 0xC0000000 + 0x100000;
1783 -  _text = .;                   /* Text and read-only data */
1784 -  .text : {
1785 -       *(.text)
1786 -       *(.fixup)
1787 -       *(.gnu.warning)
1788 -       } = 0x9090
1789 -
1790 -  _etext = .;                  /* End of text section */
1791 -
1792 -  .rodata : { *(.rodata) *(.rodata.*) }
1793 -  .kstrtab : { *(.kstrtab) }
1794 -
1795 -  . = ALIGN(16);               /* Exception table */
1796 -  __start___ex_table = .;
1797 -  __ex_table : { *(__ex_table) }
1798 -  __stop___ex_table = .;
1799 -
1800 -  __start___ksymtab = .;       /* Kernel symbol table */
1801 -  __ksymtab : { *(__ksymtab) }
1802 -  __stop___ksymtab = .;
1803 -
1804 -  .data : {                    /* Data */
1805 -       *(.data)
1806 -       CONSTRUCTORS
1807 -       }
1808 -
1809 -  _edata = .;                  /* End of data section */
1810 -
1811 -  . = ALIGN(8192);             /* init_task */
1812 -  .data.init_task : { *(.data.init_task) }
1813 -
1814 -  . = ALIGN(4096);             /* Init code and data */
1815 -  __init_begin = .;
1816 -  .text.init : { *(.text.init) }
1817 -  .data.init : { *(.data.init) }
1818 -  . = ALIGN(16);
1819 -  __setup_start = .;
1820 -  .setup.init : { *(.setup.init) }
1821 -  __setup_end = .;
1822 -  __initcall_start = .;
1823 -  .initcall.init : { *(.initcall.init) }
1824 -  __initcall_end = .;
1825 -  . = ALIGN(4096);
1826 -  __init_end = .;
1827 -
1828 -  . = ALIGN(4096);
1829 -  .data.page_aligned : { *(.data.idt) }
1830 -
1831 -  . = ALIGN(32);
1832 -  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1833 -
1834 -  __bss_start = .;             /* BSS */
1835 -  .bss : {
1836 -       *(.bss)
1837 -       }
1838 -  _end = . ;
1839 -
1840 -  /* Sections to be discarded */
1841 -  /DISCARD/ : {
1842 -       *(.text.exit)
1843 -       *(.data.exit)
1844 -       *(.exitcall.exit)
1845 -       }
1846 -
1847 -  /* Stabs debugging sections.  */
1848 -  .stab 0 : { *(.stab) }
1849 -  .stabstr 0 : { *(.stabstr) }
1850 -  .stab.excl 0 : { *(.stab.excl) }
1851 -  .stab.exclstr 0 : { *(.stab.exclstr) }
1852 -  .stab.index 0 : { *(.stab.index) }
1853 -  .stab.indexstr 0 : { *(.stab.indexstr) }
1854 -  .comment 0 : { *(.comment) }
1855 -}
1856 diff -urN linux-2.4.22.org/arch/i386/vmlinux.lds.S linux-2.4.22/arch/i386/vmlinux.lds.S
1857 --- linux-2.4.22.org/arch/i386/vmlinux.lds.S    1970-01-01 01:00:00.000000000 +0100
1858 +++ linux-2.4.22/arch/i386/vmlinux.lds.S        2003-11-22 22:14:06.000000000 +0100
1859 @@ -0,0 +1,136 @@
1860 +/* ld script to make i386 Linux kernel
1861 + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1862 + */
1863 +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1864 +OUTPUT_ARCH(i386)
1865 +ENTRY(_start)
1866 +SECTIONS
1867 +{
1868 +  . = __PAGE_OFFSET + 0x100000;
1869 +  .text.startup : {
1870 +       BYTE(0xEA) /* jmp far */
1871 +
1872 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1873 +       LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
1874 +#else
1875 +       LONG(startup_32 - __PAGE_OFFSET)
1876 +#endif
1877 +
1878 +       SHORT(__KERNEL_CS)
1879 +       }
1880 +
1881 +  . = ALIGN(32);
1882 +  _data = .;
1883 +  .data : {                    /* Data */
1884 +       *(.data)
1885 +       CONSTRUCTORS
1886 +       }
1887 +
1888 +  . = ALIGN(32);
1889 +  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1890 +
1891 +  . = ALIGN(8192);
1892 +  .data.init_task : { *(.data.init_task) }
1893 +
1894 +  . = ALIGN(4096);
1895 +  .data.page_aligned : { *(.data.swapper_pg_dir) }
1896 +
1897 +  _edata = .;                  /* End of data section */
1898 +
1899 +  __bss_start = .;             /* BSS */
1900 +  .bss : {
1901 +       *(.bss)
1902 +       LONG(0)
1903 +       } 
1904 +  __bss_end = . ;
1905 +
1906 +  . = ALIGN(4096);             /* Init code and data */
1907 +  __init_begin = .;
1908 +
1909 +  .data.init : {
1910 +       *(.data.pg0)
1911 +       *(.data.pg1)
1912 +       *(.data.pg2)
1913 +       *(.data.init)
1914 +       }
1915 +  . = ALIGN(16);
1916 +  __setup_start = .;
1917 +  .setup.init : { *(.setup.init) }
1918 +  __setup_end = .;
1919 +  __initcall_start = .;
1920 +  .initcall.init : { *(.initcall.init) }
1921 +  __initcall_end = .;
1922 +
1923 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1924 +  __text_init_start = .;
1925 +  .text.init (. - __KERNEL_TEXT_OFFSET) : AT (__text_init_start) {
1926 +       *(.text.init)
1927 +       . = ALIGN(4*1024*1024) - 1;
1928 +       BYTE(0)
1929 +       }
1930 +  __init_end = . + __KERNEL_TEXT_OFFSET;
1931 +
1932 +/*
1933 + * PaX: this must be kept in synch with the KERNEL_CS base
1934 + * in the GDTs in arch/i386/kernel/head.S
1935 + */
1936 +  _text = .;                   /* Text and read-only data */
1937 +  .text : AT (. + __KERNEL_TEXT_OFFSET) {
1938 +#else
1939 +  .text.init : { *(.text.init) }
1940 +  . = ALIGN(4096);
1941 +  __init_end = .;
1942 +  _text = .;                   /* Text and read-only data */
1943 +  .text : {
1944 +#endif
1945 +
1946 +       *(.text)
1947 +       *(.fixup)
1948 +       *(.gnu.warning)
1949 +       } = 0x9090
1950 +
1951 +  _etext = .;                  /* End of text section */
1952 +  . = ALIGN(4096);
1953 +
1954 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1955 +  . += __KERNEL_TEXT_OFFSET;
1956 +#endif
1957 +
1958 +  .rodata.page_aligned : {
1959 +       *(.data.empty_zero_page)
1960 +       *(.data.idt)
1961 +       }
1962 +  .rodata : { *(.rodata) *(.rodata.*) }
1963 +  .kstrtab : { *(.kstrtab) }
1964 +
1965 +  . = ALIGN(16);               /* Exception table */
1966 +  __start___ex_table = .;
1967 +  __ex_table : { *(__ex_table) }
1968 +  __stop___ex_table = .;
1969 +
1970 +  __start___ksymtab = .;       /* Kernel symbol table */
1971 +  __ksymtab : { *(__ksymtab) }
1972 +  __stop___ksymtab = .;
1973 +
1974 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1975 +  _end = ALIGN(4*1024*1024);
1976 +#else
1977 +  _end = .;
1978 +#endif
1979 +
1980 +  /* Sections to be discarded */
1981 +  /DISCARD/ : {
1982 +       *(.text.exit)
1983 +       *(.data.exit)
1984 +       *(.exitcall.exit)
1985 +       }
1986 +
1987 +  /* Stabs debugging sections.  */
1988 +  .stab 0 : { *(.stab) }
1989 +  .stabstr 0 : { *(.stabstr) }
1990 +  .stab.excl 0 : { *(.stab.excl) }
1991 +  .stab.exclstr 0 : { *(.stab.exclstr) }
1992 +  .stab.index 0 : { *(.stab.index) }
1993 +  .stab.indexstr 0 : { *(.stab.indexstr) }
1994 +  .comment 0 : { *(.comment) }
1995 +}
1996 diff -urN linux-2.4.22.org/arch/ia64/config.in linux-2.4.22/arch/ia64/config.in
1997 --- linux-2.4.22.org/arch/ia64/config.in        2003-11-22 22:12:28.000000000 +0100
1998 +++ linux-2.4.22/arch/ia64/config.in    2003-11-22 22:14:06.000000000 +0100
1999 @@ -296,3 +296,12 @@
2000  int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
2001  
2002  endmenu
2003 +
2004 +mainmenu_option next_comment
2005 +comment 'Grsecurity'
2006 +bool 'Grsecurity' CONFIG_GRKERNSEC
2007 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2008 +    source grsecurity/Config.in
2009 +fi
2010 +endmenu
2011 +
2012 diff -urN linux-2.4.22.org/arch/ia64/kernel/ptrace.c linux-2.4.22/arch/ia64/kernel/ptrace.c
2013 --- linux-2.4.22.org/arch/ia64/kernel/ptrace.c  2003-11-22 22:12:33.000000000 +0100
2014 +++ linux-2.4.22/arch/ia64/kernel/ptrace.c      2003-11-22 22:14:06.000000000 +0100
2015 @@ -16,6 +16,7 @@
2016  #include <linux/ptrace.h>
2017  #include <linux/smp_lock.h>
2018  #include <linux/user.h>
2019 +#include <linux/grsecurity.h>
2020  
2021  #include <asm/pgtable.h>
2022  #include <asm/processor.h>
2023 @@ -1273,6 +1274,9 @@
2024         if (pid == 1)           /* no messing around with init! */
2025                 goto out_tsk;
2026  
2027 +       if (gr_handle_ptrace(child, request))
2028 +               goto out_tsk;
2029 +
2030         if (request == PTRACE_ATTACH) {
2031                 ret = ptrace_attach(child);
2032                 goto out_tsk;
2033 diff -urN linux-2.4.22.org/arch/ia64/kernel/sys_ia64.c linux-2.4.22/arch/ia64/kernel/sys_ia64.c
2034 --- linux-2.4.22.org/arch/ia64/kernel/sys_ia64.c        2003-11-22 22:12:34.000000000 +0100
2035 +++ linux-2.4.22/arch/ia64/kernel/sys_ia64.c    2003-11-22 22:14:06.000000000 +0100
2036 @@ -15,6 +15,7 @@
2037  #include <linux/smp.h>
2038  #include <linux/smp_lock.h>
2039  #include <linux/highuid.h>
2040 +#include <linux/grsecurity.h>
2041  
2042  #include <asm/shmparam.h>
2043  #include <asm/uaccess.h>
2044 @@ -206,6 +207,11 @@
2045                 goto out;
2046         }
2047  
2048 +       if (gr_handle_mmap(file, prot)) {
2049 +               addr = -EACCES;
2050 +               goto out;
2051 +       }
2052 +
2053         down_write(&current->mm->mmap_sem);
2054         addr = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
2055         up_write(&current->mm->mmap_sem);
2056 diff -urN linux-2.4.22.org/arch/m68k/config.in linux-2.4.22/arch/m68k/config.in
2057 --- linux-2.4.22.org/arch/m68k/config.in        2003-11-22 22:12:12.000000000 +0100
2058 +++ linux-2.4.22/arch/m68k/config.in    2003-11-22 22:14:06.000000000 +0100
2059 @@ -562,3 +562,11 @@
2060  
2061  source crypto/Config.in
2062  source lib/Config.in
2063 +
2064 +mainmenu_option next_comment
2065 +comment 'Grsecurity'
2066 +bool 'Grsecurity' CONFIG_GRKERNSEC
2067 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2068 +       source grsecurity/Config.in
2069 +fi
2070 +endmenu
2071 diff -urN linux-2.4.22.org/arch/mips/config.in linux-2.4.22/arch/mips/config.in
2072 --- linux-2.4.22.org/arch/mips/config.in        2003-11-22 22:12:02.000000000 +0100
2073 +++ linux-2.4.22/arch/mips/config.in    2003-11-22 22:14:06.000000000 +0100
2074 @@ -7,3 +7,11 @@
2075  define_bool CONFIG_MIPS64 n
2076  
2077  source arch/mips/config-shared.in
2078 +
2079 +mainmenu_option next_comment
2080 +comment 'Grsecurity'
2081 +bool 'Grsecurity' CONFIG_GRKERNSEC
2082 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2083 +        source grsecurity/Config.in
2084 +fi
2085 +endmenu
2086 diff -urN linux-2.4.22.org/arch/mips64/config.in linux-2.4.22/arch/mips64/config.in
2087 --- linux-2.4.22.org/arch/mips64/config.in      2003-11-22 22:12:35.000000000 +0100
2088 +++ linux-2.4.22/arch/mips64/config.in  2003-11-22 22:14:06.000000000 +0100
2089 @@ -7,3 +7,11 @@
2090  define_bool CONFIG_MIPS64 y
2091  
2092  source arch/mips/config-shared.in
2093 +
2094 +mainmenu_option next_comment
2095 +comment 'Grsecurity'
2096 +bool 'Grsecurity' CONFIG_GRKERNSEC
2097 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2098 +        source grsecurity/Config.in
2099 +fi
2100 +endmenu
2101 diff -urN linux-2.4.22.org/arch/parisc/config.in linux-2.4.22/arch/parisc/config.in
2102 --- linux-2.4.22.org/arch/parisc/config.in      2003-11-22 22:12:37.000000000 +0100
2103 +++ linux-2.4.22/arch/parisc/config.in  2003-11-22 22:14:06.000000000 +0100
2104 @@ -205,3 +205,11 @@
2105  
2106  source crypto/Config.in
2107  source lib/Config.in
2108 +
2109 +mainmenu_option next_comment
2110 +comment 'Grsecurity'
2111 +bool 'Grsecurity' CONFIG_GRKERNSEC
2112 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2113 +       source grsecurity/Config.in
2114 +fi
2115 +endmenu
2116 diff -urN linux-2.4.22.org/arch/parisc/kernel/ioctl32.c linux-2.4.22/arch/parisc/kernel/ioctl32.c
2117 --- linux-2.4.22.org/arch/parisc/kernel/ioctl32.c       2003-11-22 22:12:37.000000000 +0100
2118 +++ linux-2.4.22/arch/parisc/kernel/ioctl32.c   2003-11-22 22:14:06.000000000 +0100
2119 @@ -1435,7 +1435,11 @@
2120          * To have permissions to do most of the vt ioctls, we either have
2121          * to be the owner of the tty, or super-user.
2122          */
2123 +#ifdef CONFIG_GRKERNSEC
2124 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
2125 +#else
2126         if (current->tty == tty || suser())
2127 +#endif
2128                 return 1;
2129         return 0;                                                    
2130  }
2131 diff -urN linux-2.4.22.org/arch/parisc/kernel/ptrace.c linux-2.4.22/arch/parisc/kernel/ptrace.c
2132 --- linux-2.4.22.org/arch/parisc/kernel/ptrace.c        2003-11-22 22:12:37.000000000 +0100
2133 +++ linux-2.4.22/arch/parisc/kernel/ptrace.c    2003-11-22 22:14:06.000000000 +0100
2134 @@ -15,7 +15,7 @@
2135  #include <linux/ptrace.h>
2136  #include <linux/user.h>
2137  #include <linux/personality.h>
2138 -
2139 +#include <linux/grsecurity.h>
2140  #include <asm/uaccess.h>
2141  #include <asm/pgtable.h>
2142  #include <asm/system.h>
2143 @@ -119,6 +119,9 @@
2144         if (pid == 1)           /* no messing around with init! */
2145                 goto out_tsk;
2146  
2147 +       if (gr_handle_ptrace(child, request))
2148 +               goto out_tsk;
2149 +
2150         if (request == PTRACE_ATTACH) {
2151                 ret = ptrace_attach(child);
2152                 goto out_tsk;
2153 diff -urN linux-2.4.22.org/arch/parisc/kernel/sys_parisc32.c linux-2.4.22/arch/parisc/kernel/sys_parisc32.c
2154 --- linux-2.4.22.org/arch/parisc/kernel/sys_parisc32.c  2003-11-22 22:12:37.000000000 +0100
2155 +++ linux-2.4.22/arch/parisc/kernel/sys_parisc32.c      2003-11-22 22:14:06.000000000 +0100
2156 @@ -50,6 +50,7 @@
2157  #include <linux/highmem.h>
2158  #include <linux/highuid.h>
2159  #include <linux/mman.h>
2160 +#include <linux/grsecurity.h>
2161  
2162  #include <asm/types.h>
2163  #include <asm/uaccess.h>
2164 @@ -177,6 +178,11 @@
2165         struct file *file;
2166         int retval;
2167         int i;
2168 +#ifdef CONFIG_GRKERNSEC
2169 +       struct file *old_exec_file;
2170 +       struct acl_subject_label *old_acl;
2171 +       struct rlimit old_rlim[RLIM_NLIMITS];
2172 +#endif
2173  
2174         file = open_exec(filename);
2175  
2176 @@ -184,7 +190,26 @@
2177         if (IS_ERR(file))
2178                 return retval;
2179  
2180 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
2181 +
2182 +       if (gr_handle_nproc()) {
2183 +               allow_write_access(file);
2184 +               fput(file);
2185 +               return -EAGAIN;
2186 +       }
2187 +
2188 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
2189 +               allow_write_access(file);
2190 +               fput(file);
2191 +               return -EACCES;
2192 +       }
2193 +
2194         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
2195 +
2196 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
2197 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
2198 +#endif
2199 +
2200         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
2201  
2202         DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs));
2203 @@ -209,11 +234,24 @@
2204         if (retval < 0)
2205                 goto out;
2206         
2207 +       if (!gr_tpe_allow(file)) {
2208 +               retval = -EACCES;
2209 +               goto out;
2210 +       }
2211 +
2212 +       if (gr_check_crash_exec(file)) {
2213 +               retval = -EACCES;
2214 +               goto out;
2215 +       }
2216 +
2217         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
2218         if (retval < 0)
2219                 goto out;
2220  
2221         bprm.exec = bprm.p;
2222 +
2223 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
2224 +
2225         retval = copy_strings32(bprm.envc, envp, &bprm);
2226         if (retval < 0)
2227                 goto out;
2228 @@ -222,11 +260,32 @@
2229         if (retval < 0)
2230                 goto out;
2231  
2232 +#ifdef CONFIG_GRKERNSEC
2233 +       old_acl = current->acl;
2234 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
2235 +       old_exec_file = current->exec_file;
2236 +       get_file(file);
2237 +       current->exec_file = file;
2238 +#endif
2239 +
2240 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
2241 +
2242         retval = search_binary_handler(&bprm,regs);
2243 -       if (retval >= 0)
2244 +       if (retval >= 0) {
2245 +#ifdef CONFIG_GRKERNSEC
2246 +               if (old_exec_file)
2247 +                       fput(old_exec_file);
2248 +#endif
2249                 /* execve success */
2250                 return retval;
2251 +       }
2252  
2253 +#ifdef CONFIG_GRKERNSEC
2254 +       current->acl = old_acl;
2255 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
2256 +       fput(current->exec_file);
2257 +       current->exec_file = old_exec_file;
2258 +#endif
2259  out:
2260         /* Something went wrong, return the inode and free the argument pages*/
2261         allow_write_access(bprm.file);
2262 diff -urN linux-2.4.22.org/arch/parisc/kernel/sys_parisc.c linux-2.4.22/arch/parisc/kernel/sys_parisc.c
2263 --- linux-2.4.22.org/arch/parisc/kernel/sys_parisc.c    2003-11-22 22:12:37.000000000 +0100
2264 +++ linux-2.4.22/arch/parisc/kernel/sys_parisc.c        2003-11-22 22:14:06.000000000 +0100
2265 @@ -12,6 +12,7 @@
2266  #include <linux/mman.h>
2267  #include <linux/shm.h>
2268  #include <linux/smp_lock.h>
2269 +#include <linux/grsecurity.h>
2270  
2271  int sys_pipe(int *fildes)
2272  {
2273 @@ -90,6 +91,11 @@
2274                 inode = filp->f_dentry->d_inode;
2275         }
2276  
2277 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2278 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
2279 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
2280 +#endif
2281 +
2282         if (inode && (flags & MAP_SHARED) && (inode->i_mapping->i_mmap_shared)) {
2283                 addr = get_shared_area(inode, addr, len, pgoff);
2284         } else {
2285 @@ -104,12 +110,23 @@
2286  {
2287         struct file * file = NULL;
2288         unsigned long error = -EBADF;
2289 +
2290 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2291 +       if (flags & MAP_MIRROR)
2292 +               return -EINVAL;
2293 +#endif
2294 +
2295         if (!(flags & MAP_ANONYMOUS)) {
2296                 file = fget(fd);
2297                 if (!file)
2298                         goto out;
2299         }
2300  
2301 +       if (gr_handle_mmap(file, prot)) {
2302 +               fput(file);
2303 +               return -EACCES;
2304 +       }
2305 +
2306         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2307  
2308         down_write(&current->mm->mmap_sem);
2309 diff -urN linux-2.4.22.org/arch/parisc/kernel/traps.c linux-2.4.22/arch/parisc/kernel/traps.c
2310 --- linux-2.4.22.org/arch/parisc/kernel/traps.c 2003-11-22 22:12:37.000000000 +0100
2311 +++ linux-2.4.22/arch/parisc/kernel/traps.c     2003-11-22 22:14:06.000000000 +0100
2312 @@ -637,9 +637,7 @@
2313  
2314                         down_read(&current->mm->mmap_sem);
2315                         vma = find_vma(current->mm,regs->iaoq[0]);
2316 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
2317 -                               && (vma->vm_flags & VM_EXEC)) {
2318 -
2319 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
2320                                 fault_address = regs->iaoq[0];
2321                                 fault_space = regs->iasq[0];
2322  
2323 diff -urN linux-2.4.22.org/arch/parisc/mm/fault.c linux-2.4.22/arch/parisc/mm/fault.c
2324 --- linux-2.4.22.org/arch/parisc/mm/fault.c     2003-11-22 22:12:37.000000000 +0100
2325 +++ linux-2.4.22/arch/parisc/mm/fault.c 2003-11-22 22:14:06.000000000 +0100
2326 @@ -15,6 +15,7 @@
2327  #include <linux/ptrace.h>
2328  #include <linux/sched.h>
2329  #include <linux/interrupt.h>
2330 +#include <linux/unistd.h>
2331  
2332  #include <asm/uaccess.h>
2333  #include <asm/traps.h>
2334 @@ -53,7 +54,7 @@
2335  static unsigned long
2336  parisc_acctyp(unsigned long code, unsigned int inst)
2337  {
2338 -       if (code == 6 || code == 16)
2339 +       if (code == 6 || code == 7 || code == 16)
2340             return VM_EXEC;
2341  
2342         switch (inst & 0xf0000000) {
2343 @@ -139,6 +140,136 @@
2344                         }
2345  #endif
2346  
2347 +/*
2348 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
2349 + *
2350 + * returns 1 when task should be killed 
2351 + *        2 when rt_sigreturn trampoline was detected
2352 + *        3 when unpatched PLT trampoline was detected
2353 + *        4 when legitimate ET_EXEC was detected
2354 + */
2355 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC  
2356 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2357 +{
2358 +       int err;
2359 +
2360 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2361 +       if (current->flags & PF_PAX_RANDEXEC) {
2362 +               if (instruction_pointer(regs) >= current->mm->start_code &&
2363 +                   instruction_pointer(regs) < current->mm->end_code)
2364 +               {
2365 +#if 0
2366 +                       /* PaX: this needs fixing */
2367 +                       if ((regs->gr[2] & ~3UL) == instruction_pointer(regs))
2368 +                               return 1;
2369 +#endif
2370 +                       regs->iaoq[0] += current->mm->delta_exec;
2371 +                       if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code &&
2372 +                           (regs->iaoq[1] & ~3UL) < current->mm->end_code)
2373 +                               regs->iaoq[1] += current->mm->delta_exec;
2374 +                       return 4;
2375 +               }
2376 +       }
2377 +#endif
2378 +
2379 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2380 +       do { /* PaX: unpatched PLT emulation */
2381 +               unsigned int bl, depwi;
2382 +
2383 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
2384 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
2385 +
2386 +               if (err)
2387 +                       break;
2388 +
2389 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
2390 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
2391 +
2392 +                       err = get_user(ldw, (unsigned int*)addr);
2393 +                       err |= get_user(bv, (unsigned int*)(addr+4));
2394 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
2395 +
2396 +                       if (err)
2397 +                               break;
2398 +
2399 +                       if (ldw == 0x0E801096U &&
2400 +                           bv == 0xEAC0C000U &&
2401 +                           ldw2 == 0x0E881095U)
2402 +                       {
2403 +                               unsigned int resolver, map;
2404 +
2405 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
2406 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
2407 +                               if (err)
2408 +                                       break;
2409 +
2410 +                               regs->gr[20] = instruction_pointer(regs)+8;
2411 +                               regs->gr[21] = map;
2412 +                               regs->gr[22] = resolver;
2413 +                               regs->iaoq[0] = resolver | 3UL;
2414 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
2415 +                               return 3;
2416 +                       }
2417 +               }
2418 +       } while (0);
2419 +#endif
2420
2421 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2422 +
2423 +#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2424 +       if (!(current->flags & PF_PAX_EMUTRAMP))
2425 +               return 1;
2426 +#endif
2427 +
2428 +       do { /* PaX: rt_sigreturn emulation */
2429 +               unsigned int ldi1, ldi2, bel, nop;
2430 +
2431 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
2432 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
2433 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
2434 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
2435 +
2436 +               if (err)
2437 +                       break;
2438 +
2439 +                if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
2440 +                   ldi2 == 0x3414015AU &&
2441 +                   bel == 0xE4008200U &&
2442 +                   nop == 0x08000240U)
2443 +               {
2444 +                       regs->gr[25] = (ldi1 & 2) >> 1;
2445 +                       regs->gr[20] = __NR_rt_sigreturn;
2446 +                       regs->gr[31] = regs->iaoq[1] + 16;
2447 +                       regs->sr[0] = regs->iasq[1];
2448 +                       regs->iaoq[0] = 0x100UL;
2449 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
2450 +                       regs->iasq[0] = regs->sr[2];
2451 +                       regs->iasq[1] = regs->sr[2];
2452 +                       return 2;
2453 +               }
2454 +       } while (0);
2455 +#endif
2456 +
2457 +       return 1;
2458 +}
2459 +
2460 +void pax_report_insns(void *pc)
2461 +{
2462 +       unsigned long i;
2463 +
2464 +       printk(KERN_ERR "PAX: bytes at PC: ");
2465 +       for (i = 0; i < 5; i++) {
2466 +               unsigned int c;
2467 +               if (get_user(c, (unsigned int*)pc+i)) {
2468 +                       printk("<invalid address>.");
2469 +                       break;
2470 +               }
2471 +               printk("%08x ", c);
2472 +       }
2473 +       printk("\n");
2474 +}
2475 +#endif
2476 +
2477  void do_page_fault(struct pt_regs *regs, unsigned long code,
2478                               unsigned long address)
2479  {
2480 @@ -164,8 +295,38 @@
2481  
2482         acc_type = parisc_acctyp(code,regs->iir);
2483  
2484 -       if ((vma->vm_flags & acc_type) != acc_type)
2485 +       if ((vma->vm_flags & acc_type) != acc_type) {
2486 +
2487 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2488 +               if ((current->flags & PF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
2489 +                   (address & ~3UL) == instruction_pointer(regs))
2490 +                  {
2491 +                       up_read(&mm->mmap_sem);
2492 +                       switch(pax_handle_fetch_fault(regs)) {
2493 +
2494 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2495 +                       case 4:
2496 +                               return;
2497 +#endif
2498 +
2499 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2500 +                       case 3:
2501 +                               return;
2502 +#endif
2503 +
2504 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2505 +                       case 2:
2506 +                               return;
2507 +#endif
2508 +
2509 +                       }
2510 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
2511 +                       do_exit(SIGKILL);
2512 +               }
2513 +#endif
2514 +
2515                 goto bad_area;
2516 +       }
2517  
2518         /*
2519          * If for any reason at all we couldn't handle the fault, make
2520 diff -urN linux-2.4.22.org/arch/ppc/config.in linux-2.4.22/arch/ppc/config.in
2521 --- linux-2.4.22.org/arch/ppc/config.in 2003-11-22 22:12:09.000000000 +0100
2522 +++ linux-2.4.22/arch/ppc/config.in     2003-11-22 22:14:06.000000000 +0100
2523 @@ -610,3 +610,12 @@
2524  int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
2525  
2526  endmenu
2527 +
2528 +mainmenu_option next_comment
2529 +comment 'Grsecurity'
2530 +bool 'Grsecurity' CONFIG_GRKERNSEC
2531 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2532 +    source grsecurity/Config.in
2533 +fi
2534 +endmenu
2535 +
2536 diff -urN linux-2.4.22.org/arch/ppc/kernel/ptrace.c linux-2.4.22/arch/ppc/kernel/ptrace.c
2537 --- linux-2.4.22.org/arch/ppc/kernel/ptrace.c   2003-11-22 22:12:10.000000000 +0100
2538 +++ linux-2.4.22/arch/ppc/kernel/ptrace.c       2003-11-22 22:14:06.000000000 +0100
2539 @@ -24,6 +24,7 @@
2540  #include <linux/errno.h>
2541  #include <linux/ptrace.h>
2542  #include <linux/user.h>
2543 +#include <linux/grsecurity.h>
2544  
2545  #include <asm/uaccess.h>
2546  #include <asm/page.h>
2547 @@ -195,6 +196,9 @@
2548         if (pid == 1)           /* you may not mess with init */
2549                 goto out_tsk;
2550  
2551 +       if (gr_handle_ptrace(child, request))
2552 +               goto out_tsk;
2553 +
2554         if (request == PTRACE_ATTACH) {
2555                 ret = ptrace_attach(child);
2556                 goto out_tsk;
2557 diff -urN linux-2.4.22.org/arch/ppc/kernel/syscalls.c linux-2.4.22/arch/ppc/kernel/syscalls.c
2558 --- linux-2.4.22.org/arch/ppc/kernel/syscalls.c 2003-11-22 22:12:11.000000000 +0100
2559 +++ linux-2.4.22/arch/ppc/kernel/syscalls.c     2003-11-22 22:19:00.000000000 +0100
2560 @@ -35,6 +35,7 @@
2561  #include <linux/ipc.h>
2562  #include <linux/utsname.h>
2563  #include <linux/file.h>
2564 +#include <linux/grsecurity.h>
2565  
2566  #include <asm/uaccess.h>
2567  #include <asm/ipc.h>
2568 @@ -191,6 +192,11 @@
2569         struct file * file = NULL;
2570         int ret = -EBADF;
2571  
2572 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2573 +        if (flags & MAP_MIRROR)
2574 +                return -EINVAL;
2575 +#endif
2576 +
2577         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2578         if (!(flags & MAP_ANONYMOUS)) {
2579                 if (!(file = fget(fd)))
2580 @@ -200,9 +206,15 @@
2581         ret = -EINVAL;
2582         if ((! allow_mmap_address(addr)) && (flags & MAP_FIXED))
2583                 goto out;
2584 +
2585 +        if (gr_handle_mmap(file, prot)) {
2586 +                fput(file);
2587 +                ret = -EACCES;
2588 +                goto out;
2589 +        }
2590         
2591         down_write(&current->mm->mmap_sem);
2592 -       ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
2593 +       ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
2594         up_write(&current->mm->mmap_sem);
2595         if (file)
2596                 fput(file);
2597 diff -urN linux-2.4.22.org/arch/ppc/mm/fault.c linux-2.4.22/arch/ppc/mm/fault.c
2598 --- linux-2.4.22.org/arch/ppc/mm/fault.c        2003-11-22 22:12:10.000000000 +0100
2599 +++ linux-2.4.22/arch/ppc/mm/fault.c    2003-11-22 22:14:06.000000000 +0100
2600 @@ -26,6 +26,9 @@
2601  #include <linux/mman.h>
2602  #include <linux/mm.h>
2603  #include <linux/interrupt.h>
2604 +#include <linux/slab.h>
2605 +#include <linux/pagemap.h>
2606 +#include <linux/compiler.h>
2607  
2608  #include <asm/page.h>
2609  #include <asm/pgtable.h>
2610 @@ -52,6 +55,360 @@
2611  void bad_page_fault(struct pt_regs *, unsigned long, int sig);
2612  void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
2613  
2614 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2615 +void pax_syscall_close(struct vm_area_struct * vma)
2616 +{
2617 +       vma->vm_mm->call_syscall = 0UL;
2618 +}
2619 +
2620 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
2621 +{
2622 +       struct page* page;
2623 +       unsigned int *kaddr;
2624 +
2625 +       page = alloc_page(GFP_HIGHUSER);
2626 +       if (!page)
2627 +               return page;
2628 +
2629 +       kaddr = kmap(page);
2630 +       memset(kaddr, 0, PAGE_SIZE);
2631 +       kaddr[0] = 0x44000002U; /* sc */
2632 +       __flush_dcache_icache(kaddr);
2633 +       kunmap(page);
2634 +       return page;
2635 +}
2636 +
2637 +static struct vm_operations_struct pax_vm_ops = {
2638 +       close:          pax_syscall_close,
2639 +       nopage:         pax_syscall_nopage,
2640 +};
2641 +
2642 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2643 +{
2644 +       vma->vm_mm = current->mm;
2645 +       vma->vm_start = addr;
2646 +       vma->vm_end = addr + PAGE_SIZE;
2647 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2648 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
2649 +       vma->vm_ops = &pax_vm_ops;
2650 +       vma->vm_pgoff = 0UL;
2651 +       vma->vm_file = NULL;
2652 +       vma->vm_private_data = NULL;
2653 +       insert_vm_struct(current->mm, vma);
2654 +       ++current->mm->total_vm;
2655 +}
2656 +#endif
2657 +
2658 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2659 +/*
2660 + * PaX: decide what to do with offenders (regs->nip = fault address)
2661 + *
2662 + * returns 1 when task should be killed
2663 + *         2 when patched GOT trampoline was detected
2664 + *         3 when patched PLT trampoline was detected
2665 + *         4 when unpatched PLT trampoline was detected
2666 + *         5 when legitimate ET_EXEC was detected
2667 + *         6 when sigreturn trampoline was detected
2668 + *         7 when rt_sigreturn trampoline was detected
2669 + */
2670 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2671 +{
2672 +       int err;
2673 +
2674 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2675 +       if (current->flags & PF_PAX_RANDEXEC) {
2676 +               if (regs->nip >= current->mm->start_code &&
2677 +                   regs->nip < current->mm->end_code)
2678 +               {
2679 +                       if (regs->link == regs->nip)
2680 +                               return 1;
2681 +
2682 +                       regs->nip += current->mm->delta_exec;
2683 +                       return 5;
2684 +               }
2685 +       }
2686 +#endif
2687 +
2688 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2689 +       do { /* PaX: patched GOT emulation */
2690 +               unsigned int blrl;
2691 +
2692 +               err = get_user(blrl, (unsigned int*)regs->nip);
2693 +
2694 +               if (!err && blrl == 0x4E800021U) {
2695 +                       unsigned long temp = regs->nip;
2696 +
2697 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
2698 +                       regs->link = temp + 4UL;
2699 +                       return 2;
2700 +               }
2701 +       } while (0);
2702 +
2703 +       do { /* PaX: patched PLT emulation #1 */
2704 +               unsigned int b;
2705 +
2706 +               err = get_user(b, (unsigned int *)regs->nip);
2707 +
2708 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
2709 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
2710 +                       return 3;
2711 +               }
2712 +       } while (0);
2713 +
2714 +       do { /* PaX: unpatched PLT emulation #1 */
2715 +               unsigned int li, b;
2716 +
2717 +               err = get_user(li, (unsigned int *)regs->nip);
2718 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2719 +
2720 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2721 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2722 +                        unsigned long addr = b | 0xFC000000UL;
2723 +
2724 +                        addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2725 +                       err = get_user(rlwinm, (unsigned int*)addr);
2726 +                       err |= get_user(add, (unsigned int*)(addr+4));
2727 +                       err |= get_user(li2, (unsigned int*)(addr+8));
2728 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
2729 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
2730 +                       err |= get_user(li3, (unsigned int*)(addr+20));
2731 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
2732 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
2733 +
2734 +                       if (err)
2735 +                               break;
2736 +
2737 +                       if (rlwinm == 0x556C083CU &&
2738 +                           add == 0x7D6C5A14U &&
2739 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2740 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2741 +                           mtctr == 0x7D8903A6U &&
2742 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2743 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2744 +                           bctr == 0x4E800420U)
2745 +                       {
2746 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2747 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2748 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2749 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2750 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2751 +                               regs->nip = regs->ctr;
2752 +                               return 4;
2753 +                       }
2754 +               }
2755 +       } while (0);
2756 +
2757 +#if 0
2758 +       do { /* PaX: unpatched PLT emulation #2 */
2759 +               unsigned int lis, lwzu, b, bctr;
2760 +
2761 +               err = get_user(lis, (unsigned int *)regs->nip);
2762 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
2763 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
2764 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
2765 +
2766 +               if (err)
2767 +                       break;
2768 +
2769 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
2770 +                   (lwzu & 0xU) == 0xU &&
2771 +                   (b & 0xFC000003U) == 0x48000000U &&
2772 +                   bctr == 0x4E800420U)
2773 +               {
2774 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2775 +                        unsigned long addr = b | 0xFC000000UL;
2776 +
2777 +                        addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2778 +                       err = get_user(addis, (unsigned int*)addr);
2779 +                       err |= get_user(addi, (unsigned int*)(addr+4));
2780 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
2781 +                       err |= get_user(add, (unsigned int*)(addr+12));
2782 +                       err |= get_user(li2, (unsigned int*)(addr+16));
2783 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
2784 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
2785 +                       err |= get_user(li3, (unsigned int*)(addr+28));
2786 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
2787 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
2788 +
2789 +                       if (err)
2790 +                               break;
2791 +
2792 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2793 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
2794 +                           rlwinm == 0x556C083CU &&
2795 +                           add == 0x7D6C5A14U &&
2796 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2797 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2798 +                           mtctr == 0x7D8903A6U &&
2799 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2800 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2801 +                           bctr == 0x4E800420U)
2802 +                       {
2803 +                               regs->gpr[PT_R11] = 
2804 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2805 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2806 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2807 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2808 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2809 +                               regs->nip = regs->ctr;
2810 +                               return 4;
2811 +                       }
2812 +               }
2813 +       } while (0);
2814 +#endif
2815 +
2816 +       do { /* PaX: unpatched PLT emulation #3 */
2817 +               unsigned int li, b;
2818 +
2819 +               err = get_user(li, (unsigned int *)regs->nip);
2820 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2821 +
2822 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2823 +                       unsigned int addis, lwz, mtctr, bctr;
2824 +                       unsigned long addr = b | 0xFC000000UL;
2825 +
2826 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2827 +                       err = get_user(addis, (unsigned int*)addr);
2828 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
2829 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
2830 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
2831 +
2832 +                       if (err)
2833 +                               break;
2834 +
2835 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2836 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
2837 +                           mtctr == 0x7D6903A6U &&
2838 +                           bctr == 0x4E800420U)
2839 +                       {
2840 +                               unsigned int r11;
2841 +
2842 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2843 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2844 +
2845 +                               err = get_user(r11, (unsigned int*)addr);
2846 +                               if (err)
2847 +                                       break;
2848 +
2849 +                               regs->gpr[PT_R11] = r11;
2850 +                               regs->ctr = r11;
2851 +                               regs->nip = r11;
2852 +                               return 4;
2853 +                       }
2854 +               }
2855 +       } while (0);
2856 +#endif
2857 +
2858 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2859 +       do { /* PaX: sigreturn emulation */
2860 +               unsigned int li, sc;
2861 +
2862 +               err = get_user(li, (unsigned int *)regs->nip);
2863 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
2864 +
2865 +               if (!err && li == 0x38007777U && sc == 0x44000002U) {
2866 +                       struct vm_area_struct *vma;
2867 +                       unsigned long call_syscall;
2868 +
2869 +                       down_read(&current->mm->mmap_sem);
2870 +                       call_syscall = current->mm->call_syscall;
2871 +                       up_read(&current->mm->mmap_sem);
2872 +                       if (likely(call_syscall))
2873 +                               goto emulate;
2874 +
2875 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
2876 +
2877 +                       down_write(&current->mm->mmap_sem);
2878 +                       if (current->mm->call_syscall) {
2879 +                               call_syscall = current->mm->call_syscall;
2880 +                               up_write(&current->mm->mmap_sem);
2881 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2882 +                               goto emulate;
2883 +                       }
2884 +
2885 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2886 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
2887 +                               up_write(&current->mm->mmap_sem);
2888 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2889 +                               return 1;
2890 +                       }
2891 +
2892 +                       pax_insert_vma(vma, call_syscall);
2893 +                       current->mm->call_syscall = call_syscall;
2894 +                       up_write(&current->mm->mmap_sem);
2895 +
2896 +emulate:
2897 +                       regs->gpr[PT_R0] = 0x7777UL;
2898 +                       regs->nip = call_syscall;
2899 +                       return 6;
2900 +               }
2901 +       } while (0);
2902 +
2903 +       do { /* PaX: rt_sigreturn emulation */
2904 +               unsigned int li, sc;
2905 +
2906 +               err = get_user(li, (unsigned int *)regs->nip);
2907 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
2908 +
2909 +               if (!err && li == 0x38006666U && sc == 0x44000002U) {
2910 +                       struct vm_area_struct *vma;
2911 +                       unsigned int call_syscall;
2912 +
2913 +                       down_read(&current->mm->mmap_sem);
2914 +                       call_syscall = current->mm->call_syscall;
2915 +                       up_read(&current->mm->mmap_sem);
2916 +                       if (likely(call_syscall))
2917 +                               goto rt_emulate;
2918 +
2919 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
2920 +
2921 +                       down_write(&current->mm->mmap_sem);
2922 +                       if (current->mm->call_syscall) {
2923 +                               call_syscall = current->mm->call_syscall;
2924 +                               up_write(&current->mm->mmap_sem);
2925 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2926 +                               goto rt_emulate;
2927 +                       }
2928 +
2929 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2930 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
2931 +                               up_write(&current->mm->mmap_sem);
2932 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2933 +                               return 1;
2934 +                       }
2935 +
2936 +                       pax_insert_vma(vma, call_syscall);
2937 +                       current->mm->call_syscall = call_syscall;
2938 +                       up_write(&current->mm->mmap_sem);
2939 +
2940 +rt_emulate:
2941 +                       regs->gpr[PT_R0] = 0x6666UL;
2942 +                       regs->nip = call_syscall;
2943 +                       return 7;
2944 +               }
2945 +       } while (0);
2946 +#endif
2947 +
2948 +        return 1;
2949 +}
2950 +
2951 +void pax_report_insns(void *pc)
2952 +{
2953 +       unsigned long i;
2954 +
2955 +       printk(KERN_ERR "PAX: bytes at PC: ");
2956 +       for (i = 0; i < 5; i++) {
2957 +               unsigned int c;
2958 +               if (get_user(c, (unsigned int*)pc+i)) {
2959 +                       printk("<invalid address>.");
2960 +                       break;
2961 +               }
2962 +               printk("%08x ", c);
2963 +       }
2964 +       printk("\n");
2965 +}
2966 +#endif
2967 +
2968  /*
2969   * Check whether the instruction at regs->nip is a store using
2970   * an update addressing form which will update r1.
2971 @@ -112,7 +469,7 @@
2972          * indicate errors in DSISR but can validly be set in SRR1.
2973          */
2974         if (regs->trap == 0x400)
2975 -               error_code &= 0x48200000;
2976 +               error_code &= 0x58200000;
2977         else
2978                 is_write = error_code & 0x02000000;
2979  #endif /* CONFIG_4xx || CONFIG_BOOKE */
2980 @@ -245,6 +602,38 @@
2981  
2982         /* User mode accesses cause a SIGSEGV */
2983         if (user_mode(regs)) {
2984 +
2985 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2986 +               if (current->flags & PF_PAX_PAGEEXEC) {
2987 +                       if ((regs->trap == 0x400) && (regs->nip == address)) {
2988 +                               switch (pax_handle_fetch_fault(regs)) {
2989 +
2990 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2991 +                               case 2:
2992 +                               case 3:
2993 +                               case 4:
2994 +                                       return;
2995 +#endif
2996 +
2997 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2998 +                               case 5:
2999 +                                       return;
3000 +#endif
3001 +
3002 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
3003 +                               case 6:
3004 +                               case 7:
3005 +                                       return;
3006 +#endif
3007 +
3008 +                               }
3009 +
3010 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
3011 +                               do_exit(SIGKILL);
3012 +                       }
3013 +               }
3014 +#endif
3015 +
3016                 info.si_signo = SIGSEGV;
3017                 info.si_errno = 0;
3018                 info.si_code = code;
3019 diff -urN linux-2.4.22.org/arch/ppc64/kernel/ioctl32.c linux-2.4.22/arch/ppc64/kernel/ioctl32.c
3020 --- linux-2.4.22.org/arch/ppc64/kernel/ioctl32.c        2003-11-22 22:11:53.000000000 +0100
3021 +++ linux-2.4.22/arch/ppc64/kernel/ioctl32.c    2003-11-22 22:14:06.000000000 +0100
3022 @@ -1801,7 +1801,11 @@
3023          * To have permissions to do most of the vt ioctls, we either have
3024          * to be the owner of the tty, or super-user.
3025          */
3026 +#ifdef CONFIG_GRKERNSEC
3027 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3028 +#else
3029         if (current->tty == tty || suser())
3030 +#endif
3031                 return 1;
3032         return 0;                                                    
3033  }
3034 diff -urN linux-2.4.22.org/arch/s390/config.in linux-2.4.22/arch/s390/config.in
3035 --- linux-2.4.22.org/arch/s390/config.in        2003-11-22 22:12:36.000000000 +0100
3036 +++ linux-2.4.22/arch/s390/config.in    2003-11-22 22:14:06.000000000 +0100
3037 @@ -87,3 +87,11 @@
3038  
3039  source crypto/Config.in
3040  source lib/Config.in
3041 +
3042 +mainmenu_option next_comment
3043 +comment 'Grsecurity'
3044 +bool 'Grsecurity' CONFIG_GRKERNSEC
3045 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3046 +       source grsecurity/Config.in
3047 +fi
3048 +endmenu
3049 diff -urN linux-2.4.22.org/arch/s390x/config.in linux-2.4.22/arch/s390x/config.in
3050 --- linux-2.4.22.org/arch/s390x/config.in       2003-11-22 22:12:38.000000000 +0100
3051 +++ linux-2.4.22/arch/s390x/config.in   2003-11-22 22:14:06.000000000 +0100
3052 @@ -91,3 +91,11 @@
3053  
3054  source crypto/Config.in
3055  source lib/Config.in
3056 +
3057 +mainmenu_option next_comment
3058 +comment 'Grsecurity'
3059 +bool 'Grsecurity' CONFIG_GRKERNSEC
3060 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3061 +       source grsecurity/Config.in
3062 +fi
3063 +endmenu
3064 diff -urN linux-2.4.22.org/arch/sh/config.in linux-2.4.22/arch/sh/config.in
3065 --- linux-2.4.22.org/arch/sh/config.in  2003-11-22 22:12:27.000000000 +0100
3066 +++ linux-2.4.22/arch/sh/config.in      2003-11-22 22:14:06.000000000 +0100
3067 @@ -491,3 +491,11 @@
3068  
3069  source crypto/Config.in
3070  source lib/Config.in
3071 +
3072 +mainmenu_option next_comment
3073 +comment 'Grsecurity'
3074 +bool 'Grsecurity' CONFIG_GRKERNSEC
3075 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3076 +       source grsecurity/Config.in
3077 +fi
3078 +endmenu
3079 diff -urN linux-2.4.22.org/arch/sparc/boot/Makefile linux-2.4.22/arch/sparc/boot/Makefile
3080 --- linux-2.4.22.org/arch/sparc/boot/Makefile   2003-11-22 22:11:57.000000000 +0100
3081 +++ linux-2.4.22/arch/sparc/boot/Makefile       2003-11-22 22:14:06.000000000 +0100
3082 @@ -24,7 +24,7 @@
3083  
3084  BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o
3085  BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
3086 -       $(DRIVERS) $(NETWORKS)
3087 +       $(DRIVERS) $(NETWORKS) $(GRSECURITY)
3088  
3089  # I wanted to make this depend upon BTOBJS so that a parallel
3090  # build would work, but this fails because $(HEAD) cannot work
3091 diff -urN linux-2.4.22.org/arch/sparc/config.in linux-2.4.22/arch/sparc/config.in
3092 --- linux-2.4.22.org/arch/sparc/config.in       2003-11-22 22:11:57.000000000 +0100
3093 +++ linux-2.4.22/arch/sparc/config.in   2003-11-22 22:14:06.000000000 +0100
3094 @@ -283,3 +283,11 @@
3095  
3096  source crypto/Config.in
3097  source lib/Config.in
3098 +
3099 +mainmenu_option next_comment
3100 +comment 'Grsecurity'
3101 +bool 'Grsecurity' CONFIG_GRKERNSEC
3102 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3103 +       source grsecurity/Config.in
3104 +fi
3105 +endmenu
3106 diff -urN linux-2.4.22.org/arch/sparc/kernel/ptrace.c linux-2.4.22/arch/sparc/kernel/ptrace.c
3107 --- linux-2.4.22.org/arch/sparc/kernel/ptrace.c 2003-11-22 22:11:59.000000000 +0100
3108 +++ linux-2.4.22/arch/sparc/kernel/ptrace.c     2003-11-22 22:14:06.000000000 +0100
3109 @@ -17,6 +17,7 @@
3110  #include <linux/user.h>
3111  #include <linux/smp.h>
3112  #include <linux/smp_lock.h>
3113 +#include <linux/grsecurity.h>
3114  
3115  #include <asm/pgtable.h>
3116  #include <asm/system.h>
3117 @@ -310,6 +311,9 @@
3118                 goto out;
3119         }
3120  
3121 +       if(gr_handle_ptrace(child, request))
3122 +               goto out_tsk;
3123 +
3124         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3125             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3126                 if (ptrace_attach(child)) {
3127 diff -urN linux-2.4.22.org/arch/sparc/kernel/sys_sparc.c linux-2.4.22/arch/sparc/kernel/sys_sparc.c
3128 --- linux-2.4.22.org/arch/sparc/kernel/sys_sparc.c      2003-11-22 22:12:00.000000000 +0100
3129 +++ linux-2.4.22/arch/sparc/kernel/sys_sparc.c  2003-11-22 22:14:06.000000000 +0100
3130 @@ -20,6 +20,7 @@
3131  #include <linux/utsname.h>
3132  #include <linux/smp.h>
3133  #include <linux/smp_lock.h>
3134 +#include <linux/grsecurity.h>
3135  
3136  #include <asm/uaccess.h>
3137  #include <asm/ipc.h>
3138 @@ -54,6 +55,13 @@
3139                 return -ENOMEM;
3140         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
3141                 return -ENOMEM;
3142 +
3143 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3144 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3145 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3146 +       else
3147 +#endif
3148 +
3149         if (!addr)
3150                 addr = TASK_UNMAPPED_BASE;
3151  
3152 @@ -225,6 +233,11 @@
3153         struct file * file = NULL;
3154         unsigned long retval = -EBADF;
3155  
3156 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3157 +       if (flags & MAP_MIRROR)
3158 +               return -EINVAL;
3159 +#endif
3160 +
3161         if (!(flags & MAP_ANONYMOUS)) {
3162                 file = fget(fd);
3163                 if (!file)
3164 @@ -243,6 +256,12 @@
3165         if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
3166                 goto out_putf;
3167  
3168 +       if (gr_handle_mmap(file, prot)) {
3169 +               fput(file);
3170 +               retval = -EACCES;
3171 +               goto out;
3172 +       }
3173 +
3174         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3175  
3176         down_write(&current->mm->mmap_sem);
3177 diff -urN linux-2.4.22.org/arch/sparc/kernel/sys_sunos.c linux-2.4.22/arch/sparc/kernel/sys_sunos.c
3178 --- linux-2.4.22.org/arch/sparc/kernel/sys_sunos.c      2003-11-22 22:11:59.000000000 +0100
3179 +++ linux-2.4.22/arch/sparc/kernel/sys_sunos.c  2003-11-22 22:14:06.000000000 +0100
3180 @@ -68,6 +68,11 @@
3181         struct file * file = NULL;
3182         unsigned long retval, ret_type;
3183  
3184 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3185 +       if (flags & MAP_MIRROR)
3186 +               return -EINVAL;
3187 +#endif
3188 +
3189         if(flags & MAP_NORESERVE) {
3190                 static int cnt;
3191                 if (cnt++ < 10)
3192 diff -urN linux-2.4.22.org/arch/sparc/mm/fault.c linux-2.4.22/arch/sparc/mm/fault.c
3193 --- linux-2.4.22.org/arch/sparc/mm/fault.c      2003-11-22 22:12:00.000000000 +0100
3194 +++ linux-2.4.22/arch/sparc/mm/fault.c  2003-11-22 22:14:06.000000000 +0100
3195 @@ -19,6 +19,9 @@
3196  #include <linux/smp.h>
3197  #include <linux/smp_lock.h>
3198  #include <linux/interrupt.h>
3199 +#include <linux/slab.h>
3200 +#include <linux/pagemap.h>
3201 +#include <linux/compiler.h>
3202  
3203  #include <asm/system.h>
3204  #include <asm/segment.h>
3205 @@ -200,6 +203,261 @@
3206         return 0;
3207  }
3208  
3209 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3210 +void pax_emuplt_close(struct vm_area_struct * vma)
3211 +{
3212 +       vma->vm_mm->call_dl_resolve = 0UL;
3213 +}
3214 +
3215 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
3216 +{
3217 +       struct page* page;
3218 +       unsigned int *kaddr;
3219 +
3220 +       page = alloc_page(GFP_HIGHUSER);
3221 +       if (!page)
3222 +               return page;
3223 +
3224 +       kaddr = kmap(page);
3225 +       memset(kaddr, 0, PAGE_SIZE);
3226 +       kaddr[0] = 0x9DE3BFA8U; /* save */
3227 +       flush_dcache_page(page);
3228 +       kunmap(page);
3229 +       return page;
3230 +}
3231 +
3232 +static struct vm_operations_struct pax_vm_ops = {
3233 +       close:          pax_emuplt_close,
3234 +       nopage:         pax_emuplt_nopage,
3235 +};
3236 +
3237 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3238 +{
3239 +       vma->vm_mm = current->mm;
3240 +       vma->vm_start = addr;
3241 +       vma->vm_end = addr + PAGE_SIZE;
3242 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3243 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3244 +       vma->vm_ops = &pax_vm_ops;
3245 +       vma->vm_pgoff = 0UL;
3246 +       vma->vm_file = NULL;
3247 +       vma->vm_private_data = NULL;
3248 +       insert_vm_struct(current->mm, vma);
3249 +       ++current->mm->total_vm;
3250 +}
3251 +
3252 +/*
3253 + * PaX: decide what to do with offenders (regs->pc = fault address)
3254 + *
3255 + * returns 1 when task should be killed
3256 + *         2 when patched PLT trampoline was detected
3257 + *         3 when unpatched PLT trampoline was detected
3258 + *        4 when legitimate ET_EXEC was detected
3259 + */
3260 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3261 +{
3262 +       int err;
3263 +
3264 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3265 +       if (current->flags & PF_PAX_RANDEXEC) {
3266 +               if (regs->pc >= current->mm->start_code &&
3267 +                   regs->pc < current->mm->end_code)
3268 +               {
3269 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
3270 +                               return 1;
3271 +
3272 +                       regs->pc += current->mm->delta_exec;
3273 +                       if (regs->npc >= current->mm->start_code &&
3274 +                           regs->npc < current->mm->end_code)
3275 +                               regs->npc += current->mm->delta_exec;
3276 +                       return 4;
3277 +               }
3278 +               if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
3279 +                   regs->pc < current->mm->end_code + current->mm->delta_exec)
3280 +               {
3281 +                       regs->pc -= current->mm->delta_exec;
3282 +                       if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
3283 +                           regs->npc < current->mm->end_code + current->mm->delta_exec)
3284 +                               regs->npc -= current->mm->delta_exec;
3285 +               }
3286 +       }
3287 +#endif
3288 +
3289 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3290 +       do { /* PaX: patched PLT emulation #1 */
3291 +               unsigned int sethi1, sethi2, jmpl;
3292 +
3293 +               err = get_user(sethi1, (unsigned int *)regs->pc);
3294 +               err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
3295 +               err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
3296 +
3297 +               if (err)
3298 +                       break;
3299 +
3300 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3301 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
3302 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
3303 +               {
3304 +                       unsigned int addr;
3305 +
3306 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3307 +                       addr = regs->u_regs[UREG_G1];
3308 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3309 +                       regs->pc = addr;
3310 +                       regs->npc = addr+4;
3311 +                       return 2;
3312 +               }
3313 +       } while (0);
3314 +
3315 +       { /* PaX: patched PLT emulation #2 */
3316 +               unsigned int ba;
3317 +
3318 +               err = get_user(ba, (unsigned int *)regs->pc);
3319 +
3320 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3321 +                       unsigned int addr;
3322 +
3323 +                       addr = regs->pc + 4 + (((ba | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3324 +                       regs->pc = addr;
3325 +                       regs->npc = addr+4;
3326 +                       return 2;
3327 +               }
3328 +       }
3329 +
3330 +       do { /* PaX: patched PLT emulation #3 */
3331 +               unsigned int sethi, jmpl, nop;
3332 +
3333 +               err = get_user(sethi, (unsigned int*)regs->pc);
3334 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
3335 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
3336 +
3337 +               if (err)
3338 +                       break;
3339 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3340 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3341 +                   nop == 0x01000000U)
3342 +               {
3343 +                       unsigned int addr;
3344 +
3345 +                       addr = (sethi & 0x003FFFFFU) << 10;
3346 +                       regs->u_regs[UREG_G1] = addr;
3347 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3348 +                       regs->pc = addr;
3349 +                       regs->npc = addr+4;
3350 +                       return 2;
3351 +               }
3352 +       } while (0);
3353 +
3354 +       do { /* PaX: unpatched PLT emulation step 1 */
3355 +               unsigned int sethi, ba, nop;
3356 +
3357 +               err = get_user(sethi, (unsigned int *)regs->pc);
3358 +               err |= get_user(ba, (unsigned int *)(regs->pc+4));
3359 +               err |= get_user(nop, (unsigned int *)(regs->pc+8));
3360 +
3361 +               if (err)
3362 +                       break;
3363 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3364 +                   (ba & 0xFFC00000U) == 0x30800000U &&
3365 +                   nop == 0x01000000U)
3366 +               {
3367 +                       unsigned int addr, save, call;
3368 +
3369 +                       addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3370 +
3371 +                       err = get_user(save, (unsigned int *)addr);
3372 +                       err |= get_user(call, (unsigned int *)(addr+4));
3373 +                       err |= get_user(nop, (unsigned int *)(addr+8)); 
3374 +                       if (err)
3375 +                               break;
3376 +
3377 +                       if (save == 0x9DE3BFA8U &&
3378 +                           (call & 0xC0000000U) == 0x40000000U &&
3379 +                           nop == 0x01000000U)
3380 +                       {
3381 +                               struct vm_area_struct *vma;
3382 +                               unsigned long call_dl_resolve;
3383 +
3384 +                               down_read(&current->mm->mmap_sem);
3385 +                               call_dl_resolve = current->mm->call_dl_resolve;
3386 +                               up_read(&current->mm->mmap_sem);
3387 +                               if (likely(call_dl_resolve))
3388 +                                       goto emulate;
3389 +
3390 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3391 +
3392 +                               down_write(&current->mm->mmap_sem);
3393 +                               if (current->mm->call_dl_resolve) {
3394 +                                       call_dl_resolve = current->mm->call_dl_resolve;
3395 +                                       up_write(&current->mm->mmap_sem);
3396 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3397 +                                       goto emulate;
3398 +                               }
3399 +
3400 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3401 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3402 +                                       up_write(&current->mm->mmap_sem);
3403 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3404 +                                       return 1;
3405 +                               }
3406 +
3407 +                               pax_insert_vma(vma, call_dl_resolve);
3408 +                               current->mm->call_dl_resolve = call_dl_resolve;
3409 +                               up_write(&current->mm->mmap_sem);
3410 +
3411 +emulate:
3412 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3413 +                               regs->pc = call_dl_resolve;
3414 +                               regs->npc = addr+4;
3415 +                               return 3;
3416 +                       }
3417 +               }
3418 +       } while (0);
3419 +
3420 +       do { /* PaX: unpatched PLT emulation step 2 */
3421 +               unsigned int save, call, nop;
3422 +
3423 +               err = get_user(save, (unsigned int*)(regs->pc-4));
3424 +               err |= get_user(call, (unsigned int*)regs->pc);
3425 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
3426 +               if (err)
3427 +                       break;
3428 +
3429 +               if (save == 0x9DE3BFA8U &&
3430 +                   (call & 0xC0000000U) == 0x40000000U &&
3431 +                   nop == 0x01000000U)
3432 +               {
3433 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
3434 +
3435 +                       regs->u_regs[UREG_RETPC] = regs->pc;
3436 +                       regs->pc = dl_resolve;
3437 +                       regs->npc = dl_resolve+4;
3438 +                       return 3;
3439 +               }
3440 +       } while (0);
3441 +
3442 +#endif
3443 +
3444 +       return 1;
3445 +}
3446 +
3447 +void pax_report_insns(void *pc)
3448 +{
3449 +       unsigned long i;
3450 +
3451 +       printk(KERN_ERR "PAX: bytes at PC: ");
3452 +       for (i = 0; i < 5; i++) {
3453 +               unsigned int c;
3454 +               if (get_user(c, (unsigned int*)pc+i)) {
3455 +                       printk("<invalid address>.");
3456 +                       break;
3457 +               }
3458 +               printk("%08x ", c);
3459 +       }
3460 +       printk("\n");
3461 +}
3462 +#endif
3463 +
3464  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
3465                                unsigned long address)
3466  {
3467 @@ -263,6 +521,29 @@
3468                 if(!(vma->vm_flags & VM_WRITE))
3469                         goto bad_area;
3470         } else {
3471 +
3472 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3473 +               if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
3474 +                       up_read(&mm->mmap_sem);
3475 +                       switch (pax_handle_fetch_fault(regs)) {
3476 +
3477 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3478 +                       case 2:
3479 +                       case 3:
3480 +                               return;
3481 +#endif
3482 +
3483 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3484 +                       case 4:
3485 +                               return;
3486 +#endif
3487 +
3488 +                       }
3489 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
3490 +                       do_exit(SIGKILL);
3491 +               }
3492 +#endif
3493 +
3494                 /* Allow reads even for write-only mappings */
3495                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
3496                         goto bad_area;
3497 diff -urN linux-2.4.22.org/arch/sparc/mm/init.c linux-2.4.22/arch/sparc/mm/init.c
3498 --- linux-2.4.22.org/arch/sparc/mm/init.c       2003-11-22 22:12:00.000000000 +0100
3499 +++ linux-2.4.22/arch/sparc/mm/init.c   2003-11-22 22:14:06.000000000 +0100
3500 @@ -350,17 +350,17 @@
3501  
3502         /* Initialize the protection map with non-constant, MMU dependent values. */
3503         protection_map[0] = PAGE_NONE;
3504 -       protection_map[1] = PAGE_READONLY;
3505 -       protection_map[2] = PAGE_COPY;
3506 -       protection_map[3] = PAGE_COPY;
3507 +       protection_map[1] = PAGE_READONLY_NOEXEC;
3508 +       protection_map[2] = PAGE_COPY_NOEXEC;
3509 +       protection_map[3] = PAGE_COPY_NOEXEC;
3510         protection_map[4] = PAGE_READONLY;
3511         protection_map[5] = PAGE_READONLY;
3512         protection_map[6] = PAGE_COPY;
3513         protection_map[7] = PAGE_COPY;
3514         protection_map[8] = PAGE_NONE;
3515 -       protection_map[9] = PAGE_READONLY;
3516 -       protection_map[10] = PAGE_SHARED;
3517 -       protection_map[11] = PAGE_SHARED;
3518 +       protection_map[9] = PAGE_READONLY_NOEXEC;
3519 +       protection_map[10] = PAGE_SHARED_NOEXEC;
3520 +       protection_map[11] = PAGE_SHARED_NOEXEC;
3521         protection_map[12] = PAGE_READONLY;
3522         protection_map[13] = PAGE_READONLY;
3523         protection_map[14] = PAGE_SHARED;
3524 diff -urN linux-2.4.22.org/arch/sparc/mm/srmmu.c linux-2.4.22/arch/sparc/mm/srmmu.c
3525 --- linux-2.4.22.org/arch/sparc/mm/srmmu.c      2003-11-22 22:12:00.000000000 +0100
3526 +++ linux-2.4.22/arch/sparc/mm/srmmu.c  2003-11-22 22:14:07.000000000 +0100
3527 @@ -2047,6 +2047,13 @@
3528         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
3529         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
3530         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
3531 +
3532 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3533 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
3534 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
3535 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
3536 +#endif
3537 +
3538         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
3539         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
3540         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
3541 diff -urN linux-2.4.22.org/arch/sparc64/config.in linux-2.4.22/arch/sparc64/config.in
3542 --- linux-2.4.22.org/arch/sparc64/config.in     2003-11-22 22:12:20.000000000 +0100
3543 +++ linux-2.4.22/arch/sparc64/config.in 2003-11-22 22:14:07.000000000 +0100
3544 @@ -318,3 +318,11 @@
3545  
3546  source crypto/Config.in
3547  source lib/Config.in
3548 +
3549 +mainmenu_option next_comment
3550 +comment 'Grsecurity'
3551 +bool 'Grsecurity' CONFIG_GRKERNSEC
3552 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3553 +       source grsecurity/Config.in
3554 +fi
3555 +endmenu
3556 diff -urN linux-2.4.22.org/arch/sparc64/kernel/ioctl32.c linux-2.4.22/arch/sparc64/kernel/ioctl32.c
3557 --- linux-2.4.22.org/arch/sparc64/kernel/ioctl32.c      2003-11-22 22:12:18.000000000 +0100
3558 +++ linux-2.4.22/arch/sparc64/kernel/ioctl32.c  2003-11-22 22:14:07.000000000 +0100
3559 @@ -2047,7 +2047,11 @@
3560          * To have permissions to do most of the vt ioctls, we either have
3561          * to be the owner of the tty, or super-user.
3562          */
3563 +#ifdef CONFIG_GRKERNSEC
3564 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3565 +#else
3566         if (current->tty == tty || suser())
3567 +#endif
3568                 return 1;
3569         return 0;                                                    
3570  }
3571 diff -urN linux-2.4.22.org/arch/sparc64/kernel/itlb_base.S linux-2.4.22/arch/sparc64/kernel/itlb_base.S
3572 --- linux-2.4.22.org/arch/sparc64/kernel/itlb_base.S    2003-11-22 22:12:19.000000000 +0100
3573 +++ linux-2.4.22/arch/sparc64/kernel/itlb_base.S        2003-11-22 22:14:07.000000000 +0100
3574 @@ -41,7 +41,9 @@
3575         CREATE_VPTE_OFFSET2(%g4, %g6)                   ! Create VPTE offset
3576         ldxa            [%g3 + %g6] ASI_P, %g5          ! Load VPTE
3577  1:     brgez,pn        %g5, 3f                         ! Not valid, branch out
3578 -        nop                                            ! Delay-slot
3579 +       and             %g5, _PAGE_EXEC, %g4
3580 +       brz,pn          %g4, 3f                         ! Not executable, branch out
3581 +       nop                                             ! Delay-slot
3582  2:     stxa            %g5, [%g0] ASI_ITLB_DATA_IN     ! Load PTE into TLB
3583         retry                                           ! Trap return
3584  3:     rdpr            %pstate, %g4                    ! Move into alternate globals
3585 @@ -74,8 +76,6 @@
3586         nop
3587         nop
3588         nop
3589 -       nop
3590 -       nop
3591         CREATE_VPTE_NOP
3592  
3593  #undef CREATE_VPTE_OFFSET1
3594 diff -urN linux-2.4.22.org/arch/sparc64/kernel/ptrace.c linux-2.4.22/arch/sparc64/kernel/ptrace.c
3595 --- linux-2.4.22.org/arch/sparc64/kernel/ptrace.c       2003-11-22 22:12:19.000000000 +0100
3596 +++ linux-2.4.22/arch/sparc64/kernel/ptrace.c   2003-11-22 22:14:07.000000000 +0100
3597 @@ -18,6 +18,7 @@
3598  #include <linux/user.h>
3599  #include <linux/smp.h>
3600  #include <linux/smp_lock.h>
3601 +#include <linux/grsecurity.h>
3602  
3603  #include <asm/asi.h>
3604  #include <asm/pgtable.h>
3605 @@ -161,6 +162,11 @@
3606                 goto out;
3607         }
3608  
3609 +       if (gr_handle_ptrace(child, (long)request)) {
3610 +               pt_error_return(regs, EPERM);
3611 +               goto out;
3612 +       }
3613 +
3614         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3615             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3616                 if (ptrace_attach(child)) {
3617 diff -urN linux-2.4.22.org/arch/sparc64/kernel/sys_sparc32.c linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c
3618 --- linux-2.4.22.org/arch/sparc64/kernel/sys_sparc32.c  2003-11-22 22:12:19.000000000 +0100
3619 +++ linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c      2003-11-22 22:14:07.000000000 +0100
3620 @@ -52,6 +52,8 @@
3621  #include <linux/sysctl.h>
3622  #include <linux/dnotify.h>
3623  #include <linux/netfilter_ipv4/ip_tables.h>
3624 +#include <linux/random.h>
3625 +#include <linux/grsecurity.h>
3626  
3627  #include <asm/types.h>
3628  #include <asm/ipc.h>
3629 @@ -3235,8 +3237,18 @@
3630         struct file * file;
3631         int retval;
3632         int i;
3633 +#ifdef CONFIG_GRKERNSEC
3634 +       struct file *old_exec_file;
3635 +       struct acl_subject_label *old_acl;
3636 +       struct rlimit old_rlim[RLIM_NLIMITS];
3637 +#endif
3638  
3639         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3640 +
3641 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
3642 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
3643 +#endif
3644 +
3645         memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3646  
3647         file = open_exec(filename);
3648 @@ -3245,6 +3257,20 @@
3649         if (IS_ERR(file))
3650                 return retval;
3651  
3652 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
3653 +
3654 +       if (gr_handle_nproc()) {
3655 +               allow_write_access(file);
3656 +               fput(file);
3657 +               return -EAGAIN;
3658 +       }
3659 +
3660 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
3661 +               allow_write_access(file);
3662 +               fput(file);
3663 +               return -EACCES;
3664 +       }
3665 +
3666         bprm.file = file;
3667         bprm.filename = filename;
3668         bprm.sh_bang = 0;
3669 @@ -3265,11 +3291,24 @@
3670         if (retval < 0)
3671                 goto out;
3672         
3673 +       if(!gr_tpe_allow(file)) {
3674 +               retval = -EACCES;
3675 +               goto out;
3676 +       }
3677 +
3678 +       if (gr_check_crash_exec(file)) {
3679 +               retval = -EACCES;
3680 +               goto out;
3681 +       }
3682 +
3683         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3684         if (retval < 0)
3685                 goto out;
3686  
3687         bprm.exec = bprm.p;
3688 +
3689 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
3690 +
3691         retval = copy_strings32(bprm.envc, envp, &bprm);
3692         if (retval < 0)
3693                 goto out;
3694 @@ -3278,11 +3317,32 @@
3695         if (retval < 0)
3696                 goto out;
3697  
3698 +#ifdef CONFIG_GRKERNSEC
3699 +       old_acl = current->acl;
3700 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
3701 +       old_exec_file = current->exec_file;
3702 +       get_file(file);
3703 +       current->exec_file = file;
3704 +#endif
3705 +
3706 +        gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
3707 +
3708         retval = search_binary_handler(&bprm, regs);
3709 -       if (retval >= 0)
3710 +       if (retval >= 0) {
3711 +#ifdef CONFIG_GRKERNSEC
3712 +               if (old_exec_file)
3713 +                       fput(old_exec_file);
3714 +#endif
3715                 /* execve success */
3716                 return retval;
3717 +       }
3718  
3719 +#ifdef CONFIG_GRKERNSEC
3720 +       current->acl = old_acl;
3721 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
3722 +       fput(current->exec_file);
3723 +       current->exec_file = old_exec_file;
3724 +#endif
3725  out:
3726         /* Something went wrong, return the inode and free the argument pages*/
3727         allow_write_access(bprm.file);
3728 diff -urN linux-2.4.22.org/arch/sparc64/kernel/sys_sparc.c linux-2.4.22/arch/sparc64/kernel/sys_sparc.c
3729 --- linux-2.4.22.org/arch/sparc64/kernel/sys_sparc.c    2003-11-22 22:12:18.000000000 +0100
3730 +++ linux-2.4.22/arch/sparc64/kernel/sys_sparc.c        2003-11-22 22:14:07.000000000 +0100
3731 @@ -24,6 +24,7 @@
3732  #include <linux/slab.h>
3733  #include <linux/ipc.h>
3734  #include <linux/personality.h>
3735 +#include <linux/grsecurity.h>
3736  
3737  #include <asm/uaccess.h>
3738  #include <asm/ipc.h>
3739 @@ -63,6 +64,13 @@
3740                 task_size = 0xf0000000UL;
3741         if (len > task_size || len > -PAGE_OFFSET)
3742                 return -ENOMEM;
3743 +
3744 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3745 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3746 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3747 +       else
3748 +#endif
3749 +
3750         if (!addr)
3751                 addr = TASK_UNMAPPED_BASE;
3752  
3753 @@ -289,11 +297,22 @@
3754         struct file * file = NULL;
3755         unsigned long retval = -EBADF;
3756  
3757 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3758 +       if (flags & MAP_MIRROR)
3759 +               return -EINVAL;
3760 +#endif
3761 +
3762         if (!(flags & MAP_ANONYMOUS)) {
3763                 file = fget(fd);
3764                 if (!file)
3765                         goto out;
3766         }
3767 +
3768 +       if (gr_handle_mmap(file, prot)) {
3769 +               retval = -EACCES;
3770 +               goto out_putf;
3771 +       }
3772 +
3773         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3774         len = PAGE_ALIGN(len);
3775         retval = -EINVAL;
3776 diff -urN linux-2.4.22.org/arch/sparc64/kernel/sys_sunos32.c linux-2.4.22/arch/sparc64/kernel/sys_sunos32.c
3777 --- linux-2.4.22.org/arch/sparc64/kernel/sys_sunos32.c  2003-11-22 22:12:19.000000000 +0100
3778 +++ linux-2.4.22/arch/sparc64/kernel/sys_sunos32.c      2003-11-22 22:14:07.000000000 +0100
3779 @@ -68,6 +68,11 @@
3780         struct file *file = NULL;
3781         unsigned long retval, ret_type;
3782  
3783 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3784 +       if (flags & MAP_MIRROR)
3785 +               return -EINVAL;
3786 +#endif
3787 +
3788         if(flags & MAP_NORESERVE) {
3789                 static int cnt;
3790                 if (cnt++ < 10)
3791 diff -urN linux-2.4.22.org/arch/sparc64/mm/fault.c linux-2.4.22/arch/sparc64/mm/fault.c
3792 --- linux-2.4.22.org/arch/sparc64/mm/fault.c    2003-11-22 22:12:19.000000000 +0100
3793 +++ linux-2.4.22/arch/sparc64/mm/fault.c        2003-11-22 22:14:07.000000000 +0100
3794 @@ -16,6 +16,9 @@
3795  #include <linux/smp_lock.h>
3796  #include <linux/init.h>
3797  #include <linux/interrupt.h>
3798 +#include <linux/slab.h>
3799 +#include <linux/pagemap.h>
3800 +#include <linux/compiler.h>
3801  
3802  #include <asm/page.h>
3803  #include <asm/pgtable.h>
3804 @@ -299,6 +302,267 @@
3805         unhandled_fault (address, current, regs);
3806  }
3807  
3808 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3809 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3810 +static void pax_emuplt_close(struct vm_area_struct * vma)
3811 +{
3812 +       vma->vm_mm->call_dl_resolve = 0UL;
3813 +}
3814 +
3815 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
3816 +{
3817 +       struct page* page;
3818 +       unsigned int *kaddr;
3819 +
3820 +       page = alloc_page(GFP_HIGHUSER);
3821 +       if (!page)
3822 +               return page;
3823 +
3824 +       kaddr = kmap(page);
3825 +       memset(kaddr, 0, PAGE_SIZE);
3826 +       kaddr[0] = 0x9DE3BFA8U; /* save */
3827 +       flush_dcache_page(page);
3828 +       kunmap(page);
3829 +       return page;
3830 +}
3831 +
3832 +static struct vm_operations_struct pax_vm_ops = {
3833 +       close:          pax_emuplt_close,
3834 +       nopage:         pax_emuplt_nopage,
3835 +};
3836 +
3837 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3838 +{
3839 +       vma->vm_mm = current->mm;
3840 +       vma->vm_start = addr;
3841 +       vma->vm_end = addr + PAGE_SIZE;
3842 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3843 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3844 +       vma->vm_ops = &pax_vm_ops;
3845 +       vma->vm_pgoff = 0UL; 
3846 +       vma->vm_file = NULL;
3847 +       vma->vm_private_data = NULL;
3848 +       insert_vm_struct(current->mm, vma);
3849 +       ++current->mm->total_vm;
3850 +}
3851 +#endif
3852 +
3853 +/*
3854 + * PaX: decide what to do with offenders (regs->tpc = fault address)
3855 + *
3856 + * returns 1 when task should be killed
3857 + *         2 when patched PLT trampoline was detected
3858 + *         3 when unpatched PLT trampoline was detected
3859 + *        4 when legitimate ET_EXEC was detected
3860 + */
3861 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3862 +{
3863 +       int err;
3864 +
3865 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3866 +       if (current->flags & PF_PAX_RANDEXEC) {
3867 +               if (regs->tpc >= current->mm->start_code &&
3868 +                   regs->tpc < current->mm->end_code)
3869 +               {
3870 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
3871 +                               return 1;
3872 +
3873 +                       regs->tpc += current->mm->delta_exec;
3874 +                       if (regs->tnpc >= current->mm->start_code &&
3875 +                           regs->tnpc < current->mm->end_code)
3876 +                               regs->tnpc += current->mm->delta_exec;
3877 +                       return 4;
3878 +               }
3879 +               if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
3880 +                   regs->tpc < current->mm->end_code + current->mm->delta_exec)
3881 +               {
3882 +                       regs->tpc -= current->mm->delta_exec;
3883 +                       if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
3884 +                           regs->tnpc < current->mm->end_code + current->mm->delta_exec)
3885 +                               regs->tnpc -= current->mm->delta_exec;
3886 +               }
3887 +       }
3888 +#endif
3889 +
3890 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3891 +       do { /* PaX: patched PLT emulation #1 */
3892 +               unsigned int sethi1, sethi2, jmpl;
3893 +
3894 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
3895 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
3896 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
3897 +
3898 +               if (err)
3899 +                       break;
3900 +
3901 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3902 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
3903 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
3904 +               {
3905 +                       unsigned long addr;
3906 +
3907 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3908 +                       addr = regs->u_regs[UREG_G1];
3909 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3910 +                       regs->tpc = addr;
3911 +                       regs->tnpc = addr+4;
3912 +                       return 2;
3913 +               }
3914 +       } while (0);
3915 +
3916 +       { /* PaX: patched PLT emulation #2 */
3917 +               unsigned int ba;
3918 +
3919 +               err = get_user(ba, (unsigned int*)regs->tpc);
3920 +
3921 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3922 +                       unsigned long addr;
3923 +
3924 +                       addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3925 +                       regs->tpc = addr;
3926 +                       regs->tnpc = addr+4;
3927 +                       return 2;
3928 +               }
3929 +       }
3930 +
3931 +       do { /* PaX: patched PLT emulation #3 */
3932 +               unsigned int sethi, jmpl, nop;
3933 +
3934 +               err = get_user(sethi, (unsigned int*)regs->tpc);
3935 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
3936 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
3937 +
3938 +               if (err)
3939 +                       break;
3940 +
3941 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3942 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3943 +                   nop == 0x01000000U)
3944 +               {
3945 +                       unsigned long addr;
3946 +
3947 +                       addr = (sethi & 0x003FFFFFU) << 10;
3948 +                       regs->u_regs[UREG_G1] = addr;
3949 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3950 +                       regs->tpc = addr;
3951 +                       regs->tnpc = addr+4;
3952 +                       return 2;
3953 +               }
3954 +       } while (0);
3955 +
3956 +       do { /* PaX: unpatched PLT emulation step 1 */
3957 +               unsigned int sethi, ba, nop;
3958 +
3959 +               err = get_user(sethi, (unsigned int*)regs->tpc);
3960 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
3961 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
3962 +
3963 +               if (err)
3964 +                       break;
3965 +
3966 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3967 +                   (ba & 0xFFC00000U) == 0x30800000U &&
3968 +                   nop == 0x01000000U)
3969 +               {
3970 +                       unsigned long addr;
3971 +                       unsigned int save, call;
3972 +
3973 +                       addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
3974 +
3975 +                       err = get_user(save, (unsigned int*)addr);
3976 +                       err |= get_user(call, (unsigned int*)(addr+4));
3977 +                       err |= get_user(nop, (unsigned int*)(addr+8));
3978 +
3979 +                       if (err)
3980 +                               break;
3981 +
3982 +                       if (save == 0x9DE3BFA8U &&
3983 +                           (call & 0xC0000000U) == 0x40000000U &&
3984 +                           nop == 0x01000000U)
3985 +                       {
3986 +                               struct vm_area_struct *vma;
3987 +                               unsigned long call_dl_resolve;
3988 +
3989 +                               down_read(&current->mm->mmap_sem);
3990 +                               call_dl_resolve = current->mm->call_dl_resolve;
3991 +                               up_read(&current->mm->mmap_sem);
3992 +                               if (likely(call_dl_resolve))
3993 +                                       goto emulate;
3994 +
3995 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3996 +
3997 +                               down_write(&current->mm->mmap_sem);
3998 +                               if (current->mm->call_dl_resolve) {
3999 +                                       call_dl_resolve = current->mm->call_dl_resolve;
4000 +                                       up_write(&current->mm->mmap_sem);
4001 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4002 +                                       goto emulate;
4003 +                               }
4004 +
4005 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4006 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4007 +                                       up_write(&current->mm->mmap_sem);
4008 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4009 +                                       return 1;
4010 +                               }
4011 +
4012 +                               pax_insert_vma(vma, call_dl_resolve);
4013 +                               current->mm->call_dl_resolve = call_dl_resolve;
4014 +                               up_write(&current->mm->mmap_sem);
4015 +
4016 +emulate:
4017 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4018 +                               regs->tpc = call_dl_resolve;
4019 +                               regs->tnpc = addr+4;
4020 +                               return 3;
4021 +                       }
4022 +               }
4023 +       } while (0);
4024 +
4025 +       do { /* PaX: unpatched PLT emulation step 2 */
4026 +               unsigned int save, call, nop;
4027 +
4028 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
4029 +               err |= get_user(call, (unsigned int*)regs->tpc);
4030 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
4031 +               if (err)
4032 +                       break;
4033 +
4034 +               if (save == 0x9DE3BFA8U &&
4035 +                   (call & 0xC0000000U) == 0x40000000U &&
4036 +                   nop == 0x01000000U)
4037 +               {
4038 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4039 +
4040 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
4041 +                       regs->tpc = dl_resolve;
4042 +                       regs->tnpc = dl_resolve+4;
4043 +                       return 3;
4044 +               }
4045 +       } while (0);
4046 +#endif
4047 +
4048 +       return 1;
4049 +}
4050 +
4051 +void pax_report_insns(void *pc)
4052 +{
4053 +       unsigned long i;
4054 +
4055 +       printk(KERN_ERR "PAX: bytes at PC: ");
4056 +       for (i = 0; i < 5; i++) {
4057 +               unsigned int c;
4058 +               if (get_user(c, (unsigned int*)pc+i)) {
4059 +                       printk("<invalid address>.");
4060 +                       break;
4061 +               }
4062 +               printk("%08x ", c);
4063 +       }
4064 +       printk("\n");
4065 +}
4066 +#endif  
4067 +
4068 +
4069  asmlinkage void do_sparc64_fault(struct pt_regs *regs)
4070  {
4071         struct mm_struct *mm = current->mm;
4072 @@ -338,6 +602,7 @@
4073  
4074         if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
4075                 regs->tpc &= 0xffffffff;
4076 +               regs->tnpc &= 0xffffffff;
4077                 address &= 0xffffffff;
4078         }
4079  
4080 @@ -346,6 +611,34 @@
4081         if (!vma)
4082                 goto bad_area;
4083  
4084 +       /* PaX: detect ITLB misses on non-exec pages */
4085 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
4086 +       if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address && 
4087 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
4088 +       {
4089 +               if (address != regs->tpc)
4090 +                       goto good_area;
4091 +
4092 +               up_read(&mm->mmap_sem);
4093 +               switch (pax_handle_fetch_fault(regs)) {
4094 +
4095 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4096 +               case 2:
4097 +               case 3:
4098 +                       goto fault_done;
4099 +#endif
4100 +
4101 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4102 +               case 4:
4103 +                       goto fault_done;
4104 +#endif
4105 +
4106 +               }
4107 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
4108 +               do_exit(SIGKILL);
4109 +       }
4110 +#endif
4111 +
4112         /* Pure DTLB misses do not tell us whether the fault causing
4113          * load/store/atomic was a write or not, it only says that there
4114          * was no match.  So in such a case we (carefully) read the
4115 diff -urN linux-2.4.22.org/arch/sparc64/solaris/misc.c linux-2.4.22/arch/sparc64/solaris/misc.c
4116 --- linux-2.4.22.org/arch/sparc64/solaris/misc.c        2003-11-22 22:12:19.000000000 +0100
4117 +++ linux-2.4.22/arch/sparc64/solaris/misc.c    2003-11-22 22:14:07.000000000 +0100
4118 @@ -54,6 +54,11 @@
4119         struct file *file = NULL;
4120         unsigned long retval, ret_type;
4121  
4122 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4123 +       if (flags & MAP_MIRROR)
4124 +               return -EINVAL;
4125 +#endif
4126 +
4127         /* Do we need it here? */
4128         set_personality(PER_SVR4);
4129         if (flags & MAP_NORESERVE) {
4130 diff -urN linux-2.4.22.org/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c
4131 --- linux-2.4.22.org/arch/x86_64/ia32/ia32_ioctl.c      2003-11-22 22:11:53.000000000 +0100
4132 +++ linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c  2003-11-22 22:14:07.000000000 +0100
4133 @@ -1933,7 +1933,11 @@
4134          * To have permissions to do most of the vt ioctls, we either have
4135          * to be the owner of the tty, or super-user.
4136          */
4137 +#ifdef CONFIG_GRKERNSEC
4138 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
4139 +#else
4140         if (current->tty == tty || suser())
4141 +#endif
4142                 return 1;
4143         return 0;                                                    
4144  }
4145 diff -urN linux-2.4.22.org/Documentation/Configure.help linux-2.4.22/Documentation/Configure.help
4146 --- linux-2.4.22.org/Documentation/Configure.help       2003-11-22 22:12:56.000000000 +0100
4147 +++ linux-2.4.22/Documentation/Configure.help   2003-11-22 22:14:06.000000000 +0100
4148 @@ -2993,6 +2993,20 @@
4149    If you want to compile it as a module, say M here and read
4150    Documentation/modules.txt.  If unsure, say `N'.
4151  
4152 +stealth networking support
4153 +CONFIG_IP_NF_MATCH_STEALTH
4154 +  Enabling this option will drop all syn packets coming to unserved tcp
4155 +  ports as well as all packets coming to unserved udp ports.  If you
4156 +  are using your system to route any type of packets (ie. via NAT)
4157 +  you should put this module at the end of your ruleset, since it will 
4158 +  drop packets that aren't going to ports that are listening on your 
4159 +  machine itself, it doesn't take into account that the packet might be 
4160 +  destined for someone on your internal network if you're using NAT for 
4161 +  instance.
4162 +
4163 +  If you want to compile it as a module, say M here and read
4164 +  Documentation/modules.txt.  If unsure, say `N'.
4165 +
4166  MAC address match support
4167  CONFIG_IP_NF_MATCH_MAC
4168    MAC matching allows you to match packets based on the source
4169 @@ -24221,6 +24235,871 @@
4170  
4171    "Area6" will work for most boards. For ADX, select "Area5".
4172  
4173 +Grsecurity
4174 +CONFIG_GRKERNSEC
4175 +  If you say Y here, you will be able to configure many features that
4176 +  will enhance the security of your system.  It is highly recommended
4177 +  that you say Y here and read through the help for each option so
4178 +  you fully understand the features and can evaluate their usefulness
4179 +  for your machine.
4180 +
4181 +Additional security levels
4182 +CONFIG_GRKERNSEC_LOW
4183 +
4184 +  Low additional security
4185 +  -----------------------------------------------------------------------
4186 +  If you choose this option, several of the grsecurity options will
4187 +  be enabled that will give you greater protection against a number
4188 +  of attacks, while assuring that none of your software will have any 
4189 +  conflicts with the additional security measures.  If you run a lot of 
4190 +  unusual software, or you are having problems with the higher security 
4191 +  levels, you should say Y here.  With this option, the following features
4192 +  are enabled:
4193 +  
4194 +  linking restrictions
4195 +  fifo restrictions
4196 +  random pids
4197 +  enforcing nproc on execve()
4198 +  restricted dmesg
4199 +  random ip ids
4200 +  enforced chdir("/") on chroot
4201 +
4202 +  Medium additional security
4203 +  -----------------------------------------------------------------------
4204 +  If you say Y here, several features in addition to those included in the 
4205 +  low additional security level will be enabled.  These features provide
4206 +  even more security to your system, though in rare cases they may
4207 +  be incompatible with very old or poorly written software.  If you 
4208 +  enable this option, make sure that your auth service (identd) is 
4209 +  running as gid 10 (usually group wheel). With this option the following 
4210 +  features (in addition to those provided in the low additional security 
4211 +  level) will be enabled:
4212 +
4213 +  random tcp source ports
4214 +  altered ping ids
4215 +  failed fork logging
4216 +  time change logging
4217 +  signal logging
4218 +  deny mounts in chroot
4219 +  deny double chrooting
4220 +  deny sysctl writes in chroot
4221 +  deny mknod in chroot
4222 +  deny access to abstract AF_UNIX sockets out of chroot
4223 +  deny pivot_root in chroot
4224 +  denied writes of /dev/kmem, /dev/mem, and /dev/port
4225 +  /proc restrictions with special gid set to 10 (usually wheel)
4226 +  address space layout randomization
4227 +
4228 +  High additional security
4229 +  ----------------------------------------------------------------------
4230 +  If you say Y here, many of the features of grsecurity will be enabled,
4231 +  that will protect you against many kinds of attacks against
4232 +  your system.  The heightened security comes at a cost of an 
4233 +  increased chance of incompatibilities with rare software on your 
4234 +  machine.  It is highly recommended that you view 
4235 +  <http://grsecurity.net/features.htm> and read about each option.  Since 
4236 +  this security level enabled PaX, you should also view 
4237 +  <http://pageexec.virtualave.net> and read about the PaX project.  While 
4238 +  you are there, download chpax.c and run chpax -p on binaries that cause 
4239 +  problems with PaX.  Also remember that since the /proc restrictions are 
4240 +  enabled, you must run your identd as group wheel (gid 10).  
4241 +  This security level enables the following features in addition to those
4242 +  listed in the low and medium security levels:
4243 +
4244 +  additional /proc restrictions
4245 +  chmod restrictions in chroot
4246 +  no signals, ptrace, or viewing processes outside of chroot
4247 +  capability restrictions in chroot
4248 +  deny fchdir out of chroot
4249 +  priority restrictions in chroot
4250 +  segmentation-based implementation of PaX
4251 +  mprotect restrictions
4252 +  removal of /proc/<pid>/[maps|mem]
4253 +  kernel stack randomization
4254 +  mount/unmount/remount logging
4255 +  kernel symbol hiding
4256 +
4257 +Customized additional security
4258 +CONFIG_GRKERNSEC_CUSTOM
4259 +  If you say Y here, you will be able to configure every grsecurity 
4260 +  option, which allows you to enable many more features that aren't 
4261 +  covered in the basic security levels.  These additional features include 
4262 +  TPE, socket restrictions, and the sysctl system for grsecurity.  It is 
4263 +  advised that you read through the help for each option to determine its 
4264 +  usefulness in your situation.
4265 +
4266 +Enforce non-executable pages
4267 +CONFIG_GRKERNSEC_PAX_NOEXEC
4268 +  By design some architectures do not allow for protecting memory
4269 +  pages against execution or even if they do, Linux does not make
4270 +  use of this feature.  In practice this means that if a page is
4271 +  readable (such as the stack or heap) it is also executable.
4272 +
4273 +  There is a well known exploit technique that makes use of this
4274 +  fact and a common programming mistake where an attacker can
4275 +  introduce code of his choice somewhere in the attacked program's
4276 +  memory (typically the stack or the heap) and then execute it.
4277 +
4278 +  If the attacked program was running with different (typically
4279 +  higher) privileges than that of the attacker, then he can elevate
4280 +  his own privilege level (e.g. get a root shell, write to files for
4281 +  which he does not have write access to, etc).
4282 +
4283 +  Enabling this option will let you choose from various features
4284 +  that prevent the injection and execution of 'foreign' code in
4285 +  a program.
4286 +
4287 +  This will also break programs that rely on the old behaviour and
4288 +  expect that dynamically allocated memory via the malloc() family
4289 +  of functions is executable (which it is not).  Notable examples
4290 +  are the XFree86 4.x server, the java runtime and wine.
4291 +
4292 +  NOTE: you can use the 'chpax' utility to enable/disable this
4293 +  feature on a per file basis.  chpax is available at
4294 +  <http://pageexec.virtualave.net>
4295 +
4296 +Paging based non-executable pages
4297 +CONFIG_GRKERNSEC_PAX_PAGEEXEC
4298 +  This implementation is based on the paging feature of the CPU.
4299 +  On i386 it has a variable performance impact on applications
4300 +  depending on their memory usage pattern.  You should carefully
4301 +  test your applications before using this feature in production.
4302 +  On alpha, parisc, sparc and sparc64 there is no performance
4303 +  impact.  On ppc there is a slight performance impact.
4304 +
4305 +Segmentation based non-executable pages
4306 +CONFIG_GRKERNSEC_PAX_SEGMEXEC
4307 +  This implementation is based on the segmentation feature of the
4308 +  CPU and has little performance impact, however applications will
4309 +  be limited to a 1.5 GB address space instead of the normal 3 GB.
4310 +
4311 +Emulate trampolines
4312 +CONFIG_GRKERNSEC_PAX_EMUTRAMP
4313 +  There are some programs and libraries that for one reason or
4314 +  another attempt to execute special small code snippets from
4315 +  non-executable memory pages.  Most notable examples are the
4316 +  signal handler return code generated by the kernel itself and
4317 +  the GCC trampolines.
4318 +
4319 +  If you enabled CONFIG_GRKERNSEC_PAX_PAGEEXEC or 
4320 +  CONFIG_GRKERNSEC_PAX_SEGMEXEC then such programs will no longer
4321 +  work under your kernel.
4322 +
4323 +  As a remedy you can say Y here and use the 'chpax' utility to
4324 +  enable trampoline emulation for the affected programs yet still
4325 +  have the protection provided by the non-executable pages.
4326 +
4327 +  On parisc and ppc you MUST enable this option and EMUSIGRT as
4328 +  well, otherwise your system will not even boot.
4329 +
4330 +  Alternatively you can say N here and use the 'chpax' utility
4331 +  to disable CONFIG_GRKERNSEC_PAX_PAGEEXEC and 
4332 +  CONFIG_GRKERNSEC_PAX_SEGMEXEC for the affected files.
4333 +
4334 +  NOTE: enabling this feature *may* open up a loophole in the
4335 +  protection provided by non-executable pages that an attacker
4336 +  could abuse.  Therefore the best solution is to not have any
4337 +  files on your system that would require this option.  This can
4338 +  be achieved by not using libc5 (which relies on the kernel
4339 +  signal handler return code) and not using or rewriting programs
4340 +  that make use of the nested function implementation of GCC.
4341 +  Skilled users can just fix GCC itself so that it implements
4342 +  nested function calls in a way that does not interfere with PaX.
4343 +
4344 +Automatically emulate sigreturn trampolines
4345 +CONFIG_GRKERNSEC_PAX_EMUSIGRT
4346 +  Enabling this option will have the kernel automatically detect
4347 +  and emulate signal return trampolines executing on the stack
4348 +  that would otherwise lead to task termination.
4349 +
4350 +  This solution is intended as a temporary one for users with
4351 +  legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
4352 +  Modula-3 runtime, etc) or executables linked to such, basically
4353 +  everything that does not specify its own SA_RESTORER function in
4354 +  normal executable memory like glibc 2.1+ does.
4355 +
4356 +  On parisc and ppc you MUST enable this option, otherwise your
4357 +  system will not even boot.
4358 +
4359 +  NOTE: this feature cannot be disabled on a per executable basis
4360 +  and since it *does* open up a loophole in the protection provided
4361 +  by non-executable pages, the best solution is to not have any
4362 +  files on your system that would require this option.
4363 +
4364 +Restrict mprotect()
4365 +CONFIG_GRKERNSEC_PAX_MPROTECT
4366 +  Enabling this option will prevent programs from
4367 +   - changing the executable status of memory pages that were
4368 +     not originally created as executable,
4369 +   - making read-only executable pages writable again,
4370 +   - creating executable pages from anonymous memory.
4371 +
4372 +  You should say Y here to complete the protection provided by
4373 +  the enforcement of non-executable pages.
4374 +
4375 +  NOTE: you can use the 'chpax' utility to control this
4376 +  feature on a per file basis. chpax is available at
4377 +  <http://pageexec.virtualave.net>
4378 +
4379 +Disallow ELF text relocations
4380 +CONFIG_GRKERNSEC_PAX_NOELFRELOCS
4381 +  Non-executable pages and mprotect() restrictions are effective
4382 +  in preventing the introduction of new executable code into an
4383 +  attacked task's address space.  There remain only two venues
4384 +  for this kind of attack: if the attacker can execute already
4385 +  existing code in the attacked task then he can either have it
4386 +  create and mmap() a file containing his code or have it mmap()
4387 +  an already existing ELF library that does not have position
4388 +  independent code in it and use mprotect() on it to make it
4389 +  writable and copy his code there.  While protecting against
4390 +  the former approach is beyond PaX, the latter can be prevented
4391 +  by having only PIC ELF libraries on one's system (which do not
4392 +  need to relocate their code).  If you are sure this is your case,
4393 +  then enable this option otherwise be careful as you may not even
4394 +  be able to boot or log on your system (for example, some PAM
4395 +  modules are erroneously compiled as non-PIC by default).
4396 +
4397 +  NOTE: if you are using dynamic ELF executables (as suggested
4398 +  when using ASLR) then you must have made sure that you linked
4399 +  your files using the PIC version of crt1 (the et_dyn.zip package
4400 +  referenced there has already been updated to support this).
4401 +
4402 +Enforce non-executable kernel pages
4403 +CONFIG_GRKERNSEC_PAX_KERNEXEC
4404 +  This is the kernel land equivalent of PAGEEXEC and MPROTECT,
4405 +  that is, enabling this option will make it harder to inject
4406 +  and execute 'foreign' code in kernel memory itself.
4407 +
4408 +Address Space Layout Randomization
4409 +CONFIG_GRKERNSEC_PAX_ASLR
4410 +  Many if not most exploit techniques rely on the knowledge of
4411 +  certain addresses in the attacked program.  The following options
4412 +  will allow the kernel to apply a certain amount of randomization
4413 +  to specific parts of the program thereby forcing an attacker to
4414 +  guess them in most cases.  Any failed guess will most likely crash
4415 +  the attacked program which allows the kernel to detect such attempts
4416 +  and react on them.  PaX itself provides no reaction mechanisms,
4417 +  instead it is strongly encouraged that you make use of grsecurity's
4418 +  built-in crash detection features or develop one yourself.
4419 +
4420 +  By saying Y here you can choose to randomize the following areas:
4421 +   - top of the task's kernel stack
4422 +   - top of the task's userland stack
4423 +   - base address for mmap() requests that do not specify one
4424 +     (this includes all libraries)
4425 +   - base address of the main executable
4426 +
4427 +  It is strongly recommended to say Y here as address space layout
4428 +  randomization has negligible impact on performance yet it provides
4429 +  a very effective protection.
4430 +
4431 +  NOTE: you can use the 'chpax' utility to control most of these features
4432 +  on a per file basis.
4433 +
4434 +Randomize kernel stack base
4435 +CONFIG_GRKERNSEC_PAX_RANDKSTACK
4436 +  By saying Y here the kernel will randomize every task's kernel
4437 +  stack on every system call.  This will not only force an attacker
4438 +  to guess it but also prevent him from making use of possible
4439 +  leaked information about it.
4440 +
4441 +  Since the kernel stack is a rather scarce resource, randomization
4442 +  may cause unexpected stack overflows, therefore you should very
4443 +  carefully test your system.  Note that once enabled in the kernel
4444 +  configuration, this feature cannot be disabled on a per file basis.
4445 +
4446 +Randomize user stack base
4447 +CONFIG_GRKERNSEC_PAX_RANDUSTACK
4448 +  By saying Y here the kernel will randomize every task's userland
4449 +  stack.  The randomization is done in two steps where the second
4450 +  one may apply a big amount of shift to the top of the stack and
4451 +  cause problems for programs that want to use lots of memory (more
4452 +  than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
4453 +  For this reason the second step can be controlled by 'chpax' on
4454 +  a per file basis.
4455 +
4456 +Randomize ET_EXEC base
4457 +CONFIG_GRKERNSEC_PAX_RANDEXEC     
4458 +  By saying Y here the kernel will randomize the base address of normal
4459 +  ET_EXEC ELF executables as well.  This is accomplished by mapping the
4460 +  executable in memory in a special way which also allows for detecting
4461 +  attackers who attempt to execute its code for their purposes.  Since
4462 +  this special mapping causes performance degradation and the attack
4463 +  detection may create false alarms as well, you should carefully test
4464 +  your executables when this feature is enabled.
4465 +
4466 +  This solution is intended only as a temporary one until you relink
4467 +  your programs as a dynamic ELF file.
4468 +
4469 +  NOTE: you can use the 'chpax' utility to control this feature
4470 +  on a per file basis.
4471 +
4472 +Allow ELF ET_EXEC text relocations
4473 +CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
4474 +  On some architectures like the alpha there are incorrectly
4475 +  created applications that require text relocations and would
4476 +  not work without enabling this option.  If you are an alpha
4477 +  user, you should enable this option and disable it once you
4478 +  have made sure that none of your applications need it.
4479 +
4480 +Automatically emulate ELF PLT
4481 +CONFIG_GRKERNSEC_PAX_EMUPLT
4482 +  Enabling this option will have the kernel automatically detect
4483 +  and emulate the Procedure Linkage Table entries in ELF files.
4484 +  On some architectures such entries are in writable memory, and
4485 +  become non-executable leading to task termination.  Therefore
4486 +  it is mandatory that you enable this option on alpha, parisc, ppc,
4487 +  sparc and sparc64, otherwise your system would not even boot.
4488 +
4489 +  NOTE: this feature *does* open up a loophole in the protection
4490 +  provided by the non-executable pages, therefore the proper
4491 +  solution is to modify the toolchain to produce a PLT that does
4492 +  not need to be writable.
4493 +
4494 +
4495 +Randomize mmap() base
4496 +CONFIG_GRKERNSEC_PAX_RANDMMAP
4497 +  By saying Y here the kernel will use a randomized base address for
4498 +  mmap() requests that do not specify one themselves.  As a result
4499 +  all dynamically loaded libraries will appear at random addresses
4500 +  and therefore be harder to exploit by a technique where an attacker
4501 +  attempts to execute library code for his purposes (e.g. spawn a
4502 +  shell from an exploited program that is running at an elevated
4503 +  privilege level).
4504 +
4505 +  Furthermore, if a program is relinked as a dynamic ELF file, its
4506 +  base address will be randomized as well, completing the full
4507 +  randomization of the address space layout.  Attacking such programs
4508 +  becomes a guess game.  You can find an example of doing this at
4509 +  <http://pageexec.virtualave.net/et_dyn.zip> and practical samples at
4510 +  <http://www.grsecurity.net/grsec-gcc-specs.tar.gz> .
4511 +
4512 +  NOTE: you can use the 'chpax' utility to control this feature
4513 +  on a per file basis.
4514 +
4515 +Deny writing to /dev/kmem, /dev/mem, and /dev/port
4516 +CONFIG_GRKERNSEC_KMEM
4517 +  If you say Y here, /dev/kmem and /dev/mem won't be allowed to
4518 +  be written to via mmap or otherwise to modify the running kernel.
4519 +  /dev/port will also not be allowed to be opened. If you have module
4520 +  support disabled, enabling this will close up four ways that are
4521 +  currently used  to insert malicious code into the running kernel.
4522 +  Even with all these features enabled, we still highly recommend that
4523 +  you use the ACL system, as it is still possible for an attacker to 
4524 +  modify the running kernel through privileged I/O granted by ioperm/iopl.
4525 +  If you are not using XFree86, you may be able to stop this additional
4526 +  case by enabling the 'Disable privileged I/O' option. Though nothing
4527 +  legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
4528 +  but only to video memory, which is the only writing we allow in this
4529 +  case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
4530 +  not be allowed to mprotect it with PROT_WRITE later.
4531 +  Enabling this feature could make certain apps like VMWare stop working,
4532 +  as they need to write to other locations in /dev/mem.
4533 +  It is highly recommended that you say Y here if you meet all the 
4534 +  conditions above.
4535 +
4536 +Disable privileged I/O
4537 +CONFIG_GRKERNSEC_IO
4538 +  If you say Y here, all ioperm and iopl calls will return an error.
4539 +  Ioperm and iopl can be used to modify the running kernel.
4540 +  Unfortunately, some programs need this access to operate properly,
4541 +  the most notable of which are XFree86 and hwclock.  hwclock can be
4542 +  remedied by having RTC support in the kernel, so CONFIG_RTC is
4543 +  enabled if this option is enabled, to ensure that hwclock operates
4544 +  correctly.  XFree86 still will not operate correctly with this option
4545 +  enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
4546 +  and you still want to protect your kernel against modification,
4547 +  use the ACL system.
4548 +
4549 +Hide kernel symbols
4550 +CONFIG_GRKERNSEC_HIDESYM
4551 +  If you say Y here, getting information on loaded modules, and 
4552 +  displaying all kernel symbols through a syscall will be restricted
4553 +  to users with CAP_SYS_MODULE.  This option is only effective 
4554 +  provided the following conditions are met:
4555 +  1) The kernel using grsecurity is not precompiled by some distribution
4556 +  2) You are using the ACL system and hiding other files such as your
4557 +     kernel image and System.map
4558 +  3) You have the additional /proc restrictions enabled, which removes
4559 +     /proc/kcore
4560 +  If the above conditions are met, this option will aid to provide a
4561 +  useful protection against local and remote kernel exploitation of
4562 +  overflows and arbitrary read/write vulnerabilities.
4563 +
4564 +/proc/<pid>/ipaddr support
4565 +CONFIG_GRKERNSEC_PROC_IPADDR
4566 +  If you say Y here, a new entry will be added to each /proc/<pid>
4567 +  directory that contains the IP address of the person using the task.
4568 +  The IP is carried across local TCP and AF_UNIX stream sockets.
4569 +  This information can be useful for IDS/IPSes to perform remote response
4570 +  to a local attack.  The entry is readable by only the owner of the 
4571 +  process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
4572 +  the RBAC system), and thus does not create privacy concerns.
4573 +
4574 +Proc Restrictions
4575 +CONFIG_GRKERNSEC_PROC
4576 +  If you say Y here, the permissions of the /proc filesystem
4577 +  will be altered to enhance system security and privacy.  Depending
4578 +  upon the options you choose, you can either restrict users to see
4579 +  only the processes they themselves run, or choose a group that can
4580 +  view all processes and files normally restricted to root if you choose
4581 +  the "restrict to user only" option.  NOTE: If you're running identd as 
4582 +  a non-root user, you will have to run it as the group you specify here.
4583 +
4584 +Restrict /proc to user only
4585 +CONFIG_GRKERNSEC_PROC_USER
4586 +  If you say Y here, non-root users will only be able to view their own 
4587 +  processes, and restricts them from viewing network-related information,  
4588 +  and viewing kernel symbol and module information.
4589 +
4590 +Restrict /proc to user and group
4591 +CONFIG_GRKERNSEC_PROC_USERGROUP
4592 +  If you say Y here, you will be able to select a group that will be
4593 +  able to view all processes, network-related information, and
4594 +  kernel and symbol information.  This option is useful if you want
4595 +  to run identd as a non-root user.
4596 +
4597 +Remove addresses from /proc/pid/[maps|stat]
4598 +CONFIG_GRKERNSEC_PROC_MEMMAP
4599 +  If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
4600 +  give no information about the addresses of its mappings if
4601 +  PaX features that rely on random addresses are enabled on the task.
4602 +  If you use PaX it is greatly recommended that you say Y here as it 
4603 +  closes up a hole that makes the full ASLR useless for suid 
4604 +  binaries.
4605 +
4606 +Additional proc restrictions
4607 +CONFIG_GRKERNSEC_PROC_ADD
4608 +  If you say Y here, additional restrictions will be placed on
4609 +  /proc that keep normal users from viewing cpu and device information.
4610 +
4611 +Dmesg(8) Restriction
4612 +CONFIG_GRKERNSEC_DMESG
4613 +  If you say Y here, non-root users will not be able to use dmesg(8)
4614 +  to view up to the last 4kb of messages in the kernel's log buffer.
4615 +  If the sysctl option is enabled, a sysctl option with name "dmesg" is 
4616 +  created.
4617 +
4618 +Linking restrictions
4619 +CONFIG_GRKERNSEC_LINK
4620 +  If you say Y here, /tmp race exploits will be prevented, since users
4621 +  will no longer be able to follow symlinks owned by other users in 
4622 +  world-writable +t directories (i.e. /tmp), unless the owner of the 
4623 +  symlink is the owner of the directory. users will also not be
4624 +  able to hardlink to files they do not own.  If the sysctl option is
4625 +  enabled, a sysctl option with name "linking_restrictions" is created.
4626 +
4627 +FIFO restrictions
4628 +CONFIG_GRKERNSEC_FIFO
4629 +  If you say Y here, users will not be able to write to FIFOs they don't
4630 +  own in world-writable +t directories (i.e. /tmp), unless the owner of
4631 +  the FIFO is the same owner of the directory it's held in.  If the sysctl
4632 +  option is enabled, a sysctl option with name "fifo_restrictions" is 
4633 +  created.
4634 +
4635 +Enforce RLIMIT_NPROC on execs
4636 +CONFIG_GRKERNSEC_EXECVE
4637 +  If you say Y here, users with a resource limit on processes will
4638 +  have the value checked during execve() calls.  The current system
4639 +  only checks the system limit during fork() calls.  If the sysctl option
4640 +  is enabled, a sysctl option with name "execve_limiting" is created.
4641 +
4642 +Single group for auditing
4643 +CONFIG_GRKERNSEC_AUDIT_GROUP
4644 +  If you say Y here, the exec, chdir, (un)mount, and ipc logging features
4645 +  will only operate on a group you specify.  This option is recommended
4646 +  if you only want to watch certain users instead of having a large
4647 +  amount of logs from the entire system.  If the sysctl option is enabled,
4648 +  a sysctl option with name "audit_group" is created.
4649 +
4650 +GID for auditing
4651 +CONFIG_GRKERNSEC_AUDIT_GID
4652 +  Here you can choose the GID that will be the target of kernel auditing.
4653 +  Remember to add the users you want to log to the GID specified here.
4654 +  If the sysctl option is enabled, whatever you choose here won't matter. 
4655 +  You'll have to specify the GID in your bootup script by echoing the GID 
4656 +  to the proper /proc entry.  View the help on the sysctl option for more 
4657 +  information.  If the sysctl option is enabled, a sysctl option with name 
4658 +  "audit_gid" is created.
4659 +
4660 +Chdir logging
4661 +CONFIG_GRKERNSEC_AUDIT_CHDIR
4662 +  If you say Y here, all chdir() calls will be logged.  If the sysctl 
4663 +  option is enabled, a sysctl option with name "audit_chdir" is created.
4664 +
4665 +(Un)Mount logging
4666 +CONFIG_GRKERNSEC_AUDIT_MOUNT
4667 +  If you say Y here, all mounts and unmounts will be logged.  If the 
4668 +  sysctl option is enabled, a sysctl option with name "audit_mount" is 
4669 +  created.
4670 +
4671 +IPC logging
4672 +CONFIG_GRKERNSEC_AUDIT_IPC
4673 +  If you say Y here, creation and removal of message queues, semaphores,
4674 +  and shared memory will be logged.  If the sysctl option is enabled, a
4675 +  sysctl option with name "audit_ipc" is created.
4676 +
4677 +Exec logging
4678 +CONFIG_GRKERNSEC_EXECLOG
4679 +  If you say Y here, all execve() calls will be logged (since the
4680 +  other exec*() calls are frontends to execve(), all execution
4681 +  will be logged).  Useful for shell-servers that like to keep track
4682 +  of their users.  If the sysctl option is enabled, a sysctl option with
4683 +  name "exec_logging" is created.
4684 +  WARNING: This option when enabled will produce a LOT of logs, especially
4685 +  on an active system.
4686 +
4687 +Resource logging
4688 +CONFIG_GRKERNSEC_RESLOG
4689 +  If you say Y here, all attempts to overstep resource limits will
4690 +  be logged with the resource name, the requested size, and the current
4691 +  limit.  It is highly recommended that you say Y here.
4692 +
4693 +Signal logging
4694 +CONFIG_GRKERNSEC_SIGNAL
4695 +  If you say Y here, certain important signals will be logged, such as
4696 +  SIGSEGV, which will as a result inform you of when a error in a program
4697 +  occurred, which in some cases could mean a possible exploit attempt.
4698 +  If the sysctl option is enabled, a sysctl option with name 
4699 +  "signal_logging" is created.
4700 +
4701 +Fork failure logging
4702 +CONFIG_GRKERNSEC_FORKFAIL
4703 +  If you say Y here, all failed fork() attempts will be logged.
4704 +  This could suggest a fork bomb, or someone attempting to overstep
4705 +  their process limit.  If the sysctl option is enabled, a sysctl option
4706 +  with name "forkfail_logging" is created.
4707 +
4708 +Time change logging
4709 +CONFIG_GRKERNSEC_TIME
4710 +  If you say Y here, any changes of the system clock will be logged.
4711 +  If the sysctl option is enabled, a sysctl option with name 
4712 +  "timechange_logging" is created.
4713 +
4714 +Chroot jail restrictions
4715 +CONFIG_GRKERNSEC_CHROOT
4716 +  If you say Y here, you will be able to choose several options that will
4717 +  make breaking out of a chrooted jail much more difficult.  If you
4718 +  encounter no software incompatibilities with the following options, it
4719 +  is recommended that you enable each one.
4720 +
4721 +Deny access to abstract AF_UNIX sockets out of chroot
4722 +CONFIG_GRKERNSEC_CHROOT_UNIX
4723 +  If you say Y here, processes inside a chroot will not be able to
4724 +  connect to abstract (meaning not belonging to a filesystem) Unix
4725 +  domain sockets that were bound outside of a chroot.  It is recommended
4726 +  that you say Y here.  If the sysctl option is enabled, a sysctl option
4727 +  with name "chroot_deny_unix" is created.
4728 +
4729 +Deny shmat() out of chroot
4730 +CONFIG_GRKERNSEC_CHROOT_SHMAT
4731 +  If you say Y here, processes inside a chroot will not be able to attach
4732 +  to shared memory segments that were created outside of the chroot jail.
4733 +  It is recommended that you say Y here.  If the sysctl option is enabled,
4734 +  a sysctl option with name "chroot_deny_shmat" is created.
4735 +
4736 +Protect outside processes
4737 +CONFIG_GRKERNSEC_CHROOT_FINDTASK
4738 +  If you say Y here, processes inside a chroot will not be able to
4739 +  kill, send signals with fcntl, ptrace, capget, setpgid, getpgid, 
4740 +  getsid, or view any process outside of the chroot.  If the sysctl 
4741 +  option is enabled, a sysctl option with name "chroot_findtask" is 
4742 +  created.
4743 +
4744 +Deny mounts in chroot
4745 +CONFIG_GRKERNSEC_CHROOT_MOUNT
4746 +  If you say Y here, processes inside a chroot will not be able to
4747 +  mount or remount filesystems.  If the sysctl option is enabled, a 
4748 +  sysctl option with name "chroot_deny_mount" is created.
4749 +
4750 +Deny pivot_root in chroot
4751 +CONFIG_GRKERNSEC_CHROOT_PIVOT
4752 +  If you say Y here, processes inside a chroot will not be able to use
4753 +  a function called pivot_root() that was introduced in Linux 2.3.41.  It 
4754 +  works similar to chroot in that it changes the root filesystem.  This 
4755 +  function could be misused in a chrooted process to attempt to break out 
4756 +  of the chroot, and therefore should not be allowed.  If the sysctl 
4757 +  option is enabled, a sysctl option with name "chroot_deny_pivot" is 
4758 +  created.
4759 +
4760 +Deny double-chroots
4761 +CONFIG_GRKERNSEC_CHROOT_DOUBLE
4762 +  If you say Y here, processes inside a chroot will not be able to chroot
4763 +  again.  This is a widely used method of breaking out of a chroot jail
4764 +  and should not be allowed.  If the sysctl option is enabled, a sysctl
4765 +  option with name "chroot_deny_chroot" is created.
4766 +
4767 +Deny fchdir outside of chroot
4768 +CONFIG_GRKERNSEC_CHROOT_FCHDIR
4769 +  If you say Y here, a well-known method of breaking chroots by fchdir'ing
4770 +  to a file descriptor of the chrooting process that points to a directory
4771 +  outside the filesystem will be stopped.  If the sysctl option
4772 +  is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
4773 +
4774 +Enforce chdir("/") on all chroots
4775 +CONFIG_GRKERNSEC_CHROOT_CHDIR
4776 +  If you say Y here, the current working directory of all newly-chrooted
4777 +  applications will be set to the the root directory of the chroot.
4778 +  The man page on chroot(2) states:
4779 +  Note that this call does not change  the  current  working
4780 +  directory,  so  that `.' can be outside the tree rooted at
4781 +  `/'.  In particular, the  super-user  can  escape  from  a
4782 +  `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.  
4783 +
4784 +  It is recommended that you say Y here, since it's not known to break
4785 +  any software.  If the sysctl option is enabled, a sysctl option with
4786 +  name "chroot_enforce_chdir" is created.
4787 +
4788 +Deny (f)chmod +s in chroot
4789 +CONFIG_GRKERNSEC_CHROOT_CHMOD
4790 +  If you say Y here, processes inside a chroot will not be able to chmod
4791 +  or fchmod files to make them have suid or sgid bits.  This protects 
4792 +  against another published method of breaking a chroot.  If the sysctl 
4793 +  option is enabled, a sysctl option with name "chroot_deny_chmod" is
4794 +  created.
4795 +
4796 +Deny mknod in chroot
4797 +CONFIG_GRKERNSEC_CHROOT_MKNOD
4798 +  If you say Y here, processes inside a chroot will not be allowed to
4799 +  mknod.  The problem with using mknod inside a chroot is that it
4800 +  would allow an attacker to create a device entry that is the same
4801 +  as one on the physical root of your system, which could range from
4802 +  anything from the console device to a device for your harddrive (which
4803 +  they could then use to wipe the drive or steal data).  It is recommended
4804 +  that you say Y here, unless you run into software incompatibilities.
4805 +  If the sysctl option is enabled, a sysctl option with name
4806 +  "chroot_deny_mknod" is created.
4807 +
4808 +Restrict priority changes in chroot
4809 +CONFIG_GRKERNSEC_CHROOT_NICE
4810 +  If you say Y here, processes inside a chroot will not be able to raise
4811 +  the priority of processes in the chroot, or alter the priority of 
4812 +  processes outside the chroot.  This provides more security than simply
4813 +  removing CAP_SYS_NICE from the process' capability set.  If the
4814 +  sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
4815 +  is created.
4816 +
4817 +Log all execs within chroot
4818 +CONFIG_GRKERNSEC_CHROOT_EXECLOG
4819 +  If you say Y here, all executions inside a chroot jail will be logged 
4820 +  to syslog.  This can cause a large amount of logs if certain
4821 +  applications (eg. djb's daemontools) are installed on the system, and
4822 +  is therefore left as an option.  If the sysctl option is enabled, a 
4823 +  sysctl option with name "chroot_execlog" is created.
4824 +
4825 +Deny sysctl writes in chroot
4826 +CONFIG_GRKERNSEC_CHROOT_SYSCTL
4827 +  If you say Y here, an attacker in a chroot will not be able to
4828 +  write to sysctl entries, either by sysctl(2) or through a /proc
4829 +  interface.  It is strongly recommended that you say Y here. If the
4830 +  sysctl option is enabled, a sysctl option with name 
4831 +  "chroot_deny_sysctl" is created.
4832 +
4833 +Chroot jail capability restrictions
4834 +CONFIG_GRKERNSEC_CHROOT_CAPS
4835 +  If you say Y here, the capabilities on all root processes within a
4836 +  chroot jail will be lowered to stop module insertion, raw i/o,
4837 +  system and net admin tasks, rebooting the system, modifying immutable 
4838 +  files, modifying IPC owned by another, and changing the system time.
4839 +  This is left an option because it can break some apps.  Disable this
4840 +  if your chrooted apps are having problems performing those kinds of
4841 +  tasks.  If the sysctl option is enabled, a sysctl option with
4842 +  name "chroot_caps" is created.
4843 +
4844 +Trusted path execution
4845 +CONFIG_GRKERNSEC_TPE
4846 +  If you say Y here, you will be able to choose a gid to add to the
4847 +  supplementary groups of users you want to mark as "untrusted."
4848 +  These users will not be able to execute any files that are not in
4849 +  root-owned directories writable only by root.  If the sysctl option
4850 +  is enabled, a sysctl option with name "tpe" is created.
4851 +
4852 +Group for trusted path execution
4853 +CONFIG_GRKERNSEC_TPE_GID
4854 +  Here you can choose the GID to enable trusted path protection for.
4855 +  Remember to add the users you want protection enabled for to the GID 
4856 +  specified here.  If the sysctl option is enabled, whatever you choose
4857 +  here won't matter. You'll have to specify the GID in your bootup 
4858 +  script by echoing the GID to the proper /proc entry.  View the help
4859 +  on the sysctl option for more information.  If the sysctl option is
4860 +  enabled, a sysctl option with name "tpe_gid" is created.
4861 +
4862 +Partially restrict non-root users
4863 +CONFIG_GRKERNSEC_TPE_ALL
4864 +  If you say Y here, All non-root users other than the ones in the 
4865 +  group specified in the main TPE option will only be allowed to
4866 +  execute files in directories they own that are not group or
4867 +  world-writable, or in directories owned by root and writable only by
4868 +  root.  If the sysctl option is enabled, a sysctl option with name 
4869 +  "tpe_restrict_all" is created.
4870 +
4871 +Randomized PIDs
4872 +CONFIG_GRKERNSEC_RANDPID
4873 +  If you say Y here, all PIDs created on the system will be
4874 +  pseudo-randomly generated.  This is extremely effective along
4875 +  with the /proc restrictions to disallow an attacker from guessing
4876 +  pids of daemons, etc.  PIDs are also used in some cases as part
4877 +  of a naming system for temporary files, so this option would keep
4878 +  those filenames from being predicted as well.  We also use code
4879 +  to make sure that PID numbers aren't reused too soon.  If the sysctl
4880 +  option is enabled, a sysctl option with name "rand_pids" is created.
4881 +
4882 +Larger entropy pools
4883 +CONFIG_GRKERNSEC_RANDNET
4884 +  If you say Y here, the entropy pools used for many features of Linux
4885 +  and grsecurity will be doubled in size.  Since several grsecurity 
4886 +  features use additional randomness, it is recommended that you say Y 
4887 +  here.  Saying Y here has a similar effect as modifying
4888 +  /proc/sys/kernel/random/poolsize.
4889 +
4890 +Truly random TCP ISN selection
4891 +CONFIG_GRKERNSEC_RANDISN
4892 +  If you say Y here, Linux's default selection of TCP Initial Sequence
4893 +  Numbers (ISNs) will be replaced with that of OpenBSD.  Linux uses
4894 +  an MD4 hash based on the connection plus a time value to create the
4895 +  ISN, while OpenBSD's selection is random.  If the sysctl option is 
4896 +  enabled, a sysctl option with name "rand_isns" is created.
4897 +
4898 +Randomized IP IDs
4899 +CONFIG_GRKERNSEC_RANDID
4900 +  If you say Y here, all the id field on all outgoing packets
4901 +  will be randomized.  This hinders os fingerprinters and
4902 +  keeps your machine from being used as a bounce for an untraceable
4903 +  portscan.  Ids are used for fragmented packets, fragments belonging
4904 +  to the same packet have the same id.  By default linux only
4905 +  increments the id value on each packet sent to an individual host.
4906 +  We use a port of the OpenBSD random ip id code to achieve the
4907 +  randomness, while keeping the possibility of id duplicates to
4908 +  near none.  If the sysctl option is enabled, a sysctl option with name
4909 +  "rand_ip_ids" is created.
4910 +
4911 +Randomized TCP source ports
4912 +CONFIG_GRKERNSEC_RANDSRC
4913 +  If you say Y here, situations where a source port is generated on the
4914 +  fly for the TCP protocol (ie. with connect() ) will be altered so that
4915 +  the source port is generated at random, instead of a simple incrementing
4916 +  algorithm.  If the sysctl option is enabled, a sysctl option with name
4917 +  "rand_tcp_src_ports" is created.
4918 +
4919 +Randomized RPC XIDs
4920 +CONFIG_GRKERNSEC_RANDRPC
4921 +  If you say Y here, the method of determining XIDs for RPC requests will
4922 +  be randomized, instead of using linux's default behavior of simply
4923 +  incrementing the XID.  If you want your RPC connections to be more
4924 +  secure, say Y here.  If the sysctl option is enabled, a sysctl option 
4925 +  with name "rand_rpc" is created.
4926 +
4927 +Socket restrictions
4928 +CONFIG_GRKERNSEC_SOCKET
4929 +  If you say Y here, you will be able to choose from several options.
4930 +  If you assign a GID on your system and add it to the supplementary
4931 +  groups of users you want to restrict socket access to, this patch
4932 +  will perform up to three things, based on the option(s) you choose.
4933 +
4934 +Deny all socket access
4935 +CONFIG_GRKERNSEC_SOCKET_ALL
4936 +  If you say Y here, you will be able to choose a GID of whose users will
4937 +  be unable to connect to other hosts from your machine or run server
4938 +  applications from your machine.  If the sysctl option is enabled, a
4939 +  sysctl option with name "socket_all" is created.
4940 +
4941 +Group for disabled socket access
4942 +CONFIG_GRKERNSEC_SOCKET_ALL_GID
4943 +  Here you can choose the GID to disable socket access for. Remember to 
4944 +  add the users you want socket access disabled for to the GID 
4945 +  specified here.  If the sysctl option is enabled, whatever you choose
4946 +  here won't matter. You'll have to specify the GID in your bootup 
4947 +  script by echoing the GID to the proper /proc entry.  View the help
4948 +  on the sysctl option for more information.  If the sysctl option is
4949 +  enabled, a sysctl option with name "socket_all_gid" is created.
4950 +
4951 +Deny all client socket access
4952 +CONFIG_GRKERNSEC_SOCKET_CLIENT
4953 +  If you say Y here, you will be able to choose a GID of whose users will
4954 +  be unable to connect to other hosts from your machine, but will be
4955 +  able to run servers.  If this option is enabled, all users in the group
4956 +  you specify will have to use passive mode when initiating ftp transfers
4957 +  from the shell on your machine.  If the sysctl option is enabled, a
4958 +  sysctl option with name "socket_client" is created.
4959 +
4960 +Group for disabled client socket access
4961 +CONFIG_GRKERNSEC_SOCKET_CLIENT_GID
4962 +  Here you can choose the GID to disable client socket access for. 
4963 +  Remember to add the users you want client socket access disabled for to 
4964 +  the GID specified here.  If the sysctl option is enabled, whatever you 
4965 +  choose here won't matter. You'll have to specify the GID in your bootup 
4966 +  script by echoing the GID to the proper /proc entry.  View the help
4967 +  on the sysctl option for more information.  If the sysctl option is
4968 +  enabled, a sysctl option with name "socket_client_gid" is created.
4969 +
4970 +Deny all server socket access
4971 +CONFIG_GRKERNSEC_SOCKET_SERVER
4972 +  If you say Y here, you will be able to choose a GID of whose users will
4973 +  be unable to run server applications from your machine.  If the sysctl 
4974 +  option is enabled, a sysctl option with name "socket_server" is created.
4975 +
4976 +Group for disabled server socket access
4977 +CONFIG_GRKERNSEC_SOCKET_SERVER_GID
4978 +  Here you can choose the GID to disable server socket access for. 
4979 +  Remember to add the users you want server socket access disabled for to 
4980 +  the GID specified here.  If the sysctl option is enabled, whatever you 
4981 +  choose here won't matter. You'll have to specify the GID in your bootup 
4982 +  script by echoing the GID to the proper /proc entry.  View the help
4983 +  on the sysctl option for more information.  If the sysctl option is
4984 +  enabled, a sysctl option with name "socket_server_gid" is created.
4985 +
4986 +Sysctl support
4987 +CONFIG_GRKERNSEC_SYSCTL
4988 +  If you say Y here, you will be able to change the options that
4989 +  grsecurity runs with at bootup, without having to recompile your
4990 +  kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
4991 +  to enable (1) or disable (0) various features.  All the sysctl entries
4992 +  are mutable until the "grsec_lock" entry is set to a non-zero value.
4993 +  All features are disabled by default. Please note that this option could 
4994 +  reduce the effectiveness of the added security of this patch if an ACL 
4995 +  system is not put in place.  Your init scripts should be read-only, and 
4996 +  root should not have access to adding modules or performing raw i/o 
4997 +  operations.  All options should be set at startup, and the grsec_lock 
4998 +  entry should be set to a non-zero value after all the options are set.  
4999 +  *THIS IS EXTREMELY IMPORTANT*
5000 +
5001 +Number of burst messages
5002 +CONFIG_GRKERNSEC_FLOODBURST
5003 +  This option allows you to choose the maximum number of messages allowed
5004 +  within the flood time interval you chose in a separate option.  The 
5005 +  default should be suitable for most people, however if you find that 
5006 +  many of your logs are being interpreted as flooding, you may want to 
5007 +  raise this value.
5008 +
5009 +Seconds in between log messages
5010 +CONFIG_GRKERNSEC_FLOODTIME
5011 +  This option allows you to enforce the number of seconds between
5012 +  grsecurity log messages.  The default should be suitable for most 
5013 +  people, however, if you choose to change it, choose a value small enough
5014 +  to allow informative logs to be produced, but large enough to
5015 +  prevent flooding.
5016 +
5017 +Hide kernel processes
5018 +CONFIG_GRKERNSEC_ACL_HIDEKERN
5019 +  If you say Y here, when the ACL system is enabled via gradm -E,
5020 +  an additional ACL will be passed to the kernel that hides all kernel
5021 +  processes.  These processes will only be viewable by the authenticated
5022 +  admin, or processes that have viewing access set.
5023 +
5024 +Maximum tries before password lockout
5025 +CONFIG_GRKERNSEC_ACL_MAXTRIES
5026 +  This option enforces the maximum number of times a user can attempt
5027 +  to authorize themselves with the grsecurity ACL system before being
5028 +  denied the ability to attempt authorization again for a specified time.  
5029 +  The lower the number, the harder it will be to brute-force a password.
5030 +
5031 +Time to wait after max password tries, in seconds
5032 +CONFIG_GRKERNSEC_ACL_TIMEOUT
5033 +  This option specifies the time the user must wait after attempting to 
5034 +  authorize to the ACL system with the maximum number of invalid 
5035 +  passwords.  The higher the number, the harder it will be to brute-force 
5036 +  a password.
5037 +
5038  Disable data cache
5039  CONFIG_DCACHE_DISABLE
5040    This option allows you to run the kernel with data cache disabled.
5041 diff -urN linux-2.4.22.org/drivers/char/keyboard.c linux-2.4.22/drivers/char/keyboard.c
5042 --- linux-2.4.22.org/drivers/char/keyboard.c    2003-11-22 22:10:20.000000000 +0100
5043 +++ linux-2.4.22/drivers/char/keyboard.c        2003-11-22 22:14:07.000000000 +0100
5044 @@ -545,6 +545,16 @@
5045         if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
5046             !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
5047                 return;
5048 +
5049 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
5050 +       {
5051 +               void *func = spec_fn_table[value];
5052 +               if (func == show_state || func == show_ptregs ||
5053 +                   func == show_mem)
5054 +                       return;
5055 +       }
5056 +#endif
5057 +
5058         spec_fn_table[value]();
5059  }
5060  
5061 diff -urN linux-2.4.22.org/drivers/char/mem.c linux-2.4.22/drivers/char/mem.c
5062 --- linux-2.4.22.org/drivers/char/mem.c 2003-11-22 22:10:20.000000000 +0100
5063 +++ linux-2.4.22/drivers/char/mem.c     2003-11-22 22:19:23.000000000 +0100
5064 @@ -22,6 +22,7 @@
5065  #include <linux/tty.h>
5066  #include <linux/capability.h>
5067  #include <linux/ptrace.h>
5068 +#include <linux/grsecurity.h>
5069  
5070  #include <asm/uaccess.h>
5071  #include <asm/io.h>
5072 @@ -42,6 +43,10 @@
5073  #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
5074  extern void tapechar_init(void);
5075  #endif
5076 +
5077 +#ifdef CONFIG_GRKERNSEC
5078 +extern struct file_operations grsec_fops;
5079 +#endif
5080       
5081  static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
5082                             const char * buf, size_t count, loff_t *ppos)
5083 @@ -115,6 +120,11 @@
5084         unsigned long p = *ppos;
5085         unsigned long end_mem;
5086  
5087 +#ifdef CONFIG_GRKERNSEC_KMEM
5088 +       gr_handle_mem_write();
5089 +       return -EPERM;
5090 +#endif
5091 +
5092         end_mem = __pa(high_memory);
5093         if (p >= end_mem)
5094                 return 0;
5095 @@ -187,6 +197,12 @@
5096  {
5097         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5098  
5099 +#ifdef CONFIG_GRKERNSEC_KMEM
5100 +       if (gr_handle_mem_mmap(offset, vma))
5101 +               return -EPERM;
5102 +#endif
5103 +
5104 +
5105         /*
5106          * Accessing memory above the top the kernel knows about or
5107          * through a file pointer that was marked O_SYNC will be
5108 @@ -286,6 +302,11 @@
5109         ssize_t virtr = 0;
5110         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
5111  
5112 +#ifdef CONFIG_GRKERNSEC_KMEM
5113 +       gr_handle_kmem_write();
5114 +       return -EPERM;
5115 +#endif
5116 +
5117         if (p < (unsigned long) high_memory) {
5118                 wrote = count;
5119                 if (count > (unsigned long) high_memory - p)
5120 @@ -402,7 +423,7 @@
5121                         count = size;
5122  
5123                 zap_page_range(mm, addr, count);
5124 -               zeromap_page_range(addr, count, PAGE_COPY);
5125 +               zeromap_page_range(addr, count, vma->vm_page_prot); 
5126  
5127                 size -= count;
5128                 buf += count;
5129 @@ -525,6 +546,15 @@
5130  
5131  static int open_port(struct inode * inode, struct file * filp)
5132  {
5133 +#ifdef CONFIG_GRKERNSEC_KMEM
5134 +       gr_handle_open_port();
5135 +       return -EPERM;
5136 +#endif
5137 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5138 +}
5139 +
5140 +static int open_mem(struct inode * inode, struct file * filp)
5141 +{
5142         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5143  }
5144  
5145 @@ -582,6 +612,11 @@
5146         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5147         unsigned long size = vma->vm_end - vma->vm_start;
5148  
5149 +#ifdef CONFIG_GRKERNSEC_KMEM
5150 +       if (gr_handle_mem_mmap(offset, vma))
5151 +               return -EPERM;
5152 +#endif
5153 +
5154         /*
5155          * If the user is not attempting to mmap a high memory address then
5156          * the standard mmap_mem mechanism will work.  High memory addresses
5157 @@ -617,7 +652,6 @@
5158  #define full_lseek      null_lseek
5159  #define write_zero     write_null
5160  #define read_full       read_zero
5161 -#define open_mem       open_port
5162  #define open_kmem      open_mem
5163  
5164  static struct file_operations mem_fops = {
5165 @@ -693,6 +727,11 @@
5166                 case 9:
5167                         filp->f_op = &urandom_fops;
5168                         break;
5169 +#ifdef CONFIG_GRKERNSEC
5170 +               case 10:
5171 +                       filp->f_op = &grsec_fops;
5172 +                       break;
5173 +#endif
5174                 default:
5175                         return -ENXIO;
5176         }
5177 @@ -719,7 +758,10 @@
5178         {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
5179         {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
5180         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
5181 -       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
5182 +       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
5183 +#ifdef CONFIG_GRKERNSEC
5184 +       {10,"grsec",   S_IRUSR | S_IWUGO,           &grsec_fops}
5185 +#endif
5186      };
5187      int i;
5188  
5189 diff -urN linux-2.4.22.org/drivers/char/random.c linux-2.4.22/drivers/char/random.c
5190 --- linux-2.4.22.org/drivers/char/random.c      2003-11-22 22:10:20.000000000 +0100
5191 +++ linux-2.4.22/drivers/char/random.c  2003-11-22 22:14:07.000000000 +0100
5192 @@ -262,9 +262,15 @@
5193  /*
5194   * Configuration information
5195   */
5196 +#ifdef CONFIG_GRKERNSEC_RANDNET
5197 +#define DEFAULT_POOL_SIZE 1024
5198 +#define SECONDARY_POOL_SIZE 256
5199 +#define BATCH_ENTROPY_SIZE 512
5200 +#else
5201  #define DEFAULT_POOL_SIZE 512
5202  #define SECONDARY_POOL_SIZE 128
5203  #define BATCH_ENTROPY_SIZE 256
5204 +#endif
5205  #define USE_SHA
5206  
5207  /*
5208 @@ -389,6 +395,7 @@
5209  /*
5210   * Static global variables
5211   */
5212 +
5213  static struct entropy_store *random_state; /* The default global store */
5214  static struct entropy_store *sec_random_state; /* secondary store */
5215  static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
5216 @@ -2202,6 +2209,29 @@
5217         return halfMD4Transform(hash, keyptr->secret);
5218  }
5219  
5220 +#ifdef CONFIG_GRKERNSEC
5221 +/* the following function is provided by PaX under the GPL */
5222 +unsigned long get_random_long(void)
5223 +{       
5224 +       static time_t rekey_time;
5225 +       static __u32 secret[12];
5226 +       time_t t;
5227 +
5228 +       /*
5229 +        * Pick a random secret every REKEY_INTERVAL seconds
5230 +        */
5231 +       t = CURRENT_TIME;
5232 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
5233 +               rekey_time = t;
5234 +               get_random_bytes(secret, sizeof(secret));
5235 +       }
5236 +
5237 +       secret[1] = halfMD4Transform(secret+8, secret);
5238 +       secret[0] = halfMD4Transform(secret+8, secret);
5239 +       return *(unsigned long *)secret;
5240 +}
5241 +#endif
5242 +
5243  #ifdef CONFIG_SYN_COOKIES
5244  /*
5245   * Secure SYN cookie computation. This is the algorithm worked out by
5246 diff -urN linux-2.4.22.org/drivers/char/tty_io.c linux-2.4.22/drivers/char/tty_io.c
5247 --- linux-2.4.22.org/drivers/char/tty_io.c      2003-11-22 22:10:19.000000000 +0100
5248 +++ linux-2.4.22/drivers/char/tty_io.c  2003-11-22 22:14:07.000000000 +0100
5249 @@ -99,7 +99,7 @@
5250  #include <linux/vt_kern.h>
5251  #include <linux/selection.h>
5252  #include <linux/devfs_fs_kernel.h>
5253 -
5254 +#include <linux/grsecurity.h>
5255  #include <linux/kmod.h>
5256  
5257  #ifdef CONFIG_VT
5258 @@ -1426,7 +1426,11 @@
5259                 retval = -ENODEV;
5260         filp->f_flags = saved_flags;
5261  
5262 +#ifdef CONFIG_GRKERNSEC
5263 +       if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG))
5264 +#else
5265         if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
5266 +#endif
5267                 retval = -EBUSY;
5268  
5269         if (retval) {
5270 @@ -1533,7 +1537,11 @@
5271  {
5272         char ch, mbz = 0;
5273  
5274 +#ifdef CONFIG_GRKERNSEC
5275 +       if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG))
5276 +#else
5277         if ((current->tty != tty) && !suser())
5278 +#endif
5279                 return -EPERM;
5280         if (get_user(ch, arg))
5281                 return -EFAULT;
5282 @@ -1571,7 +1579,11 @@
5283         if (inode->i_rdev == SYSCONS_DEV ||
5284             inode->i_rdev == CONSOLE_DEV) {
5285                 struct file *f;
5286 +#ifdef CONFIG_GRKERNSEC
5287 +               if (!capable(CAP_SYS_TTY_CONFIG))
5288 +#else
5289                 if (!suser())
5290 +#endif
5291                         return -EPERM;
5292                 spin_lock(&redirect_lock);
5293                 f = redirect;
5294 @@ -1623,7 +1635,11 @@
5295                  * This tty is already the controlling
5296                  * tty for another session group!
5297                  */
5298 +#ifdef CONFIG_GRKERNSEC
5299 +               if ((arg == 1) && capable(CAP_SYS_ADMIN)) {
5300 +#else
5301                 if ((arg == 1) && suser()) {
5302 +#endif
5303                         /*
5304                          * Steal it away
5305                          */
5306 diff -urN linux-2.4.22.org/drivers/char/vt.c linux-2.4.22/drivers/char/vt.c
5307 --- linux-2.4.22.org/drivers/char/vt.c  2003-11-22 22:10:20.000000000 +0100
5308 +++ linux-2.4.22/drivers/char/vt.c      2003-11-22 22:14:07.000000000 +0100
5309 @@ -32,6 +32,7 @@
5310  #include <linux/vt_kern.h>
5311  #include <linux/kbd_diacr.h>
5312  #include <linux/selection.h>
5313 +#include <linux/grsecurity.h>
5314  
5315  #ifdef CONFIG_FB_COMPAT_XPMAC
5316  #include <asm/vc_ioctl.h>
5317 @@ -443,7 +444,11 @@
5318          * to be the owner of the tty, or super-user.
5319          */
5320         perm = 0;
5321 +#ifdef CONFIG_GRKERNSEC
5322 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
5323 +#else
5324         if (current->tty == tty || suser())
5325 +#endif
5326                 perm = 1;
5327   
5328         kbd = kbd_table + console;
5329 @@ -1038,12 +1043,20 @@
5330                 return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
5331  
5332         case VT_LOCKSWITCH:
5333 +#ifdef CONFIG_GRKERNSEC
5334 +               if (!capable(CAP_SYS_TTY_CONFIG))
5335 +#else
5336                 if (!suser())
5337 +#endif
5338                    return -EPERM;
5339                 vt_dont_switch = 1;
5340                 return 0;
5341         case VT_UNLOCKSWITCH:
5342 +#ifdef CONFIG_GRKERNSEC
5343 +               if (!capable(CAP_SYS_TTY_CONFIG))
5344 +#else
5345                 if (!suser())
5346 +#endif
5347                    return -EPERM;
5348                 vt_dont_switch = 0;
5349                 return 0;
5350 diff -urN linux-2.4.22.org/drivers/pci/proc.c linux-2.4.22/drivers/pci/proc.c
5351 --- linux-2.4.22.org/drivers/pci/proc.c 2003-11-22 22:10:57.000000000 +0100
5352 +++ linux-2.4.22/drivers/pci/proc.c     2003-11-22 22:14:07.000000000 +0100
5353 @@ -562,7 +562,15 @@
5354                 pci_for_each_dev(dev) {
5355                         pci_proc_attach_device(dev);
5356                 }
5357 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
5358 +#ifdef CONFIG_GRKERNSEC_PROC_USER
5359 +               entry = create_proc_entry("pci", S_IRUSR, NULL);
5360 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
5361 +               entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
5362 +#endif
5363 +#else
5364                 entry = create_proc_entry("pci", 0, NULL);
5365 +#endif
5366                 if (entry)
5367                         entry->proc_fops = &proc_pci_operations;
5368         }
5369 diff -urN linux-2.4.22.org/fs/binfmt_aout.c linux-2.4.22/fs/binfmt_aout.c
5370 --- linux-2.4.22.org/fs/binfmt_aout.c   2003-11-22 22:09:01.000000000 +0100
5371 +++ linux-2.4.22/fs/binfmt_aout.c       2003-11-22 22:14:07.000000000 +0100
5372 @@ -5,6 +5,7 @@
5373   */
5374  
5375  #include <linux/module.h>
5376 +#include <linux/config.h>
5377  
5378  #include <linux/sched.h>
5379  #include <linux/kernel.h>
5380 @@ -113,10 +114,12 @@
5381  /* If the size of the dump file exceeds the rlimit, then see what would happen
5382     if we wrote the stack, but not the data area.  */
5383  #ifdef __sparc__
5384 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize);
5385         if ((dump.u_dsize+dump.u_ssize) >
5386             current->rlim[RLIMIT_CORE].rlim_cur)
5387                 dump.u_dsize = 0;
5388  #else
5389 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE);
5390         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
5391             current->rlim[RLIMIT_CORE].rlim_cur)
5392                 dump.u_dsize = 0;
5393 @@ -124,10 +127,12 @@
5394  
5395  /* Make sure we have enough room to write the stack and data areas. */
5396  #ifdef __sparc__
5397 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize);
5398         if ((dump.u_ssize) >
5399             current->rlim[RLIMIT_CORE].rlim_cur)
5400                 dump.u_ssize = 0;
5401  #else
5402 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE);
5403         if ((dump.u_ssize+1) * PAGE_SIZE >
5404             current->rlim[RLIMIT_CORE].rlim_cur)
5405                 dump.u_ssize = 0;
5406 @@ -276,6 +281,8 @@
5407         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
5408         if (rlim >= RLIM_INFINITY)
5409                 rlim = ~0;
5410 +
5411 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss);
5412         if (ex.a_data + ex.a_bss > rlim)
5413                 return -ENOMEM;
5414  
5415 @@ -307,6 +314,24 @@
5416         current->mm->mmap = NULL;
5417         compute_creds(bprm);
5418         current->flags &= ~PF_FORKNOEXEC;
5419 +
5420 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5421 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
5422 +               current->flags |= PF_PAX_PAGEEXEC;
5423 +
5424 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5425 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
5426 +                       current->flags |= PF_PAX_EMUTRAMP;
5427 +#endif
5428 +
5429 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5430 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))        
5431 +                       current->flags |= PF_PAX_MPROTECT;
5432 +#endif
5433 +
5434 +       }
5435 +#endif
5436 +
5437  #ifdef __sparc__
5438         if (N_MAGIC(ex) == NMAGIC) {
5439                 loff_t pos = fd_offset;
5440 @@ -393,7 +418,7 @@
5441  
5442                 down_write(&current->mm->mmap_sem);
5443                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
5444 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
5445 +                               PROT_READ | PROT_WRITE,
5446                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
5447                                 fd_offset + ex.a_text);
5448                 up_write(&current->mm->mmap_sem);
5449 diff -urN linux-2.4.22.org/fs/binfmt_elf.c linux-2.4.22/fs/binfmt_elf.c
5450 --- linux-2.4.22.org/fs/binfmt_elf.c    2003-11-22 22:08:59.000000000 +0100
5451 +++ linux-2.4.22/fs/binfmt_elf.c        2003-11-22 22:14:07.000000000 +0100
5452 @@ -11,6 +11,7 @@
5453  
5454  #include <linux/module.h>
5455  
5456 +#include <linux/config.h>
5457  #include <linux/fs.h>
5458  #include <linux/stat.h>
5459  #include <linux/sched.h>
5460 @@ -33,10 +34,13 @@
5461  #include <linux/smp_lock.h>
5462  #include <linux/compiler.h>
5463  #include <linux/highmem.h>
5464 +#include <linux/random.h>
5465 +#include <linux/grsecurity.h>
5466  
5467  #include <asm/uaccess.h>
5468  #include <asm/param.h>
5469  #include <asm/pgalloc.h>
5470 +#include <asm/system.h>
5471  
5472  #define DLINFO_ITEMS 13
5473  
5474 @@ -86,6 +90,12 @@
5475         if (end <= start)
5476                 return;
5477         do_brk(start, end - start);
5478 +
5479 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5480 +       if (current->flags & PF_PAX_RANDEXEC)
5481 +               do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
5482 +#endif
5483 +
5484  }
5485  
5486  
5487 @@ -446,6 +456,11 @@
5488         struct exec interp_ex;
5489         char passed_fileno[6];
5490         struct files_struct *files;
5491 +
5492 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5493 +       unsigned long load_addr_random = 0UL;
5494 +       unsigned long load_bias_random = 0UL;
5495 +#endif
5496         
5497         /* Get the exec-header */
5498         elf_ex = *((struct elfhdr *) bprm->buf);
5499 @@ -618,7 +633,63 @@
5500         current->mm->end_data = 0;
5501         current->mm->end_code = 0;
5502         current->mm->mmap = NULL;
5503 +
5504 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5505 +       current->mm->delta_mmap = 0UL;
5506 +       current->mm->delta_exec = 0UL;
5507 +       current->mm->delta_stack = 0UL;
5508 +#endif
5509 +
5510         current->flags &= ~PF_FORKNOEXEC;
5511 +
5512 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5513 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) {
5514 +               current->flags |= PF_PAX_PAGEEXEC;
5515 +
5516 +#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
5517 +               current->mm->call_dl_resolve = 0UL;
5518 +#endif
5519 +
5520 +       }
5521 +#endif
5522 +
5523 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5524 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
5525 +               current->flags &= ~PF_PAX_PAGEEXEC;
5526 +               current->flags |= PF_PAX_SEGMEXEC;
5527 +       }
5528 +#endif
5529 +
5530 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5531 +       if (elf_ex.e_ident[EI_PAX] & EF_PAX_EMUTRAMP)
5532 +               current->flags |= PF_PAX_EMUTRAMP;
5533 +#endif
5534 +
5535 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5536 +       if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex.e_ident[EI_PAX] & EF_PAX_MPROTECT))
5537 +               current->flags |= PF_PAX_MPROTECT;
5538 +#endif
5539 +
5540 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5541 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_RANDMMAP)) {
5542 +               current->flags |= PF_PAX_RANDMMAP;
5543 +
5544 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
5545 +
5546 +               current->mm->delta_mmap = pax_delta_mask(get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
5547 +               current->mm->delta_exec = pax_delta_mask(get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
5548 +               current->mm->delta_stack = pax_delta_mask(get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
5549 +       }
5550 +#endif
5551 +
5552 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5553 +       if ((elf_ex.e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC) &&
5554 +           (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)))
5555 +               current->flags |= PF_PAX_RANDEXEC;
5556 +#endif
5557 +
5558 +       gr_set_pax_flags(current);      
5559 +
5560         elf_entry = (unsigned long) elf_ex.e_entry;
5561  
5562         /* Do this so that we can load the interpreter, if need be.  We will
5563 @@ -674,11 +745,84 @@
5564                            base, as well as whatever program they might try to exec.  This
5565                            is because the brk will follow the loader, and is not movable.  */
5566                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
5567 +
5568 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
5569 +                       /* PaX: randomize base address at the default exe base if requested */
5570 +                       if (current->flags & PF_PAX_RANDMMAP) {
5571 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
5572 +                               elf_flags |= MAP_FIXED;
5573 +                       }
5574 +#endif
5575 +
5576                 }
5577  
5578 -               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5579 -               if (BAD_ADDR(error))
5580 -                       continue;
5581 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5582 +               if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
5583 +                       unsigned long addr, len;
5584 +
5585 +                       error = -ENOMEM;
5586 +
5587 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5588 +                       if (current->flags & PF_PAX_PAGEEXEC)
5589 +                               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
5590 +#endif
5591 +
5592 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5593 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5594 +                               addr = ELF_PAGESTART(load_bias + vaddr);
5595 +                               len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
5596 +                               if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
5597 +                                       continue;
5598 +                               down_write(&current->mm->mmap_sem);
5599 +                               error = do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
5600 +                               up_write(&current->mm->mmap_sem);
5601 +                       }
5602 +#endif
5603 +
5604 +                       if (BAD_ADDR(error))
5605 +                               continue;
5606 +
5607 +                       /* PaX: mirror at a randomized base */
5608 +                       down_write(&current->mm->mmap_sem);
5609 +
5610 +                       if (!load_addr_set) {
5611 +                               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);
5612 +                               if (BAD_ADDR(load_addr_random)) {
5613 +                                       up_write(&current->mm->mmap_sem);
5614 +                                       continue;
5615 +                               }
5616 +                               load_bias_random = load_addr_random - vaddr;
5617 +                       }
5618 +
5619 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5620 +                       if (current->flags & PF_PAX_PAGEEXEC)
5621 +                               load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5622 +#endif
5623 +
5624 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5625 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5626 +                               if (elf_prot & PROT_EXEC) {
5627 +                                       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);
5628 +                                       if (!BAD_ADDR(load_addr_random)) {
5629 +                                               load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5630 +                                               if (!BAD_ADDR(load_addr_random))
5631 +                                                       load_addr_random -= SEGMEXEC_TASK_SIZE;
5632 +                                       }
5633 +                               } else
5634 +                                       load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5635 +                       }
5636 +#endif
5637 +
5638 +                       up_write(&current->mm->mmap_sem);
5639 +                       if (BAD_ADDR(load_addr_random))
5640 +                               continue;
5641 +               } else
5642 +#endif
5643 +               {
5644 +                       error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5645 +                       if (BAD_ADDR(error))
5646 +                               continue;
5647 +               }
5648  
5649                 if (!load_addr_set) {
5650                         load_addr_set = 1;
5651 @@ -689,6 +833,11 @@
5652                                 load_addr += load_bias;
5653                                 reloc_func_desc = load_addr;
5654                         }
5655 +
5656 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5657 +                       current->mm->delta_exec = load_addr_random - load_addr;
5658 +#endif
5659 +
5660                 }
5661                 k = elf_ppnt->p_vaddr;
5662                 if (k < start_code) start_code = k;
5663 @@ -715,6 +864,18 @@
5664         start_data += load_bias;
5665         end_data += load_bias;
5666  
5667 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
5668 +       elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT);
5669 +#undef pax_delta_mask
5670 +#endif
5671 +
5672 +       /* Calling set_brk effectively mmaps the pages that we need
5673 +        * for the bss and break sections
5674 +        */
5675 +       set_brk(elf_bss, elf_brk);
5676 +
5677 +       padzero(elf_bss);
5678 +
5679         if (elf_interpreter) {
5680                 if (interpreter_type == INTERPRETER_AOUT)
5681                         elf_entry = load_aout_interp(&interp_ex,
5682 @@ -763,13 +924,6 @@
5683         current->mm->end_data = end_data;
5684         current->mm->start_stack = bprm->p;
5685  
5686 -       /* Calling set_brk effectively mmaps the pages that we need
5687 -        * for the bss and break sections
5688 -        */
5689 -       set_brk(elf_bss, elf_brk);
5690 -
5691 -       padzero(elf_bss);
5692 -
5693  #if 0
5694         printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
5695         printk("(end_code) %lx\n" , (long) current->mm->end_code);
5696 @@ -806,6 +960,10 @@
5697         ELF_PLAT_INIT(regs, reloc_func_desc);
5698  #endif
5699  
5700 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5701 +       pax_switch_segments(current);
5702 +#endif
5703 +
5704         start_thread(regs, elf_entry, bprm->p);
5705         if (current->ptrace & PT_PTRACED)
5706                 send_sig(SIGTRAP, current, 0);
5707 @@ -1033,8 +1191,11 @@
5708  #undef DUMP_SEEK
5709  
5710  #define DUMP_WRITE(addr, nr)   \
5711 +       do { \
5712 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr)); \
5713         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
5714 -               goto end_coredump;
5715 +               goto end_coredump; \
5716 +       } while (0);
5717  #define DUMP_SEEK(off) \
5718         if (!dump_seek(file, (off))) \
5719                 goto end_coredump;
5720 diff -urN linux-2.4.22.org/fs/buffer.c linux-2.4.22/fs/buffer.c
5721 --- linux-2.4.22.org/fs/buffer.c        2003-11-22 22:09:07.000000000 +0100
5722 +++ linux-2.4.22/fs/buffer.c    2003-11-22 22:14:07.000000000 +0100
5723 @@ -1906,6 +1906,9 @@
5724         int err;
5725  
5726         err = -EFBIG;
5727 +
5728 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size);
5729 +
5730          limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
5731         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
5732                 send_sig(SIGXFSZ, current, 0);
5733 diff -urN linux-2.4.22.org/fs/exec.c linux-2.4.22/fs/exec.c
5734 --- linux-2.4.22.org/fs/exec.c  2003-11-22 22:08:59.000000000 +0100
5735 +++ linux-2.4.22/fs/exec.c      2003-11-22 22:14:07.000000000 +0100
5736 @@ -43,6 +43,9 @@
5737  #include <asm/uaccess.h>
5738  #include <asm/pgalloc.h>
5739  #include <asm/mmu_context.h>
5740 +#include <linux/major.h>
5741 +#include <linux/random.h>
5742 +#include <linux/grsecurity.h>
5743  
5744  #ifdef CONFIG_KMOD
5745  #include <linux/kmod.h>
5746 @@ -346,6 +349,11 @@
5747                 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
5748                 mpnt->vm_end = STACK_TOP;
5749                 mpnt->vm_flags = VM_STACK_FLAGS;
5750 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5751 +               if (!(current->flags & PF_PAX_PAGEEXEC))
5752 +                       mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7];
5753 +               else
5754 +#endif
5755                 mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
5756                 mpnt->vm_ops = NULL;
5757                 mpnt->vm_pgoff = 0;
5758 @@ -606,6 +614,30 @@
5759         }
5760         current->comm[i] = '\0';
5761  
5762 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5763 +       current->flags &= ~PF_PAX_PAGEEXEC;
5764 +#endif
5765 +
5766 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5767 +       current->flags &= ~PF_PAX_EMUTRAMP;
5768 +#endif
5769 +
5770 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5771 +       current->flags &= ~PF_PAX_MPROTECT;
5772 +#endif
5773 +
5774 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5775 +       current->flags &= ~PF_PAX_RANDMMAP;
5776 +#endif
5777 +
5778 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5779 +       current->flags &= ~PF_PAX_RANDEXEC;
5780 +#endif
5781 +
5782 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5783 +       current->flags &= ~PF_PAX_SEGMEXEC;
5784 +#endif
5785 +
5786         flush_thread();
5787  
5788         de_thread(current);
5789 @@ -705,6 +737,9 @@
5790                         cap_set_full(bprm->cap_effective);
5791         }
5792  
5793 +       if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
5794 +               return -EACCES;
5795 +
5796         memset(bprm->buf,0,BINPRM_BUF_SIZE);
5797         return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
5798  }
5799 @@ -770,6 +805,8 @@
5800          current->suid = current->euid = current->fsuid = bprm->e_uid;
5801          current->sgid = current->egid = current->fsgid = bprm->e_gid;
5802  
5803 +       gr_handle_chroot_caps(current);
5804 +
5805         if(do_unlock)
5806                 unlock_kernel();
5807         current->keep_capabilities = 0;
5808 @@ -903,6 +940,11 @@
5809         struct file *file;
5810         int retval;
5811         int i;
5812 +#ifdef CONFIG_GRKERNSEC
5813 +       struct file *old_exec_file;
5814 +       struct acl_subject_label *old_acl;
5815 +       struct rlimit old_rlim[RLIM_NLIMITS];
5816 +#endif
5817  
5818         file = open_exec(filename);
5819  
5820 @@ -910,7 +952,26 @@
5821         if (IS_ERR(file))
5822                 return retval;
5823  
5824 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
5825 +
5826 +       if (gr_handle_nproc()) {
5827 +               allow_write_access(file);
5828 +               fput(file);
5829 +               return -EAGAIN;
5830 +       }
5831 +
5832 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
5833 +               allow_write_access(file);
5834 +               fput(file);
5835 +               return -EACCES;
5836 +       }
5837 +
5838         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
5839 +
5840 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
5841 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
5842 +#endif
5843 +
5844         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
5845  
5846         bprm.file = file;
5847 @@ -934,11 +995,26 @@
5848         if (retval < 0) 
5849                 goto out; 
5850  
5851 +       if (!gr_tpe_allow(file)) {
5852 +               retval = -EACCES;
5853 +               goto out;
5854 +       }
5855 +
5856 +       if(gr_check_crash_exec(file)) {
5857 +               retval = -EACCES;
5858 +               goto out;
5859 +       }
5860 +
5861         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
5862         if (retval < 0) 
5863                 goto out; 
5864  
5865         bprm.exec = bprm.p;
5866 +
5867 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
5868 +
5869 +       gr_handle_exec_args(&bprm, argv);
5870 +
5871         retval = copy_strings(bprm.envc, envp, &bprm);
5872         if (retval < 0) 
5873                 goto out; 
5874 @@ -947,11 +1023,32 @@
5875         if (retval < 0) 
5876                 goto out; 
5877  
5878 +#ifdef CONFIG_GRKERNSEC
5879 +       old_acl = current->acl;
5880 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
5881 +       old_exec_file = current->exec_file;
5882 +       get_file(file);
5883 +       current->exec_file = file;
5884 +#endif
5885 +
5886 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
5887 +
5888         retval = search_binary_handler(&bprm,regs);
5889 -       if (retval >= 0)
5890 +       if (retval >= 0) {
5891 +#ifdef CONFIG_GRKERNSEC
5892 +               if (old_exec_file)
5893 +                       fput(old_exec_file);
5894 +#endif
5895                 /* execve success */
5896                 return retval;
5897 +       }
5898  
5899 +#ifdef CONFIG_GRKERNSEC
5900 +       current->acl = old_acl;
5901 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
5902 +       fput(current->exec_file);
5903 +       current->exec_file = old_exec_file;
5904 +#endif
5905  out:
5906         /* Something went wrong, return the inode and free the argument pages*/
5907         allow_write_access(bprm.file);
5908 @@ -1093,6 +1190,43 @@
5909         *out_ptr = 0;
5910  }
5911  
5912 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
5913 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
5914 +{
5915 +       struct task_struct *tsk = current;
5916 +       struct mm_struct *mm = current->mm;
5917 +       char* buffer = (char*)__get_free_page(GFP_ATOMIC);
5918 +       char* path=NULL;
5919 +
5920 +       if (buffer) {
5921 +               struct vm_area_struct* vma;
5922 +
5923 +               down_read(&mm->mmap_sem);
5924 +               vma = mm->mmap;
5925 +               while (vma) {
5926 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
5927 +                               break;
5928 +                       }
5929 +                       vma = vma->vm_next;
5930 +               }
5931 +               if (vma)
5932 +                       path = d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt, buffer, PAGE_SIZE);
5933 +               up_read(&mm->mmap_sem);
5934 +       }
5935 +       if (tsk->curr_ip)
5936 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: terminating task: %s(%s):%d, uid/euid: %u/%u, "
5937 +                               "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), path, tsk->comm, tsk->pid,
5938 +                               tsk->uid, tsk->euid, pc, sp);
5939 +       else
5940 +               printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
5941 +                               "PC: %p, SP: %p\n", path, tsk->comm, tsk->pid,
5942 +                               tsk->uid, tsk->euid, pc, sp);
5943 +       if (buffer) free_page((unsigned long)buffer);
5944 +       pax_report_insns(pc);
5945 +       do_coredump(SIGKILL, regs);
5946 +}
5947 +#endif
5948 +
5949  int do_coredump(long signr, struct pt_regs * regs)
5950  {
5951         struct linux_binfmt * binfmt;
5952 @@ -1113,6 +1247,7 @@
5953                 current->fsuid = 0;
5954         }
5955         current->mm->dumpable = 0;
5956 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump);
5957         if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
5958                 goto fail;
5959  
5960 @@ -1132,7 +1267,7 @@
5961                 goto close_fail;
5962         if (!file->f_op->write)
5963                 goto close_fail;
5964 -       if (do_truncate(file->f_dentry, 0) != 0)
5965 +       if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
5966                 goto close_fail;
5967  
5968         retval = binfmt->core_dump(signr, regs, file);
5969 diff -urN linux-2.4.22.org/fs/fcntl.c linux-2.4.22/fs/fcntl.c
5970 --- linux-2.4.22.org/fs/fcntl.c 2003-11-22 22:08:59.000000000 +0100
5971 +++ linux-2.4.22/fs/fcntl.c     2003-11-22 22:19:45.000000000 +0100
5972 @@ -12,6 +12,7 @@
5973  #include <linux/slab.h>
5974  #include <linux/iobuf.h>
5975  #include <linux/ptrace.h>
5976 +#include <linux/grsecurity.h>
5977  
5978  #include <asm/poll.h>
5979  #include <asm/siginfo.h>
5980 @@ -65,6 +66,8 @@
5981         int error;
5982         int start;
5983  
5984 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start);
5985 +
5986         write_lock(&files->file_lock);
5987         
5988         error = -EINVAL;
5989 @@ -87,6 +90,7 @@
5990         }
5991         
5992         error = -EMFILE;
5993 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd);
5994         if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
5995                 goto out;
5996  
5997 @@ -142,6 +146,8 @@
5998         struct file * file, *tofree;
5999         struct files_struct * files = current->files;
6000  
6001 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd);
6002 +
6003         write_lock(&files->file_lock);
6004         if (!(file = fcheck(oldfd)))
6005                 goto out_unlock;
6006 @@ -450,6 +456,10 @@
6007                         match = -p->pgrp;
6008                 if (pid != match)
6009                         continue;
6010 +               if (gr_check_protected_task(p))
6011 +                       continue;
6012 +               if (gr_pid_is_chrooted(p))
6013 +                       continue;
6014                 send_sigio_to_task(p, fown, fd, band);
6015         }
6016  out:
6017 diff -urN linux-2.4.22.org/fs/locks.c linux-2.4.22/fs/locks.c
6018 --- linux-2.4.22.org/fs/locks.c 2003-11-22 22:08:59.000000000 +0100
6019 +++ linux-2.4.22/fs/locks.c     2003-11-22 22:14:07.000000000 +0100
6020 @@ -138,4 +138,5 @@
6021  static struct file_lock *locks_alloc_lock(void)
6022  {
6023 +       gr_learn_resource(current, RLIMIT_LOCKS, current->locks);
6024         return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
6025  }
6026 diff -urN linux-2.4.22.org/fs/namei.c linux-2.4.22/fs/namei.c
6027 --- linux-2.4.22.org/fs/namei.c 2003-11-22 22:09:07.000000000 +0100
6028 +++ linux-2.4.22/fs/namei.c     2003-11-22 22:14:07.000000000 +0100
6029 @@ -22,6 +22,7 @@
6030  #include <linux/dnotify.h>
6031  #include <linux/smp_lock.h>
6032  #include <linux/personality.h>
6033 +#include <linux/grsecurity.h>
6034  
6035  #include <asm/namei.h>
6036  #include <asm/uaccess.h>
6037 @@ -343,6 +344,13 @@
6038                 current->state = TASK_RUNNING;
6039                 schedule();
6040         }
6041 +
6042 +       if (gr_handle_follow_link(dentry->d_parent->d_inode,
6043 +                                 dentry->d_inode, dentry, nd->mnt)) {
6044 +               path_release(nd);
6045 +               return -EACCES;
6046 +       }
6047 +
6048         current->link_count++;
6049         current->total_link_count++;
6050         UPDATE_ATIME(dentry->d_inode);
6051 @@ -643,6 +651,10 @@
6052                         }
6053                 }
6054  return_base:
6055 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
6056 +                       path_release(nd);
6057 +                       return -ENOENT;
6058 +               }
6059                 return 0;
6060  out_dput:
6061                 dput(dentry);
6062 @@ -1005,7 +1017,7 @@
6063         struct dentry *dentry;
6064         struct dentry *dir;
6065         int count = 0;
6066 -
6067 +       
6068         acc_mode = ACC_MODE(flag);
6069  
6070         /*
6071 @@ -1015,7 +1027,19 @@
6072                 error = path_lookup(pathname, lookup_flags(flag), nd);
6073                 if (error)
6074                         return error;
6075 +
6076 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
6077 +                       error = -EPERM;
6078 +                       goto exit;
6079 +               }
6080 +       
6081 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
6082 +                       error = -EACCES;
6083 +                       goto exit;
6084 +               }
6085 +
6086                 dentry = nd->dentry;
6087 +
6088                 goto ok;
6089         }
6090  
6091 @@ -1050,7 +1074,16 @@
6092         if (!dentry->d_inode) {
6093                 if (!IS_POSIXACL(dir->d_inode))
6094                         mode &= ~current->fs->umask;
6095 +               if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
6096 +                       error = -EACCES;
6097 +                       up(&dir->d_inode->i_sem);
6098 +                       goto exit_dput;
6099 +               }
6100 +
6101                 error = vfs_create(dir->d_inode, dentry, mode);
6102 +               if (!error)
6103 +                       gr_handle_create(dentry, nd->mnt);
6104 +
6105                 up(&dir->d_inode->i_sem);
6106                 dput(nd->dentry);
6107                 nd->dentry = dentry;
6108 @@ -1059,12 +1092,35 @@
6109                 /* Don't check for write permission, don't truncate */
6110                 acc_mode = 0;
6111                 flag &= ~O_TRUNC;
6112 +
6113                 goto ok;
6114         }
6115  
6116         /*
6117          * It already exists.
6118          */
6119 +
6120 +       if (gr_acl_is_enabled() && S_ISBLK(dentry->d_inode->i_mode) &&
6121 +           !capable(CAP_SYS_RAWIO)) {
6122 +               error = -EPERM;
6123 +               up(&dir->d_inode->i_sem);
6124 +               goto exit_dput;
6125 +       }
6126 +
6127 +       if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
6128 +               error = -EACCES;
6129 +               up(&dir->d_inode->i_sem);
6130 +               goto exit_dput;
6131 +       }
6132 +
6133 +       inode = dentry->d_inode;
6134 +
6135 +       if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
6136 +               up(&dir->d_inode->i_sem);
6137 +               error = -EACCES;
6138 +               goto exit_dput;
6139 +       }
6140 +
6141         up(&dir->d_inode->i_sem);
6142  
6143         error = -EEXIST;
6144 @@ -1154,7 +1210,7 @@
6145                 if (!error) {
6146                         DQUOT_INIT(inode);
6147                         
6148 -                       error = do_truncate(dentry, 0);
6149 +                       error = do_truncate(dentry,0,nd->mnt);
6150                 }
6151                 put_write_access(inode);
6152                 if (error)
6153 @@ -1185,6 +1241,13 @@
6154          * stored in nd->last.name and we will have to putname() it when we
6155          * are done. Procfs-like symlinks just set LAST_BIND.
6156          */
6157 +
6158 +       if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
6159 +                                 dentry, nd->mnt)) {
6160 +               error = -EACCES;
6161 +               goto exit_dput;
6162 +       }
6163 +
6164         UPDATE_ATIME(dentry->d_inode);
6165         error = dentry->d_inode->i_op->follow_link(dentry, nd);
6166         dput(dentry);
6167 @@ -1284,6 +1347,18 @@
6168         if (!IS_POSIXACL(nd.dentry->d_inode))
6169                 mode &= ~current->fs->umask;
6170         if (!IS_ERR(dentry)) {
6171 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
6172 +                       error = -EPERM;
6173 +                       dput(dentry);
6174 +                       goto out_dput;
6175 +               }
6176 +
6177 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
6178 +                       error = -EACCES;
6179 +                       dput(dentry);
6180 +                       goto out_dput;
6181 +               }
6182 +       
6183                 switch (mode & S_IFMT) {
6184                 case 0: case S_IFREG:
6185                         error = vfs_create(nd.dentry->d_inode,dentry,mode);
6186 @@ -1297,8 +1372,13 @@
6187                 default:
6188                         error = -EINVAL;
6189                 }
6190 +
6191 +               if(!error)
6192 +                       gr_handle_create(dentry, nd.mnt);
6193 +
6194                 dput(dentry);
6195         }
6196 +out_dput:
6197         up(&nd.dentry->d_inode->i_sem);
6198         path_release(&nd);
6199  out:
6200 @@ -1352,7 +1432,16 @@
6201                 if (!IS_ERR(dentry)) {
6202                         if (!IS_POSIXACL(nd.dentry->d_inode))
6203                                 mode &= ~current->fs->umask;
6204 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6205 +                       error = 0;
6206 +
6207 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
6208 +                               error = -EACCES;
6209 +
6210 +                       if(!error)
6211 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6212 +                       if(!error)
6213 +                               gr_handle_create(dentry, nd.mnt);
6214 +                       
6215                         dput(dentry);
6216                 }
6217                 up(&nd.dentry->d_inode->i_sem);
6218 @@ -1436,6 +1525,8 @@
6219         char * name;
6220         struct dentry *dentry;
6221         struct nameidata nd;
6222 +       ino_t saved_ino = 0;
6223 +       kdev_t saved_dev = 0;
6224  
6225         name = getname(pathname);
6226         if(IS_ERR(name))
6227 @@ -1460,7 +1551,22 @@
6228         dentry = lookup_hash(&nd.last, nd.dentry);
6229         error = PTR_ERR(dentry);
6230         if (!IS_ERR(dentry)) {
6231 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
6232 +               error = 0;
6233 +               if (dentry->d_inode) {
6234 +                       if (dentry->d_inode->i_nlink <= 1) {
6235 +                               saved_ino = dentry->d_inode->i_ino;
6236 +                               saved_dev = dentry->d_inode->i_dev;
6237 +                       }
6238 +
6239 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
6240 +                               error = -EACCES;
6241 +               }
6242 +
6243 +               if (!error)
6244 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
6245 +               if (!error && (saved_dev || saved_ino))
6246 +                       gr_handle_delete(saved_ino,saved_dev);
6247 +
6248                 dput(dentry);
6249         }
6250         up(&nd.dentry->d_inode->i_sem);
6251 @@ -1505,6 +1611,8 @@
6252         char * name;
6253         struct dentry *dentry;
6254         struct nameidata nd;
6255 +       ino_t saved_ino = 0;
6256 +       kdev_t saved_dev = 0;
6257  
6258         name = getname(pathname);
6259         if(IS_ERR(name))
6260 @@ -1523,7 +1631,21 @@
6261                 /* Why not before? Because we want correct error value */
6262                 if (nd.last.name[nd.last.len])
6263                         goto slashes;
6264 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
6265 +               error = 0;
6266 +               if (dentry->d_inode) {
6267 +                       if (dentry->d_inode->i_nlink <= 1) {
6268 +                               saved_ino = dentry->d_inode->i_ino;
6269 +                               saved_dev = dentry->d_inode->i_dev;
6270 +                       }
6271 +
6272 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
6273 +                               error = -EACCES;
6274 +               }
6275 +
6276 +               if (!error)
6277 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
6278 +               if (!error && (saved_ino || saved_dev))
6279 +                       gr_handle_delete(saved_ino,saved_dev);
6280         exit2:
6281                 dput(dentry);
6282         }
6283 @@ -1587,7 +1709,15 @@
6284                 dentry = lookup_create(&nd, 0);
6285                 error = PTR_ERR(dentry);
6286                 if (!IS_ERR(dentry)) {
6287 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6288 +                       error = 0;
6289 +
6290 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
6291 +                               error = -EACCES;
6292 +
6293 +                       if(!error)      
6294 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6295 +                       if (!error)
6296 +                               gr_handle_create(dentry, nd.mnt);
6297                         dput(dentry);
6298                 }
6299                 up(&nd.dentry->d_inode->i_sem);
6300 @@ -1671,7 +1801,27 @@
6301                 new_dentry = lookup_create(&nd, 0);
6302                 error = PTR_ERR(new_dentry);
6303                 if (!IS_ERR(new_dentry)) {
6304 -                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
6305 +                       error = 0;
6306 +
6307 +                       if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
6308 +                                              old_nd.dentry->d_inode,
6309 +                                              old_nd.dentry->d_inode->i_mode, to)) {
6310 +                               error = -EPERM;
6311 +                               goto out_error;
6312 +                       }
6313 +
6314 +                       if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
6315 +                                                old_nd.dentry, old_nd.mnt, to)) {
6316 +                               error = -EACCES;
6317 +                               goto out_error;
6318 +                       }
6319 +
6320 +                       error = vfs_link(old_nd.dentry, 
6321 +                                       nd.dentry->d_inode, new_dentry);
6322 +
6323 +                       if (!error)
6324 +                               gr_handle_create(new_dentry, nd.mnt);
6325 +out_error:
6326                         dput(new_dentry);
6327                 }
6328                 up(&nd.dentry->d_inode->i_sem);
6329 @@ -1907,10 +2057,15 @@
6330         if (IS_ERR(new_dentry))
6331                 goto exit4;
6332  
6333 -       lock_kernel();
6334 -       error = vfs_rename(old_dir->d_inode, old_dentry,
6335 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
6336 +                                    old_dentry, old_dir->d_inode, oldnd.mnt, newname);
6337 +
6338 +       if (error == 1) {
6339 +               lock_kernel();
6340 +               error = vfs_rename(old_dir->d_inode, old_dentry,
6341                                    new_dir->d_inode, new_dentry);
6342 -       unlock_kernel();
6343 +               unlock_kernel();
6344 +       }
6345  
6346         dput(new_dentry);
6347  exit4:
6348 diff -urN linux-2.4.22.org/fs/namespace.c linux-2.4.22/fs/namespace.c
6349 --- linux-2.4.22.org/fs/namespace.c     2003-11-22 22:08:59.000000000 +0100
6350 +++ linux-2.4.22/fs/namespace.c 2003-11-22 22:14:07.000000000 +0100
6351 @@ -15,6 +15,8 @@
6352  #include <linux/quotaops.h>
6353  #include <linux/acct.h>
6354  #include <linux/module.h>
6355 +#include <linux/sched.h>
6356 +#include <linux/grsecurity.h>
6357  
6358  #include <asm/uaccess.h>
6359  
6360 @@ -325,6 +327,8 @@
6361                         lock_kernel();
6362                         retval = do_remount_sb(sb, MS_RDONLY, 0);
6363                         unlock_kernel();
6364 +
6365 +                       gr_log_remount(mnt->mnt_devname, retval);
6366                 }
6367                 up_write(&sb->s_umount);
6368                 return retval;
6369 @@ -350,6 +354,9 @@
6370         }
6371         spin_unlock(&dcache_lock);
6372         up_write(&current->namespace->sem);
6373 +
6374 +       gr_log_unmount(mnt->mnt_devname, retval);
6375 +
6376         return retval;
6377  }
6378  
6379 @@ -729,6 +736,12 @@
6380         if (retval)
6381                 return retval;
6382  
6383 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
6384 +               retval = -EPERM;
6385 +               path_release(&nd);
6386 +               return retval;
6387 +       }
6388 +
6389         if (flags & MS_REMOUNT)
6390                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
6391                                     data_page);
6392 @@ -740,6 +753,9 @@
6393                 retval = do_add_mount(&nd, type_page, flags, mnt_flags,
6394                                       dev_name, data_page);
6395         path_release(&nd);
6396 +
6397 +       gr_log_mount(dev_name, dir_name, retval);
6398 +
6399         return retval;
6400  }
6401  
6402 @@ -909,6 +925,9 @@
6403         if (!capable(CAP_SYS_ADMIN))
6404                 return -EPERM;
6405  
6406 +       if (gr_handle_chroot_pivot())
6407 +               return -EPERM;
6408 +
6409         lock_kernel();
6410  
6411         error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
6412 diff -urN linux-2.4.22.org/fs/open.c linux-2.4.22/fs/open.c
6413 --- linux-2.4.22.org/fs/open.c  2003-11-22 22:08:59.000000000 +0100
6414 +++ linux-2.4.22/fs/open.c      2003-11-22 22:14:07.000000000 +0100
6415 @@ -15,6 +15,7 @@
6416  #include <linux/slab.h>
6417  #include <linux/tty.h>
6418  #include <linux/iobuf.h>
6419 +#include <linux/grsecurity.h>
6420  
6421  #include <asm/uaccess.h>
6422  
6423 @@ -95,7 +96,7 @@
6424         write_unlock(&files->file_lock);
6425  }
6426  
6427 -int do_truncate(struct dentry *dentry, loff_t length)
6428 +int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
6429  {
6430         struct inode *inode = dentry->d_inode;
6431         int error;
6432 @@ -105,6 +106,9 @@
6433         if (length < 0)
6434                 return -EINVAL;
6435  
6436 +       if (!gr_acl_handle_truncate(dentry, mnt))
6437 +               return -EACCES;
6438 +
6439         down_write(&inode->i_alloc_sem);
6440         down(&inode->i_sem);
6441         newattrs.ia_size = length;
6442 @@ -165,7 +169,7 @@
6443         error = locks_verify_truncate(inode, NULL, length);
6444         if (!error) {
6445                 DQUOT_INIT(inode);
6446 -               error = do_truncate(nd.dentry, length);
6447 +               error = do_truncate(nd.dentry, length, nd.mnt);
6448         }
6449         put_write_access(inode);
6450  
6451 @@ -217,7 +221,7 @@
6452  
6453         error = locks_verify_truncate(inode, file, length);
6454         if (!error)
6455 -               error = do_truncate(dentry, length);
6456 +               error = do_truncate(dentry, length, file->f_vfsmnt);
6457  out_putf:
6458         fput(file);
6459  out:
6460 @@ -292,6 +296,12 @@
6461                     (error = permission(inode,MAY_WRITE)) != 0)
6462                         goto dput_and_out;
6463         }
6464 +
6465 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6466 +               error = -EACCES;
6467 +               goto dput_and_out;
6468 +       }
6469 +
6470         error = notify_change(nd.dentry, &newattrs);
6471  dput_and_out:
6472         path_release(&nd);
6473 @@ -344,6 +354,12 @@
6474                     (error = permission(inode,MAY_WRITE)) != 0)
6475                         goto dput_and_out;
6476         }
6477 +
6478 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6479 +               error = -EACCES;
6480 +               goto dput_and_out;
6481 +       }
6482 +
6483         error = notify_change(nd.dentry, &newattrs);
6484  dput_and_out:
6485         path_release(&nd);
6486 @@ -386,6 +402,10 @@
6487                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
6488                    && !special_file(nd.dentry->d_inode->i_mode))
6489                         res = -EROFS;
6490 +               
6491 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
6492 +                       res =  -EACCES;
6493 +
6494                 path_release(&nd);
6495         }
6496  
6497 @@ -409,6 +429,8 @@
6498         if (error)
6499                 goto dput_and_out;
6500  
6501 +       gr_log_chdir(nd.dentry, nd.mnt);
6502 +
6503         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
6504  
6505  dput_and_out:
6506 @@ -439,6 +461,13 @@
6507                 goto out_putf;
6508  
6509         error = permission(inode, MAY_EXEC);
6510 +
6511 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
6512 +               error = -EPERM;
6513 +
6514 +       if (!error)
6515 +               gr_log_chdir(dentry, mnt);
6516 +
6517         if (!error)
6518                 set_fs_pwd(current->fs, mnt, dentry);
6519  out_putf:
6520 @@ -465,8 +494,16 @@
6521         if (!capable(CAP_SYS_CHROOT))
6522                 goto dput_and_out;
6523  
6524 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
6525 +               goto dput_and_out;
6526 +
6527         set_fs_root(current->fs, nd.mnt, nd.dentry);
6528         set_fs_altroot();
6529 +
6530 +       gr_handle_chroot_caps(current);
6531 +
6532 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
6533 +
6534         error = 0;
6535  dput_and_out:
6536         path_release(&nd);
6537 @@ -495,8 +532,20 @@
6538         err = -EPERM;
6539         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6540                 goto out_putf;
6541 +
6542 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
6543 +               err = -EACCES;
6544 +               goto out_putf;
6545 +       }
6546 +
6547         if (mode == (mode_t) -1)
6548                 mode = inode->i_mode;
6549 +
6550 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
6551 +               err = -EPERM;
6552 +               goto out_putf;
6553 +       }           
6554 +
6555         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6556         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6557         err = notify_change(dentry, &newattrs);
6558 @@ -527,8 +576,19 @@
6559         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6560                 goto dput_and_out;
6561  
6562 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
6563 +               error = -EACCES;
6564 +               goto dput_and_out;
6565 +       }
6566 +
6567         if (mode == (mode_t) -1)
6568                 mode = inode->i_mode;
6569 +
6570 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
6571 +               error = -EACCES;
6572 +               goto dput_and_out;
6573 +       }
6574 +
6575         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6576         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6577         error = notify_change(nd.dentry, &newattrs);
6578 @@ -539,7 +599,7 @@
6579         return error;
6580  }
6581  
6582 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
6583 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
6584  {
6585         struct inode * inode;
6586         int error;
6587 @@ -556,6 +616,12 @@
6588         error = -EPERM;
6589         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6590                 goto out;
6591 +
6592 +       if (!gr_acl_handle_chown(dentry, mnt)) {
6593 +               error = -EACCES;
6594 +               goto out;
6595 +       }
6596 +
6597         if (user == (uid_t) -1)
6598                 user = inode->i_uid;
6599         if (group == (gid_t) -1)
6600 @@ -606,7 +672,7 @@
6601  
6602         error = user_path_walk(filename, &nd);
6603         if (!error) {
6604 -               error = chown_common(nd.dentry, user, group);
6605 +               error = chown_common(nd.dentry, user, group, nd.mnt);
6606                 path_release(&nd);
6607         }
6608         return error;
6609 @@ -619,7 +685,7 @@
6610  
6611         error = user_path_walk_link(filename, &nd);
6612         if (!error) {
6613 -               error = chown_common(nd.dentry, user, group);
6614 +               error = chown_common(nd.dentry, user, group, nd.mnt);
6615                 path_release(&nd);
6616         }
6617         return error;
6618 @@ -633,7 +699,8 @@
6619  
6620         file = fget(fd);
6621         if (file) {
6622 -               error = chown_common(file->f_dentry, user, group);
6623 +               error = chown_common(file->f_dentry, user,
6624 +                               group, file->f_vfsmnt);
6625                 fput(file);
6626         }
6627         return error;
6628 @@ -753,6 +820,7 @@
6629          * N.B. For clone tasks sharing a files structure, this test
6630          * will limit the total number of files that can be opened.
6631          */
6632 +       gr_learn_resource(current, RLIMIT_NOFILE, fd);
6633         if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6634                 goto out;
6635  
6636 diff -urN linux-2.4.22.org/fs/proc/array.c linux-2.4.22/fs/proc/array.c
6637 --- linux-2.4.22.org/fs/proc/array.c    2003-11-22 22:08:59.000000000 +0100
6638 +++ linux-2.4.22/fs/proc/array.c        2003-11-22 22:31:12.000000000 +0100
6639 @@ -298,6 +298,12 @@
6640         return buffer - orig;
6641  }
6642  
6643 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6644 +#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
6645 +                       task->flags & PF_PAX_SEGMEXEC || \
6646 +                       task->flags & PF_PAX_RANDEXEC)
6647 +#endif
6648 +
6649  int proc_pid_stat(struct task_struct *task, char * buffer)
6650  {
6651         unsigned long vsize, eip, esp, wchan;
6652 @@ -335,6 +341,19 @@
6653  
6654         wchan = get_wchan(task);
6655  
6656 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6657 +       if (PAX_RAND_FLAGS) {
6658 +               eip = 0;
6659 +               esp = 0;
6660 +               wchan = 0;
6661 +       }
6662 +#endif
6663 +#ifdef CONFIG_GRKERNSEC_HIDESYM
6664 +       wchan = 0;
6665 +       eip = 0;
6666 +       esp = 0;
6667 +#endif
6668 +
6669         collect_sigign_sigcatch(task, &sigign, &sigcatch);
6670  
6671         /* scale priority and nice values from timeslices to -20..20 */
6672 @@ -373,9 +392,15 @@
6673                 vsize,
6674                 mm ? mm->rss : 0, /* you might want to shift this left 3 */
6675                 task->rlim[RLIMIT_RSS].rlim_cur,
6676 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6677 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
6678 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
6679 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
6680 +#else
6681                 mm ? mm->start_code : 0,
6682                 mm ? mm->end_code : 0,
6683                 mm ? mm->start_stack : 0,
6684 +#endif
6685                 esp,
6686                 eip,
6687                 /* The signal information here is obsolete.
6688 @@ -513,6 +538,7 @@
6689  
6690  static int show_map(struct seq_file *m, void *v)
6691  {
6692 +       struct task_struct *task = m->private;
6693         struct vm_area_struct *map = v;
6694         struct file *file = map->vm_file;
6695         int flags = map->vm_flags;
6696 @@ -526,8 +551,13 @@
6697         }
6698  
6699         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
6700 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6701 +                       PAX_RAND_FLAGS ? 0UL : map->vm_start,
6702 +                       PAX_RAND_FLAGS ? 0UL : map->vm_end,
6703 +#else
6704                         map->vm_start,
6705                         map->vm_end,
6706 +#endif
6707                         flags & VM_READ ? 'r' : '-',
6708                         flags & VM_WRITE ? 'w' : '-',
6709                         flags & VM_EXEC ? 'x' : '-',
6710 @@ -601,6 +643,16 @@
6711         .show   = show_map
6712  };
6713  
6714 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR     
6715 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)    
6716 +{       
6717 +       int len;         
6718 +
6719 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));  
6720 +       return len;      
6721 +}       
6722 +#endif
6723 +
6724  #ifdef CONFIG_SMP
6725  int proc_pid_cpu(struct task_struct *task, char * buffer)
6726  {
6727 diff -urN linux-2.4.22.org/fs/proc/base.c linux-2.4.22/fs/proc/base.c
6728 --- linux-2.4.22.org/fs/proc/base.c     2003-11-22 22:08:59.000000000 +0100
6729 +++ linux-2.4.22/fs/proc/base.c 2003-11-22 22:14:07.000000000 +0100
6730 @@ -25,6 +25,7 @@
6731  #include <linux/string.h>
6732  #include <linux/seq_file.h>
6733  #include <linux/namespace.h>
6734 +#include <linux/grsecurity.h>
6735  
6736  /*
6737   * For hysterical raisins we keep the same inumbers as in the old procfs.
6738 @@ -40,6 +41,9 @@
6739  int proc_pid_status(struct task_struct*,char*);
6740  int proc_pid_statm(struct task_struct*,char*);
6741  int proc_pid_cpu(struct task_struct*,char*);
6742 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6743 +int proc_pid_ipaddr(struct task_struct*,char*);
6744 +#endif
6745  
6746  static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
6747  {
6748 @@ -263,9 +267,22 @@
6749  
6750  static int proc_permission(struct inode *inode, int mask)
6751  {
6752 +       int ret;
6753 +       struct task_struct *task;
6754 +
6755         if (vfs_permission(inode, mask) != 0)
6756                 return -EACCES;
6757 -       return proc_check_root(inode);
6758 +       ret = proc_check_root(inode);
6759 +
6760 +       if (ret)
6761 +               return ret;
6762 +
6763 +       task = inode->u.proc_i.task;
6764 +
6765 +       if (!task)
6766 +               return 0;
6767 +
6768 +       return gr_acl_handle_procpidmem(task);
6769  }
6770  
6771  extern struct seq_operations proc_pid_maps_op;
6772 @@ -598,6 +615,9 @@
6773         PROC_PID_STATM,
6774         PROC_PID_MAPS,
6775         PROC_PID_CPU,
6776 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6777 +       PROC_PID_IPADDR,
6778 +#endif
6779         PROC_PID_MOUNTS,
6780         PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
6781  };
6782 @@ -613,6 +633,9 @@
6783  #ifdef CONFIG_SMP
6784    E(PROC_PID_CPU,      "cpu",          S_IFREG|S_IRUGO),
6785  #endif
6786 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6787 +  E(PROC_PID_IPADDR,   "ipaddr",       S_IFREG|S_IRUSR),
6788 +#endif
6789    E(PROC_PID_MAPS,     "maps",         S_IFREG|S_IRUGO),
6790    E(PROC_PID_MEM,      "mem",          S_IFREG|S_IRUSR|S_IWUSR),
6791    E(PROC_PID_CWD,      "cwd",          S_IFLNK|S_IRWXUGO),
6792 @@ -769,10 +792,17 @@
6793         get_task_struct(task);
6794         inode->u.proc_i.task = task;
6795         inode->i_uid = 0;
6796 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6797 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6798 +#else
6799         inode->i_gid = 0;
6800 +#endif
6801 +
6802         if (ino == PROC_PID_INO || task_dumpable(task)) {
6803                 inode->i_uid = task->euid;
6804 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
6805                 inode->i_gid = task->egid;
6806 +#endif
6807         }
6808  
6809  out:
6810 @@ -980,6 +1010,12 @@
6811                         inode->u.proc_i.op.proc_read = proc_pid_cpu;
6812                         break;
6813  #endif
6814 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6815 +               case PROC_PID_IPADDR:
6816 +                       inode->i_fop = &proc_info_file_operations;
6817 +                       inode->u.proc_i.op.proc_read = proc_pid_ipaddr;
6818 +                       break;
6819 +#endif
6820                 case PROC_PID_MEM:
6821                         inode->i_op = &proc_mem_inode_operations;
6822                         inode->i_fop = &proc_mem_operations;
6823 @@ -1078,13 +1114,34 @@
6824         if (!task)
6825                 goto out;
6826  
6827 +       if(gr_check_hidden_task(task)) {
6828 +               free_task_struct(task);
6829 +               goto out;
6830 +       }
6831 +       
6832 +#ifdef CONFIG_GRKERNSEC_PROC
6833 +       if (current->uid && (task->uid != current->uid)
6834 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6835 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
6836 +#endif
6837 +       ) {
6838 +               free_task_struct(task);
6839 +               goto out;
6840 +       }       
6841 +#endif
6842         inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
6843  
6844         free_task_struct(task);
6845  
6846         if (!inode)
6847                 goto out;
6848 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6849 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
6850 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6851 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
6852 +#else
6853         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
6854 +#endif
6855         inode->i_op = &proc_base_inode_operations;
6856         inode->i_fop = &proc_base_operations;
6857         inode->i_nlink = 3;
6858 @@ -1124,6 +1181,18 @@
6859                 int pid = p->pid;
6860                 if (!pid)
6861                         continue;
6862 +               if(gr_pid_is_chrooted(p))
6863 +                       continue;
6864 +               if(gr_check_hidden_task(p)) 
6865 +                       continue;
6866 +#ifdef CONFIG_GRKERNSEC_PROC
6867 +               if (current->uid && (p->uid != current->uid)
6868 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6869 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
6870 +#endif
6871 +               )
6872 +                       continue;       
6873 +#endif
6874                 if (--index >= 0)
6875                         continue;
6876                 pids[nr_pids] = pid;
6877 diff -urN linux-2.4.22.org/fs/proc/generic.c linux-2.4.22/fs/proc/generic.c
6878 --- linux-2.4.22.org/fs/proc/generic.c  2003-11-22 22:08:59.000000000 +0100
6879 +++ linux-2.4.22/fs/proc/generic.c      2003-11-22 22:14:07.000000000 +0100
6880 @@ -504,6 +504,32 @@
6881         return ent;
6882  }
6883  
6884 +#ifdef CONFIG_GRKERNSEC_PROC
6885 +struct proc_dir_entry *proc_priv_mkdir(const char *name, struct proc_dir_entry *parent)
6886 +{
6887 +       struct proc_dir_entry *ent;
6888 +       mode_t mode = 0;
6889 +
6890 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6891 +       mode = S_IFDIR | S_IRUSR | S_IXUSR;
6892 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6893 +       mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP;
6894 +#endif
6895 +
6896 +       ent = proc_create(&parent, name, mode, 2);
6897 +       if (ent) {
6898 +               ent->proc_fops = &proc_dir_operations;
6899 +               ent->proc_iops = &proc_dir_inode_operations;
6900 +
6901 +               if (proc_register(parent, ent) < 0) {
6902 +                       kfree(ent);
6903 +                       ent = NULL;
6904 +               }
6905 +       }
6906 +       return ent;
6907 +}
6908 +#endif
6909 +
6910  struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
6911                                          struct proc_dir_entry *parent)
6912  {
6913 diff -urN linux-2.4.22.org/fs/proc/inode.c linux-2.4.22/fs/proc/inode.c
6914 --- linux-2.4.22.org/fs/proc/inode.c    2003-11-22 22:08:59.000000000 +0100
6915 +++ linux-2.4.22/fs/proc/inode.c        2003-11-22 22:14:07.000000000 +0100
6916 @@ -152,7 +152,11 @@
6917                 if (de->mode) {
6918                         inode->i_mode = de->mode;
6919                         inode->i_uid = de->uid;
6920 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6921 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6922 +#else
6923                         inode->i_gid = de->gid;
6924 +#endif                 
6925                 }
6926                 if (de->size)
6927                         inode->i_size = de->size;
6928
6929 diff -urN linux-2.4.23/fs/proc/proc_misc.c linux-2.4.23/fs/proc/proc_misc.c
6930 --- linux-2.4.23/fs/proc/proc_misc.c    2003-11-28 13:26:21.000000000 -0500
6931 +++ linux-2.4.23/fs/proc/proc_misc.c    2003-11-30 16:37:16.000000000 -0500
6932 @@ -590,6 +590,7 @@
6933  void __init proc_misc_init(void)
6934  {
6935         struct proc_dir_entry *entry;
6936 +       int gr_mode = 0;
6937         static struct {
6938                 char *name;
6939                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
6940 @@ -604,17 +605,21 @@
6941  #ifdef CONFIG_STRAM_PROC
6942                 {"stram",       stram_read_proc},
6943  #endif
6944 -#ifdef CONFIG_MODULES
6945 +#if defined(CONFIG_MODULES) && !defined(CONFIG_GRKERNSEC_PROC)
6946                 {"modules",     modules_read_proc},
6947  #endif
6948                 {"stat",        kstat_read_proc},
6949 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
6950                 {"devices",     devices_read_proc},
6951 -#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
6952 +#endif
6953 +#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
6954                 {"interrupts",  interrupts_read_proc},
6955  #endif
6956                 {"filesystems", filesystems_read_proc},
6957 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
6958                 {"dma",         dma_read_proc},
6959                 {"cmdline",     cmdline_read_proc},
6960 +#endif
6961  #ifdef CONFIG_SGI_DS1286
6962                 {"rtc",         ds1286_read_proc},
6963  #endif
6964 @@ -626,29 +631,60 @@
6965         for (p = simple_ones; p->name; p++)
6966                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
6967  
6968 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6969 +       gr_mode = S_IRUSR;
6970 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6971 +       gr_mode = S_IRUSR | S_IRGRP;
6972 +#endif
6973 +#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES)
6974 +       create_proc_read_entry("modules", gr_mode, NULL, &modules_read_proc, NULL);
6975 +#endif
6976 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6977 +       create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
6978 +       create_proc_read_entry("dma", gr_mode, NULL, &dma_read_proc, NULL);
6979 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
6980 +#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
6981 +       create_proc_read_entry("interrupts", gr_mode, NULL, &interrupts_read_proc, NULL);
6982 +#endif
6983 +#endif
6984 +
6985         proc_symlink("mounts", NULL, "self/mounts");
6986  
6987         /* And now for trickier ones */
6988         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
6989         if (entry)
6990                 entry->proc_fops = &proc_kmsg_operations;
6991 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6992 +       create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
6993 +#else
6994         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
6995 -#if defined(CONFIG_X86)
6996 +#endif
6997 +#if defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
6998         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
6999 +#elif defined(CONFIG_X86)
7000 +       create_seq_entry("interrupts", gr_mode, &proc_interrupts_operations);
7001  #endif
7002 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7003 +       create_seq_entry("ioports", gr_mode, &proc_ioports_operations);
7004 +       create_seq_entry("iomem", gr_mode, &proc_iomem_operations);
7005 +       create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
7006 +#else
7007         create_seq_entry("ioports", 0, &proc_ioports_operations);
7008         create_seq_entry("iomem", 0, &proc_iomem_operations);
7009 -       create_seq_entry("partitions", 0, &proc_partitions_operations);
7010         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
7011 +#endif
7012 +       create_seq_entry("partitions", 0, &proc_partitions_operations);
7013  #ifdef CONFIG_MODULES
7014 -       create_seq_entry("ksyms", 0, &proc_ksyms_operations);
7015 +       create_seq_entry("ksyms", gr_mode, &proc_ksyms_operations);
7016  #endif
7017 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7018         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
7019         if (proc_root_kcore) {
7020                 proc_root_kcore->proc_fops = &proc_kcore_operations;
7021                 proc_root_kcore->size =
7022                                 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
7023         }
7024 +#endif
7025         if (prof_shift) {
7026                 entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
7027                 if (entry) {
7028 diff -urN linux-2.4.22.org/fs/proc/proc_tty.c linux-2.4.22/fs/proc/proc_tty.c
7029 --- linux-2.4.22.org/fs/proc/proc_tty.c 2003-11-22 22:09:00.000000000 +0100
7030 +++ linux-2.4.22/fs/proc/proc_tty.c     2003-11-22 22:14:07.000000000 +0100
7031 @@ -174,7 +174,11 @@
7032         if (!proc_mkdir("tty", 0))
7033                 return;
7034         proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
7035 +#ifdef CONFIG_GRKERNSEC_PROC
7036 +       proc_tty_driver = proc_priv_mkdir("tty/driver", 0);
7037 +#else
7038         proc_tty_driver = proc_mkdir("tty/driver", 0);
7039 +#endif
7040  
7041         create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
7042         create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
7043 diff -urN linux-2.4.22.org/fs/proc/root.c linux-2.4.22/fs/proc/root.c
7044 --- linux-2.4.22.org/fs/proc/root.c     2003-11-22 22:08:59.000000000 +0100
7045 +++ linux-2.4.22/fs/proc/root.c 2003-11-22 22:14:07.000000000 +0100
7046 @@ -37,13 +37,21 @@
7047                 return;
7048         }
7049         proc_misc_init();
7050 +#ifdef CONFIG_GRKERNSEC_PROC
7051 +       proc_net = proc_priv_mkdir("net", 0);
7052 +#else
7053         proc_net = proc_mkdir("net", 0);
7054 +#endif
7055  #ifdef CONFIG_SYSVIPC
7056         proc_mkdir("sysvipc", 0);
7057  #endif
7058  #ifdef CONFIG_SYSCTL
7059 +#ifdef CONFIG_GRKERNSEC_PROC
7060 +       proc_sys_root = proc_priv_mkdir("sys", 0);
7061 +#else
7062         proc_sys_root = proc_mkdir("sys", 0);
7063  #endif
7064 +#endif
7065  #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
7066         proc_mkdir("sys/fs", 0);
7067         proc_mkdir("sys/fs/binfmt_misc", 0);
7068 @@ -67,7 +75,12 @@
7069  #ifdef CONFIG_PPC_RTAS
7070         proc_rtas_init();
7071  #endif
7072 +
7073 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7074 +       proc_bus = proc_priv_mkdir("bus", 0);
7075 +#else
7076         proc_bus = proc_mkdir("bus", 0);
7077 +#endif
7078  }
7079  
7080  static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
7081 diff -urN linux-2.4.22.org/fs/readdir.c linux-2.4.22/fs/readdir.c
7082 --- linux-2.4.22.org/fs/readdir.c       2003-11-22 22:08:59.000000000 +0100
7083 +++ linux-2.4.22/fs/readdir.c   2003-11-22 22:14:07.000000000 +0100
7084 @@ -10,6 +10,7 @@
7085  #include <linux/stat.h>
7086  #include <linux/file.h>
7087  #include <linux/smp_lock.h>
7088 +#include <linux/grsecurity.h>
7089  
7090  #include <asm/uaccess.h>
7091  
7092 @@ -181,6 +182,7 @@
7093  struct readdir_callback {
7094         struct old_linux_dirent * dirent;
7095         int count;
7096 +       struct nameidata nd;
7097  };
7098  
7099  static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
7100 @@ -191,6 +193,10 @@
7101  
7102         if (buf->count)
7103                 return -EINVAL;
7104 +
7105 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7106 +               return 0;
7107 +           
7108         buf->count++;
7109         dirent = buf->dirent;
7110         put_user(ino, &dirent->d_ino);
7111 @@ -215,6 +221,9 @@
7112         buf.count = 0;
7113         buf.dirent = dirent;
7114  
7115 +       buf.nd.dentry = file->f_dentry;
7116 +       buf.nd.mnt = file->f_vfsmnt;
7117 +
7118         error = vfs_readdir(file, fillonedir, &buf);
7119         if (error >= 0)
7120                 error = buf.count;
7121 @@ -242,6 +251,7 @@
7122         struct linux_dirent * previous;
7123         int count;
7124         int error;
7125 +       struct nameidata nd;
7126  };
7127  
7128  static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
7129 @@ -254,6 +264,10 @@
7130         buf->error = -EINVAL;   /* only used if we fail.. */
7131         if (reclen > buf->count)
7132                 return -EINVAL;
7133 +
7134 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7135 +               return 0;
7136 +
7137         dirent = buf->previous;
7138         if (dirent)
7139                 put_user(offset, &dirent->d_off);
7140 @@ -286,6 +300,9 @@
7141         buf.count = count;
7142         buf.error = 0;
7143  
7144 +       buf.nd.dentry = file->f_dentry;
7145 +       buf.nd.mnt = file->f_vfsmnt;
7146 +
7147         error = vfs_readdir(file, filldir, &buf);
7148         if (error < 0)
7149                 goto out_putf;
7150 @@ -320,6 +337,7 @@
7151         struct linux_dirent64 * previous;
7152         int count;
7153         int error;
7154 +       struct nameidata nd;
7155  };
7156  
7157  static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
7158 @@ -332,6 +350,10 @@
7159         buf->error = -EINVAL;   /* only used if we fail.. */
7160         if (reclen > buf->count)
7161                 return -EINVAL;
7162 +
7163 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7164 +               return 0;
7165 +       
7166         dirent = buf->previous;
7167         if (dirent) {
7168                 d.d_off = offset;
7169 @@ -369,6 +391,9 @@
7170         buf.count = count;
7171         buf.error = 0;
7172  
7173 +       buf.nd.mnt = file->f_vfsmnt;
7174 +       buf.nd.dentry = file->f_dentry;
7175 +
7176         error = vfs_readdir(file, filldir64, &buf);
7177         if (error < 0)
7178                 goto out_putf;
7179 diff -urN linux-2.4.22.org/grsecurity/Config.in linux-2.4.22/grsecurity/Config.in
7180 --- linux-2.4.22.org/grsecurity/Config.in       1970-01-01 01:00:00.000000000 +0100
7181 +++ linux-2.4.22/grsecurity/Config.in   2003-11-22 22:14:07.000000000 +0100
7182 @@ -0,0 +1,366 @@
7183 +define_bool CONFIG_CRYPTO y
7184 +define_bool CONFIG_CRYPTO_SHA256 y
7185 +choice 'Security level' \
7186 +        "Low           CONFIG_GRKERNSEC_LOW \
7187 +         Medium                CONFIG_GRKERNSEC_MID \
7188 +         High          CONFIG_GRKERNSEC_HI \
7189 +         Customized    CONFIG_GRKERNSEC_CUSTOM" Customized
7190 +if [ "$CONFIG_GRKERNSEC_LOW" = "y" ]; then
7191 +define_bool CONFIG_GRKERNSEC_RANDSRC n
7192 +define_bool CONFIG_GRKERNSEC_RANDRPC n
7193 +define_bool CONFIG_GRKERNSEC_FORKFAIL n
7194 +define_bool CONFIG_GRKERNSEC_TIME n
7195 +define_bool CONFIG_GRKERNSEC_SIGNAL n
7196 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7197 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT n
7198 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7199 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE n
7200 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT n
7201 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD n
7202 +define_bool CONFIG_GRKERNSEC_PROC n
7203 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7204 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
7205 +define_bool CONFIG_GRKERNSEC_HIDESYM n
7206 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7207 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n
7208 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n
7209 +define_bool CONFIG_GRKERNSEC_KMEM n
7210 +define_bool CONFIG_GRKERNSEC_PROC_ADD n
7211 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7212 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7213 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7214 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK n
7215 +define_bool CONFIG_GRKERNSEC_PAX_ASLR n
7216 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP n
7217 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7218 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7219 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7220 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7221 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7222 +if [ "$CONFIG_X86" = "y" ]; then
7223 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7224 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7225 +define_bool CONFIG_GRKERNSEC_IO n
7226 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7227 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7228 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7229 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7230 +fi
7231 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7232 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7233 +define_bool CONFIG_GRKERNSEC_RESLOG n
7234 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7235 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7236 +
7237 +define_int  CONFIG_GRKERNSEC_FLOODTIME 10
7238 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7239 +define_bool CONFIG_GRKERNSEC_LINK y
7240 +define_bool CONFIG_GRKERNSEC_FIFO y
7241 +define_bool CONFIG_GRKERNSEC_RANDPID y
7242 +define_bool CONFIG_GRKERNSEC_EXECVE y
7243 +define_bool CONFIG_GRKERNSEC_RANDNET y
7244 +define_bool CONFIG_GRKERNSEC_RANDISN n
7245 +define_bool CONFIG_GRKERNSEC_DMESG y
7246 +define_bool CONFIG_GRKERNSEC_RANDID y
7247 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7248 +fi
7249 +if [ "$CONFIG_GRKERNSEC_MID" = "y" ]; then
7250 +define_bool CONFIG_GRKERNSEC_KMEM n
7251 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7252 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
7253 +define_bool CONFIG_GRKERNSEC_HIDESYM n
7254 +define_bool CONFIG_GRKERNSEC_PROC_ADD n
7255 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7256 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7257 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7258 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7259 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7260 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7261 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7262 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7263 +if [ "$CONFIG_X86" = "y" ]; then
7264 +define_bool CONFIG_GRKERNSEC_IO n
7265 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7266 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7267 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7268 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7269 +fi
7270 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7271 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7272 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7273 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7274 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7275 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7276 +define_bool CONFIG_GRKERNSEC_RESLOG n
7277 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7278 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7279 +
7280 +define_int  CONFIG_GRKERNSEC_FLOODTIME 10
7281 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7282 +define_bool CONFIG_GRKERNSEC_LINK y
7283 +define_bool CONFIG_GRKERNSEC_FIFO y
7284 +define_bool CONFIG_GRKERNSEC_RANDPID y
7285 +define_bool CONFIG_GRKERNSEC_EXECVE y
7286 +define_bool CONFIG_GRKERNSEC_DMESG y
7287 +define_bool CONFIG_GRKERNSEC_RANDID y
7288 +define_bool CONFIG_GRKERNSEC_RANDNET y
7289 +define_bool CONFIG_GRKERNSEC_RANDISN y
7290 +define_bool CONFIG_GRKERNSEC_RANDSRC y
7291 +define_bool CONFIG_GRKERNSEC_RANDRPC y
7292 +define_bool CONFIG_GRKERNSEC_FORKFAIL y
7293 +define_bool CONFIG_GRKERNSEC_TIME y
7294 +define_bool CONFIG_GRKERNSEC_SIGNAL y
7295 +define_bool CONFIG_GRKERNSEC_CHROOT y
7296 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7297 +define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7298 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7299 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7300 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7301 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7302 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7303 +define_bool CONFIG_GRKERNSEC_PROC y
7304 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7305 +define_int  CONFIG_GRKERNSEC_PROC_GID 10
7306 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7307 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7308 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7309 +define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7310 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7311 +fi
7312 +if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then
7313 +define_int CONFIG_GRKERNSEC_FLOODTIME 10
7314 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7315 +define_bool CONFIG_GRKERNSEC_LINK y
7316 +define_bool CONFIG_GRKERNSEC_FIFO y
7317 +define_bool CONFIG_GRKERNSEC_RANDPID y
7318 +define_bool CONFIG_GRKERNSEC_EXECVE y
7319 +define_bool CONFIG_GRKERNSEC_DMESG y
7320 +define_bool CONFIG_GRKERNSEC_RANDID y
7321 +define_bool CONFIG_GRKERNSEC_RANDSRC y
7322 +define_bool CONFIG_GRKERNSEC_RANDRPC y
7323 +define_bool CONFIG_GRKERNSEC_FORKFAIL y
7324 +define_bool CONFIG_GRKERNSEC_TIME y
7325 +define_bool CONFIG_GRKERNSEC_SIGNAL y
7326 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT y
7327 +define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7328 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7329 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR y
7330 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7331 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7332 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7333 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7334 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS y
7335 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7336 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK y
7337 +define_bool CONFIG_GRKERNSEC_PROC y
7338 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7339 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y
7340 +define_bool CONFIG_GRKERNSEC_HIDESYM y
7341 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7342 +define_int  CONFIG_GRKERNSEC_PROC_GID 10
7343 +define_bool CONFIG_GRKERNSEC_KMEM y
7344 +define_bool CONFIG_GRKERNSEC_RESLOG y
7345 +define_bool CONFIG_GRKERNSEC_RANDNET y
7346 +define_bool CONFIG_GRKERNSEC_RANDISN y
7347 +
7348 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7349 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7350 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7351 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7352 +
7353 +define_bool CONFIG_GRKERNSEC_PROC_ADD y
7354 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD y
7355 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE y
7356 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7357 +define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7358 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7359 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC y
7360 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7361 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7362 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT y
7363 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7364 +if [ "$CONFIG_X86" = "y" ]; then
7365 +define_bool CONFIG_GRKERNSEC_IO n
7366 +if [ "$CONFIG_MODULES" = "n" ]; then
7367 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC y
7368 +fi
7369 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK y
7370 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC y
7371 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC y
7372 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7373 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7374 +fi
7375 +if [ "$CONFIG_PARISC" = "y" ]; then
7376 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP y
7377 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT y
7378 +fi
7379 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT y
7380 +fi
7381 +if [ "$CONFIG_GRKERNSEC_CUSTOM" = "y" ]; then
7382 +mainmenu_option next_comment
7383 +comment 'Address Space Protection'
7384 +bool 'Enforce non-executable pages' CONFIG_GRKERNSEC_PAX_NOEXEC
7385 +if [ "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7386 +  bool 'Paging based non-executable pages' CONFIG_GRKERNSEC_PAX_PAGEEXEC
7387 +  if [ "$CONFIG_X86" = "y" ]; then
7388 +    bool 'Segmentation based non-executable pages' CONFIG_GRKERNSEC_PAX_SEGMEXEC
7389 +  fi
7390 +  if [ "$CONFIG_X86" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7391 +    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7392 +      bool '   Emulate trampolines' CONFIG_GRKERNSEC_PAX_EMUTRAMP
7393 +      if [ "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then
7394 +        bool '    Automatically emulate sigreturn trampolines' CONFIG_GRKERNSEC_PAX_EMUSIGRT
7395 +      fi
7396 +    fi
7397 +  fi
7398 +  bool '   Restrict mprotect()' CONFIG_GRKERNSEC_PAX_MPROTECT
7399 +  if [ "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then
7400 +    if [ "$CONFIG_X86" = "y" ]; then
7401 +      bool '    Disallow ELF text relocations (DANGEROUS)' CONFIG_GRKERNSEC_PAX_NOELFRELOCS
7402 +    else
7403 +    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" ]; then
7404 +      bool '    Allow ELF ET_EXEC text relocations' CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
7405 +    fi
7406 +    if [ "$CONFIG_PPC32" = "y" ]; then
7407 +      define_bool CONFIG_GRKERNSEC_PAX_SYSCALL y
7408 +    fi
7409 +    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7410 +      bool '    Automatically emulate ELF PLT' CONFIG_GRKERNSEC_PAX_EMUPLT
7411 +      if [ "$CONFIG_GRKERNSEC_PAX_EMUPLT" = "y" ]; then
7412 +        if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
7413 +         define_bool CONFIG_GRKERNSEC_PAX_DLRESOLVE y
7414 +        fi
7415 +      fi
7416 +    fi
7417 +    fi
7418 +  fi
7419 +fi
7420 +if [ "$CONFIG_X86" = "y" -a "$CONFIG_MODULES" = "n" ]; then
7421 +  bool 'Enforce non-executable kernel pages' CONFIG_GRKERNSEC_PAX_KERNEXEC
7422 +fi
7423 +bool 'Address Space Layout Randomization' CONFIG_GRKERNSEC_PAX_ASLR
7424 +if [ "$CONFIG_GRKERNSEC_PAX_ASLR" = "y" ]; then
7425 +  if [ "$CONFIG_X86_TSC" = "y" ]; then
7426 +    bool '  Randomize kernel stack base' CONFIG_GRKERNSEC_PAX_RANDKSTACK
7427 +  fi
7428 +  bool '  Randomize user stack base' CONFIG_GRKERNSEC_PAX_RANDUSTACK
7429 +  bool '  Randomize mmap() base' CONFIG_GRKERNSEC_PAX_RANDMMAP
7430 +  if [ "$CONFIG_GRKERNSEC_PAX_RANDMMAP" = "y" -a "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7431 +    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7432 +      bool '  Randomize ET_EXEC base' CONFIG_GRKERNSEC_PAX_RANDEXEC
7433 +    fi
7434 +  fi
7435 +fi
7436 +bool 'Deny writing to /dev/kmem, /dev/mem, and /dev/port' CONFIG_GRKERNSEC_KMEM
7437 +if [ "$CONFIG_X86" = "y" ]; then
7438 +  bool 'Disable privileged I/O' CONFIG_GRKERNSEC_IO
7439 +  if [ "$CONFIG_GRKERNSEC_IO" = "y" ]; then
7440 +    define_bool CONFIG_RTC y
7441 +  fi
7442 +fi
7443 +bool 'Remove addresses from /proc/pid/[maps|stat]' CONFIG_GRKERNSEC_PROC_MEMMAP
7444 +bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM
7445 +endmenu
7446 +mainmenu_option next_comment
7447 +comment 'Role Based Access Control Options'
7448 +bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN
7449 +int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7450 +int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7451 +endmenu
7452 +mainmenu_option next_comment
7453 +comment 'Filesystem Protections'
7454 +bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC
7455 +if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then
7456 + bool '   Restrict to user only' CONFIG_GRKERNSEC_PROC_USER
7457 + if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then
7458 +  bool '   Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP
7459 +  if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7460 +   int  '   GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001
7461 +  fi
7462 + fi
7463 + if [ "$CONFIG_GRKERNSEC_PROC_USER" != "n" -o "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7464 +  bool '   Additional restrictions' CONFIG_GRKERNSEC_PROC_ADD
7465 + fi
7466 +fi
7467 +bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK
7468 +bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO
7469 +bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT
7470 +if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then
7471 +bool '   Deny mounts' CONFIG_GRKERNSEC_CHROOT_MOUNT
7472 +bool '   Deny double-chroots' CONFIG_GRKERNSEC_CHROOT_DOUBLE
7473 +bool '   Deny pivot_root in chroot' CONFIG_GRKERNSEC_CHROOT_PIVOT
7474 +bool '   Enforce chdir("/") on all chroots' CONFIG_GRKERNSEC_CHROOT_CHDIR
7475 +bool '   Deny (f)chmod +s' CONFIG_GRKERNSEC_CHROOT_CHMOD
7476 +bool '   Deny fchdir out of chroot' CONFIG_GRKERNSEC_CHROOT_FCHDIR
7477 +bool '   Deny mknod' CONFIG_GRKERNSEC_CHROOT_MKNOD
7478 +bool '   Deny shmat() out of chroot' CONFIG_GRKERNSEC_CHROOT_SHMAT
7479 +bool '   Deny access to abstract AF_UNIX sockets out of chroot' CONFIG_GRKERNSEC_CHROOT_UNIX
7480 +bool '   Protect outside processes' CONFIG_GRKERNSEC_CHROOT_FINDTASK
7481 +bool '   Restrict priority changes' CONFIG_GRKERNSEC_CHROOT_NICE
7482 +bool '   Deny sysctl writes in chroot' CONFIG_GRKERNSEC_CHROOT_SYSCTL
7483 +bool '   Capability restrictions within chroot' CONFIG_GRKERNSEC_CHROOT_CAPS
7484 +fi
7485 +endmenu
7486 +mainmenu_option next_comment
7487 +comment 'Kernel Auditing'
7488 +bool 'Single group for auditing' CONFIG_GRKERNSEC_AUDIT_GROUP
7489 +if [ "$CONFIG_GRKERNSEC_AUDIT_GROUP" != "n" ]; then
7490 +int  '   GID for auditing' CONFIG_GRKERNSEC_AUDIT_GID 1007
7491 +fi
7492 +bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG
7493 +bool 'Resource logging' CONFIG_GRKERNSEC_RESLOG
7494 +bool 'Log execs within chroot' CONFIG_GRKERNSEC_CHROOT_EXECLOG
7495 +bool 'Chdir logging' CONFIG_GRKERNSEC_AUDIT_CHDIR
7496 +bool '(Un)Mount logging' CONFIG_GRKERNSEC_AUDIT_MOUNT
7497 +bool 'IPC logging' CONFIG_GRKERNSEC_AUDIT_IPC
7498 +bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL
7499 +bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL
7500 +bool 'Time change logging' CONFIG_GRKERNSEC_TIME
7501 +bool '/proc/<pid>/ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR
7502 +endmenu
7503 +mainmenu_option next_comment
7504 +comment 'Executable Protections'
7505 +bool 'Enforce RLIMIT_NPROC on execs' CONFIG_GRKERNSEC_EXECVE
7506 +bool 'Dmesg(8) restriction' CONFIG_GRKERNSEC_DMESG
7507 +bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID
7508 +bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE
7509 +if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then
7510 +bool '   Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
7511 +int  '   GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
7512 +fi
7513 +endmenu
7514 +mainmenu_option next_comment
7515 +comment 'Network Protections'
7516 +bool 'Larger entropy pools' CONFIG_GRKERNSEC_RANDNET
7517 +bool 'Truly random TCP ISN selection' CONFIG_GRKERNSEC_RANDISN
7518 +bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID
7519 +bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC
7520 +bool 'Randomized RPC XIDs' CONFIG_GRKERNSEC_RANDRPC
7521 +bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET
7522 +if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then
7523 +bool '  Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL
7524 +if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then
7525 +int  '   GID to deny all sockets for:' CONFIG_GRKERNSEC_SOCKET_ALL_GID 1004
7526 +fi
7527 +bool '  Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT
7528 +if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then
7529 +int  '   GID to deny client sockets for:' CONFIG_GRKERNSEC_SOCKET_CLIENT_GID 1003
7530 +fi
7531 +bool '  Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER
7532 +if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then
7533 +int  '   GID to deny server sockets for:' CONFIG_GRKERNSEC_SOCKET_SERVER_GID 1002
7534 +fi
7535 +fi
7536 +endmenu
7537 +if [ "$CONFIG_SYSCTL" != "n" ]; then
7538 +mainmenu_option next_comment
7539 +comment 'Sysctl support'
7540 +bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL
7541 +endmenu
7542 +fi
7543 +mainmenu_option next_comment
7544 +comment 'Logging options'
7545 +int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10
7546 +int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4
7547 +endmenu
7548 +fi
7549 diff -urN linux-2.4.22.org/grsecurity/gracl_alloc.c linux-2.4.22/grsecurity/gracl_alloc.c
7550 --- linux-2.4.22.org/grsecurity/gracl_alloc.c   1970-01-01 01:00:00.000000000 +0100
7551 +++ linux-2.4.22/grsecurity/gracl_alloc.c       2003-11-22 22:14:08.000000000 +0100
7552 @@ -0,0 +1,94 @@
7553 +/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
7554 +
7555 +#include <linux/kernel.h>
7556 +#include <linux/mm.h>
7557 +#include <linux/slab.h>
7558 +#include <linux/vmalloc.h>
7559 +#include <linux/gracl.h>
7560 +#include <linux/grsecurity.h>
7561 +
7562 +static unsigned long alloc_stack_next = 1;
7563 +static unsigned long alloc_stack_size = 1;
7564 +static void **alloc_stack;
7565 +
7566 +static __inline__ int
7567 +alloc_pop(void)
7568 +{
7569 +       if ((alloc_stack_next - 1) == 0)
7570 +               return 0;
7571 +
7572 +       if (*(alloc_stack + alloc_stack_next - 2))
7573 +               kfree(*(alloc_stack + alloc_stack_next - 2));
7574 +
7575 +       alloc_stack_next--;
7576 +
7577 +       return 1;
7578 +}
7579 +
7580 +static __inline__ void
7581 +alloc_push(void *buf)
7582 +{
7583 +       if (alloc_stack_next >= alloc_stack_size)
7584 +               BUG();
7585 +
7586 +       *(alloc_stack + alloc_stack_next - 1) = buf;
7587 +
7588 +       alloc_stack_next++;
7589 +
7590 +       return;
7591 +}
7592 +
7593 +void *
7594 +acl_alloc(unsigned long len)
7595 +{
7596 +       void *ret;
7597 +
7598 +       if (len > PAGE_SIZE)
7599 +               BUG();
7600 +
7601 +       ret = kmalloc(len, GFP_KERNEL);
7602 +
7603 +       if (ret)
7604 +               alloc_push(ret);
7605 +
7606 +       return ret;
7607 +}
7608 +
7609 +void
7610 +acl_free_all(void)
7611 +{
7612 +       if (gr_acl_is_enabled() || !alloc_stack)
7613 +               return;
7614 +
7615 +       while (alloc_pop()) ;
7616 +
7617 +       if (alloc_stack) {
7618 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
7619 +                       kfree(alloc_stack);
7620 +               else
7621 +                       vfree(alloc_stack);
7622 +       }
7623 +
7624 +       alloc_stack = NULL;
7625 +       alloc_stack_size = 1;
7626 +       alloc_stack_next = 1;
7627 +
7628 +       return;
7629 +}
7630 +
7631 +int
7632 +acl_alloc_stack_init(unsigned long size)
7633 +{
7634 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
7635 +               alloc_stack =
7636 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
7637 +       else
7638 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
7639 +
7640 +       alloc_stack_size = size;
7641 +
7642 +       if (!alloc_stack)
7643 +               return 0;
7644 +       else
7645 +               return 1;
7646 +}
7647 diff -urN linux-2.4.22.org/grsecurity/gracl.c linux-2.4.22/grsecurity/gracl.c
7648 --- linux-2.4.22.org/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100
7649 +++ linux-2.4.22/grsecurity/gracl.c     2003-11-22 22:14:08.000000000 +0100
7650 @@ -0,0 +1,2766 @@
7651 +/* 
7652 + * grsecurity/gracl.c
7653 + * Copyright Brad Spengler 2001, 2002, 2003
7654 + *
7655 + */
7656 +
7657 +#include <linux/kernel.h>
7658 +#include <linux/sched.h>
7659 +#include <linux/mm.h>
7660 +#include <linux/file.h>
7661 +#include <linux/fs.h>
7662 +#include <linux/proc_fs.h>
7663 +#include <linux/smp_lock.h>
7664 +#include <linux/slab.h>
7665 +#include <linux/vmalloc.h>
7666 +#include <linux/types.h>
7667 +#include <linux/capability.h>
7668 +#include <linux/sysctl.h>
7669 +#include <linux/gracl.h>
7670 +#include <linux/gralloc.h>
7671 +#include <linux/grsecurity.h>
7672 +#include <linux/grinternal.h>
7673 +
7674 +#include <asm/uaccess.h>
7675 +#include <asm/errno.h>
7676 +#include <asm/mman.h>
7677 +
7678 +static struct acl_role_db acl_role_set;
7679 +static struct acl_role_label *role_list_head;
7680 +static struct name_db name_set;
7681 +static struct name_db inodev_set;
7682 +
7683 +static struct acl_role_label *default_role;
7684 +
7685 +static u16 acl_sp_role_value;
7686 +
7687 +static DECLARE_MUTEX(gr_dev_sem);
7688 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
7689 +
7690 +extern char *gr_shared_page[4][NR_CPUS];
7691 +struct gr_arg *gr_usermode;
7692 +
7693 +static unsigned long gr_status = GR_STATUS_INIT;
7694 +
7695 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
7696 +extern void gr_clear_learn_entries(void);
7697 +
7698 +#ifdef CONFIG_GRKERNSEC_RESLOG
7699 +extern __inline__ void gr_log_resource(const struct task_struct *task,
7700 +                                      const int res,
7701 +                                      const unsigned long wanted);
7702 +#endif
7703 +
7704 +unsigned char *gr_system_salt;
7705 +unsigned char *gr_system_sum;
7706 +
7707 +static struct sprole_pw **acl_special_roles = NULL;
7708 +static __u16 num_sprole_pws = 0;
7709 +
7710 +static struct acl_role_label *kernel_role = NULL;
7711 +
7712 +/* The following are used to keep a place held in the hash table when we move
7713 +   entries around.  They can be replaced during insert. */
7714 +
7715 +static struct acl_subject_label *deleted_subject;
7716 +static struct acl_object_label *deleted_object;
7717 +static struct name_entry *deleted_inodev;
7718 +
7719 +/* for keeping track of the last and final allocated subjects, since
7720 +   nested subject parsing is tricky
7721 +*/
7722 +static struct acl_subject_label *s_last = NULL;
7723 +static struct acl_subject_label *s_final = NULL;
7724 +
7725 +static unsigned int gr_auth_attempts = 0;
7726 +static unsigned long gr_auth_expires = 0UL;
7727 +
7728 +extern int gr_init_uidset(void);
7729 +extern void gr_free_uidset(void);
7730 +extern void gr_remove_uid(uid_t uid);
7731 +extern int gr_find_uid(uid_t uid);
7732 +
7733 +__inline__ int
7734 +gr_acl_is_enabled(void)
7735 +{
7736 +       return (gr_status & GR_READY);
7737 +}
7738 +
7739 +__inline__ int
7740 +gr_acl_tpe_check(void)
7741 +{
7742 +       if (unlikely(!(gr_status & GR_READY)))
7743 +               return 0;
7744 +       if (current->role->roletype & GR_ROLE_TPE)
7745 +               return 1;
7746 +       else
7747 +               return 0;
7748 +}
7749 +
7750 +int
7751 +gr_handle_rawio(const struct inode *inode)
7752 +{
7753 +       if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
7754 +           ((gr_status & GR_READY)
7755 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7756 +            || (grsec_enable_chroot_caps && proc_is_chrooted(current))
7757 +#endif
7758 +           ))
7759 +               return 1;
7760 +       return 0;
7761 +}
7762 +
7763 +
7764 +static __inline__ int
7765 +gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
7766 +{
7767 +       int i;
7768 +       unsigned long *l1;
7769 +       unsigned long *l2;
7770 +       unsigned char *c1;
7771 +       unsigned char *c2;
7772 +       int num_longs;
7773 +
7774 +       if (likely(lena != lenb))
7775 +               return 0;
7776 +
7777 +       l1 = (unsigned long *)a;
7778 +       l2 = (unsigned long *)b;
7779 +
7780 +       num_longs = lena / sizeof(unsigned long);
7781 +
7782 +       for (i = num_longs; i--; l1++, l2++) {
7783 +               if (unlikely(*l1 != *l2))
7784 +                       return 0;
7785 +       }
7786 +
7787 +       c1 = (unsigned char *) l1;
7788 +       c2 = (unsigned char *) l2;
7789 +
7790 +       i = lena - (num_longs * sizeof(unsigned long)); 
7791 +
7792 +       for (; i--; c1++, c2++) {
7793 +               if (unlikely(*c1 != *c2))
7794 +                       return 0;
7795 +       }
7796 +
7797 +       return 1;
7798 +}
7799 +               
7800 +static __inline__ char *
7801 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
7802 +           char *buf, int buflen)
7803 +{
7804 +       char *res;
7805 +       struct dentry *our_dentry;
7806 +       struct vfsmount *our_mount;
7807 +       struct vfsmount *rootmnt;
7808 +       struct dentry *root;
7809 +
7810 +       our_dentry = (struct dentry *) dentry;
7811 +       our_mount = (struct vfsmount *) vfsmnt;
7812 +
7813 +       read_lock(&child_reaper->fs->lock);
7814 +       rootmnt = mntget(child_reaper->fs->rootmnt);
7815 +       root = dget(child_reaper->fs->root);
7816 +       read_unlock(&child_reaper->fs->lock);
7817 +
7818 +       spin_lock(&dcache_lock);
7819 +       res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
7820 +       spin_unlock(&dcache_lock);
7821 +       dput(root);
7822 +       mntput(rootmnt);
7823 +       return res;
7824 +}
7825 +
7826 +char *
7827 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
7828 +{
7829 +       return d_real_path(dentry, mnt, gr_shared_page[0][smp_processor_id()],
7830 +                          PAGE_SIZE);
7831 +}
7832 +
7833 +char *
7834 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
7835 +{
7836 +       return d_real_path(dentry, mnt, gr_shared_page[1][smp_processor_id()],
7837 +                          PAGE_SIZE);
7838 +}
7839 +
7840 +char *
7841 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
7842 +{
7843 +       return d_real_path(dentry, mnt, gr_shared_page[2][smp_processor_id()],
7844 +                          PAGE_SIZE);
7845 +}
7846 +
7847 +char *
7848 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
7849 +{
7850 +       return d_real_path(dentry, mnt, gr_shared_page[3][smp_processor_id()],
7851 +                          PAGE_SIZE);
7852 +}
7853 +
7854 +__inline__ __u32
7855 +to_gr_audit(const __u32 reqmode)
7856 +{
7857 +       __u32 retmode = 0;
7858 +
7859 +       retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
7860 +       retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
7861 +       retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
7862 +       retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
7863 +       retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
7864 +       retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
7865 +       retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
7866 +       retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
7867 +       retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
7868 +
7869 +       return retmode;
7870 +}
7871 +
7872 +__inline__ struct acl_role_label *
7873 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
7874 +                     const gid_t gid)
7875 +{
7876 +       unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
7877 +       struct acl_role_label *match;
7878 +       struct role_allowed_ip *ipp;
7879 +       __u8 i = 0;
7880 +
7881 +       match = acl_role_set.r_hash[index];
7882 +
7883 +       while (match
7884 +              && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
7885 +               index = (index + (1 << i)) % acl_role_set.r_size;
7886 +               match = acl_role_set.r_hash[index];
7887 +               i = (i + 1) % 32;
7888 +       }
7889 +
7890 +       if (!match || match->uidgid != uid || !(match->roletype & GR_ROLE_USER)) {
7891 +             try_group:
7892 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
7893 +               match = acl_role_set.r_hash[index];
7894 +               i = 0;
7895 +
7896 +               while (match
7897 +                      && (match->uidgid != gid
7898 +                          || !(match->roletype & GR_ROLE_GROUP))) {
7899 +                       index = (index + (1 << i)) % acl_role_set.r_size;
7900 +                       match = acl_role_set.r_hash[index];
7901 +                       i = (i + 1) % 32;
7902 +               }
7903 +
7904 +               if (!match || match->uidgid != gid
7905 +                   || !(match->roletype & GR_ROLE_GROUP))
7906 +                       match = default_role;
7907 +               else if (likely(!match->allowed_ips)) {
7908 +                       return match;
7909 +               } else {
7910 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7911 +                               if (likely
7912 +                                   ((task->curr_ip & ipp->netmask) ==
7913 +                                    (ipp->addr & ipp->netmask)))
7914 +                                       return match;
7915 +                       }
7916 +                       match = default_role;
7917 +               }
7918 +       } else if (likely(!match->allowed_ips)) {
7919 +               return match;
7920 +       } else {
7921 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7922 +                       if (likely
7923 +                           ((task->curr_ip & ipp->netmask) ==
7924 +                            (ipp->addr & ipp->netmask)))
7925 +                               return match;
7926 +               }
7927 +               goto try_group;
7928 +       }
7929 +
7930 +       return match;
7931 +}
7932 +
7933 +__inline__ struct acl_subject_label *
7934 +lookup_acl_subj_label(const ino_t ino, const kdev_t dev,
7935 +                     const struct acl_role_label *role)
7936 +{
7937 +       unsigned long subj_size = role->subj_hash_size;
7938 +       struct acl_subject_label **s_hash = role->subj_hash;
7939 +       unsigned long index = fhash(ino, dev, subj_size);
7940 +       struct acl_subject_label *match;
7941 +       __u8 i = 0;
7942 +
7943 +       match = s_hash[index];
7944 +
7945 +       while (match && (match->inode != ino || match->device != dev ||
7946 +              (match->mode & GR_DELETED))) {
7947 +               index = (index + (1 << i)) % subj_size;
7948 +               match = s_hash[index];
7949 +               i = (i + 1) % 32;
7950 +       }
7951 +
7952 +       if (unlikely(match && (match != deleted_subject) &&
7953 +                    (match->inode == ino) && (match->device == dev) &&
7954 +                    !(match->mode & GR_DELETED)))
7955 +               return match;
7956 +       else
7957 +               return NULL;
7958 +}
7959 +
7960 +static __inline__ struct acl_object_label *
7961 +lookup_acl_obj_label(const ino_t ino, const kdev_t dev,
7962 +                    const struct acl_subject_label *subj)
7963 +{
7964 +       unsigned long obj_size = subj->obj_hash_size;
7965 +       struct acl_object_label **o_hash = subj->obj_hash;
7966 +       unsigned long index = fhash(ino, dev, obj_size);
7967 +       struct acl_object_label *match;
7968 +       __u8 i = 0;
7969 +
7970 +       match = o_hash[index];
7971 +
7972 +       while (match && (match->inode != ino || match->device != dev ||
7973 +              (match->mode & GR_DELETED))) {
7974 +               index = (index + (1 << i)) % obj_size;
7975 +               match = o_hash[index];
7976 +               i = (i + 1) % 32;
7977 +       }
7978 +
7979 +       if (unlikely(match && (match != deleted_object) &&
7980 +                    (match->inode == ino) && (match->device == dev) &&
7981 +                    !(match->mode & GR_DELETED)))
7982 +               return match;
7983 +       else
7984 +               return NULL;
7985 +}
7986 +
7987 +static __inline__ struct acl_object_label *
7988 +lookup_acl_obj_label_create(const ino_t ino, const kdev_t dev,
7989 +                    const struct acl_subject_label *subj)
7990 +{
7991 +       unsigned long obj_size = subj->obj_hash_size;
7992 +       struct acl_object_label **o_hash = subj->obj_hash;
7993 +       unsigned long index = fhash(ino, dev, obj_size);
7994 +       struct acl_object_label *match;
7995 +       __u8 i = 0;
7996 +
7997 +       match = o_hash[index];
7998 +
7999 +       while (match && (match->inode != ino || match->device != dev ||
8000 +              !(match->mode & GR_DELETED))) {
8001 +               index = (index + (1 << i)) % obj_size;
8002 +               match = o_hash[index];
8003 +               i = (i + 1) % 32;
8004 +       }
8005 +
8006 +       if (unlikely(match && (match != deleted_object) &&
8007 +                    (match->inode == ino) && (match->device == dev) &&
8008 +                    (match->mode & GR_DELETED)))
8009 +               return match;
8010 +
8011 +       i = 0;
8012 +       index = fhash(ino, dev, obj_size);
8013 +       match = o_hash[index];
8014 +
8015 +       while (match && (match->inode != ino || match->device != dev ||
8016 +              (match->mode & GR_DELETED))) {
8017 +               index = (index + (1 << i)) % obj_size;
8018 +               match = o_hash[index];
8019 +               i = (i + 1) % 32;
8020 +       }
8021 +
8022 +       if (unlikely(match && (match != deleted_object) &&
8023 +                    (match->inode == ino) && (match->device == dev) &&
8024 +                    !(match->mode & GR_DELETED)))
8025 +               return match;
8026 +       else
8027 +               return NULL;
8028 +}
8029 +
8030 +static __inline__ struct name_entry *
8031 +lookup_name_entry(const char *name)
8032 +{
8033 +       __u16 len = strlen(name);
8034 +       unsigned long index = nhash(name, len, name_set.n_size);
8035 +       struct name_entry *match;
8036 +       __u8 i = 0;
8037 +
8038 +       match = name_set.n_hash[index];
8039 +
8040 +       while (match && !gr_streq(match->name, name, match->len, len)) {
8041 +               index = (index + (1 << i)) % name_set.n_size;
8042 +               match = name_set.n_hash[index];
8043 +               i = (i + 1) % 32;
8044 +       }
8045 +
8046 +       if (unlikely(!match || !gr_streq(match->name, name, match->len, len)))
8047 +               return NULL;
8048 +       else
8049 +               return match;
8050 +}
8051 +
8052 +static __inline__ struct name_entry *
8053 +lookup_inodev_entry(const ino_t ino, const kdev_t dev)
8054 +{
8055 +       unsigned long index = fhash(ino, dev, inodev_set.n_size);
8056 +       struct name_entry *match;
8057 +       __u8 i = 0;
8058 +
8059 +       match = inodev_set.n_hash[index];
8060 +
8061 +       while (match && (match->inode != ino || match->device != dev)) {
8062 +               index = (index + (1 << i)) % inodev_set.n_size;
8063 +               match = inodev_set.n_hash[index];
8064 +               i = (i + 1) % 32;
8065 +       }
8066 +
8067 +       if (unlikely(match && (match != deleted_inodev) &&
8068 +                    (match->inode == ino) && (match->device == dev)))
8069 +               return match;
8070 +       else
8071 +               return NULL;
8072 +}
8073 +
8074 +static void
8075 +insert_inodev_entry(struct name_entry *nentry)
8076 +{
8077 +       unsigned long index = fhash(nentry->inode, nentry->device,
8078 +                                   inodev_set.n_size);
8079 +       struct name_entry **curr;
8080 +       __u8 i = 0;
8081 +
8082 +       curr = &inodev_set.n_hash[index];
8083 +
8084 +       while (*curr && *curr != deleted_inodev) {
8085 +               index = (index + (1 << i)) % inodev_set.n_size;
8086 +               curr = &inodev_set.n_hash[index];
8087 +               i = (i + 1) % 32;
8088 +       }
8089 +
8090 +       *curr = nentry;
8091 +
8092 +       return;
8093 +}
8094 +
8095 +static void
8096 +insert_acl_role_label(struct acl_role_label *role)
8097 +{
8098 +       unsigned long index =
8099 +           rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
8100 +       struct acl_role_label **curr;
8101 +       __u8 i = 0;
8102 +
8103 +       curr = &acl_role_set.r_hash[index];
8104 +
8105 +       while (*curr) {
8106 +               index = (index + (1 << i)) % acl_role_set.r_size;
8107 +               curr = &acl_role_set.r_hash[index];
8108 +               i = (i + 1) % 32;
8109 +       }
8110 +
8111 +       *curr = role;
8112 +
8113 +       return;
8114 +}
8115 +
8116 +static int
8117 +insert_name_entry(char *name, const ino_t inode, const kdev_t device)
8118 +{
8119 +       struct name_entry **curr;
8120 +       __u8 i = 0;
8121 +       __u16 len = strlen(name);
8122 +       unsigned long index = nhash(name, len, name_set.n_size);
8123 +
8124 +       curr = &name_set.n_hash[index];
8125 +
8126 +       while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
8127 +               index = (index + (1 << i)) % name_set.n_size;
8128 +               curr = &name_set.n_hash[index];
8129 +               i = (i + 1) % 32;
8130 +       }
8131 +
8132 +       if (!(*curr)) {
8133 +               struct name_entry *nentry =
8134 +                   acl_alloc(sizeof (struct name_entry));
8135 +               if (!nentry)
8136 +                       return 0;
8137 +               nentry->name = name;
8138 +               nentry->inode = inode;
8139 +               nentry->device = device;
8140 +               nentry->len = len;
8141 +               *curr = nentry;
8142 +               /* insert us into the table searchable by inode/dev */
8143 +               insert_inodev_entry(nentry);
8144 +       }
8145 +
8146 +       return 1;
8147 +}
8148 +
8149 +static void
8150 +insert_acl_obj_label(struct acl_object_label *obj,
8151 +                    struct acl_subject_label *subj)
8152 +{
8153 +       unsigned long index =
8154 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
8155 +       struct acl_object_label **curr;
8156 +       __u8 i = 0;
8157 +
8158 +       curr = &subj->obj_hash[index];
8159 +
8160 +       while (*curr && *curr != deleted_object) {
8161 +               index = (index + (1 << i)) % subj->obj_hash_size;
8162 +               curr = &subj->obj_hash[index];
8163 +               i = (i + 1) % 32;
8164 +       }
8165 +
8166 +       *curr = obj;
8167 +
8168 +       return;
8169 +}
8170 +
8171 +static void
8172 +insert_acl_subj_label(struct acl_subject_label *obj,
8173 +                     struct acl_role_label *role)
8174 +{
8175 +       unsigned long subj_size = role->subj_hash_size;
8176 +       struct acl_subject_label **s_hash = role->subj_hash;
8177 +       unsigned long index = fhash(obj->inode, obj->device, subj_size);
8178 +       struct acl_subject_label **curr;
8179 +       __u8 i = 0;
8180 +
8181 +       curr = &s_hash[index];
8182 +
8183 +       while (*curr && *curr != deleted_subject) {
8184 +               index = (index + (1 << i)) % subj_size;
8185 +               curr = &s_hash[index];
8186 +               i = (i + 1) % 32;
8187 +       }
8188 +
8189 +       *curr = obj;
8190 +
8191 +       return;
8192 +}
8193 +
8194 +static void **
8195 +create_table(__u32 * len)
8196 +{
8197 +       unsigned long table_sizes[] = {
8198 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
8199 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
8200 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
8201 +               268435399, 536870909, 1073741789, 2147483647
8202 +       };
8203 +       void *newtable = NULL;
8204 +       unsigned int pwr = 0;
8205 +
8206 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
8207 +              table_sizes[pwr] <= (2 * (*len)))
8208 +               pwr++;
8209 +
8210 +       if (table_sizes[pwr] <= (2 * (*len)))
8211 +               return newtable;
8212 +
8213 +       if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
8214 +               newtable =
8215 +                   kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
8216 +       else
8217 +               newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
8218 +
8219 +       *len = table_sizes[pwr];
8220 +
8221 +       return newtable;
8222 +}
8223 +
8224 +static int
8225 +init_variables(const unsigned long acl_obj_size,
8226 +              const unsigned long acl_subj_size,
8227 +              const unsigned long acl_ip_size,
8228 +              const unsigned long acl_role_size,
8229 +              const unsigned long allowed_ip_size,
8230 +              const unsigned long acl_trans_size,
8231 +              const __u16 num_sprole_pws)
8232 +{
8233 +       unsigned long stacksize;
8234 +
8235 +       acl_role_set.r_size = acl_role_size;
8236 +       name_set.n_size = (acl_obj_size + acl_subj_size);
8237 +       inodev_set.n_size = (acl_obj_size + acl_subj_size);
8238 +
8239 +       if (!gr_init_uidset())
8240 +               return 1;
8241 +
8242 +       /* set up the stack that holds allocation info */
8243 +
8244 +       stacksize = (3 * acl_obj_size) + (2 * acl_role_size) +
8245 +           (4 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
8246 +           allowed_ip_size + (2 * num_sprole_pws) + 5;
8247 +
8248 +       if (!acl_alloc_stack_init(stacksize))
8249 +               return 1;
8250 +
8251 +       /* create our empty, fake deleted acls */
8252 +       deleted_subject =
8253 +           (struct acl_subject_label *)
8254 +           acl_alloc(sizeof (struct acl_subject_label));
8255 +       deleted_object =
8256 +           (struct acl_object_label *)
8257 +           acl_alloc(sizeof (struct acl_object_label));
8258 +       deleted_inodev =
8259 +           (struct name_entry *) acl_alloc(sizeof (struct name_entry));
8260 +
8261 +       if (!deleted_subject || !deleted_object || !deleted_inodev)
8262 +               return 1;
8263 +
8264 +       memset(deleted_subject, 0, sizeof (struct acl_subject_label));
8265 +       memset(deleted_object, 0, sizeof (struct acl_object_label));
8266 +       memset(deleted_inodev, 0, sizeof (struct name_entry));
8267 +
8268 +       /* We only want 50% full tables for now */
8269 +
8270 +       acl_role_set.r_hash =
8271 +           (struct acl_role_label **) create_table(&acl_role_set.r_size);
8272 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
8273 +       inodev_set.n_hash =
8274 +           (struct name_entry **) create_table(&inodev_set.n_size);
8275 +
8276 +       if (!acl_role_set.r_hash || !name_set.n_hash || !inodev_set.n_hash)
8277 +               return 1;
8278 +       memset(acl_role_set.r_hash, 0,
8279 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
8280 +       memset(name_set.n_hash, 0,
8281 +              sizeof (struct name_entry *) * name_set.n_size);
8282 +       memset(inodev_set.n_hash, 0,
8283 +              sizeof (struct name_entry *) * inodev_set.n_size);
8284 +
8285 +       return 0;
8286 +}
8287 +
8288 +static void
8289 +free_variables(void)
8290 +{
8291 +       struct acl_subject_label *s;
8292 +       struct acl_role_label *r;
8293 +       struct task_struct *task;
8294 +
8295 +       gr_clear_learn_entries();
8296 +
8297 +       read_lock(&tasklist_lock);
8298 +       for_each_task(task) {
8299 +               task->acl_sp_role = 0;
8300 +               task->acl_role_id = 0;
8301 +               task->acl = NULL;
8302 +               task->role = NULL;
8303 +       }
8304 +       read_unlock(&tasklist_lock);
8305 +
8306 +       /* free all object hash tables */
8307 +
8308 +       if (role_list_head) {
8309 +               for (r = role_list_head; r; r = r->next) {
8310 +                       if (!r->subj_hash)
8311 +                               break;
8312 +                       for (s = r->proc_subject; s; s = s->next) {
8313 +                               if (!s->obj_hash)
8314 +                                       break;
8315 +                               if ((s->obj_hash_size *
8316 +                                    sizeof (struct acl_object_label *)) <=
8317 +                                   PAGE_SIZE)
8318 +                                       kfree(s->obj_hash);
8319 +                               else
8320 +                                       vfree(s->obj_hash);
8321 +                       }
8322 +                       if ((r->subj_hash_size *
8323 +                            sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
8324 +                               kfree(r->subj_hash);
8325 +                       else
8326 +                               vfree(r->subj_hash);
8327 +               }
8328 +       }
8329 +
8330 +       acl_free_all();
8331 +
8332 +       if (acl_role_set.r_hash) {
8333 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
8334 +                   PAGE_SIZE)
8335 +                       kfree(acl_role_set.r_hash);
8336 +               else
8337 +                       vfree(acl_role_set.r_hash);
8338 +       }
8339 +       if (name_set.n_hash) {
8340 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
8341 +                   PAGE_SIZE)
8342 +                       kfree(name_set.n_hash);
8343 +               else
8344 +                       vfree(name_set.n_hash);
8345 +       }
8346 +
8347 +       if (inodev_set.n_hash) {
8348 +               if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
8349 +                   PAGE_SIZE)
8350 +                       kfree(inodev_set.n_hash);
8351 +               else
8352 +                       vfree(inodev_set.n_hash);
8353 +       }
8354 +
8355 +       gr_free_uidset();
8356 +
8357 +       memset(&name_set, 0, sizeof (struct name_db));
8358 +       memset(&inodev_set, 0, sizeof (struct name_db));
8359 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
8360 +
8361 +       role_list_head = NULL;
8362 +       default_role = NULL;
8363 +
8364 +       return;
8365 +}
8366 +
8367 +static __u32
8368 +count_user_objs(struct acl_object_label *userp)
8369 +{
8370 +       struct acl_object_label o_tmp;
8371 +       __u32 num = 0;
8372 +
8373 +       while (userp) {
8374 +               if (copy_from_user(&o_tmp, userp,
8375 +                                  sizeof (struct acl_object_label)))
8376 +                       break;
8377 +
8378 +               userp = o_tmp.prev;
8379 +               num++;
8380 +       }
8381 +
8382 +       return num;
8383 +}
8384 +
8385 +static struct acl_subject_label *
8386 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
8387 +
8388 +static int
8389 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
8390 +              struct acl_role_label *role)
8391 +{
8392 +       struct acl_object_label *o_tmp;
8393 +       unsigned int len;
8394 +       char *tmp;
8395 +
8396 +       while (userp) {
8397 +               if ((o_tmp = (struct acl_object_label *)
8398 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
8399 +                       return -ENOMEM;
8400 +
8401 +               if (copy_from_user(o_tmp, userp,
8402 +                                  sizeof (struct acl_object_label)))
8403 +                       return -EFAULT;
8404 +
8405 +               userp = o_tmp->prev;
8406 +
8407 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
8408 +
8409 +               if (!len || len >= PATH_MAX)
8410 +                       return -EINVAL;
8411 +
8412 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
8413 +                       return -ENOMEM;
8414 +
8415 +               if (copy_from_user(tmp, o_tmp->filename, len))
8416 +                       return -EFAULT;
8417 +
8418 +               o_tmp->filename = tmp;
8419 +
8420 +               insert_acl_obj_label(o_tmp, subj);
8421 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
8422 +                                      o_tmp->device))
8423 +                       return -ENOMEM;
8424 +
8425 +               if (o_tmp->nested) {
8426 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
8427 +                       if (IS_ERR(o_tmp->nested))
8428 +                               return PTR_ERR(o_tmp->nested);
8429 +
8430 +                       s_final = o_tmp->nested;
8431 +               }
8432 +       }
8433 +
8434 +       return 0;
8435 +}
8436 +
8437 +static __u32
8438 +count_user_subjs(struct acl_subject_label *userp)
8439 +{
8440 +       struct acl_subject_label s_tmp;
8441 +       __u32 num = 0;
8442 +
8443 +       while (userp) {
8444 +               if (copy_from_user(&s_tmp, userp,
8445 +                                  sizeof (struct acl_subject_label)))
8446 +                       break;
8447 +
8448 +               userp = s_tmp.prev;
8449 +               /* do not count nested subjects against this count, since
8450 +                  they are not included in the hash table, but are
8451 +                  attached to objects.  We have already counted
8452 +                  the subjects in userspace for the allocation 
8453 +                  stack
8454 +               */
8455 +               if (!s_tmp.parent_subject)
8456 +                       num++;
8457 +       }
8458 +
8459 +       return num;
8460 +}
8461 +
8462 +static int
8463 +copy_user_allowedips(struct acl_role_label *rolep)
8464 +{
8465 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
8466 +
8467 +       ruserip = rolep->allowed_ips;
8468 +
8469 +       while (ruserip) {
8470 +               rlast = rtmp;
8471 +
8472 +               if ((rtmp = (struct role_allowed_ip *)
8473 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
8474 +                       return -ENOMEM;
8475 +
8476 +               if (copy_from_user(rtmp, ruserip,
8477 +                                  sizeof (struct role_allowed_ip)))
8478 +                       return -EFAULT;
8479 +
8480 +               ruserip = rtmp->prev;
8481 +
8482 +               if (!rlast) {
8483 +                       rtmp->prev = NULL;
8484 +                       rolep->allowed_ips = rtmp;
8485 +               } else {
8486 +                       rlast->next = rtmp;
8487 +                       rtmp->prev = rlast;
8488 +               }
8489 +
8490 +               if (!ruserip)
8491 +                       rtmp->next = NULL;
8492 +       }
8493 +
8494 +       return 0;
8495 +}
8496 +
8497 +static int
8498 +copy_user_transitions(struct acl_role_label *rolep)
8499 +{
8500 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
8501 +       unsigned int len;
8502 +       char *tmp;
8503 +
8504 +       rusertp = rolep->transitions;
8505 +
8506 +       while (rusertp) {
8507 +               rlast = rtmp;
8508 +
8509 +               if ((rtmp = (struct role_transition *)
8510 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
8511 +                       return -ENOMEM;
8512 +
8513 +               if (copy_from_user(rtmp, rusertp,
8514 +                                  sizeof (struct role_transition)))
8515 +                       return -EFAULT;
8516 +
8517 +               rusertp = rtmp->prev;
8518 +
8519 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
8520 +
8521 +               if (!len || len >= GR_SPROLE_LEN)
8522 +                       return -EINVAL;
8523 +
8524 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
8525 +                       return -ENOMEM;
8526 +
8527 +               if (copy_from_user(tmp, rtmp->rolename, len))
8528 +                       return -EFAULT;
8529 +
8530 +               rtmp->rolename = tmp;
8531 +
8532 +               if (!rlast) {
8533 +                       rtmp->prev = NULL;
8534 +                       rolep->transitions = rtmp;
8535 +               } else {
8536 +                       rlast->next = rtmp;
8537 +                       rtmp->prev = rlast;
8538 +               }
8539 +
8540 +               if (!rusertp)
8541 +                       rtmp->next = NULL;
8542 +       }
8543 +
8544 +       return 0;
8545 +}
8546 +
8547 +static struct acl_subject_label *
8548 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
8549 +{
8550 +       struct acl_subject_label *s_tmp = NULL;
8551 +       unsigned int len;
8552 +       char *tmp;
8553 +       __u32 num_objs;
8554 +       struct acl_ip_label **i_tmp, *i_utmp2;
8555 +       unsigned long i_num;
8556 +       int err;
8557 +
8558 +
8559 +       if ((s_tmp = (struct acl_subject_label *)
8560 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
8561 +               return ERR_PTR(-ENOMEM);
8562 +
8563 +       if (copy_from_user(s_tmp, userp,
8564 +                          sizeof (struct acl_subject_label)))
8565 +               return ERR_PTR(-EFAULT);
8566 +
8567 +       if (!s_last) {
8568 +               s_tmp->prev = NULL;
8569 +               role->proc_subject = s_tmp;
8570 +       } else {
8571 +               s_last->next = s_tmp;
8572 +               s_tmp->prev = s_last;
8573 +       }
8574 +
8575 +       s_last = s_tmp;
8576 +
8577 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
8578 +
8579 +       if (!len || len >= PATH_MAX)
8580 +               return ERR_PTR(-EINVAL);
8581 +
8582 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
8583 +               return ERR_PTR(-ENOMEM);
8584 +
8585 +       if (copy_from_user(tmp, s_tmp->filename, len))
8586 +               return ERR_PTR(-EFAULT);
8587 +
8588 +       s_tmp->filename = tmp;
8589 +
8590 +       if (!strcmp(s_tmp->filename, "/"))
8591 +               role->root_label = s_tmp;
8592 +
8593 +       /* set up object hash table */
8594 +       num_objs = count_user_objs(s_tmp->proc_object);
8595 +
8596 +       s_tmp->obj_hash_size = num_objs;
8597 +       s_tmp->obj_hash =
8598 +           (struct acl_object_label **)
8599 +           create_table(&(s_tmp->obj_hash_size));
8600 +
8601 +       if (!s_tmp->obj_hash)
8602 +               return ERR_PTR(-ENOMEM);
8603 +
8604 +       memset(s_tmp->obj_hash, 0,
8605 +              s_tmp->obj_hash_size *
8606 +              sizeof (struct acl_object_label *));
8607 +
8608 +       /* copy before adding in objects, since a nested
8609 +          acl could be found and be the final subject
8610 +          copied
8611 +       */
8612 +
8613 +       s_final = s_tmp;
8614 +
8615 +       /* add in objects */
8616 +       err = copy_user_objs(s_tmp->proc_object, s_tmp, role);
8617 +
8618 +       if (err)
8619 +               return ERR_PTR(err);
8620 +
8621 +       /* add in ip acls */
8622 +
8623 +       if (!s_tmp->ip_num) {
8624 +               s_tmp->ips = NULL;
8625 +               goto insert;
8626 +       }
8627 +
8628 +       i_tmp =
8629 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
8630 +                                              sizeof (struct
8631 +                                                      acl_ip_label *));
8632 +
8633 +       if (!i_tmp)
8634 +               return ERR_PTR(-ENOMEM);
8635 +
8636 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
8637 +               *(i_tmp + i_num) =
8638 +                   (struct acl_ip_label *)
8639 +                   acl_alloc(sizeof (struct acl_ip_label));
8640 +               if (!*(i_tmp + i_num))
8641 +                       return ERR_PTR(-ENOMEM);
8642 +
8643 +               if (copy_from_user
8644 +                   (&i_utmp2, s_tmp->ips + i_num,
8645 +                    sizeof (struct acl_ip_label *)))
8646 +                       return ERR_PTR(-EFAULT);
8647 +
8648 +               if (copy_from_user
8649 +                   (*(i_tmp + i_num), i_utmp2,
8650 +                    sizeof (struct acl_ip_label)))
8651 +                       return ERR_PTR(-EFAULT);
8652 +       }
8653 +
8654 +       s_tmp->ips = i_tmp;
8655 +
8656 +insert:
8657 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
8658 +                              s_tmp->device))
8659 +               return ERR_PTR(-ENOMEM);
8660 +
8661 +       return s_tmp;
8662 +}
8663 +
8664 +static int
8665 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
8666 +{
8667 +       struct acl_subject_label s_pre;
8668 +       struct acl_subject_label * ret;
8669 +       int err;
8670 +
8671 +       while (userp) {
8672 +               if (copy_from_user(&s_pre, userp,
8673 +                                  sizeof (struct acl_subject_label)))
8674 +                       return -EFAULT;
8675 +               
8676 +               /* do not add nested subjects here, add
8677 +                  while parsing objects
8678 +               */
8679 +
8680 +               if (s_pre.parent_subject) {
8681 +                       userp = s_pre.prev;
8682 +                       continue;
8683 +               }
8684 +
8685 +               ret = do_copy_user_subj(userp, role);
8686 +
8687 +               err = PTR_ERR(ret);
8688 +               if (IS_ERR(ret))
8689 +                       return err;
8690 +
8691 +               insert_acl_subj_label(ret, role);
8692 +
8693 +               userp = s_pre.prev;
8694 +       }
8695 +
8696 +       s_final->next = NULL;
8697 +
8698 +       return 0;
8699 +}
8700 +
8701 +static int
8702 +copy_user_acl(struct gr_arg *arg)
8703 +{
8704 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
8705 +       struct sprole_pw *sptmp;
8706 +       unsigned long r_num;
8707 +       unsigned int len;
8708 +       char *tmp;
8709 +       int err = 0;
8710 +       __u16 i;
8711 +       __u32 num_subjs;
8712 +
8713 +       /* we need a default and kernel role */
8714 +       if (arg->role_db.r_entries < 2)
8715 +               return -EINVAL;
8716 +
8717 +       /* copy special role authentication info from userspace */
8718 +
8719 +       num_sprole_pws = arg->num_sprole_pws;
8720 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
8721 +
8722 +       if (!acl_special_roles) {
8723 +               err = -ENOMEM;
8724 +               goto cleanup;
8725 +       }
8726 +
8727 +       for (i = 0; i < num_sprole_pws; i++) {
8728 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
8729 +               if (!sptmp) {
8730 +                       err = -ENOMEM;
8731 +                       goto cleanup;
8732 +               }
8733 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
8734 +                                  sizeof (struct sprole_pw))) {
8735 +                       err = -EFAULT;
8736 +                       goto cleanup;
8737 +               }
8738 +
8739 +               len =
8740 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
8741 +
8742 +               if (!len || len >= GR_SPROLE_LEN) {
8743 +                       err = -EINVAL;
8744 +                       goto cleanup;
8745 +               }
8746 +
8747 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
8748 +                       err = -ENOMEM;
8749 +                       goto cleanup;
8750 +               }
8751 +
8752 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
8753 +                       err = -EFAULT;
8754 +                       goto cleanup;
8755 +               }
8756 +
8757 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
8758 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
8759 +#endif
8760 +               sptmp->rolename = tmp;
8761 +               acl_special_roles[i] = sptmp;
8762 +       }
8763 +
8764 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
8765 +
8766 +       for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
8767 +               r_last = r_tmp;
8768 +
8769 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
8770 +
8771 +               if (!r_tmp) {
8772 +                       err = -ENOMEM;
8773 +                       goto cleanup;
8774 +               }
8775 +
8776 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
8777 +                                  sizeof (struct acl_role_label *))) {
8778 +                       err = -EFAULT;
8779 +                       goto cleanup;
8780 +               }
8781 +
8782 +               if (copy_from_user(r_tmp, r_utmp2,
8783 +                                  sizeof (struct acl_role_label))) {
8784 +                       err = -EFAULT;
8785 +                       goto cleanup;
8786 +               }
8787 +
8788 +               if (!r_last) {
8789 +                       r_tmp->prev = NULL;
8790 +                       role_list_head = r_tmp;
8791 +               } else {
8792 +                       r_last->next = r_tmp;
8793 +                       r_tmp->prev = r_last;
8794 +               }
8795 +
8796 +               if (r_num == (arg->role_db.r_entries - 1))
8797 +                       r_tmp->next = NULL;
8798 +
8799 +               len = strnlen_user(r_tmp->rolename, PATH_MAX);
8800 +
8801 +               if (!len || len >= PATH_MAX) {
8802 +                       err = -EINVAL;
8803 +                       goto cleanup;
8804 +               }
8805 +
8806 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
8807 +                       err = -ENOMEM;
8808 +                       goto cleanup;
8809 +               }
8810 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
8811 +                       err = -EFAULT;
8812 +                       goto cleanup;
8813 +               }
8814 +               r_tmp->rolename = tmp;
8815 +
8816 +               if (!strcmp(r_tmp->rolename, "default")
8817 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
8818 +                       default_role = r_tmp;
8819 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
8820 +                       kernel_role = r_tmp;
8821 +               }
8822 +
8823 +               num_subjs = count_user_subjs(r_tmp->proc_subject);
8824 +
8825 +               r_tmp->subj_hash_size = num_subjs;
8826 +               r_tmp->subj_hash =
8827 +                   (struct acl_subject_label **)
8828 +                   create_table(&(r_tmp->subj_hash_size));
8829 +
8830 +               if (!r_tmp->subj_hash) {
8831 +                       err = -ENOMEM;
8832 +                       goto cleanup;
8833 +               }
8834 +
8835 +               err = copy_user_allowedips(r_tmp);
8836 +               if (err)
8837 +                       goto cleanup;
8838 +
8839 +               err = copy_user_transitions(r_tmp);
8840 +               if (err)
8841 +                       goto cleanup;
8842 +
8843 +               memset(r_tmp->subj_hash, 0,
8844 +                      r_tmp->subj_hash_size *
8845 +                      sizeof (struct acl_subject_label *));
8846 +
8847 +               s_last = NULL;
8848 +
8849 +               err = copy_user_subjs(r_tmp->proc_subject, r_tmp);
8850 +
8851 +               if (err)
8852 +                       goto cleanup;
8853 +
8854 +               insert_acl_role_label(r_tmp);
8855 +       }
8856 +
8857 +       goto return_err;
8858 +      cleanup:
8859 +       free_variables();
8860 +      return_err:
8861 +       return err;
8862 +
8863 +}
8864 +
8865 +static int
8866 +gracl_init(struct gr_arg *args)
8867 +{
8868 +       int error = 0;
8869 +
8870 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
8871 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
8872 +
8873 +       if (init_variables(args->role_db.o_entries, args->role_db.s_entries,
8874 +                          args->role_db.i_entries, args->role_db.r_entries,
8875 +                          args->role_db.a_entries, args->role_db.t_entries,
8876 +                          args->num_sprole_pws)) {
8877 +               security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
8878 +               error = -ENOMEM;
8879 +               free_variables();
8880 +               goto out;
8881 +       }
8882 +
8883 +       error = copy_user_acl(args);
8884 +       if (error)
8885 +               goto out;
8886 +
8887 +       if ((error = gr_set_acls(0))) {
8888 +               free_variables();
8889 +               goto out;
8890 +       }
8891 +
8892 +       gr_status |= GR_READY;
8893 +      out:
8894 +       return error;
8895 +}
8896 +
8897 +static struct acl_object_label *
8898 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
8899 +             const struct acl_subject_label *subj)
8900 +{
8901 +       struct dentry *dentry = (struct dentry *) l_dentry;
8902 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
8903 +       struct dentry *root;
8904 +       struct vfsmount *rootmnt;
8905 +       struct acl_object_label *retval;
8906 +
8907 +       read_lock(&child_reaper->fs->lock);
8908 +       rootmnt = mntget(child_reaper->fs->rootmnt);
8909 +       root = dget(child_reaper->fs->root);
8910 +       read_unlock(&child_reaper->fs->lock);
8911 +       spin_lock(&dcache_lock);
8912 +
8913 +       for (;;) {
8914 +               if (unlikely(dentry == root && mnt == rootmnt))
8915 +                       break;
8916 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
8917 +                       if (mnt->mnt_parent == mnt)
8918 +                               break;
8919 +
8920 +                       read_lock(&gr_inode_lock);
8921 +                       retval =
8922 +                           lookup_acl_obj_label(dentry->d_inode->i_ino,
8923 +                                                dentry->d_inode->i_dev, subj);
8924 +                       read_unlock(&gr_inode_lock);
8925 +                       if (unlikely(retval != NULL))
8926 +                               goto out;
8927 +
8928 +                       dentry = mnt->mnt_mountpoint;
8929 +                       mnt = mnt->mnt_parent;
8930 +                       continue;
8931 +               }
8932 +
8933 +               read_lock(&gr_inode_lock);
8934 +               retval =
8935 +                   lookup_acl_obj_label(dentry->d_inode->i_ino,
8936 +                                        dentry->d_inode->i_dev, subj);
8937 +               read_unlock(&gr_inode_lock);
8938 +               if (unlikely(retval != NULL))
8939 +                       goto out;
8940 +
8941 +               dentry = dentry->d_parent;
8942 +       }
8943 +
8944 +       read_lock(&gr_inode_lock);
8945 +       retval =
8946 +           lookup_acl_obj_label(dentry->d_inode->i_ino, dentry->d_inode->i_dev,
8947 +                                subj);
8948 +       read_unlock(&gr_inode_lock);
8949 +
8950 +       if (unlikely(retval == NULL)) {
8951 +               read_lock(&gr_inode_lock);
8952 +               retval =
8953 +                   lookup_acl_obj_label(root->d_inode->i_ino,
8954 +                                        root->d_inode->i_dev, subj);
8955 +               read_unlock(&gr_inode_lock);
8956 +       }
8957 +      out:
8958 +       spin_unlock(&dcache_lock);
8959 +       dput(root);
8960 +       mntput(rootmnt);
8961 +
8962 +       return retval;
8963 +}
8964 +
8965 +static struct acl_subject_label *
8966 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
8967 +              const struct acl_role_label *role)
8968 +{
8969 +       struct dentry *dentry = (struct dentry *) l_dentry;
8970 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
8971 +       struct dentry *root;
8972 +       struct vfsmount *rootmnt;
8973 +       struct acl_subject_label *retval;
8974 +
8975 +       read_lock(&child_reaper->fs->lock);
8976 +       rootmnt = mntget(child_reaper->fs->rootmnt);
8977 +       root = dget(child_reaper->fs->root);
8978 +       read_unlock(&child_reaper->fs->lock);
8979 +       spin_lock(&dcache_lock);
8980 +
8981 +       for (;;) {
8982 +               if (unlikely(dentry == root && mnt == rootmnt))
8983 +                       break;
8984 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
8985 +                       if (mnt->mnt_parent == mnt)
8986 +                               break;
8987 +
8988 +                       read_lock(&gr_inode_lock);
8989 +                       retval =
8990 +                           lookup_acl_subj_label(dentry->d_inode->i_ino,
8991 +                                                 dentry->d_inode->i_dev, role);
8992 +                       read_unlock(&gr_inode_lock);
8993 +                       if (unlikely(retval != NULL))
8994 +                               goto out;
8995 +
8996 +                       dentry = mnt->mnt_mountpoint;
8997 +                       mnt = mnt->mnt_parent;
8998 +                       continue;
8999 +               }
9000 +
9001 +               read_lock(&gr_inode_lock);
9002 +               retval =
9003 +                   lookup_acl_subj_label(dentry->d_inode->i_ino,
9004 +                                         dentry->d_inode->i_dev, role);
9005 +               read_unlock(&gr_inode_lock);
9006 +               if (unlikely(retval != NULL))
9007 +                       goto out;
9008 +
9009 +               dentry = dentry->d_parent;
9010 +       }
9011 +
9012 +       read_lock(&gr_inode_lock);
9013 +       retval =
9014 +           lookup_acl_subj_label(dentry->d_inode->i_ino,
9015 +                                 dentry->d_inode->i_dev, role);
9016 +       read_unlock(&gr_inode_lock);
9017 +
9018 +       if (unlikely(retval == NULL)) {
9019 +               read_lock(&gr_inode_lock);
9020 +               retval =
9021 +                   lookup_acl_subj_label(root->d_inode->i_ino,
9022 +                                         root->d_inode->i_dev, role);
9023 +               read_unlock(&gr_inode_lock);
9024 +       }
9025 +      out:
9026 +       spin_unlock(&dcache_lock);
9027 +       dput(root);
9028 +       mntput(rootmnt);
9029 +
9030 +       return retval;
9031 +}
9032 +
9033 +static __inline__ void
9034 +gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
9035 +            const struct task_struct *task, const char *pathname,
9036 +            const __u32 mode)
9037 +{
9038 +       security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
9039 +                      uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
9040 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
9041 +                      1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
9042 +
9043 +       return;
9044 +}
9045 +
9046 +__u32
9047 +gr_check_link(const struct dentry * new_dentry,
9048 +             const struct dentry * parent_dentry,
9049 +             const struct vfsmount * parent_mnt,
9050 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
9051 +{
9052 +       struct acl_object_label *obj;
9053 +       __u32 oldmode, newmode;
9054 +
9055 +       if (unlikely(!(gr_status & GR_READY)))
9056 +               return (GR_WRITE | GR_CREATE);
9057 +
9058 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
9059 +       oldmode = obj->mode;
9060 +
9061 +       if (current->acl->mode & GR_LEARN)
9062 +               oldmode |= (GR_WRITE | GR_CREATE);
9063 +       newmode =
9064 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
9065 +                           oldmode | GR_CREATE | GR_AUDIT_CREATE |
9066 +                           GR_AUDIT_WRITE | GR_SUPPRESS);
9067 +
9068 +       if ((newmode & oldmode) == oldmode)
9069 +               return newmode;
9070 +       else if (current->acl->mode & GR_LEARN) {
9071 +               gr_log_learn(current->role, current->uid, current->gid,
9072 +                       current, gr_to_filename(old_dentry, old_mnt), oldmode);
9073 +               return (GR_WRITE | GR_CREATE);
9074 +       } else if (newmode & GR_SUPPRESS)
9075 +               return GR_SUPPRESS;
9076 +       else
9077 +               return 0;
9078 +}
9079 +
9080 +__u32
9081 +gr_search_file(const struct dentry * dentry, const __u32 mode,
9082 +              const struct vfsmount * mnt)
9083 +{
9084 +       __u32 retval = mode;
9085 +       struct acl_subject_label *curracl;
9086 +       struct acl_object_label *currobj;
9087 +
9088 +       if (unlikely(!(gr_status & GR_READY)))
9089 +               return (mode & ~GR_AUDITS);
9090 +
9091 +       curracl = current->acl;
9092 +
9093 +       currobj = chk_obj_label(dentry, mnt, curracl);
9094 +       retval = currobj->mode & mode;
9095 +
9096 +       if (unlikely
9097 +           ((curracl->mode & GR_LEARN) && (mode != GR_PTRACERD)
9098 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
9099 +               __u32 new_mode = mode;
9100 +
9101 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9102 +
9103 +               retval = new_mode;
9104 +
9105 +               if (!(mode & GR_NOLEARN))
9106 +                       gr_log_learn(current->role, current->uid, current->gid,
9107 +                                    current, gr_to_filename(dentry, mnt), new_mode);
9108 +       }
9109 +
9110 +       return retval;
9111 +}
9112 +
9113 +__u32
9114 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
9115 +               const struct vfsmount * mnt, const __u32 mode)
9116 +{
9117 +       struct name_entry *match;
9118 +       struct acl_object_label *matchpo;
9119 +       struct acl_subject_label *curracl;
9120 +       __u32 retval;
9121 +
9122 +       if (unlikely(!(gr_status & GR_READY)))
9123 +               return (mode & ~GR_AUDITS);
9124 +
9125 +       match = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9126 +
9127 +       if (!match)
9128 +               goto check_parent;
9129 +
9130 +       curracl = current->acl;
9131 +
9132 +       read_lock(&gr_inode_lock);
9133 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
9134 +       read_unlock(&gr_inode_lock);
9135 +
9136 +       if (matchpo) {
9137 +               if ((matchpo->mode & mode) !=
9138 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
9139 +                   && curracl->mode & GR_LEARN) {
9140 +                       __u32 new_mode = mode;
9141 +
9142 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9143 +
9144 +                       gr_log_learn(current->role, current->uid, current->gid,
9145 +                                    current, gr_to_filename(new_dentry, mnt), new_mode);
9146 +
9147 +                       return new_mode;
9148 +               }
9149 +               return (matchpo->mode & mode);
9150 +       }
9151 +
9152 +      check_parent:
9153 +       curracl = current->acl;
9154 +
9155 +       matchpo = chk_obj_label(parent, mnt, curracl);
9156 +       retval = matchpo->mode & mode;
9157 +
9158 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
9159 +           && (curracl->mode & GR_LEARN)) {
9160 +               __u32 new_mode = mode;
9161 +
9162 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9163 +
9164 +               gr_log_learn(current->role, current->uid, current->gid, 
9165 +                            current, gr_to_filename(new_dentry, mnt), new_mode);
9166 +               return new_mode;
9167 +       }
9168 +
9169 +       return retval;
9170 +}
9171 +
9172 +int
9173 +gr_check_hidden_task(const struct task_struct *task)
9174 +{
9175 +       if (unlikely(!(gr_status & GR_READY)))
9176 +               return 0;
9177 +
9178 +       if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
9179 +               return 1;
9180 +
9181 +       return 0;
9182 +}
9183 +
9184 +int
9185 +gr_check_protected_task(const struct task_struct *task)
9186 +{
9187 +       if (unlikely(!(gr_status & GR_READY) || !task))
9188 +               return 0;
9189 +
9190 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
9191 +               return 1;
9192 +
9193 +       return 0;
9194 +}
9195 +
9196 +__inline__ void
9197 +gr_copy_label(struct task_struct *tsk)
9198 +{
9199 +       tsk->used_accept = 0;
9200 +       tsk->used_connect = 0;
9201 +       tsk->acl_sp_role = 0;
9202 +       tsk->acl_role_id = current->acl_role_id;
9203 +       tsk->acl = current->acl;
9204 +       tsk->role = current->role;
9205 +       tsk->curr_ip = current->curr_ip;
9206 +       if (current->exec_file)
9207 +               get_file(current->exec_file);
9208 +       tsk->exec_file = current->exec_file;
9209 +       tsk->is_writable = current->is_writable;
9210 +       if (unlikely(current->used_accept))
9211 +               current->curr_ip = 0;
9212 +
9213 +       return;
9214 +}
9215 +
9216 +static __inline__ void
9217 +gr_set_proc_res(void)
9218 +{
9219 +       struct acl_subject_label *proc;
9220 +       unsigned short i;
9221 +
9222 +       proc = current->acl;
9223 +
9224 +       if (proc->mode & GR_LEARN)
9225 +               return;
9226 +
9227 +       for (i = 0; i < RLIM_NLIMITS; i++) {
9228 +               if (!(proc->resmask & (1 << i)))
9229 +                       continue;
9230 +
9231 +               current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
9232 +               current->rlim[i].rlim_max = proc->res[i].rlim_max;
9233 +       }
9234 +
9235 +       return;
9236 +}
9237 +
9238 +void
9239 +gr_set_pax_flags(struct task_struct *task)
9240 +{
9241 +       struct acl_subject_label *proc;
9242 +
9243 +       if (unlikely(!(gr_status & GR_READY)))
9244 +               return;
9245 +
9246 +       proc = task->acl;
9247 +
9248 +       if (proc->mode & GR_PAXPAGE)
9249 +               task->flags &= ~PF_PAX_PAGEEXEC;
9250 +       if (proc->mode & GR_PAXSEGM)
9251 +               task->flags &= ~PF_PAX_SEGMEXEC;
9252 +       if (proc->mode & GR_PAXGCC)
9253 +               task->flags |= PF_PAX_EMUTRAMP;
9254 +       if (proc->mode & GR_PAXMPROTECT)
9255 +               task->flags &= ~PF_PAX_MPROTECT;
9256 +       if (proc->mode & GR_PAXRANDMMAP)
9257 +               task->flags &= ~PF_PAX_RANDMMAP;
9258 +       if (proc->mode & GR_PAXRANDEXEC)
9259 +               task->flags |= PF_PAX_RANDEXEC;
9260 +
9261 +       return;
9262 +}
9263 +
9264 +static __inline__ void
9265 +do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
9266 +{
9267 +       task->role = lookup_acl_role_label(task, uid, gid);
9268 +
9269 +       return;
9270 +}
9271 +
9272 +void
9273 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
9274 +{
9275 +       struct acl_object_label *obj;
9276 +       struct file *filp;
9277 +
9278 +       if (unlikely(!(gr_status & GR_READY)))
9279 +               return;
9280 +
9281 +       filp = task->exec_file;
9282 +
9283 +       /* kernel process, we'll give them the kernel role */
9284 +       if (unlikely(!filp)) {
9285 +               task->role = kernel_role;
9286 +               task->acl = kernel_role->root_label;
9287 +               return;
9288 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
9289 +               do_set_role_label(task, uid, gid);
9290 +
9291 +       task->acl =
9292 +           chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
9293 +
9294 +       task->is_writable = 0;
9295 +
9296 +       /* ignore additional mmap checks for processes that are writable 
9297 +          by the default ACL */
9298 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9299 +       if (unlikely(obj->mode & GR_WRITE))
9300 +               task->is_writable = 1;
9301 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9302 +       if (unlikely(obj->mode & GR_WRITE))
9303 +               task->is_writable = 1;
9304 +
9305 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9306 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9307 +#endif
9308 +
9309 +       gr_set_proc_res();
9310 +
9311 +       return;
9312 +}
9313 +
9314 +void
9315 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
9316 +{
9317 +       struct acl_subject_label *newacl;
9318 +       struct acl_object_label *obj;
9319 +       __u32 retmode;
9320 +
9321 +       if (unlikely(!(gr_status & GR_READY)))
9322 +               return;
9323 +
9324 +       newacl = chk_subj_label(dentry, mnt, current->role);
9325 +
9326 +       obj = chk_obj_label(dentry, mnt, current->acl);
9327 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
9328 +
9329 +       if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
9330 +               if (obj->nested)
9331 +                       current->acl = obj->nested;
9332 +               else
9333 +                       current->acl = newacl;
9334 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
9335 +               security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
9336 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
9337 +
9338 +       current->is_writable = 0;
9339 +
9340 +       /* ignore additional mmap checks for processes that are writable 
9341 +          by the default ACL */
9342 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
9343 +       if (unlikely(obj->mode & GR_WRITE))
9344 +               current->is_writable = 1;
9345 +       obj = chk_obj_label(dentry, mnt, current->role->root_label);
9346 +       if (unlikely(obj->mode & GR_WRITE))
9347 +               current->is_writable = 1;
9348 +
9349 +       gr_set_proc_res();
9350 +
9351 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9352 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
9353 +#endif
9354 +       return;
9355 +}
9356 +
9357 +static __inline__ void
9358 +do_handle_delete(const ino_t ino, const kdev_t dev)
9359 +{
9360 +       struct acl_object_label *matchpo;
9361 +       struct acl_subject_label *matchps;
9362 +       struct acl_subject_label *i;
9363 +       struct acl_role_label *role;
9364 +
9365 +       for (role = role_list_head; role; role = role->next) {
9366 +               for (i = role->proc_subject; i; i = i->next) {
9367 +                       if (unlikely(i->parent_subject &&
9368 +                                    (i->inode == ino) &&
9369 +                                    (i->device == dev)))
9370 +                               i->mode |= GR_DELETED;
9371 +                       if (unlikely((matchpo =
9372 +                            lookup_acl_obj_label(ino, dev, i)) != NULL))
9373 +                               matchpo->mode |= GR_DELETED;
9374 +               }
9375 +
9376 +               if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
9377 +                       matchps->mode |= GR_DELETED;
9378 +       }
9379 +
9380 +       return;
9381 +}
9382 +
9383 +void
9384 +gr_handle_delete(const ino_t ino, const kdev_t dev)
9385 +{
9386 +       if (unlikely(!(gr_status & GR_READY)))
9387 +               return;
9388 +
9389 +       write_lock(&gr_inode_lock);
9390 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
9391 +               do_handle_delete(ino, dev);
9392 +       write_unlock(&gr_inode_lock);
9393 +
9394 +       return;
9395 +}
9396 +
9397 +static __inline__ void
9398 +update_acl_obj_label(const ino_t oldinode, const kdev_t olddevice,
9399 +                    const ino_t newinode, const kdev_t newdevice,
9400 +                    struct acl_subject_label *subj)
9401 +{
9402 +       unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
9403 +       struct acl_object_label **match;
9404 +       struct acl_object_label *tmp;
9405 +       __u8 i = 0;
9406 +
9407 +       match = &subj->obj_hash[index];
9408 +
9409 +       while (*match && ((*match)->inode != oldinode ||
9410 +              (*match)->device != olddevice ||
9411 +              !((*match)->mode & GR_DELETED))) {
9412 +               index = (index + (1 << i)) % subj->obj_hash_size;
9413 +               match = &subj->obj_hash[index];
9414 +               i = (i + 1) % 32;
9415 +       }
9416 +
9417 +       if (*match && ((*match) != deleted_object)
9418 +           && ((*match)->inode == oldinode)
9419 +           && ((*match)->device == olddevice)
9420 +           && ((*match)->mode & GR_DELETED)) {
9421 +               tmp = *match;
9422 +               tmp->inode = newinode;
9423 +               tmp->device = newdevice;
9424 +               tmp->mode &= ~GR_DELETED;
9425 +
9426 +               *match = deleted_object;
9427 +
9428 +               insert_acl_obj_label(tmp, subj);
9429 +       }
9430 +
9431 +       return;
9432 +}
9433 +
9434 +static __inline__ void
9435 +update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice,
9436 +                     const ino_t newinode, const kdev_t newdevice,
9437 +                     struct acl_role_label *role)
9438 +{
9439 +       struct acl_subject_label **s_hash = role->subj_hash;
9440 +       unsigned long subj_size = role->subj_hash_size;
9441 +       unsigned long index = fhash(oldinode, olddevice, subj_size);
9442 +       struct acl_subject_label **match;
9443 +       struct acl_subject_label *tmp;
9444 +       __u8 i = 0;
9445 +
9446 +       match = &s_hash[index];
9447 +
9448 +       while (*match && ((*match)->inode != oldinode ||
9449 +              (*match)->device != olddevice ||
9450 +              !((*match)->mode & GR_DELETED))) {
9451 +               index = (index + (1 << i)) % subj_size;
9452 +               i = (i + 1) % 32;
9453 +               match = &s_hash[index];
9454 +       }
9455 +
9456 +       if (*match && (*match != deleted_subject)
9457 +           && ((*match)->inode == oldinode)
9458 +           && ((*match)->device == olddevice)
9459 +           && ((*match)->mode & GR_DELETED)) {
9460 +               tmp = *match;
9461 +
9462 +               tmp->inode = newinode;
9463 +               tmp->device = newdevice;
9464 +               tmp->mode &= ~GR_DELETED;
9465 +
9466 +               *match = deleted_subject;
9467 +
9468 +               insert_acl_subj_label(tmp, role);
9469 +       }
9470 +
9471 +       return;
9472 +}
9473 +
9474 +static __inline__ void
9475 +update_inodev_entry(const ino_t oldinode, const kdev_t olddevice,
9476 +                   const ino_t newinode, const kdev_t newdevice)
9477 +{
9478 +       unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
9479 +       struct name_entry **match;
9480 +       struct name_entry *tmp;
9481 +       __u8 i = 0;
9482 +
9483 +       match = &inodev_set.n_hash[index];
9484 +
9485 +       while (*match
9486 +              && ((*match)->inode != oldinode
9487 +                  || (*match)->device != olddevice)) {
9488 +               index = (index + (1 << i)) % inodev_set.n_size;
9489 +               i = (i + 1) % 32;
9490 +               match = &inodev_set.n_hash[index];
9491 +       }
9492 +
9493 +       if (*match && (*match != deleted_inodev)
9494 +           && ((*match)->inode == oldinode)
9495 +           && ((*match)->device == olddevice)) {
9496 +               tmp = *match;
9497 +
9498 +               tmp->inode = newinode;
9499 +               tmp->device = newdevice;
9500 +
9501 +               *match = deleted_inodev;
9502 +
9503 +               insert_inodev_entry(tmp);
9504 +       }
9505 +
9506 +       return;
9507 +}
9508 +
9509 +static __inline__ void
9510 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
9511 +                const struct vfsmount *mnt)
9512 +{
9513 +       struct acl_subject_label *i;
9514 +       struct acl_role_label *role;
9515 +
9516 +       for (role = role_list_head; role; role = role->next) {
9517 +               update_acl_subj_label(matchn->inode, matchn->device,
9518 +                                     dentry->d_inode->i_ino,
9519 +                                     dentry->d_inode->i_dev, role);
9520 +
9521 +               for (i = role->proc_subject; i; i = i->next) {
9522 +                       if (unlikely(i->parent_subject &&
9523 +                                    (i->inode == dentry->d_inode->i_ino) &&
9524 +                                    (i->device == dentry->d_inode->i_dev))) {
9525 +                               i->inode = dentry->d_inode->i_ino;
9526 +                               i->device = dentry->d_inode->i_dev;
9527 +                       }
9528 +                       update_acl_obj_label(matchn->inode, matchn->device,
9529 +                                            dentry->d_inode->i_ino,
9530 +                                            dentry->d_inode->i_dev, i);
9531 +               }
9532 +       }
9533 +
9534 +       update_inodev_entry(matchn->inode, matchn->device,
9535 +                           dentry->d_inode->i_ino, dentry->d_inode->i_dev);
9536 +
9537 +       return;
9538 +}
9539 +
9540 +void
9541 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
9542 +{
9543 +       struct name_entry *matchn;
9544 +
9545 +       if (unlikely(!(gr_status & GR_READY)))
9546 +               return;
9547 +
9548 +       matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
9549 +
9550 +       if (unlikely((unsigned long)matchn)) {
9551 +               write_lock(&gr_inode_lock);
9552 +               do_handle_create(matchn, dentry, mnt);
9553 +               write_unlock(&gr_inode_lock);
9554 +       }
9555 +
9556 +       return;
9557 +}
9558 +
9559 +int
9560 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
9561 +                struct dentry *old_dentry,
9562 +                struct dentry *new_dentry,
9563 +                struct vfsmount *mnt, const __u8 replace)
9564 +{
9565 +       struct name_entry *matchn;
9566 +       int error = 0;
9567 +
9568 +       matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9569 +
9570 +       lock_kernel();
9571 +       error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
9572 +       unlock_kernel();
9573 +
9574 +       if (unlikely(error))
9575 +               return error;
9576 +
9577 +       /* we wouldn't have to check d_inode if it weren't for
9578 +          NFS silly-renaming
9579 +        */
9580 +
9581 +       write_lock(&gr_inode_lock);
9582 +       if (unlikely(replace && new_dentry->d_inode)) {
9583 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
9584 +                                       new_dentry->d_inode->i_dev) &&
9585 +                   (old_dentry->d_inode->i_nlink <= 1)))
9586 +                       do_handle_delete(new_dentry->d_inode->i_ino,
9587 +                                        new_dentry->d_inode->i_dev);
9588 +       }
9589 +
9590 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
9591 +                               old_dentry->d_inode->i_dev) &&
9592 +           (old_dentry->d_inode->i_nlink <= 1)))
9593 +               do_handle_delete(old_dentry->d_inode->i_ino,
9594 +                                old_dentry->d_inode->i_dev);
9595 +
9596 +       if (unlikely((unsigned long)matchn))
9597 +               do_handle_create(matchn, old_dentry, mnt);
9598 +       write_unlock(&gr_inode_lock);
9599 +
9600 +       return error;
9601 +}
9602 +
9603 +static int
9604 +lookup_special_role_auth(const char *rolename, unsigned char **salt,
9605 +                        unsigned char **sum)
9606 +{
9607 +       struct acl_role_label *r;
9608 +       struct role_transition *trans;
9609 +       __u16 i;
9610 +       int found = 0;
9611 +
9612 +       /* check transition table */
9613 +
9614 +       for (trans = current->role->transitions; trans; trans = trans->next) {
9615 +               if (!strcmp(rolename, trans->rolename)) {
9616 +                       found = 1;
9617 +                       break;
9618 +               }
9619 +       }
9620 +
9621 +       if (!found)
9622 +               return 0;
9623 +
9624 +       /* handle special roles that do not require authentication */
9625 +
9626 +       for (r = role_list_head; r; r = r->next) {
9627 +               if (!strcmp(rolename, r->rolename)
9628 +                   && (r->roletype & GR_ROLE_NOPW)) {
9629 +                       *salt = NULL;
9630 +                       *sum = NULL;
9631 +                       return 1;
9632 +               }
9633 +       }
9634 +
9635 +       for (i = 0; i < num_sprole_pws; i++) {
9636 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
9637 +                       *salt = acl_special_roles[i]->salt;
9638 +                       *sum = acl_special_roles[i]->sum;
9639 +                       return 1;
9640 +               }
9641 +       }
9642 +
9643 +       return 0;
9644 +}
9645 +
9646 +static void
9647 +assign_special_role(char *rolename)
9648 +{
9649 +       struct acl_object_label *obj;
9650 +       struct acl_role_label *r;
9651 +       struct acl_role_label *assigned = NULL;
9652 +       struct task_struct *tsk;
9653 +       struct file *filp;
9654 +
9655 +       for (r = role_list_head; r; r = r->next)
9656 +               if (!strcmp(rolename, r->rolename) &&
9657 +                   (r->roletype & GR_ROLE_SPECIAL))
9658 +                       assigned = r;
9659 +
9660 +       if (!assigned)
9661 +               return;
9662 +
9663 +       tsk = current->p_pptr;
9664 +       filp = tsk->exec_file;
9665 +
9666 +       if (tsk && filp) {
9667 +               tsk->is_writable = 0;
9668 +
9669 +               acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
9670 +               tsk->acl_sp_role = 1;
9671 +               tsk->acl_role_id = acl_sp_role_value;
9672 +               tsk->role = assigned;
9673 +               tsk->acl =
9674 +                   chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
9675 +
9676 +               /* ignore additional mmap checks for processes that are writable 
9677 +                  by the default ACL */
9678 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9679 +               if (unlikely(obj->mode & GR_WRITE))
9680 +                       tsk->is_writable = 1;
9681 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
9682 +               if (unlikely(obj->mode & GR_WRITE))
9683 +                       tsk->is_writable = 1;
9684 +
9685 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9686 +               printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
9687 +#endif
9688 +       }
9689 +
9690 +       return;
9691 +}
9692 +
9693 +ssize_t
9694 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
9695 +{
9696 +       struct gr_arg *arg;
9697 +       unsigned char *sprole_salt;
9698 +       unsigned char *sprole_sum;
9699 +       int error = sizeof (struct gr_arg);
9700 +       int error2 = 0;
9701 +
9702 +       down(&gr_dev_sem);
9703 +
9704 +       arg = (struct gr_arg *) buf;
9705 +
9706 +       if (count != sizeof (struct gr_arg)) {
9707 +               security_alert_good(GR_DEV_ACL_MSG, count,
9708 +                                   (int) sizeof (struct gr_arg));
9709 +               error = -EINVAL;
9710 +               goto out;
9711 +       }
9712 +
9713 +       if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9714 +           && time_before_eq(gr_auth_expires, jiffies)) {
9715 +               gr_auth_expires = 0;
9716 +               gr_auth_attempts = 0;
9717 +       }
9718 +
9719 +       if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
9720 +               error = -EFAULT;
9721 +               goto out;
9722 +       }
9723 +
9724 +       if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) {
9725 +               error = -EBUSY;
9726 +               goto out;
9727 +       }
9728 +
9729 +       /* if non-root trying to do anything other than use a special role,
9730 +          do not attempt authentication, do not count towards authentication
9731 +          locking
9732 +        */
9733 +
9734 +       if (gr_usermode->mode != SPROLE && current->uid) {
9735 +               error = -EPERM;
9736 +               goto out;
9737 +       }
9738 +
9739 +       /* ensure pw and special role name are null terminated */
9740 +
9741 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
9742 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
9743 +
9744 +       /* Okay. 
9745 +        * We have our enough of the argument structure..(we have yet
9746 +        * to copy_from_user the tables themselves) . Copy the tables
9747 +        * only if we need them, i.e. for loading operations. */
9748 +
9749 +       switch (gr_usermode->mode) {
9750 +       case STATUS:
9751 +                       if (gr_status & GR_READY)
9752 +                               error = 1;
9753 +                       else
9754 +                               error = 2;
9755 +                       goto out;
9756 +       case SHUTDOWN:
9757 +               if ((gr_status & GR_READY)
9758 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9759 +                       gr_status &= ~GR_READY;
9760 +                       security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
9761 +                       free_variables();
9762 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
9763 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
9764 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
9765 +               } else if (gr_status & GR_READY) {
9766 +                       security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
9767 +                       error = -EPERM;
9768 +               } else {
9769 +                       security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
9770 +                       error = -EAGAIN;
9771 +               }
9772 +               break;
9773 +       case ENABLE:
9774 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
9775 +                       security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
9776 +               else {
9777 +                       if (gr_status & GR_READY)
9778 +                               error = -EAGAIN;
9779 +                       else
9780 +                               error = error2;
9781 +                       security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
9782 +                                      DEFAULTSECARGS);
9783 +               }
9784 +               break;
9785 +       case RELOAD:
9786 +               if (!(gr_status & GR_READY)) {
9787 +                       security_alert_good(GR_RELOADI_ACL_MSG);
9788 +                       error = -EAGAIN;
9789 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9790 +                       lock_kernel();
9791 +                       gr_status &= ~GR_READY;
9792 +                       free_variables();
9793 +                       if (!(error2 = gracl_init(gr_usermode))) {
9794 +                               unlock_kernel();
9795 +                               security_alert_good(GR_RELOAD_ACL_MSG,
9796 +                                                   GR_VERSION);
9797 +                       } else {
9798 +                               unlock_kernel();
9799 +                               error = error2;
9800 +                               security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
9801 +                                              DEFAULTSECARGS);
9802 +                       }
9803 +               } else {
9804 +                       security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
9805 +                                      DEFAULTSECARGS);
9806 +                       error = -EPERM;
9807 +               }
9808 +               break;
9809 +       case SEGVMOD:
9810 +               if (unlikely(!(gr_status & GR_READY))) {
9811 +                       security_alert_good(GR_SEGVMODI_ACL_MSG,
9812 +                                           DEFAULTSECARGS);
9813 +                       error = -EAGAIN;
9814 +                       break;
9815 +               }
9816 +
9817 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9818 +                       security_alert_good(GR_SEGVMODS_ACL_MSG,
9819 +                                           DEFAULTSECARGS);
9820 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
9821 +                               struct acl_subject_label *segvacl;
9822 +                               segvacl =
9823 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
9824 +                                                         gr_usermode->segv_device,
9825 +                                                         current->role);
9826 +                               if (segvacl) {
9827 +                                       segvacl->crashes = 0;
9828 +                                       segvacl->expires = 0;
9829 +                               }
9830 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
9831 +                               gr_remove_uid(gr_usermode->segv_uid);
9832 +                       }
9833 +               } else {
9834 +                       security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
9835 +                       error = -EPERM;
9836 +               }
9837 +               break;
9838 +       case SPROLE:
9839 +               if (unlikely(!(gr_status & GR_READY))) {
9840 +                       security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
9841 +                       error = -EAGAIN;
9842 +                       break;
9843 +               }
9844 +
9845 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9846 +                   && time_before_eq(current->role->expires, jiffies)) {
9847 +                       current->role->expires = 0;
9848 +                       current->role->auth_attempts = 0;
9849 +               }
9850 +
9851 +               if (time_after(current->role->expires, jiffies)) {
9852 +                       error = -EBUSY;
9853 +                       goto out;
9854 +               }
9855 +
9856 +               if (lookup_special_role_auth
9857 +                   (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
9858 +                   && ((!sprole_salt && !sprole_sum)
9859 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
9860 +                       assign_special_role(gr_usermode->sp_role);
9861 +                       security_alert_good(GR_SPROLES_ACL_MSG,
9862 +                                           (current->p_pptr) ? current->
9863 +                                           p_pptr->role->rolename : "",
9864 +                                           acl_sp_role_value, DEFAULTSECARGS);
9865 +               } else {
9866 +                       security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
9867 +                                      DEFAULTSECARGS);
9868 +                       error = -EPERM;
9869 +                       current->role->auth_attempts++;
9870 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9871 +                               current->role->expires =
9872 +                                   jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
9873 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
9874 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
9875 +                                      gr_usermode->sp_role, DEFAULTSECARGS);
9876 +                       }
9877 +
9878 +                       goto out;
9879 +               }
9880 +               break;
9881 +       case UNSPROLE:
9882 +               if (unlikely(!(gr_status & GR_READY))) {
9883 +                       security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
9884 +                       error = -EAGAIN;
9885 +                       break;
9886 +               }
9887 +
9888 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9889 +                   && time_before_eq(current->role->expires, jiffies)) {
9890 +                       current->role->expires = 0;
9891 +                       current->role->auth_attempts = 0;
9892 +               }
9893 +
9894 +               if (time_after(current->role->expires, jiffies)) {
9895 +                       error = -EBUSY;
9896 +                       goto out;
9897 +               }
9898 +
9899 +               if ((current->role->roletype & GR_ROLE_SPECIAL) && 
9900 +                   lookup_special_role_auth
9901 +                   (current->role->rolename, &sprole_salt, &sprole_sum)
9902 +                   && ((!sprole_salt && !sprole_sum)
9903 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
9904 +                       security_alert_good(GR_UNSPROLES_ACL_MSG,
9905 +                                           (current->p_pptr) ? current->
9906 +                                           p_pptr->role->rolename : "",
9907 +                                           (current->p_pptr) ? current->
9908 +                                           p_pptr->acl_role_id : 0, DEFAULTSECARGS);
9909 +                       gr_set_acls(1);
9910 +                       if (current->p_pptr)
9911 +                               current->p_pptr->acl_sp_role = 0;
9912 +               } else {
9913 +                       security_alert(GR_UNSPROLEF_ACL_MSG, gr_usermode->sp_role,
9914 +                                      DEFAULTSECARGS);
9915 +                       error = -EPERM;
9916 +                       current->role->auth_attempts++;
9917 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9918 +                               current->role->expires =
9919 +                                   jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
9920 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
9921 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
9922 +                                      current->role->rolename, DEFAULTSECARGS);
9923 +                       }
9924 +
9925 +                       goto out;
9926 +               }
9927 +               break;
9928 +       default:
9929 +               security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
9930 +                              DEFAULTSECARGS);
9931 +               error = -EINVAL;
9932 +               break;
9933 +       }
9934 +
9935 +       if (error != -EPERM)
9936 +               goto out;
9937 +
9938 +       gr_auth_attempts++;
9939 +
9940 +       if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9941 +               security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
9942 +               gr_auth_expires = jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
9943 +       }
9944 +
9945 +      out:
9946 +       up(&gr_dev_sem);
9947 +       return error;
9948 +}
9949 +
9950 +int
9951 +gr_set_acls(const int type)
9952 +{
9953 +       struct acl_object_label *obj;
9954 +       struct task_struct *task;
9955 +       struct file *filp;
9956 +       unsigned short i;
9957 +
9958 +       read_lock(&tasklist_lock);
9959 +       for_each_task(task) {
9960 +               /* check to see if we're called from the exit handler,
9961 +                  if so, only replace ACLs that have inherited the admin
9962 +                  ACL */
9963 +
9964 +               if (type && (task->role != current->role ||
9965 +                            task->acl_role_id != current->acl_role_id))
9966 +                       continue;
9967 +
9968 +               task->acl_role_id = 0;
9969 +
9970 +               if ((filp = task->exec_file)) {
9971 +                       do_set_role_label(task, task->uid, task->gid);
9972 +
9973 +                       task->acl =
9974 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
9975 +                                          task->role);
9976 +                       if (task->acl) {
9977 +                               struct acl_subject_label *curr;
9978 +                               curr = task->acl;
9979 +
9980 +                               task->is_writable = 0;
9981 +                               /* ignore additional mmap checks for processes that are writable 
9982 +                                  by the default ACL */
9983 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9984 +                               if (unlikely(obj->mode & GR_WRITE))
9985 +                                       task->is_writable = 1;
9986 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9987 +                               if (unlikely(obj->mode & GR_WRITE))
9988 +                                       task->is_writable = 1;
9989 +
9990 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9991 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9992 +#endif
9993 +                               if (!(curr->mode & GR_LEARN))
9994 +                                       for (i = 0; i < RLIM_NLIMITS; i++) {
9995 +                                               if (!(curr->resmask & (1 << i)))
9996 +                                                       continue;
9997 +
9998 +                                               task->rlim[i].rlim_cur =
9999 +                                                   curr->res[i].rlim_cur;
10000 +                                               task->rlim[i].rlim_max =
10001 +                                                   curr->res[i].rlim_max;
10002 +                                       }
10003 +                       } else {
10004 +                               read_unlock(&tasklist_lock);
10005 +                               security_alert_good(GR_DEFACL_MSG, task->comm,
10006 +                                                   task->pid);
10007 +                               return 1;
10008 +                       }
10009 +               } else {
10010 +                       // it's a kernel process
10011 +                       task->role = kernel_role;
10012 +                       task->acl = kernel_role->root_label;
10013 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
10014 +                       task->acl->mode &= ~GR_FIND;
10015 +#endif
10016 +               }
10017 +       }
10018 +       read_unlock(&tasklist_lock);
10019 +       return 0;
10020 +}
10021 +
10022 +void
10023 +gr_learn_resource(const struct task_struct *task,
10024 +                 const int res, const unsigned long wanted)
10025 +{
10026 +       struct acl_subject_label *acl;
10027 +
10028 +       if (unlikely((gr_status & GR_READY) &&
10029 +                    task->acl && (task->acl->mode & GR_LEARN)))
10030 +               goto skip_reslog;
10031 +
10032 +#ifdef CONFIG_GRKERNSEC_RESLOG
10033 +       gr_log_resource(task, res, wanted);
10034 +#endif
10035 +      skip_reslog:
10036 +
10037 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
10038 +               return;
10039 +
10040 +       acl = task->acl;
10041 +
10042 +       if (likely(!acl || !(acl->mode & GR_LEARN) ||
10043 +                  !(acl->resmask & (1 << (unsigned short) res))))
10044 +               return;
10045 +
10046 +       if (wanted >= acl->res[res].rlim_cur) {
10047 +               unsigned long res_add;
10048 +
10049 +               res_add = wanted;
10050 +               switch (res) {
10051 +               case RLIMIT_CPU:
10052 +                       res_add += GR_RLIM_CPU_BUMP;
10053 +                       break;
10054 +               case RLIMIT_FSIZE:
10055 +                       res_add += GR_RLIM_FSIZE_BUMP;
10056 +                       break;
10057 +               case RLIMIT_DATA:
10058 +                       res_add += GR_RLIM_DATA_BUMP;
10059 +                       break;
10060 +               case RLIMIT_STACK:
10061 +                       res_add += GR_RLIM_STACK_BUMP;
10062 +                       break;
10063 +               case RLIMIT_CORE:
10064 +                       res_add += GR_RLIM_CORE_BUMP;
10065 +                       break;
10066 +               case RLIMIT_RSS:
10067 +                       res_add += GR_RLIM_RSS_BUMP;
10068 +                       break;
10069 +               case RLIMIT_NPROC:
10070 +                       res_add += GR_RLIM_NPROC_BUMP;
10071 +                       break;
10072 +               case RLIMIT_NOFILE:
10073 +                       res_add += GR_RLIM_NOFILE_BUMP;
10074 +                       break;
10075 +               case RLIMIT_MEMLOCK:
10076 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
10077 +                       break;
10078 +               case RLIMIT_AS:
10079 +                       res_add += GR_RLIM_AS_BUMP;
10080 +                       break;
10081 +               case RLIMIT_LOCKS:
10082 +                       res_add += GR_RLIM_LOCKS_BUMP;
10083 +                       break;
10084 +               }
10085 +
10086 +               acl->res[res].rlim_cur = res_add;
10087 +
10088 +               if (wanted > acl->res[res].rlim_max)
10089 +                       acl->res[res].rlim_max = res_add;
10090 +
10091 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10092 +                              current->role->roletype, acl->filename,
10093 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
10094 +                              "", (unsigned long) res);
10095 +       }
10096 +
10097 +       return;
10098 +}
10099 +
10100 +#ifdef CONFIG_SYSCTL
10101 +extern struct proc_dir_entry *proc_sys_root;
10102 +
10103 +__u32
10104 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
10105 +                const void *newval)
10106 +{
10107 +       struct proc_dir_entry *tmp;
10108 +       struct nameidata nd;
10109 +       const char *proc_sys = "/proc/sys";
10110 +       char *path = gr_shared_page[0][smp_processor_id()];
10111 +       struct acl_object_label *obj;
10112 +       unsigned short len = 0, pos = 0, depth = 0, i;
10113 +       __u32 err = 0;
10114 +       __u32 mode = 0;
10115 +
10116 +       if (unlikely(!(gr_status & GR_READY)))
10117 +               return 1;
10118 +
10119 +       if (oldval)
10120 +               mode |= GR_READ;
10121 +       if (newval)
10122 +               mode |= GR_WRITE;
10123 +
10124 +       /* convert the requested sysctl entry into a pathname */
10125 +
10126 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
10127 +               len += strlen(tmp->name);
10128 +               len++;
10129 +               depth++;
10130 +       }
10131 +
10132 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
10133 +               return 0;       // deny
10134 +
10135 +       memset(path, 0, PAGE_SIZE);
10136 +
10137 +       memcpy(path, proc_sys, strlen(proc_sys));
10138 +
10139 +       pos += strlen(proc_sys);
10140 +
10141 +       for (; depth > 0; depth--) {
10142 +               path[pos] = '/';
10143 +               pos++;
10144 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
10145 +                    tmp = tmp->parent) {
10146 +                       if (depth == i) {
10147 +                               memcpy(path + pos, tmp->name,
10148 +                                      strlen(tmp->name));
10149 +                               pos += strlen(tmp->name);
10150 +                       }
10151 +                       i++;
10152 +               }
10153 +       }
10154 +
10155 +       if (path_init(path, LOOKUP_FOLLOW, &nd))
10156 +               err = path_walk(path, &nd);
10157 +
10158 +       if (err)
10159 +               goto out;
10160 +
10161 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
10162 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
10163 +
10164 +       if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
10165 +               __u32 new_mode = mode;
10166 +
10167 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10168 +
10169 +               err = new_mode;
10170 +               gr_log_learn(current->role, current->uid, current->gid,
10171 +                            current, path, new_mode);
10172 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
10173 +               security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
10174 +                              (mode & GR_READ) ? " reading" : "",
10175 +                              (mode & GR_WRITE) ? " writing" : "",
10176 +                              DEFAULTSECARGS);
10177 +               err = 0;
10178 +       } else if ((err & mode) != mode) {
10179 +               err = 0;
10180 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
10181 +               security_audit(GR_SYSCTL_ACL_MSG, "successful",
10182 +                              path, (mode & GR_READ) ? " reading" : "",
10183 +                              (mode & GR_WRITE) ? " writing" : "",
10184 +                              DEFAULTSECARGS);
10185 +       }
10186 +
10187 +       path_release(&nd);
10188 +
10189 +      out:
10190 +       return err;
10191 +}
10192 +#endif
10193 +
10194 +int
10195 +gr_handle_ptrace(struct task_struct *task, const long request)
10196 +{
10197 +       struct file *filp;
10198 +       __u32 retmode;
10199 +
10200 +       if (unlikely(!(gr_status & GR_READY)))
10201 +               return 0;
10202 +
10203 +       filp = task->exec_file;
10204 +
10205 +       if (unlikely(!filp))
10206 +               return 0;
10207 +
10208 +       retmode = gr_search_file(filp->f_dentry, GR_PTRACERD, filp->f_vfsmnt);
10209 +
10210 +       if (retmode & GR_PTRACERD) {
10211 +               switch (request) {
10212 +               case PTRACE_POKETEXT:
10213 +               case PTRACE_POKEDATA:
10214 +               case PTRACE_POKEUSR:
10215 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
10216 +               case PTRACE_SETREGS:
10217 +               case PTRACE_SETFPREGS:
10218 +#endif
10219 +#ifdef CONFIG_X86
10220 +               case PTRACE_SETFPXREGS:
10221 +#endif
10222 +#ifdef CONFIG_ALTIVEC
10223 +               case PTRACE_SETVRREGS:
10224 +#endif
10225 +                       return 1;
10226 +               default:
10227 +                       return 0;
10228 +               }
10229 +       } else if (!(current->acl->mode & GR_OVERRIDE) &&
10230 +                  !(current->role->roletype & GR_ROLE_GOD)
10231 +                  && (current->acl != task->acl
10232 +                      || (current->acl != current->role->root_label
10233 +                          && current->pid != task->pid))) {
10234 +               security_alert(GR_PTRACE_ACL_MSG,
10235 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10236 +                              task->comm, task->pid, DEFAULTSECARGS);
10237 +               return 1;
10238 +       }
10239 +
10240 +       return 0;
10241 +}
10242 +
10243 +int
10244 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
10245 +{
10246 +       __u32 retmode;
10247 +       struct acl_subject_label *subj;
10248 +
10249 +       if (unlikely(!(gr_status & GR_READY)))
10250 +               return 0;
10251 +
10252 +       if (unlikely
10253 +           ((current->ptrace & PT_PTRACED)
10254 +            && !(current->acl->mode & GR_OVERRIDE)))
10255 +               retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
10256 +       else
10257 +               return 0;
10258 +
10259 +       subj = chk_subj_label(dentry, mnt, current->role);
10260 +
10261 +       if (!(retmode & GR_PTRACERD) &&
10262 +           !(current->role->roletype & GR_ROLE_GOD) &&
10263 +           (current->acl != subj)) {
10264 +               security_alert(GR_PTRACE_EXEC_ACL_MSG,
10265 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
10266 +               return 1;
10267 +       }
10268 +
10269 +       return 0;
10270 +}
10271 +
10272 +int
10273 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
10274 +{
10275 +       struct acl_object_label *obj, *obj2;
10276 +
10277 +       if (unlikely(!(gr_status & GR_READY) ||
10278 +                    (current->acl->mode & GR_OVERRIDE) || !filp ||
10279 +                    !(prot & PROT_EXEC)))
10280 +               return 0;
10281 +
10282 +       if (unlikely(current->is_writable))
10283 +               return 0;
10284 +
10285 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10286 +       obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
10287 +                            current->role->root_label);
10288 +       if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
10289 +               security_alert(GR_WRITLIB_ACL_MSG,
10290 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10291 +                              DEFAULTSECARGS);
10292 +               return 1;
10293 +       }
10294 +
10295 +       return 0;
10296 +}
10297 +
10298 +int
10299 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
10300 +{
10301 +       __u32 mode;
10302 +
10303 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10304 +               return 1;
10305 +
10306 +       mode =
10307 +           gr_search_file(file->f_dentry,
10308 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10309 +                          file->f_vfsmnt);
10310 +
10311 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10312 +               security_alert(GR_MMAP_ACL_MSG, "denied",
10313 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10314 +                              DEFAULTSECARGS);
10315 +               return 0;
10316 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10317 +               return 0;
10318 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10319 +               security_audit(GR_MMAP_ACL_MSG, "successful",
10320 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10321 +                              DEFAULTSECARGS);
10322 +               return 1;
10323 +       }
10324 +
10325 +       return 1;
10326 +}
10327 +
10328 +int
10329 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
10330 +{
10331 +       __u32 mode;
10332 +
10333 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10334 +               return 1;
10335 +
10336 +       mode =
10337 +           gr_search_file(file->f_dentry,
10338 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10339 +                          file->f_vfsmnt);
10340 +
10341 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10342 +               security_alert(GR_MPROTECT_ACL_MSG, "denied",
10343 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10344 +                              DEFAULTSECARGS);
10345 +               return 0;
10346 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10347 +               return 0;
10348 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10349 +               security_audit(GR_MPROTECT_ACL_MSG, "successful",
10350 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10351 +                              DEFAULTSECARGS);
10352 +               return 1;
10353 +       }
10354 +
10355 +       return 1;
10356 +}
10357 +
10358 +void
10359 +gr_acl_handle_psacct(struct task_struct *task, const long code)
10360 +{
10361 +       unsigned long runtime;
10362 +       unsigned long cputime;
10363 +       unsigned int wday, cday;
10364 +       __u8 whr, chr;
10365 +       __u8 wmin, cmin;
10366 +       __u8 wsec, csec;
10367 +       char cur_tty[64] = { 0 };
10368 +       char parent_tty[64] = { 0 };
10369 +
10370 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
10371 +                    !(task->acl->mode & GR_PROCACCT)))
10372 +               return;
10373 +
10374 +       runtime = (jiffies - task->start_time) / HZ;
10375 +       wday = runtime / (3600 * 24);
10376 +       runtime -= wday * (3600 * 24);
10377 +       whr = runtime / 3600;
10378 +       runtime -= whr * 3600;
10379 +       wmin = runtime / 60;
10380 +       runtime -= wmin * 60;
10381 +       wsec = runtime;
10382 +
10383 +       cputime = (task->times.tms_utime + task->times.tms_stime) / HZ;
10384 +       cday = cputime / (3600 * 24);
10385 +       cputime -= cday * (3600 * 24);
10386 +       chr = cputime / 3600;
10387 +       cputime -= chr * 3600;
10388 +       cmin = cputime / 60;
10389 +       cputime -= cmin * 60;
10390 +       csec = cputime;
10391 +
10392 +       security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
10393 +                      task->pid, NIPQUAD(task->curr_ip), tty_name(task->tty,
10394 +                                                                  cur_tty),
10395 +                      task->uid, task->euid, task->gid, task->egid, wday, whr,
10396 +                      wmin, wsec, cday, chr, cmin, csec,
10397 +                      (task->
10398 +                       flags & PF_SIGNALED) ? "killed by signal" : "exited",
10399 +                      code, gr_parent_task_fullpath(task), 
10400 +                      task->p_pptr->comm, task->p_pptr->pid,
10401 +                      NIPQUAD(task->p_pptr->curr_ip),
10402 +                      tty_name(task->p_pptr->tty, parent_tty),
10403 +                      task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid,
10404 +                      task->p_pptr->egid);
10405 +
10406 +       return;
10407 +}
10408 +
10409 +void gr_set_kernel_label(struct task_struct *task)
10410 +{
10411 +       if (gr_status & GR_READY) {
10412 +               task->role = kernel_role;
10413 +               task->acl = kernel_role->root_label;
10414 +       }
10415 +       return;
10416 +}
10417 diff -urN linux-2.4.22.org/grsecurity/gracl_cap.c linux-2.4.22/grsecurity/gracl_cap.c
10418 --- linux-2.4.22.org/grsecurity/gracl_cap.c     1970-01-01 01:00:00.000000000 +0100
10419 +++ linux-2.4.22/grsecurity/gracl_cap.c 2003-11-22 22:14:08.000000000 +0100
10420 @@ -0,0 +1,71 @@
10421 +/* capability handling routines, (c) Brad Spengler 2002,2003 */
10422 +
10423 +#include <linux/kernel.h>
10424 +#include <linux/sched.h>
10425 +#include <linux/capability.h>
10426 +#include <linux/gracl.h>
10427 +#include <linux/grsecurity.h>
10428 +#include <linux/grinternal.h>
10429 +
10430 +static const char *captab_log[29] = {
10431 +       "CAP_CHOWN",
10432 +       "CAP_DAC_OVERRIDE",
10433 +       "CAP_DAC_READ_SEARCH",
10434 +       "CAP_FOWNER",
10435 +       "CAP_FSETID",
10436 +       "CAP_KILL",
10437 +       "CAP_SETGID",
10438 +       "CAP_SETUID",
10439 +       "CAP_SETPCAP",
10440 +       "CAP_LINUX_IMMUTABLE",
10441 +       "CAP_NET_BIND_SERVICE",
10442 +       "CAP_NET_BROADCAST",
10443 +       "CAP_NET_ADMIN",
10444 +       "CAP_NET_RAW",
10445 +       "CAP_IPC_LOCK",
10446 +       "CAP_IPC_OWNER",
10447 +       "CAP_SYS_MODULE",
10448 +       "CAP_SYS_RAWIO",
10449 +       "CAP_SYS_CHROOT",
10450 +       "CAP_SYS_PTRACE",
10451 +       "CAP_SYS_PACCT",
10452 +       "CAP_SYS_ADMIN",
10453 +       "CAP_SYS_BOOT",
10454 +       "CAP_SYS_NICE",
10455 +       "CAP_SYS_RESOURCE",
10456 +       "CAP_SYS_TIME",
10457 +       "CAP_SYS_TTY_CONFIG",
10458 +       "CAP_MKNOD",
10459 +       "CAP_LEASE"
10460 +};
10461 +
10462 +int
10463 +gr_is_capable(const int cap)
10464 +{
10465 +       struct acl_subject_label *curracl;
10466 +
10467 +       if (!gr_acl_is_enabled())
10468 +               return 1;
10469 +
10470 +       curracl = current->acl;
10471 +
10472 +       if (!cap_raised(curracl->cap_lower, cap))
10473 +               return 1;
10474 +
10475 +       if ((curracl->mode & GR_LEARN)
10476 +           && cap_raised(current->cap_effective, cap)) {
10477 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10478 +                              current->role->roletype, current->uid,
10479 +                              current->gid, current->exec_file ?
10480 +                              gr_to_filename(current->exec_file->f_dentry,
10481 +                              current->exec_file->f_vfsmnt) : curracl->filename,
10482 +                              curracl->filename, 0UL,
10483 +                              0UL, "", (unsigned long) cap, NIPQUAD(current->curr_ip));
10484 +               return 1;
10485 +       }
10486 +
10487 +       if ((cap >= 0) && (cap < 29) && cap_raised(current->cap_effective, cap))
10488 +               security_alert(GR_CAP_ACL_MSG, captab_log[cap], DEFAULTSECARGS);
10489 +
10490 +       return 0;
10491 +}
10492 diff -urN linux-2.4.22.org/grsecurity/gracl_fs.c linux-2.4.22/grsecurity/gracl_fs.c
10493 --- linux-2.4.22.org/grsecurity/gracl_fs.c      1970-01-01 01:00:00.000000000 +0100
10494 +++ linux-2.4.22/grsecurity/gracl_fs.c  2003-11-22 22:14:08.000000000 +0100
10495 @@ -0,0 +1,469 @@
10496 +#include <linux/kernel.h>
10497 +#include <linux/sched.h>
10498 +#include <linux/types.h>
10499 +#include <linux/fs.h>
10500 +#include <linux/file.h>
10501 +#include <linux/grsecurity.h>
10502 +#include <linux/grinternal.h>
10503 +#include <linux/gracl.h>
10504 +
10505 +__u32
10506 +gr_acl_handle_hidden_file(const struct dentry * dentry,
10507 +                         const struct vfsmount * mnt)
10508 +{
10509 +       __u32 mode;
10510 +
10511 +       if (unlikely(!dentry->d_inode))
10512 +               return GR_FIND;
10513 +
10514 +       mode =
10515 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
10516 +
10517 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
10518 +               security_audit(GR_HIDDEN_ACL_MSG, "successful",
10519 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
10520 +               return mode;
10521 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
10522 +               security_alert(GR_HIDDEN_ACL_MSG, "denied",
10523 +                              gr_to_filename(dentry, mnt),
10524 +                              DEFAULTSECARGS);
10525 +               return 0;
10526 +       } else if (unlikely(!(mode & GR_FIND)))
10527 +               return 0;
10528 +
10529 +       return GR_FIND;
10530 +}
10531 +
10532 +__u32
10533 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
10534 +                  const int fmode)
10535 +{
10536 +       __u32 reqmode = GR_FIND;
10537 +       __u32 mode;
10538 +
10539 +       if (unlikely(!dentry->d_inode))
10540 +               return reqmode;
10541 +
10542 +       if (unlikely(fmode & O_APPEND))
10543 +               reqmode |= GR_APPEND;
10544 +       else if (unlikely(fmode & FMODE_WRITE))
10545 +               reqmode |= GR_WRITE;
10546 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
10547 +               reqmode |= GR_READ;
10548 +
10549 +       mode =
10550 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
10551 +                          mnt);
10552 +
10553 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10554 +               security_audit(GR_OPEN_ACL_MSG, "successful",
10555 +                              gr_to_filename(dentry, mnt),
10556 +                              reqmode & GR_READ ? " reading" : "",
10557 +                              reqmode & GR_WRITE ? " writing" :
10558 +                              reqmode & GR_APPEND ? " appending" : "",
10559 +                              DEFAULTSECARGS);
10560 +               return reqmode;
10561 +       } else
10562 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10563 +       {
10564 +               security_alert(GR_OPEN_ACL_MSG, "denied",
10565 +                              gr_to_filename(dentry, mnt),
10566 +                              reqmode & GR_READ ? " reading" : "",
10567 +                              reqmode & GR_WRITE ? " writing" : reqmode &
10568 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
10569 +               return 0;
10570 +       } else if (unlikely((mode & reqmode) != reqmode))
10571 +               return 0;
10572 +
10573 +       return reqmode;
10574 +}
10575 +
10576 +__u32
10577 +gr_acl_handle_creat(const struct dentry * dentry,
10578 +                   const struct dentry * p_dentry,
10579 +                   const struct vfsmount * p_mnt, const int fmode,
10580 +                   const int imode)
10581 +{
10582 +       __u32 reqmode = GR_WRITE | GR_CREATE;
10583 +       __u32 mode;
10584 +
10585 +       if (unlikely(fmode & O_APPEND))
10586 +               reqmode |= GR_APPEND;
10587 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
10588 +               reqmode |= GR_READ;
10589 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
10590 +               reqmode |= GR_SETID;
10591 +
10592 +       mode =
10593 +           gr_check_create(dentry, p_dentry, p_mnt,
10594 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
10595 +
10596 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10597 +               security_audit(GR_CREATE_ACL_MSG, "successful",
10598 +                              gr_to_filename(dentry, p_mnt),
10599 +                              reqmode & GR_READ ? " reading" : "",
10600 +                              reqmode & GR_WRITE ? " writing" :
10601 +                              reqmode & GR_APPEND ? " appending" : "",
10602 +                              DEFAULTSECARGS);
10603 +               return reqmode;
10604 +       } else
10605 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10606 +       {
10607 +               security_alert(GR_CREATE_ACL_MSG, "denied",
10608 +                              gr_to_filename(dentry, p_mnt),
10609 +                              reqmode & GR_READ ? " reading" : "",
10610 +                              reqmode & GR_WRITE ? " writing" : reqmode &
10611 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
10612 +               return 0;
10613 +       } else if (unlikely((mode & reqmode) != reqmode))
10614 +               return 0;
10615 +
10616 +       return reqmode;
10617 +}
10618 +
10619 +__u32
10620 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
10621 +                    const int fmode)
10622 +{
10623 +       __u32 mode, reqmode = GR_FIND;
10624 +
10625 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
10626 +               reqmode |= GR_EXEC;
10627 +       if (fmode & S_IWOTH)
10628 +               reqmode |= GR_WRITE;
10629 +       if (fmode & S_IROTH)
10630 +               reqmode |= GR_READ;
10631 +
10632 +       mode =
10633 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
10634 +                          mnt);
10635 +
10636 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10637 +               security_audit(GR_ACCESS_ACL_MSG, "successful",
10638 +                              gr_to_filename(dentry, mnt),
10639 +                              reqmode & GR_READ ? " reading" : "",
10640 +                              reqmode & GR_WRITE ? " writing" : "",
10641 +                              reqmode & GR_EXEC ? " executing" : "",
10642 +                              DEFAULTSECARGS);
10643 +               return reqmode;
10644 +       } else
10645 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10646 +       {
10647 +               security_alert(GR_ACCESS_ACL_MSG, "denied",
10648 +                              gr_to_filename(dentry, mnt),
10649 +                              reqmode & GR_READ ? " reading" : "",
10650 +                              reqmode & GR_WRITE ? " writing" : "",
10651 +                              reqmode & GR_EXEC ? " executing" : "",
10652 +                              DEFAULTSECARGS);
10653 +               return 0;
10654 +       } else if (unlikely((mode & reqmode) != reqmode))
10655 +               return 0;
10656 +
10657 +       return reqmode;
10658 +}
10659 +
10660 +#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
10661 +{ \
10662 +       __u32 mode; \
10663 +       \
10664 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
10665 +       \
10666 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
10667 +               security_audit(fmt, "successful", \
10668 +                               gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
10669 +               return mode; \
10670 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
10671 +               security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
10672 +                               DEFAULTSECARGS); \
10673 +               return 0; \
10674 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
10675 +               return 0; \
10676 +       \
10677 +       return (reqmode); \
10678 +}
10679 +
10680 +__u32
10681 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
10682 +{
10683 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
10684 +}
10685 +
10686 +__u32
10687 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
10688 +{
10689 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
10690 +}
10691 +
10692 +__u32
10693 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
10694 +{
10695 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
10696 +}
10697 +
10698 +__u32
10699 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
10700 +{
10701 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
10702 +}
10703 +
10704 +__u32
10705 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
10706 +                    mode_t mode)
10707 +{
10708 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
10709 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
10710 +                                  GR_FCHMOD_ACL_MSG);
10711 +       } else {
10712 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
10713 +       }
10714 +}
10715 +
10716 +__u32
10717 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
10718 +                   mode_t mode)
10719 +{
10720 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
10721 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
10722 +                                  GR_CHMOD_ACL_MSG);
10723 +       } else {
10724 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
10725 +       }
10726 +}
10727 +
10728 +__u32
10729 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
10730 +{
10731 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
10732 +}
10733 +
10734 +__u32
10735 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
10736 +{
10737 +       generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
10738 +}
10739 +
10740 +__u32
10741 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
10742 +{
10743 +       generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
10744 +                          GR_UNIXCONNECT_ACL_MSG);
10745 +}
10746 +
10747 +__u32
10748 +gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
10749 +                     const ino_t ino)
10750 +{
10751 +       if (likely((unsigned long)(dentry->d_inode))) {
10752 +               struct dentry d = *dentry;
10753 +               struct inode inode = *(dentry->d_inode);
10754 +
10755 +               inode.i_ino = ino;
10756 +               d.d_inode = &inode;
10757 +
10758 +               if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
10759 +                       return 0;
10760 +       }
10761 +
10762 +       return 1;
10763 +}
10764 +
10765 +__u32
10766 +gr_acl_handle_link(const struct dentry * new_dentry,
10767 +                  const struct dentry * parent_dentry,
10768 +                  const struct vfsmount * parent_mnt,
10769 +                  const struct dentry * old_dentry,
10770 +                  const struct vfsmount * old_mnt, const char *to)
10771 +{
10772 +       __u32 needmode = GR_WRITE | GR_CREATE;
10773 +       __u32 mode;
10774 +
10775 +       mode =
10776 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
10777 +                         old_mnt);
10778 +
10779 +       if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
10780 +               security_audit(GR_LINK_ACL_MSG, "successful",
10781 +                              gr_to_filename(old_dentry, old_mnt), to,
10782 +                              DEFAULTSECARGS);
10783 +               return mode;
10784 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
10785 +               security_alert(GR_LINK_ACL_MSG, "denied",
10786 +                              gr_to_filename(old_dentry, old_mnt), to,
10787 +                              DEFAULTSECARGS);
10788 +               return 0;
10789 +       } else if (unlikely((mode & needmode) != needmode))
10790 +               return 0;
10791 +
10792 +       return (GR_WRITE | GR_CREATE);
10793 +}
10794 +
10795 +__u32
10796 +gr_acl_handle_symlink(const struct dentry * new_dentry,
10797 +                     const struct dentry * parent_dentry,
10798 +                     const struct vfsmount * parent_mnt, const char *from)
10799 +{
10800 +       __u32 needmode = GR_WRITE | GR_CREATE;
10801 +       __u32 mode;
10802 +
10803 +       mode =
10804 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
10805 +                           GR_CREATE | GR_AUDIT_CREATE |
10806 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
10807 +
10808 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
10809 +               security_audit(GR_SYMLINK_ACL_MSG, "successful",
10810 +                              from, gr_to_filename(new_dentry, parent_mnt),
10811 +                              DEFAULTSECARGS);
10812 +               return mode;
10813 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
10814 +               security_alert(GR_SYMLINK_ACL_MSG, "denied",
10815 +                              from, gr_to_filename(new_dentry, parent_mnt),
10816 +                              DEFAULTSECARGS);
10817 +               return 0;
10818 +       } else if (unlikely((mode & needmode) != needmode))
10819 +               return 0;
10820 +
10821 +       return (GR_WRITE | GR_CREATE);
10822 +}
10823 +
10824 +#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
10825 +{ \
10826 +       __u32 mode; \
10827 +       \
10828 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
10829 +       \
10830 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
10831 +               security_audit(fmt, "successful", \
10832 +                               gr_to_filename(new_dentry, parent_mnt), \
10833 +                               DEFAULTSECARGS); \
10834 +               return mode; \
10835 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
10836 +               security_alert(fmt, "denied", \
10837 +                               gr_to_filename(new_dentry, parent_mnt), \
10838 +                               DEFAULTSECARGS); \
10839 +               return 0; \
10840 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
10841 +               return 0; \
10842 +       \
10843 +       return (reqmode); \
10844 +}
10845 +
10846 +__u32
10847 +gr_acl_handle_mknod(const struct dentry * new_dentry,
10848 +                   const struct dentry * parent_dentry,
10849 +                   const struct vfsmount * parent_mnt,
10850 +                   const int mode)
10851 +{
10852 +       __u32 reqmode = GR_WRITE | GR_CREATE;
10853 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
10854 +               reqmode |= GR_SETID;
10855 +
10856 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
10857 +                                 reqmode, GR_MKNOD_ACL_MSG);
10858 +}
10859 +
10860 +__u32
10861 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
10862 +                   const struct dentry *parent_dentry,
10863 +                   const struct vfsmount *parent_mnt)
10864 +{
10865 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
10866 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
10867 +}
10868 +
10869 +#define RENAME_CHECK_SUCCESS(old, new) \
10870 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
10871 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
10872 +
10873 +int
10874 +gr_acl_handle_rename(struct dentry *new_dentry,
10875 +                    struct dentry *parent_dentry,
10876 +                    const struct vfsmount *parent_mnt,
10877 +                    struct dentry *old_dentry,
10878 +                    struct inode *old_parent_inode,
10879 +                    struct vfsmount *old_mnt, const char *newname)
10880 +{
10881 +       __u8 gr_replace = 1;
10882 +       __u32 comp1, comp2;
10883 +       int error = 0;
10884 +
10885 +       if (unlikely(!gr_acl_is_enabled()))
10886 +               return 1;
10887 +
10888 +       if (!new_dentry->d_inode) {
10889 +               gr_replace = 0;
10890 +
10891 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
10892 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
10893 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
10894 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
10895 +                                      GR_DELETE | GR_AUDIT_DELETE |
10896 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
10897 +                                      GR_SUPPRESS, old_mnt);
10898 +       } else {
10899 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
10900 +                                      GR_CREATE | GR_DELETE |
10901 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
10902 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
10903 +                                      GR_SUPPRESS, parent_mnt);
10904 +               comp2 =
10905 +                   gr_search_file(old_dentry,
10906 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
10907 +                                  GR_DELETE | GR_AUDIT_DELETE |
10908 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
10909 +       }
10910 +
10911 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
10912 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
10913 +               security_audit(GR_RENAME_ACL_MSG, "successful",
10914 +                              gr_to_filename(old_dentry, old_mnt),
10915 +                              newname, DEFAULTSECARGS);
10916 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
10917 +                && !(comp2 & GR_SUPPRESS)) {
10918 +               security_alert(GR_RENAME_ACL_MSG, "denied",
10919 +                              gr_to_filename(old_dentry, old_mnt), newname,
10920 +                              DEFAULTSECARGS);
10921 +               error = -EACCES;
10922 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
10923 +               error = -EACCES;
10924 +
10925 +       if (error)
10926 +               return error;
10927 +
10928 +       error = gr_handle_rename(old_parent_inode, parent_dentry->d_inode,
10929 +                                old_dentry, new_dentry, old_mnt, gr_replace);
10930 +
10931 +       return error;
10932 +}
10933 +
10934 +void
10935 +gr_acl_handle_exit(void)
10936 +{
10937 +       u16 id;
10938 +       char *rolename;
10939 +
10940 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
10941 +               id = current->acl_role_id;
10942 +               rolename = current->role->rolename;
10943 +               gr_set_acls(1);
10944 +               security_alert_good(GR_SPROLEL_ACL_MSG,
10945 +                                   rolename, id, DEFAULTSECARGS);
10946 +       }
10947 +
10948 +       if (current->exec_file) {
10949 +               fput(current->exec_file);
10950 +               current->exec_file = NULL;
10951 +       }
10952 +}
10953 +
10954 +int
10955 +gr_acl_handle_procpidmem(const struct task_struct *task)
10956 +{
10957 +       if (unlikely(!gr_acl_is_enabled()))
10958 +               return 0;
10959 +
10960 +       if (task->acl->mode & GR_PROTPROCFD)
10961 +               return -EACCES;
10962 +
10963 +       return 0;
10964 +}
10965 diff -urN linux-2.4.22.org/grsecurity/gracl_ip.c linux-2.4.22/grsecurity/gracl_ip.c
10966 --- linux-2.4.22.org/grsecurity/gracl_ip.c      1970-01-01 01:00:00.000000000 +0100
10967 +++ linux-2.4.22/grsecurity/gracl_ip.c  2003-11-22 22:14:08.000000000 +0100
10968 @@ -0,0 +1,235 @@
10969 +/* 
10970 + * grsecurity/gracl_ip.c
10971 + * Copyright Brad Spengler 2002, 2003
10972 + *
10973 + */
10974 +
10975 +#include <linux/kernel.h>
10976 +#include <asm/uaccess.h>
10977 +#include <asm/errno.h>
10978 +#include <net/sock.h>
10979 +#include <linux/file.h>
10980 +#include <linux/fs.h>
10981 +#include <linux/net.h>
10982 +#include <linux/in.h>
10983 +#include <linux/skbuff.h>
10984 +#include <linux/ip.h>
10985 +#include <linux/udp.h>
10986 +#include <linux/smp_lock.h>
10987 +#include <linux/types.h>
10988 +#include <linux/sched.h>
10989 +#include <linux/gracl.h>
10990 +#include <linux/grsecurity.h>
10991 +#include <linux/grinternal.h>
10992 +
10993 +#define GR_BIND        0x01
10994 +#define GR_CONNECT     0x02
10995 +
10996 +static const char * gr_protocols[256] = {
10997 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
10998 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
10999 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
11000 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
11001 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
11002 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
11003 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
11004 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
11005 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
11006 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
11007 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
11008 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
11009 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
11010 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
11011 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
11012 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
11013 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
11014 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
11015 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
11016 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
11017 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
11018 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
11019 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
11020 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
11021 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
11022 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
11023 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
11024 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
11025 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
11026 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
11027 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
11028 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
11029 +       };
11030 +
11031 +static const char * gr_socktypes[11] = {
11032 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
11033 +       "unknown:7", "unknown:8", "unknown:9", "packet"
11034 +       };
11035 +
11036 +static __inline__ const char *
11037 +gr_proto_to_name(unsigned char proto)
11038 +{
11039 +       return gr_protocols[proto];
11040 +}
11041 +
11042 +static __inline__ const char *
11043 +gr_socktype_to_name(unsigned char type)
11044 +{
11045 +       return gr_socktypes[type];
11046 +}
11047 +
11048 +int
11049 +gr_search_socket(const int domain, const int type, const int protocol)
11050 +{
11051 +       struct acl_subject_label *curr;
11052 +
11053 +       if (unlikely(!gr_acl_is_enabled()))
11054 +               goto exit;
11055 +
11056 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
11057 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
11058 +               goto exit;      // let the kernel handle it
11059 +
11060 +       curr = current->acl;
11061 +
11062 +       if (!curr->ips)
11063 +               goto exit;
11064 +
11065 +       if ((curr->ip_type & (1 << type)) &&
11066 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
11067 +               goto exit;
11068 +
11069 +       if (curr->mode & GR_LEARN) {
11070 +               /* we don't place acls on raw sockets , and sometimes
11071 +                  dgram/ip sockets are opened for ioctl and not
11072 +                  bind/connect, so we'll fake a bind learn log */
11073 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
11074 +                       __u32 fakeip = 0;
11075 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11076 +                                      current->role->roletype, current->uid,
11077 +                                      current->gid, current->exec_file ?
11078 +                                      gr_to_filename(current->exec_file->f_dentry,
11079 +                                      current->exec_file->f_vfsmnt) :
11080 +                                      curr->filename, curr->filename,
11081 +                                      NIPQUAD(fakeip), 0, type,
11082 +                                      protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
11083 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
11084 +                       __u32 fakeip = 0;
11085 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11086 +                                      current->role->roletype, current->uid,
11087 +                                      current->gid, current->exec_file ?
11088 +                                      gr_to_filename(current->exec_file->f_dentry,
11089 +                                      current->exec_file->f_vfsmnt) :
11090 +                                      curr->filename, curr->filename,
11091 +                                      NIPQUAD(fakeip), 0, type,
11092 +                                      protocol, GR_BIND, NIPQUAD(current->curr_ip));
11093 +               }
11094 +               /* we'll log when they use connect or bind */
11095 +               goto exit;
11096 +       }
11097 +
11098 +       security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
11099 +                      gr_proto_to_name(protocol), DEFAULTSECARGS);
11100 +
11101 +       return 0;
11102 +      exit:
11103 +       return 1;
11104 +}
11105 +
11106 +static __inline__ int
11107 +gr_search_connectbind(const int mode, const struct sock *sk,
11108 +                     const struct sockaddr_in *addr, const int type)
11109 +{
11110 +       struct acl_subject_label *curr;
11111 +       struct acl_ip_label *ip;
11112 +       unsigned long i;
11113 +       __u32 ip_addr = 0;
11114 +       __u16 ip_port = 0;
11115 +
11116 +       if (unlikely(!gr_acl_is_enabled() || sk->family != PF_INET))
11117 +               return 1;
11118 +
11119 +       curr = current->acl;
11120 +
11121 +       if (!curr->ips)
11122 +               return 1;
11123 +
11124 +       ip_addr = addr->sin_addr.s_addr;
11125 +       ip_port = ntohs(addr->sin_port);
11126 +
11127 +       for (i = 0; i < curr->ip_num; i++) {
11128 +               ip = *(curr->ips + i);
11129 +               if ((ip->mode & mode) &&
11130 +                   (ip_port >= ip->low) &&
11131 +                   (ip_port <= ip->high) &&
11132 +                   ((ntohl(ip_addr) & ip->netmask) ==
11133 +                    (ntohl(ip->addr) & ip->netmask))
11134 +                   && (ip->
11135 +                       proto[sk->protocol / 32] & (1 << (sk->protocol % 32)))
11136 +                   && (ip->type & (1 << type)))
11137 +                       return 1;
11138 +       }
11139 +
11140 +       if (curr->mode & GR_LEARN) {
11141 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11142 +                              current->role->roletype, current->uid,
11143 +                              current->gid, current->exec_file ?
11144 +                              gr_to_filename(current->exec_file->f_dentry,
11145 +                              current->exec_file->f_vfsmnt) :
11146 +                              curr->filename, curr->filename,
11147 +                              NIPQUAD(ip_addr), ip_port, type,
11148 +                              sk->protocol, mode, NIPQUAD(current->curr_ip));
11149 +               return 1;
11150 +       }
11151 +
11152 +       if (mode == GR_BIND)
11153 +               security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11154 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11155 +                              DEFAULTSECARGS);
11156 +       else if (mode == GR_CONNECT)
11157 +               security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11158 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11159 +                              DEFAULTSECARGS);
11160 +
11161 +       return 0;
11162 +}
11163 +
11164 +int
11165 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
11166 +{
11167 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
11168 +}
11169 +
11170 +int
11171 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
11172 +{
11173 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
11174 +}
11175 +
11176 +int
11177 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
11178 +{
11179 +       if (addr)
11180 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
11181 +       else {
11182 +               struct sockaddr_in sin;
11183 +
11184 +               sin.sin_addr.s_addr = sk->daddr;
11185 +               sin.sin_port = sk->dport;
11186 +
11187 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11188 +       }
11189 +}
11190 +
11191 +int
11192 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
11193 +{
11194 +       struct sockaddr_in sin;
11195 +
11196 +       if (unlikely(skb->len < sizeof (struct udphdr)))
11197 +               return 1;       // skip this packet
11198 +
11199 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
11200 +       sin.sin_port = skb->h.uh->source;
11201 +
11202 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11203 +}
11204 diff -urN linux-2.4.22.org/grsecurity/gracl_learn.c linux-2.4.22/grsecurity/gracl_learn.c
11205 --- linux-2.4.22.org/grsecurity/gracl_learn.c   1970-01-01 01:00:00.000000000 +0100
11206 +++ linux-2.4.22/grsecurity/gracl_learn.c       2003-11-22 22:14:08.000000000 +0100
11207 @@ -0,0 +1,228 @@
11208 +#include <linux/kernel.h>
11209 +#include <linux/mm.h>
11210 +#include <linux/sched.h>
11211 +#include <linux/poll.h>
11212 +#include <linux/smp_lock.h>
11213 +#include <linux/string.h>
11214 +#include <linux/file.h>
11215 +#include <linux/types.h>
11216 +#include <linux/vmalloc.h>
11217 +#include <linux/grinternal.h>
11218 +
11219 +extern ssize_t write_grsec_handler(struct file * file, const char * buf,
11220 +                                  size_t count, loff_t *ppos);
11221 +extern int gr_acl_is_enabled(void);
11222 +
11223 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
11224 +static DECLARE_WAIT_QUEUE_HEAD(input_wait);
11225 +static atomic_t learn_buffer_count = ATOMIC_INIT(0);
11226 +static int gr_learn_attached;
11227 +
11228 +#define LEARN_BUFFER_SLOTS 256
11229 +#define LEARN_BUFFER_SIZE 16384
11230 +
11231 +static spinlock_t learn_buffer_lock[LEARN_BUFFER_SLOTS] = { [0 ... (LEARN_BUFFER_SLOTS - 1)] = SPIN_LOCK_UNLOCKED };
11232 +static char *learn_buffer[LEARN_BUFFER_SLOTS];
11233 +static int learn_buffer_len[LEARN_BUFFER_SLOTS];
11234 +
11235 +static ssize_t
11236 +read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
11237 +{
11238 +       DECLARE_WAITQUEUE(wait, current);
11239 +       ssize_t retval = 0;
11240 +       char *tmp;
11241 +       unsigned int len;
11242 +       int i;
11243 +
11244 +       add_wait_queue(&learn_wait, &wait);
11245 +       set_current_state(TASK_INTERRUPTIBLE);
11246 +       do {
11247 +               if (atomic_read(&learn_buffer_count) > 1)
11248 +                       break;
11249 +
11250 +               if (file->f_flags & O_NONBLOCK) {
11251 +                       retval = -EAGAIN;
11252 +                       goto out;
11253 +               }
11254 +               if (signal_pending(current)) {
11255 +                       retval = -ERESTARTSYS;
11256 +                       goto out;
11257 +               }
11258 +
11259 +               schedule();
11260 +       } while (1);
11261 +
11262 +
11263 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11264 +               spin_lock(&learn_buffer_lock[i]);
11265 +               len = learn_buffer_len[i];
11266 +               tmp = learn_buffer[i];
11267 +               if (!len || !tmp) {
11268 +                       spin_unlock(&learn_buffer_lock[i]);
11269 +                       continue;
11270 +               }
11271 +               learn_buffer[i] = NULL;
11272 +               learn_buffer_len[i] = 0;
11273 +               spin_unlock(&learn_buffer_lock[i]);
11274 +
11275 +               if (count < ((i * LEARN_BUFFER_SIZE) + len)) {
11276 +                       retval = -EINVAL;
11277 +                       vfree(tmp);
11278 +                       goto out;
11279 +               }
11280 +               if (copy_to_user(buf + (i * LEARN_BUFFER_SIZE), tmp, len)) {
11281 +                       retval = -EFAULT;
11282 +                       vfree(tmp);
11283 +                       goto out;
11284 +               }
11285 +
11286 +               retval += len;
11287 +               vfree(tmp);
11288 +               atomic_dec(&learn_buffer_count);
11289 +               atomic_dec(&learn_buffer_count);
11290 +       }
11291 +
11292 +       wake_up(&input_wait);
11293 +out:
11294 +       set_current_state(TASK_RUNNING);
11295 +       remove_wait_queue(&learn_wait, &wait);
11296 +       return retval;
11297 +}
11298 +
11299 +static unsigned int
11300 +poll_learn(struct file * file, poll_table * wait)
11301 +{
11302 +       poll_wait(file, &learn_wait, wait);
11303 +
11304 +       if (atomic_read(&learn_buffer_count) > 1)
11305 +               return (POLLIN | POLLRDNORM);
11306 +
11307 +       return 0;
11308 +}
11309 +
11310 +void
11311 +gr_clear_learn_entries(void)
11312 +{
11313 +       int i;
11314 +
11315 +       atomic_set(&learn_buffer_count, 0);
11316 +       wake_up(&input_wait);
11317 +       
11318 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11319 +               if (learn_buffer_len[i]) {
11320 +                       vfree(learn_buffer[i]);
11321 +                       learn_buffer[i] = NULL;
11322 +                       learn_buffer_len[i] = 0;
11323 +               }
11324 +       }
11325 +
11326 +       return;
11327 +}
11328 +
11329 +void
11330 +gr_add_learn_entry(const char *fmt, ...)
11331 +{
11332 +       DECLARE_WAITQUEUE(wait, current);
11333 +       va_list args;
11334 +       char *tmpbuf;
11335 +       char *buf;
11336 +       int i;
11337 +       unsigned int len;
11338 +
11339 +       if (!gr_learn_attached)
11340 +               return;
11341 +
11342 +       tmpbuf = vmalloc(LEARN_BUFFER_SIZE);
11343 +
11344 +       if (tmpbuf == NULL)
11345 +               return;
11346 +
11347 +       va_start(args, fmt);
11348 +       len = vsnprintf(tmpbuf, LEARN_BUFFER_SIZE, fmt, args);
11349 +       va_end(args);
11350 +
11351 +       if (len < 0)
11352 +               len = LEARN_BUFFER_SIZE - 1;
11353 +
11354 +       buf = vmalloc(len + 1);
11355 +
11356 +       if (buf == NULL) {
11357 +               vfree(tmpbuf);
11358 +               return;
11359 +       }
11360 +
11361 +       memcpy(buf, tmpbuf, len);
11362 +       buf[len] = '\0';
11363 +       vfree(tmpbuf);
11364 +
11365 +       add_wait_queue(&input_wait, &wait);
11366 +
11367 +       atomic_inc(&learn_buffer_count);
11368 +       if (atomic_read(&learn_buffer_count) > ((2 * (LEARN_BUFFER_SLOTS - 1)) + 1)) {
11369 +               /* don't sleep under the BKL */
11370 +//             if (unlikely(current->lock_depth >= 0)) {
11371 +               remove_wait_queue(&input_wait, &wait);
11372 +               atomic_dec(&learn_buffer_count);
11373 +               vfree(buf);
11374 +               return;
11375 +//             }
11376 +//             sleep_on(&input_wait);
11377 +       }
11378 +
11379 +       if (!gr_acl_is_enabled()) {
11380 +               remove_wait_queue(&input_wait, &wait);
11381 +               atomic_dec(&learn_buffer_count);
11382 +               vfree(buf);
11383 +               return;
11384 +       }
11385 +
11386 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11387 +               spin_lock(&learn_buffer_lock[i]);
11388 +
11389 +               if (learn_buffer_len[i]) {
11390 +                       spin_unlock(&learn_buffer_lock[i]);
11391 +                       continue;
11392 +               }
11393 +
11394 +               learn_buffer[i] = buf;
11395 +
11396 +               learn_buffer_len[i] = len + 1;
11397 +
11398 +               atomic_inc(&learn_buffer_count);
11399 +               spin_unlock(&learn_buffer_lock[i]);
11400 +               break;
11401 +       }
11402 +
11403 +       remove_wait_queue(&input_wait, &wait);
11404 +       wake_up_interruptible(&learn_wait);
11405 +
11406 +       return;
11407 +}
11408 +
11409 +static int
11410 +open_learn(struct inode *inode, struct file *file)
11411 +{
11412 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
11413 +               return -EBUSY;
11414 +       else if (file->f_mode & FMODE_READ)
11415 +               gr_learn_attached = 1;
11416 +
11417 +       return 0;
11418 +}
11419 +
11420 +static int
11421 +close_learn(struct inode *inode, struct file *file)
11422 +{
11423 +       if (file->f_mode & FMODE_READ)
11424 +               gr_learn_attached = 0;
11425 +
11426 +       return 0;
11427 +}
11428 +               
11429 +struct file_operations grsec_fops = {
11430 +       read:           read_learn,
11431 +       write:          write_grsec_handler,
11432 +       open:           open_learn,
11433 +       release:        close_learn,
11434 +       poll:           poll_learn,
11435 +};
11436 diff -urN linux-2.4.22.org/grsecurity/gracl_res.c linux-2.4.22/grsecurity/gracl_res.c
11437 --- linux-2.4.22.org/grsecurity/gracl_res.c     1970-01-01 01:00:00.000000000 +0100
11438 +++ linux-2.4.22/grsecurity/gracl_res.c 2003-11-22 22:14:08.000000000 +0100
11439 @@ -0,0 +1,45 @@
11440 +/* resource handling routines (c) Brad Spengler 2002, 2003 */
11441 +
11442 +#include <linux/kernel.h>
11443 +#include <linux/sched.h>
11444 +#include <linux/gracl.h>
11445 +#include <linux/grinternal.h>
11446 +
11447 +static const char *restab_log[11] = {
11448 +       "RLIMIT_CPU",
11449 +       "RLIMIT_FSIZE",
11450 +       "RLIMIT_DATA",
11451 +       "RLIMIT_STACK",
11452 +       "RLIMIT_CORE",
11453 +       "RLIMIT_RSS",
11454 +       "RLIMIT_NPROC",
11455 +       "RLIMIT_NOFILE",
11456 +       "RLIMIT_MEMLOCK",
11457 +       "RLIMIT_AS",
11458 +       "RLIMIT_LOCKS"
11459 +};
11460 +
11461 +__inline__ void
11462 +gr_log_resource(const struct task_struct *task,
11463 +               const int res, const unsigned long wanted)
11464 +{
11465 +       if (unlikely(res == RLIMIT_NPROC && 
11466 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
11467 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
11468 +               return;
11469 +
11470 +       if (unlikely(wanted >= task->rlim[res].rlim_cur &&
11471 +                    task->rlim[res].rlim_cur != RLIM_INFINITY))
11472 +               security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
11473 +                              task->rlim[res].rlim_cur,
11474 +                              gr_task_fullpath(task), task->comm,
11475 +                              task->pid, task->uid, task->euid,
11476 +                              task->gid, task->egid,
11477 +                              gr_parent_task_fullpath(task),
11478 +                              task->p_pptr->comm,
11479 +                              task->p_pptr->pid, task->p_pptr->uid, 
11480 +                              task->p_pptr->euid, task->p_pptr->gid,
11481 +                              task->p_pptr->egid);
11482 +
11483 +       return;
11484 +}
11485 diff -urN linux-2.4.22.org/grsecurity/gracl_segv.c linux-2.4.22/grsecurity/gracl_segv.c
11486 --- linux-2.4.22.org/grsecurity/gracl_segv.c    1970-01-01 01:00:00.000000000 +0100
11487 +++ linux-2.4.22/grsecurity/gracl_segv.c        2003-11-22 22:14:08.000000000 +0100
11488 @@ -0,0 +1,327 @@
11489 +/* 
11490 + * grsecurity/gracl_segv.c
11491 + * Copyright Brad Spengler 2002, 2003
11492 + *
11493 + */
11494 +
11495 +#include <linux/kernel.h>
11496 +#include <linux/mm.h>
11497 +#include <asm/uaccess.h>
11498 +#include <asm/errno.h>
11499 +#include <asm/mman.h>
11500 +#include <net/sock.h>
11501 +#include <linux/file.h>
11502 +#include <linux/fs.h>
11503 +#include <linux/net.h>
11504 +#include <linux/in.h>
11505 +#include <linux/smp_lock.h>
11506 +#include <linux/slab.h>
11507 +#include <linux/types.h>
11508 +#include <linux/sched.h>
11509 +#include <linux/timer.h>
11510 +#include <linux/gracl.h>
11511 +#include <linux/grsecurity.h>
11512 +#include <linux/grinternal.h>
11513 +
11514 +static struct crash_uid *uid_set;
11515 +static unsigned short uid_used;
11516 +static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
11517 +extern rwlock_t gr_inode_lock;
11518 +extern __inline__ struct acl_subject_label *lookup_acl_subj_label(const ino_t
11519 +                                                                 inode,
11520 +                                                                 const kdev_t
11521 +                                                                 dev,
11522 +                                                                 struct
11523 +                                                                 acl_role_label
11524 +                                                                 *role);
11525 +
11526 +int
11527 +gr_init_uidset(void)
11528 +{
11529 +       uid_set =
11530 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
11531 +       uid_used = 0;
11532 +
11533 +       return uid_set ? 1 : 0;
11534 +}
11535 +
11536 +void
11537 +gr_free_uidset(void)
11538 +{
11539 +       if (uid_set)
11540 +               kfree(uid_set);
11541 +
11542 +       return;
11543 +}
11544 +
11545 +int
11546 +gr_find_uid(const uid_t uid)
11547 +{
11548 +       struct crash_uid *tmp = uid_set;
11549 +       uid_t buid;
11550 +       int low = 0, high = uid_used - 1, mid;
11551 +
11552 +       while (high >= low) {
11553 +               mid = (low + high) >> 1;
11554 +               buid = tmp[mid].uid;
11555 +               if (buid == uid)
11556 +                       return mid;
11557 +               if (buid > uid)
11558 +                       high = mid - 1;
11559 +               if (buid < uid)
11560 +                       low = mid + 1;
11561 +       }
11562 +
11563 +       return -1;
11564 +}
11565 +
11566 +static __inline__ void
11567 +gr_insertsort(void)
11568 +{
11569 +       unsigned short i, j;
11570 +       struct crash_uid index;
11571 +
11572 +       for (i = 1; i < uid_used; i++) {
11573 +               index = uid_set[i];
11574 +               j = i;
11575 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
11576 +                       uid_set[j] = uid_set[j - 1];
11577 +                       j--;
11578 +               }
11579 +               uid_set[j] = index;
11580 +       }
11581 +
11582 +       return;
11583 +}
11584 +
11585 +static __inline__ void
11586 +gr_insert_uid(const uid_t uid, const unsigned long expires)
11587 +{
11588 +       int loc;
11589 +
11590 +       if (uid_used == GR_UIDTABLE_MAX)
11591 +               return;
11592 +
11593 +       loc = gr_find_uid(uid);
11594 +
11595 +       if (loc >= 0) {
11596 +               uid_set[loc].expires = expires;
11597 +               return;
11598 +       }
11599 +
11600 +       uid_set[uid_used].uid = uid;
11601 +       uid_set[uid_used].expires = expires;
11602 +       uid_used++;
11603 +
11604 +       gr_insertsort();
11605 +
11606 +       return;
11607 +}
11608 +
11609 +void
11610 +gr_remove_uid(const unsigned short loc)
11611 +{
11612 +       unsigned short i;
11613 +
11614 +       for (i = loc + 1; i < uid_used; i++)
11615 +               uid_set[i - i] = uid_set[i];
11616 +
11617 +       uid_used--;
11618 +
11619 +       return;
11620 +}
11621 +
11622 +int
11623 +gr_check_crash_uid(const uid_t uid)
11624 +{
11625 +       int loc;
11626 +
11627 +       if (unlikely(!gr_acl_is_enabled()))
11628 +               return 0;
11629 +
11630 +       read_lock(&gr_uid_lock);
11631 +       loc = gr_find_uid(uid);
11632 +       read_unlock(&gr_uid_lock);
11633 +
11634 +       if (loc < 0)
11635 +               return 0;
11636 +
11637 +       write_lock(&gr_uid_lock);
11638 +       if (time_before_eq(uid_set[loc].expires, jiffies))
11639 +               gr_remove_uid(loc);
11640 +       else {
11641 +               write_unlock(&gr_uid_lock);
11642 +               return 1;
11643 +       }
11644 +
11645 +       write_unlock(&gr_uid_lock);
11646 +       return 0;
11647 +}
11648 +
11649 +static __inline__ int
11650 +proc_is_setxid(const struct task_struct *task)
11651 +{
11652 +       if (task->uid != task->euid || task->uid != task->suid ||
11653 +           task->uid != task->fsuid)
11654 +               return 1;
11655 +       if (task->gid != task->egid || task->gid != task->sgid ||
11656 +           task->gid != task->fsgid)
11657 +               return 1;
11658 +
11659 +       return 0;
11660 +}
11661 +static __inline__ int
11662 +gr_fake_force_sig(int sig, struct task_struct *t)
11663 +{
11664 +       unsigned long int flags;
11665 +
11666 +       spin_lock_irqsave(&t->sigmask_lock, flags);
11667 +       if (t->sig == NULL) {
11668 +               spin_unlock_irqrestore(&t->sigmask_lock, flags);
11669 +               return -ESRCH;
11670 +       }
11671 +
11672 +       if (t->sig->action[sig - 1].sa.sa_handler == SIG_IGN)
11673 +               t->sig->action[sig - 1].sa.sa_handler = SIG_DFL;
11674 +       sigdelset(&t->blocked, sig);
11675 +       recalc_sigpending(t);
11676 +       spin_unlock_irqrestore(&t->sigmask_lock, flags);
11677 +
11678 +       return send_sig_info(sig, (void *) 1L, t);
11679 +}
11680 +
11681 +void
11682 +gr_handle_crash(struct task_struct *task, const int sig)
11683 +{
11684 +       struct acl_subject_label *curr;
11685 +       struct acl_subject_label *curr2;
11686 +       struct task_struct *tsk;
11687 +
11688 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
11689 +               return;
11690 +
11691 +       if (unlikely(!gr_acl_is_enabled()))
11692 +               return;
11693 +
11694 +       curr = task->acl;
11695 +
11696 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
11697 +               return;
11698 +
11699 +       if (time_before_eq(curr->expires, jiffies)) {
11700 +               curr->expires = 0;
11701 +               curr->crashes = 0;
11702 +       }
11703 +
11704 +       curr->crashes++;
11705 +
11706 +       if (!curr->expires)
11707 +               curr->expires = jiffies + curr->res[GR_CRASH_RES].rlim_max;
11708 +
11709 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
11710 +           time_after(curr->expires, jiffies)) {
11711 +               if (task->uid && proc_is_setxid(task)) {
11712 +                       security_alert(GR_SEGVSTART_ACL_MSG,
11713 +                                      gr_task_fullpath(task), task->comm,
11714 +                                      task->pid, task->uid, task->euid,
11715 +                                      task->gid, task->egid,
11716 +                                      gr_parent_task_fullpath(task),
11717 +                                      task->p_pptr->comm, task->p_pptr->pid,
11718 +                                      task->p_pptr->uid, task->p_pptr->euid,
11719 +                                      task->p_pptr->gid, task->p_pptr->egid,
11720 +                                      task->uid,
11721 +                                      curr->res[GR_CRASH_RES].rlim_max / HZ);
11722 +                       write_lock(&gr_uid_lock);
11723 +                       gr_insert_uid(task->uid, curr->expires);
11724 +                       write_unlock(&gr_uid_lock);
11725 +                       curr->expires = 0;
11726 +                       curr->crashes = 0;
11727 +                       read_lock(&tasklist_lock);
11728 +                       for_each_task(tsk) {
11729 +                               if (tsk != task && tsk->uid == task->uid)
11730 +                                       gr_fake_force_sig(SIGKILL, tsk);
11731 +                       }
11732 +                       read_unlock(&tasklist_lock);
11733 +               } else {
11734 +                       security_alert(GR_SEGVNOSUID_ACL_MSG,
11735 +                                      gr_task_fullpath(task), task->comm,
11736 +                                      task->pid, task->uid, task->euid,
11737 +                                      task->gid, task->egid,
11738 +                                      gr_parent_task_fullpath(task),
11739 +                                      task->p_pptr->comm, task->p_pptr->pid,
11740 +                                      task->p_pptr->uid, task->p_pptr->euid,
11741 +                                      task->p_pptr->gid, task->p_pptr->egid,
11742 +                                      kdevname(curr->device), curr->inode,
11743 +                                      curr->res[GR_CRASH_RES].rlim_max / HZ);
11744 +                       read_lock(&tasklist_lock);
11745 +                       for_each_task(tsk) {
11746 +                               if (likely(tsk != task)) {
11747 +                                       curr2 = tsk->acl;
11748 +
11749 +                                       if (curr2->device == curr->device &&
11750 +                                           curr2->inode == curr->inode)
11751 +                                               gr_fake_force_sig(SIGKILL, tsk);
11752 +                               }
11753 +                       }
11754 +                       read_unlock(&tasklist_lock);
11755 +               }
11756 +       }
11757 +
11758 +       return;
11759 +}
11760 +
11761 +int
11762 +gr_check_crash_exec(const struct file *filp)
11763 +{
11764 +       struct acl_subject_label *curr;
11765 +
11766 +       if (unlikely(!gr_acl_is_enabled()))
11767 +               return 0;
11768 +
11769 +       read_lock(&gr_inode_lock);
11770 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
11771 +                                    filp->f_dentry->d_inode->i_dev,
11772 +                                    current->role);
11773 +       read_unlock(&gr_inode_lock);
11774 +
11775 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
11776 +           (!curr->crashes && !curr->expires))
11777 +               return 0;
11778 +
11779 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
11780 +           time_after(curr->expires, jiffies))
11781 +               return 1;
11782 +       else if (time_before_eq(curr->expires, jiffies)) {
11783 +               curr->crashes = 0;
11784 +               curr->expires = 0;
11785 +       }
11786 +
11787 +       return 0;
11788 +}
11789 +
11790 +void
11791 +gr_handle_alertkill(void)
11792 +{
11793 +       struct acl_subject_label *curracl;
11794 +       __u32 curr_ip;
11795 +       struct task_struct *task;
11796 +
11797 +       if (unlikely(!gr_acl_is_enabled()))
11798 +               return;
11799 +
11800 +       curracl = current->acl;
11801 +       curr_ip = current->curr_ip;
11802 +
11803 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
11804 +           (curr_ip != 0xffffffff)) {
11805 +               read_lock(&tasklist_lock);
11806 +               for_each_task(task) {
11807 +                       if (task->curr_ip == curr_ip)
11808 +                               gr_fake_force_sig(SIGKILL, task);
11809 +               }
11810 +               read_unlock(&tasklist_lock);
11811 +       } else if (curracl->mode & GR_KILLPROC)
11812 +               gr_fake_force_sig(SIGKILL, current);
11813 +
11814 +       return;
11815 +}
11816 diff -urN linux-2.4.22.org/grsecurity/gracl_shm.c linux-2.4.22/grsecurity/gracl_shm.c
11817 --- linux-2.4.22.org/grsecurity/gracl_shm.c     1970-01-01 01:00:00.000000000 +0100
11818 +++ linux-2.4.22/grsecurity/gracl_shm.c 2003-11-22 22:14:08.000000000 +0100
11819 @@ -0,0 +1,36 @@
11820 +/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
11821 +
11822 +#include <linux/kernel.h>
11823 +#include <linux/mm.h>
11824 +#include <linux/sched.h>
11825 +#include <linux/file.h>
11826 +#include <linux/ipc.h>
11827 +#include <linux/gracl.h>
11828 +#include <linux/grsecurity.h>
11829 +#include <linux/grinternal.h>
11830 +
11831 +int
11832 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
11833 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
11834 +{
11835 +       struct task_struct *task;
11836 +
11837 +       if (!gr_acl_is_enabled())
11838 +               return 1;
11839 +
11840 +       task = find_task_by_pid(shm_cprid);
11841 +
11842 +       if (unlikely(!task))
11843 +               task = find_task_by_pid(shm_lapid);
11844 +
11845 +       if (unlikely(task && ((task->start_time < shm_createtime) ||
11846 +                             (task->pid == shm_lapid)) &&
11847 +                    (task->acl->mode & GR_PROTSHM) &&
11848 +                    (task->acl != current->acl))) {
11849 +               security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
11850 +                              DEFAULTSECARGS);
11851 +               return 0;
11852 +       }
11853 +
11854 +       return 1;
11855 +}
11856 diff -urN linux-2.4.22.org/grsecurity/grsec_chdir.c linux-2.4.22/grsecurity/grsec_chdir.c
11857 --- linux-2.4.22.org/grsecurity/grsec_chdir.c   1970-01-01 01:00:00.000000000 +0100
11858 +++ linux-2.4.22/grsecurity/grsec_chdir.c       2003-11-22 22:14:08.000000000 +0100
11859 @@ -0,0 +1,20 @@
11860 +#include <linux/kernel.h>
11861 +#include <linux/sched.h>
11862 +#include <linux/fs.h>
11863 +#include <linux/file.h>
11864 +#include <linux/grsecurity.h>
11865 +#include <linux/grinternal.h>
11866 +
11867 +void
11868 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
11869 +{
11870 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
11871 +       if ((grsec_enable_chdir && grsec_enable_group &&
11872 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
11873 +                                             !grsec_enable_group)) {
11874 +               security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
11875 +                              DEFAULTSECARGS);
11876 +       }
11877 +#endif
11878 +       return;
11879 +}
11880 diff -urN linux-2.4.22.org/grsecurity/grsec_chroot.c linux-2.4.22/grsecurity/grsec_chroot.c
11881 --- linux-2.4.22.org/grsecurity/grsec_chroot.c  1970-01-01 01:00:00.000000000 +0100
11882 +++ linux-2.4.22/grsecurity/grsec_chroot.c      2003-11-22 22:14:08.000000000 +0100
11883 @@ -0,0 +1,333 @@
11884 +#include <linux/kernel.h>
11885 +#include <linux/sched.h>
11886 +#include <linux/file.h>
11887 +#include <linux/fs.h>
11888 +#include <linux/types.h>
11889 +#include <linux/grinternal.h>
11890 +
11891 +int
11892 +gr_handle_chroot_unix(const pid_t pid)
11893 +{
11894 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
11895 +       struct task_struct *p, **htable;
11896 +
11897 +       if (unlikely(!grsec_enable_chroot_unix))
11898 +               return 1;
11899 +
11900 +       if (likely(!proc_is_chrooted(current)))
11901 +               return 1;
11902 +
11903 +       read_lock(&tasklist_lock);
11904 +
11905 +       htable = &pidhash[pid_hashfn(pid)];
11906 +
11907 +       for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ;
11908 +
11909 +       if (unlikely(p && !have_same_root(current, p))) {
11910 +               read_unlock(&tasklist_lock);
11911 +               security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
11912 +               return 0;
11913 +       }
11914 +       read_unlock(&tasklist_lock);
11915 +#endif
11916 +       return 1;
11917 +}
11918 +
11919 +int
11920 +gr_handle_chroot_nice(void)
11921 +{
11922 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
11923 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
11924 +               security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
11925 +               return -EPERM;
11926 +       }
11927 +#endif
11928 +       return 0;
11929 +}
11930 +
11931 +int
11932 +gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval)
11933 +{
11934 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
11935 +       if (grsec_enable_chroot_nice && (!have_same_root(p, current)
11936 +                                        || (have_same_root(p, current)
11937 +                                            && (niceval < task_nice(p))
11938 +                                            && proc_is_chrooted(current)))) {
11939 +               security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
11940 +                              DEFAULTSECARGS);
11941 +               return -ESRCH;
11942 +       }
11943 +#endif
11944 +       return 0;
11945 +}
11946 +
11947 +int
11948 +gr_handle_chroot_capset(const struct task_struct *target)
11949 +{
11950 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11951 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
11952 +           !have_same_root(current, target)) {
11953 +               security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
11954 +                              DEFAULTSECARGS);
11955 +               return 1;
11956 +       }
11957 +#endif
11958 +       return 0;
11959 +}
11960 +
11961 +int
11962 +gr_handle_chroot_rawio(const struct inode *inode)
11963 +{
11964 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11965 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
11966 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
11967 +               return 1;
11968 +#endif
11969 +       return 0;
11970 +}
11971 +
11972 +int
11973 +gr_pid_is_chrooted(const struct task_struct *p)
11974 +{
11975 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
11976 +       if (!grsec_enable_chroot_findtask || (current->pid <= 1))
11977 +               return 0;
11978 +
11979 +       if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
11980 +           child_reaper && child_reaper->fs && child_reaper->fs->root &&
11981 +           child_reaper->fs->root->d_inode && current && current->fs &&
11982 +           current->fs->root && current->fs->root->d_inode) {
11983 +               if (proc_is_chrooted(current) && !have_same_root(current, p))
11984 +                       return 1;
11985 +       }
11986 +#endif
11987 +       return 0;
11988 +}
11989 +
11990 +int
11991 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
11992 +{
11993 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
11994 +       if (!grsec_enable_chroot_fchdir)
11995 +               return 1;
11996 +
11997 +       if (!proc_is_chrooted(current))
11998 +               return 1;
11999 +       else {
12000 +               struct dentry *dentry = u_dentry;
12001 +               struct vfsmount *mnt = u_mnt;
12002 +               struct dentry *realroot;
12003 +               struct vfsmount *realrootmnt;
12004 +               struct dentry *currentroot;
12005 +               struct vfsmount *currentmnt;
12006 +
12007 +               read_lock(&child_reaper->fs->lock);
12008 +               realrootmnt = mntget(child_reaper->fs->rootmnt);
12009 +               realroot = dget(child_reaper->fs->root);
12010 +               read_unlock(&child_reaper->fs->lock);
12011 +
12012 +               read_lock(&current->fs->lock);
12013 +               currentmnt = mntget(current->fs->rootmnt);
12014 +               currentroot = dget(current->fs->root);
12015 +               read_unlock(&current->fs->lock);
12016 +
12017 +               spin_lock(&dcache_lock);
12018 +               for (;;) {
12019 +                       if (unlikely
12020 +                           ((dentry == realroot && mnt == realrootmnt)
12021 +                            || (dentry == currentroot && mnt == currentmnt)))
12022 +                               break;
12023 +                       if (unlikely
12024 +                           (dentry == mnt->mnt_root || IS_ROOT(dentry))) {
12025 +                               if (mnt->mnt_parent == mnt)
12026 +                                       break;
12027 +                               dentry = mnt->mnt_mountpoint;
12028 +                               mnt = mnt->mnt_parent;
12029 +                               continue;
12030 +                       }
12031 +                       dentry = dentry->d_parent;
12032 +               }
12033 +               spin_unlock(&dcache_lock);
12034 +
12035 +               dput(currentroot);
12036 +               mntput(currentmnt);
12037 +
12038 +               if (dentry == realroot && mnt == realrootmnt) {
12039 +                       /* ok, they're definitely trying to fchdir outside of the
12040 +                          chroot. */
12041 +                       dput(realroot);
12042 +                       mntput(realrootmnt);
12043 +                       security_alert(GR_CHROOT_FCHDIR_MSG,
12044 +                                      gr_to_filename(u_dentry, u_mnt),
12045 +                                      DEFAULTSECARGS);
12046 +                       return 0;
12047 +               } else {
12048 +                       dput(realroot);
12049 +                       mntput(realrootmnt);
12050 +                       return 1;
12051 +               }
12052 +       }
12053 +#endif
12054 +       return 1;
12055 +}
12056 +
12057 +int
12058 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12059 +               const time_t shm_createtime)
12060 +{
12061 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12062 +       struct task_struct *p, **htable;
12063 +
12064 +       if (unlikely(!grsec_enable_chroot_shmat))
12065 +               return 1;
12066 +
12067 +       if (likely(!proc_is_chrooted(current)))
12068 +               return 1;
12069 +
12070 +       read_lock(&tasklist_lock);
12071 +
12072 +       htable = &pidhash[pid_hashfn(shm_cprid)];
12073 +
12074 +       for (p = *htable; p && p->pid != shm_cprid; p = p->pidhash_next) ;
12075 +
12076 +       if (unlikely(p && !have_same_root(current, p) &&
12077 +                    (p->start_time < shm_createtime))) {
12078 +               read_unlock(&tasklist_lock);
12079 +               security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12080 +               return 0;
12081 +       }
12082 +
12083 +       if (unlikely(!p)) {
12084 +               htable = &pidhash[pid_hashfn(shm_lapid)];
12085 +               for (p = *htable; p && p->pid != shm_lapid;
12086 +                    p = p->pidhash_next) ;
12087 +
12088 +               if (unlikely(p && !have_same_root(current, p))) {
12089 +                       read_unlock(&tasklist_lock);
12090 +                       security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12091 +                       return 0;
12092 +               }
12093 +       }
12094 +
12095 +       read_unlock(&tasklist_lock);
12096 +#endif
12097 +       return 1;
12098 +}
12099 +
12100 +void
12101 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12102 +{
12103 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12104 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
12105 +               security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
12106 +                              DEFAULTSECARGS);
12107 +#endif
12108 +       return;
12109 +}
12110 +
12111 +int
12112 +gr_handle_chroot_mknod(const struct dentry *dentry,
12113 +                      const struct vfsmount *mnt, const int mode)
12114 +{
12115 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12116 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) &&
12117 +           proc_is_chrooted(current)) {
12118 +               security_alert(GR_MKNOD_CHROOT_MSG,
12119 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12120 +               return -EPERM;
12121 +       }
12122 +#endif
12123 +       return 0;
12124 +}
12125 +
12126 +int
12127 +gr_handle_chroot_mount(const struct dentry *dentry,
12128 +                      const struct vfsmount *mnt, const char *dev_name)
12129 +{
12130 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12131 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
12132 +               security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
12133 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12134 +               return -EPERM;
12135 +       }
12136 +#endif
12137 +       return 0;
12138 +}
12139 +
12140 +int
12141 +gr_handle_chroot_pivot(void)
12142 +{
12143 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12144 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
12145 +               security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
12146 +               return -EPERM;
12147 +       }
12148 +#endif
12149 +       return 0;
12150 +}
12151 +
12152 +int
12153 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
12154 +{
12155 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12156 +       if (grsec_enable_chroot_double && proc_is_chrooted(current)) {
12157 +               security_alert(GR_CHROOT_CHROOT_MSG,
12158 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12159 +               return -EPERM;
12160 +       }
12161 +#endif
12162 +       return 0;
12163 +}
12164 +
12165 +void
12166 +gr_handle_chroot_caps(struct task_struct *task)
12167 +{
12168 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12169 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
12170 +               task->cap_permitted =
12171 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
12172 +               task->cap_inheritable =
12173 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
12174 +               task->cap_effective =
12175 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
12176 +       }
12177 +#endif
12178 +       return;
12179 +}
12180 +
12181 +int
12182 +gr_handle_chroot_sysctl(const int op)
12183 +{
12184 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12185 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
12186 +           && (op & 002))
12187 +               return -EACCES;
12188 +#endif
12189 +       return 0;
12190 +}
12191 +
12192 +void
12193 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
12194 +{
12195 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12196 +       if (grsec_enable_chroot_chdir)
12197 +               set_fs_pwd(current->fs, mnt, dentry);
12198 +#endif
12199 +       return;
12200 +}
12201 +
12202 +int
12203 +gr_handle_chroot_chmod(const struct dentry *dentry,
12204 +                      const struct vfsmount *mnt, const int mode)
12205 +{
12206 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12207 +       if (grsec_enable_chroot_chmod &&
12208 +           ((mode & S_ISUID) || (mode & S_ISGID)) &&
12209 +           proc_is_chrooted(current)) {
12210 +               security_alert(GR_CHMOD_CHROOT_MSG,
12211 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12212 +               return -EPERM;
12213 +       }
12214 +#endif
12215 +       return 0;
12216 +}
12217 diff -urN linux-2.4.22.org/grsecurity/grsec_disabled.c linux-2.4.22/grsecurity/grsec_disabled.c
12218 --- linux-2.4.22.org/grsecurity/grsec_disabled.c        1970-01-01 01:00:00.000000000 +0100
12219 +++ linux-2.4.22/grsecurity/grsec_disabled.c    2003-11-22 22:14:08.000000000 +0100
12220 @@ -0,0 +1,380 @@
12221 +/* 
12222 + * when grsecurity is disabled, compile all external functions into nothing
12223 + */
12224 +
12225 +#include <linux/kernel.h>
12226 +#include <linux/config.h>
12227 +#include <linux/sched.h>
12228 +#include <linux/file.h>
12229 +#include <linux/fs.h>
12230 +#include <linux/kdev_t.h>
12231 +#include <linux/net.h>
12232 +#include <linux/in.h>
12233 +#include <linux/ip.h>
12234 +#include <linux/skbuff.h>
12235 +#include <linux/sysctl.h>
12236 +
12237 +#ifdef CONFIG_SYSCTL
12238 +__u32
12239 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
12240 +{
12241 +       return mode;
12242 +}
12243 +#endif
12244 +
12245 +int
12246 +gr_acl_is_enabled(void)
12247 +{
12248 +       return 0;
12249 +}
12250 +
12251 +int
12252 +gr_handle_rawio(const struct inode *inode)
12253 +{
12254 +       return 0;
12255 +}
12256 +
12257 +void
12258 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12259 +{
12260 +       return;
12261 +}
12262 +
12263 +int
12264 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12265 +{
12266 +       return 0;
12267 +}
12268 +
12269 +int
12270 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
12271 +{
12272 +       return 0;
12273 +}
12274 +
12275 +int
12276 +gr_handle_ptrace(struct task_struct *task, const long request)
12277 +{
12278 +       return 0;
12279 +}
12280 +
12281 +void
12282 +gr_learn_resource(const struct task_struct *task,
12283 +                 const int res, const unsigned long wanted)
12284 +{
12285 +       return;
12286 +}
12287 +
12288 +int
12289 +gr_set_acls(const int type)
12290 +{
12291 +       return 0;
12292 +}
12293 +
12294 +int
12295 +gr_check_hidden_task(const struct task_struct *tsk)
12296 +{
12297 +       return 0;
12298 +}
12299 +
12300 +int
12301 +gr_check_protected_task(const struct task_struct *task)
12302 +{
12303 +       return 0;
12304 +}
12305 +
12306 +__inline__ void
12307 +gr_copy_label(struct task_struct *tsk)
12308 +{
12309 +       return;
12310 +}
12311 +
12312 +void
12313 +gr_set_pax_flags(struct task_struct *task)
12314 +{
12315 +       return;
12316 +}
12317 +
12318 +void
12319 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
12320 +{
12321 +       return;
12322 +}
12323 +
12324 +void
12325 +gr_handle_delete(const ino_t ino, const kdev_t dev)
12326 +{
12327 +       return;
12328 +}
12329 +
12330 +void
12331 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
12332 +{
12333 +       return;
12334 +}
12335 +
12336 +void
12337 +gr_handle_crash(struct task_struct *task, const int sig)
12338 +{
12339 +       return;
12340 +}
12341 +
12342 +int
12343 +gr_check_crash_exec(const struct file *filp)
12344 +{
12345 +       return 0;
12346 +}
12347 +
12348 +int
12349 +gr_check_crash_uid(const uid_t uid)
12350 +{
12351 +       return 0;
12352 +}
12353 +
12354 +int
12355 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
12356 +                struct dentry *old_dentry,
12357 +                struct dentry *new_dentry,
12358 +                struct vfsmount *mnt, const __u8 replace)
12359 +{
12360 +       return 0;
12361 +}
12362 +
12363 +int
12364 +gr_search_socket(const int family, const int type, const int protocol)
12365 +{
12366 +       return 1;
12367 +}
12368 +
12369 +int
12370 +gr_search_connectbind(const int mode, const struct socket *sock,
12371 +                     const struct sockaddr_in *addr)
12372 +{
12373 +       return 1;
12374 +}
12375 +
12376 +int
12377 +gr_is_capable(const int cap)
12378 +{
12379 +       return 1;
12380 +}
12381 +
12382 +void
12383 +gr_handle_alertkill(void)
12384 +{
12385 +       return;
12386 +}
12387 +
12388 +__u32
12389 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
12390 +{
12391 +       return 1;
12392 +}
12393 +
12394 +__u32
12395 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12396 +                         const struct vfsmount * mnt)
12397 +{
12398 +       return 1;
12399 +}
12400 +
12401 +__u32
12402 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12403 +                  const int fmode)
12404 +{
12405 +       return 1;
12406 +}
12407 +
12408 +__u32
12409 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12410 +{
12411 +       return 1;
12412 +}
12413 +
12414 +__u32
12415 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
12416 +{
12417 +       return 1;
12418 +}
12419 +
12420 +int
12421 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
12422 +                  unsigned int *vm_flags)
12423 +{
12424 +       return 1;
12425 +}
12426 +
12427 +__u32
12428 +gr_acl_handle_truncate(const struct dentry * dentry,
12429 +                      const struct vfsmount * mnt)
12430 +{
12431 +       return 1;
12432 +}
12433 +
12434 +__u32
12435 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
12436 +{
12437 +       return 1;
12438 +}
12439 +
12440 +__u32
12441 +gr_acl_handle_access(const struct dentry * dentry,
12442 +                    const struct vfsmount * mnt, const int fmode)
12443 +{
12444 +       return 1;
12445 +}
12446 +
12447 +__u32
12448 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
12449 +                    mode_t mode)
12450 +{
12451 +       return 1;
12452 +}
12453 +
12454 +__u32
12455 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
12456 +                   mode_t mode)
12457 +{
12458 +       return 1;
12459 +}
12460 +
12461 +__u32
12462 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
12463 +{
12464 +       return 1;
12465 +}
12466 +
12467 +void
12468 +grsecurity_init(void)
12469 +{
12470 +       return;
12471 +}
12472 +
12473 +__u32
12474 +gr_acl_handle_mknod(const struct dentry * new_dentry,
12475 +                   const struct dentry * parent_dentry,
12476 +                   const struct vfsmount * parent_mnt,
12477 +                   const int mode)
12478 +{
12479 +       return 1;
12480 +}
12481 +
12482 +__u32
12483 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
12484 +                   const struct dentry * parent_dentry,
12485 +                   const struct vfsmount * parent_mnt)
12486 +{
12487 +       return 1;
12488 +}
12489 +
12490 +__u32
12491 +gr_acl_handle_symlink(const struct dentry * new_dentry,
12492 +                     const struct dentry * parent_dentry,
12493 +                     const struct vfsmount * parent_mnt, const char *from)
12494 +{
12495 +       return 1;
12496 +}
12497 +
12498 +__u32
12499 +gr_acl_handle_link(const struct dentry * new_dentry,
12500 +                  const struct dentry * parent_dentry,
12501 +                  const struct vfsmount * parent_mnt,
12502 +                  const struct dentry * old_dentry,
12503 +                  const struct vfsmount * old_mnt, const char *to)
12504 +{
12505 +       return 1;
12506 +}
12507 +
12508 +int
12509 +gr_acl_handle_rename(const struct dentry *new_dentry,
12510 +                    const struct dentry *parent_dentry,
12511 +                    const struct vfsmount *parent_mnt,
12512 +                    const struct dentry *old_dentry,
12513 +                    const struct inode *old_parent_inode,
12514 +                    const struct vfsmount *old_mnt, const char *newname)
12515 +{
12516 +       return 1;
12517 +}
12518 +
12519 +__u32
12520 +gr_acl_handle_filldir(const struct dentry * dentry,
12521 +                     const struct vfsmount * mnt, const ino_t ino)
12522 +{
12523 +       return 1;
12524 +}
12525 +
12526 +int
12527 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12528 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
12529 +{
12530 +       return 1;
12531 +}
12532 +
12533 +int
12534 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
12535 +{
12536 +       return 1;
12537 +}
12538 +
12539 +int
12540 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
12541 +{
12542 +       return 1;
12543 +}
12544 +
12545 +__u32
12546 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
12547 +{
12548 +       return 1;
12549 +}
12550 +
12551 +__u32
12552 +gr_acl_handle_creat(const struct dentry * dentry,
12553 +                   const struct dentry * p_dentry,
12554 +                   const struct vfsmount * p_mnt, const int fmode,
12555 +                   const int imode)
12556 +{
12557 +       return 1;
12558 +}
12559 +
12560 +void
12561 +gr_acl_handle_exit(void)
12562 +{
12563 +       return;
12564 +}
12565 +
12566 +int
12567 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
12568 +{
12569 +       return 1;
12570 +}
12571 +
12572 +void
12573 +gr_set_role_label(const uid_t uid, const gid_t gid)
12574 +{
12575 +       return;
12576 +}
12577 +
12578 +int
12579 +gr_acl_handle_procpidmem(const struct task_struct *task)
12580 +{
12581 +       return 0;
12582 +}
12583 +
12584 +int
12585 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
12586 +{
12587 +       return 1;
12588 +}
12589 +
12590 +int
12591 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
12592 +{
12593 +       return 1;
12594 +}
12595 +
12596 +void
12597 +gr_set_kernel_label(struct task_struct *task)
12598 +{
12599 +       return;
12600 +}
12601 diff -urN linux-2.4.22.org/grsecurity/grsec_exec.c linux-2.4.22/grsecurity/grsec_exec.c
12602 --- linux-2.4.22.org/grsecurity/grsec_exec.c    1970-01-01 01:00:00.000000000 +0100
12603 +++ linux-2.4.22/grsecurity/grsec_exec.c        2003-11-22 22:14:08.000000000 +0100
12604 @@ -0,0 +1,70 @@
12605 +#include <linux/kernel.h>
12606 +#include <linux/sched.h>
12607 +#include <linux/file.h>
12608 +#include <linux/fs.h>
12609 +#include <linux/types.h>
12610 +#include <linux/grdefs.h>
12611 +#include <linux/grinternal.h>
12612 +#include <linux/capability.h>
12613 +
12614 +#include <asm/uaccess.h>
12615 +
12616 +int
12617 +gr_handle_nproc(void)
12618 +{
12619 +#ifdef CONFIG_GRKERNSEC_EXECVE
12620 +       if (grsec_enable_execve && current->user &&
12621 +           (atomic_read(&current->user->processes) >
12622 +            current->rlim[RLIMIT_NPROC].rlim_cur) &&
12623 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
12624 +               security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
12625 +               return -EAGAIN;
12626 +       }
12627 +#endif
12628 +       return 0;
12629 +}
12630 +
12631 +void
12632 +gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
12633 +{
12634 +#ifdef CONFIG_GRKERNSEC_EXECLOG
12635 +       char grarg[64] = { 0 };
12636 +       __u8 execlen = 0;
12637 +       unsigned int i;
12638 +
12639 +       if (!((grsec_enable_execlog && grsec_enable_group &&
12640 +              in_group_p(grsec_audit_gid))
12641 +             || (grsec_enable_execlog && !grsec_enable_group)))
12642 +               return;
12643 +
12644 +       if (unlikely(!argv))
12645 +               goto log;
12646 +
12647 +       for (i = 0; i < bprm->argc && execlen < 62; i++) {
12648 +               char *p;
12649 +               __u8 len;
12650 +
12651 +               if (get_user(p, argv + i))
12652 +                       goto log;
12653 +               if (!p)
12654 +                       goto log;
12655 +               len = strnlen_user(p, 62 - execlen);
12656 +               if (len > 62 - execlen)
12657 +                       len = 62 - execlen;
12658 +               else if (len > 0)
12659 +                       len--;
12660 +               if (copy_from_user(grarg + execlen, p, len))
12661 +                       goto log;
12662 +               execlen += len;
12663 +               *(grarg + execlen) = ' ';
12664 +               *(grarg + execlen + 1) = '\0';
12665 +               execlen++;
12666 +       }
12667 +
12668 +      log:
12669 +       security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
12670 +                                                        bprm->file->f_vfsmnt),
12671 +                      grarg, DEFAULTSECARGS);
12672 +#endif
12673 +       return;
12674 +}
12675 diff -urN linux-2.4.22.org/grsecurity/grsec_fifo.c linux-2.4.22/grsecurity/grsec_fifo.c
12676 --- linux-2.4.22.org/grsecurity/grsec_fifo.c    1970-01-01 01:00:00.000000000 +0100
12677 +++ linux-2.4.22/grsecurity/grsec_fifo.c        2003-11-22 22:14:08.000000000 +0100
12678 @@ -0,0 +1,24 @@
12679 +#include <linux/kernel.h>
12680 +#include <linux/sched.h>
12681 +#include <linux/fs.h>
12682 +#include <linux/file.h>
12683 +#include <linux/grinternal.h>
12684 +
12685 +int
12686 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
12687 +              const struct dentry *dir, const int flag, const int acc_mode)
12688 +{
12689 +#ifdef CONFIG_GRKERNSEC_FIFO
12690 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
12691 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
12692 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
12693 +           (current->fsuid != dentry->d_inode->i_uid)) {
12694 +               if (!permission(dentry->d_inode, acc_mode))
12695 +                       security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
12696 +                                      dentry->d_inode->i_uid,
12697 +                                      dentry->d_inode->i_gid, DEFAULTSECARGS);
12698 +               return -EACCES;
12699 +       }
12700 +#endif
12701 +       return 0;
12702 +}
12703 diff -urN linux-2.4.22.org/grsecurity/grsec_fork.c linux-2.4.22/grsecurity/grsec_fork.c
12704 --- linux-2.4.22.org/grsecurity/grsec_fork.c    1970-01-01 01:00:00.000000000 +0100
12705 +++ linux-2.4.22/grsecurity/grsec_fork.c        2003-11-22 22:14:08.000000000 +0100
12706 @@ -0,0 +1,14 @@
12707 +#include <linux/kernel.h>
12708 +#include <linux/sched.h>
12709 +#include <linux/grsecurity.h>
12710 +#include <linux/grinternal.h>
12711 +
12712 +void
12713 +gr_log_forkfail(const int retval)
12714 +{
12715 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
12716 +       if (grsec_enable_forkfail)
12717 +               security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
12718 +#endif
12719 +       return;
12720 +}
12721 diff -urN linux-2.4.22.org/grsecurity/grsec_init.c linux-2.4.22/grsecurity/grsec_init.c
12722 --- linux-2.4.22.org/grsecurity/grsec_init.c    1970-01-01 01:00:00.000000000 +0100
12723 +++ linux-2.4.22/grsecurity/grsec_init.c        2003-11-22 22:14:08.000000000 +0100
12724 @@ -0,0 +1,210 @@
12725 +#include <linux/kernel.h>
12726 +#include <linux/sched.h>
12727 +#include <linux/mm.h>
12728 +#include <linux/smp_lock.h>
12729 +#include <linux/gracl.h>
12730 +#include <linux/slab.h>
12731 +
12732 +int grsec_enable_link;
12733 +int grsec_enable_dmesg;
12734 +int grsec_enable_fifo;
12735 +int grsec_enable_execve;
12736 +int grsec_enable_execlog;
12737 +int grsec_enable_signal;
12738 +int grsec_enable_forkfail;
12739 +int grsec_enable_time;
12740 +int grsec_enable_group;
12741 +int grsec_audit_gid;
12742 +int grsec_enable_chdir;
12743 +int grsec_enable_audit_ipc;
12744 +int grsec_enable_mount;
12745 +int grsec_enable_chroot_findtask;
12746 +int grsec_enable_chroot_mount;
12747 +int grsec_enable_chroot_shmat;
12748 +int grsec_enable_chroot_fchdir;
12749 +int grsec_enable_chroot_double;
12750 +int grsec_enable_chroot_pivot;
12751 +int grsec_enable_chroot_chdir;
12752 +int grsec_enable_chroot_chmod;
12753 +int grsec_enable_chroot_mknod;
12754 +int grsec_enable_chroot_nice;
12755 +int grsec_enable_chroot_execlog;
12756 +int grsec_enable_chroot_caps;
12757 +int grsec_enable_chroot_sysctl;
12758 +int grsec_enable_chroot_unix;
12759 +int grsec_enable_tpe;
12760 +int grsec_tpe_gid;
12761 +int grsec_enable_tpe_all;
12762 +int grsec_enable_randpid;
12763 +int grsec_enable_randid;
12764 +int grsec_enable_randisn;
12765 +int grsec_enable_randsrc;
12766 +int grsec_enable_randrpc;
12767 +int grsec_enable_socket_all;
12768 +int grsec_socket_all_gid;
12769 +int grsec_enable_socket_client;
12770 +int grsec_socket_client_gid;
12771 +int grsec_enable_socket_server;
12772 +int grsec_socket_server_gid;
12773 +int grsec_lock;
12774 +
12775 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
12776 +unsigned long grsec_alert_wtime = 0;
12777 +unsigned long grsec_alert_fyet = 0;
12778 +
12779 +spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
12780 +unsigned long grsec_alertgood_wtime = 0;
12781 +unsigned long grsec_alertgood_fyet = 0;
12782 +
12783 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
12784 +
12785 +char *gr_shared_page[4][NR_CPUS];
12786 +extern struct gr_arg *gr_usermode;
12787 +extern unsigned char *gr_system_salt;
12788 +extern unsigned char *gr_system_sum;
12789 +
12790 +void
12791 +grsecurity_init(void)
12792 +{
12793 +       int i, j;
12794 +       /* create the per-cpu shared pages */
12795 +
12796 +       for (j = 0; j < 4; j++) {
12797 +               for (i = 0; i < NR_CPUS; i++) {
12798 +                       gr_shared_page[j][i] = (char *) get_zeroed_page(GFP_KERNEL);
12799 +                       if (!gr_shared_page[j][i]) {
12800 +                               panic("Unable to allocate grsecurity shared page");
12801 +                               return;
12802 +                       }
12803 +               }
12804 +       }
12805 +
12806 +       /* allocate memory for authentication structure */
12807 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
12808 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
12809 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
12810 +
12811 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
12812 +               panic("Unable to allocate grsecurity authentication structure");
12813 +               return;
12814 +       }
12815 +
12816 +#ifndef CONFIG_GRKERNSEC_SYSCTL
12817 +       grsec_lock = 1;
12818 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
12819 +       grsec_enable_group = 1;
12820 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
12821 +#endif
12822 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
12823 +       grsec_enable_chdir = 1;
12824 +#endif
12825 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12826 +       grsec_enable_audit_ipc = 1;
12827 +#endif
12828 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
12829 +       grsec_enable_mount = 1;
12830 +#endif
12831 +#ifdef CONFIG_GRKERNSEC_LINK
12832 +       grsec_enable_link = 1;
12833 +#endif
12834 +#ifdef CONFIG_GRKERNSEC_DMESG
12835 +       grsec_enable_dmesg = 1;
12836 +#endif
12837 +#ifdef CONFIG_GRKERNSEC_FIFO
12838 +       grsec_enable_fifo = 1;
12839 +#endif
12840 +#ifdef CONFIG_GRKERNSEC_EXECVE
12841 +       grsec_enable_execve = 1;
12842 +#endif
12843 +#ifdef CONFIG_GRKERNSEC_EXECLOG
12844 +       grsec_enable_execlog = 1;
12845 +#endif
12846 +#ifdef CONFIG_GRKERNSEC_SIGNAL
12847 +       grsec_enable_signal = 1;
12848 +#endif
12849 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
12850 +       grsec_enable_forkfail = 1;
12851 +#endif
12852 +#ifdef CONFIG_GRKERNSEC_TIME
12853 +       grsec_enable_time = 1;
12854 +#endif
12855 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
12856 +       grsec_enable_chroot_findtask = 1;
12857 +#endif
12858 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12859 +       grsec_enable_chroot_unix = 1;
12860 +#endif
12861 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12862 +       grsec_enable_chroot_mount = 1;
12863 +#endif
12864 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
12865 +       grsec_enable_chroot_fchdir = 1;
12866 +#endif
12867 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12868 +       grsec_enable_chroot_shmat = 1;
12869 +#endif
12870 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12871 +       grsec_enable_chroot_double = 1;
12872 +#endif
12873 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12874 +       grsec_enable_chroot_pivot = 1;
12875 +#endif
12876 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12877 +       grsec_enable_chroot_chdir = 1;
12878 +#endif
12879 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12880 +       grsec_enable_chroot_chmod = 1;
12881 +#endif
12882 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12883 +       grsec_enable_chroot_mknod = 1;
12884 +#endif
12885 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12886 +       grsec_enable_chroot_nice = 1;
12887 +#endif
12888 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12889 +       grsec_enable_chroot_execlog = 1;
12890 +#endif
12891 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12892 +       grsec_enable_chroot_caps = 1;
12893 +#endif
12894 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12895 +       grsec_enable_chroot_sysctl = 1;
12896 +#endif
12897 +#ifdef CONFIG_GRKERNSEC_TPE
12898 +       grsec_enable_tpe = 1;
12899 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
12900 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
12901 +       grsec_enable_tpe_all = 1;
12902 +#endif
12903 +#endif
12904 +#ifdef CONFIG_GRKERNSEC_RANDPID
12905 +       grsec_enable_randpid = 1;
12906 +#endif
12907 +#ifdef CONFIG_GRKERNSEC_RANDID
12908 +       grsec_enable_randid = 1;
12909 +#endif
12910 +#ifdef CONFIG_GRKERNSEC_RANDISN
12911 +       grsec_enable_randisn = 1;
12912 +#endif
12913 +#ifdef CONFIG_GRKERNSEC_RANDSRC
12914 +       grsec_enable_randsrc = 1;
12915 +#endif
12916 +#ifdef CONFIG_GRKERNSEC_RANDRPC
12917 +       grsec_enable_randrpc = 1;
12918 +#endif
12919 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
12920 +       grsec_enable_socket_all = 1;
12921 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
12922 +#endif
12923 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
12924 +       grsec_enable_socket_client = 1;
12925 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
12926 +#endif
12927 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
12928 +       grsec_enable_socket_server = 1;
12929 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
12930 +#endif
12931 +#endif
12932 +
12933 +       return;
12934 +}
12935 diff -urN linux-2.4.22.org/grsecurity/grsec_ipc.c linux-2.4.22/grsecurity/grsec_ipc.c
12936 --- linux-2.4.22.org/grsecurity/grsec_ipc.c     1970-01-01 01:00:00.000000000 +0100
12937 +++ linux-2.4.22/grsecurity/grsec_ipc.c 2003-11-22 22:14:08.000000000 +0100
12938 @@ -0,0 +1,81 @@
12939 +#include <linux/kernel.h>
12940 +#include <linux/sched.h>
12941 +#include <linux/types.h>
12942 +#include <linux/ipc.h>
12943 +#include <linux/grsecurity.h>
12944 +#include <linux/grinternal.h>
12945 +
12946 +void
12947 +gr_log_msgget(const int ret, const int msgflg)
12948 +{
12949 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12950 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12951 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
12952 +                                         !grsec_enable_group)) && (ret >= 0)
12953 +           && (msgflg & IPC_CREAT))
12954 +               security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
12955 +#endif
12956 +       return;
12957 +}
12958 +
12959 +void
12960 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
12961 +{
12962 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12963 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12964 +            grsec_enable_audit_ipc) ||
12965 +           (grsec_enable_audit_ipc && !grsec_enable_group))
12966 +               security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
12967 +#endif
12968 +       return;
12969 +}
12970 +
12971 +void
12972 +gr_log_semget(const int err, const int semflg)
12973 +{
12974 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12975 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12976 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
12977 +                                         !grsec_enable_group)) && (err >= 0)
12978 +           && (semflg & IPC_CREAT))
12979 +               security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
12980 +#endif
12981 +       return;
12982 +}
12983 +
12984 +void
12985 +gr_log_semrm(const uid_t uid, const uid_t cuid)
12986 +{
12987 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12988 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12989 +            grsec_enable_audit_ipc) ||
12990 +           (grsec_enable_audit_ipc && !grsec_enable_group))
12991 +               security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
12992 +#endif
12993 +       return;
12994 +}
12995 +
12996 +void
12997 +gr_log_shmget(const int err, const int shmflg, const size_t size)
12998 +{
12999 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13000 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13001 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13002 +                                         !grsec_enable_group)) && (err >= 0)
13003 +           && (shmflg & IPC_CREAT))
13004 +               security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
13005 +#endif
13006 +       return;
13007 +}
13008 +
13009 +void
13010 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
13011 +{
13012 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13013 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13014 +            grsec_enable_audit_ipc) ||
13015 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13016 +               security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13017 +#endif
13018 +       return;
13019 +}
13020 diff -urN linux-2.4.22.org/grsecurity/grsec_link.c linux-2.4.22/grsecurity/grsec_link.c
13021 --- linux-2.4.22.org/grsecurity/grsec_link.c    1970-01-01 01:00:00.000000000 +0100
13022 +++ linux-2.4.22/grsecurity/grsec_link.c        2003-11-22 22:14:08.000000000 +0100
13023 @@ -0,0 +1,41 @@
13024 +#include <linux/kernel.h>
13025 +#include <linux/sched.h>
13026 +#include <linux/fs.h>
13027 +#include <linux/file.h>
13028 +#include <linux/grinternal.h>
13029 +
13030 +int
13031 +gr_handle_follow_link(const struct inode *parent,
13032 +                     const struct inode *inode,
13033 +                     const struct dentry *dentry, const struct vfsmount *mnt)
13034 +{
13035 +#ifdef CONFIG_GRKERNSEC_LINK
13036 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
13037 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
13038 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
13039 +               security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
13040 +                              inode->i_uid, inode->i_gid, DEFAULTSECARGS);
13041 +               return -EACCES;
13042 +       }
13043 +#endif
13044 +       return 0;
13045 +}
13046 +
13047 +int
13048 +gr_handle_hardlink(const struct dentry *dentry,
13049 +                  const struct vfsmount *mnt,
13050 +                  struct inode *inode, const int mode, const char *to)
13051 +{
13052 +#ifdef CONFIG_GRKERNSEC_LINK
13053 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
13054 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
13055 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
13056 +            (permission(inode, MAY_READ | MAY_WRITE))) &&
13057 +           !capable(CAP_FOWNER) && current->uid) {
13058 +               security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
13059 +                              inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
13060 +               return -EPERM;
13061 +       }
13062 +#endif
13063 +       return 0;
13064 +}
13065 diff -urN linux-2.4.22.org/grsecurity/grsec_mem.c linux-2.4.22/grsecurity/grsec_mem.c
13066 --- linux-2.4.22.org/grsecurity/grsec_mem.c     1970-01-01 01:00:00.000000000 +0100
13067 +++ linux-2.4.22/grsecurity/grsec_mem.c 2003-11-22 22:14:08.000000000 +0100
13068 @@ -0,0 +1,54 @@
13069 +#include <linux/kernel.h>
13070 +#include <linux/sched.h>
13071 +#include <linux/mm.h>
13072 +#include <linux/grinternal.h>
13073 +
13074 +void
13075 +gr_handle_ioperm(void)
13076 +{
13077 +       security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
13078 +       return;
13079 +}
13080 +
13081 +void
13082 +gr_handle_iopl(void)
13083 +{
13084 +       security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
13085 +       return;
13086 +}
13087 +
13088 +void
13089 +gr_handle_mem_write(void)
13090 +{
13091 +       security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
13092 +       return;
13093 +}
13094 +
13095 +void
13096 +gr_handle_kmem_write(void)
13097 +{
13098 +       security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
13099 +       return;
13100 +}
13101 +
13102 +void
13103 +gr_handle_open_port(void)
13104 +{
13105 +       security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
13106 +       return;
13107 +}
13108 +
13109 +int
13110 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
13111 +{
13112 +       if (offset < __pa(high_memory) &&
13113 +           (pgprot_val(vma->vm_page_prot) & PROT_WRITE) &&
13114 +           !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
13115 +           !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
13116 +               security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
13117 +               return -EPERM;
13118 +       } else if (offset < __pa(high_memory))
13119 +               vma->vm_flags &= ~VM_MAYWRITE;
13120 +
13121 +       return 0;
13122 +}
13123 diff -urN linux-2.4.22.org/grsecurity/grsec_mount.c linux-2.4.22/grsecurity/grsec_mount.c
13124 --- linux-2.4.22.org/grsecurity/grsec_mount.c   1970-01-01 01:00:00.000000000 +0100
13125 +++ linux-2.4.22/grsecurity/grsec_mount.c       2003-11-22 22:14:08.000000000 +0100
13126 @@ -0,0 +1,34 @@
13127 +#include <linux/kernel.h>
13128 +#include <linux/sched.h>
13129 +#include <linux/grsecurity.h>
13130 +#include <linux/grinternal.h>
13131 +
13132 +void
13133 +gr_log_remount(const char *devname, const int retval)
13134 +{
13135 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13136 +       if (grsec_enable_mount && (retval >= 0))
13137 +               security_audit(GR_REMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13138 +#endif
13139 +       return;
13140 +}
13141 +
13142 +void
13143 +gr_log_unmount(const char *devname, const int retval)
13144 +{
13145 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13146 +       if (grsec_enable_mount && (retval >= 0))
13147 +               security_audit(GR_UNMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13148 +#endif
13149 +       return;
13150 +}
13151 +
13152 +void
13153 +gr_log_mount(const char *from, const char *to, const int retval)
13154 +{
13155 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13156 +       if (grsec_enable_mount && (retval >= 0))
13157 +               security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
13158 +#endif
13159 +       return;
13160 +}
13161 diff -urN linux-2.4.22.org/grsecurity/grsec_rand.c linux-2.4.22/grsecurity/grsec_rand.c
13162 --- linux-2.4.22.org/grsecurity/grsec_rand.c    1970-01-01 01:00:00.000000000 +0100
13163 +++ linux-2.4.22/grsecurity/grsec_rand.c        2003-11-22 22:14:08.000000000 +0100
13164 @@ -0,0 +1,36 @@
13165 +#include <linux/kernel.h>
13166 +#include <linux/sched.h>
13167 +#include <linux/smp_lock.h>
13168 +#include <linux/grsecurity.h>
13169 +#include <linux/grinternal.h>
13170 +
13171 +extern int last_pid;
13172 +
13173 +int
13174 +gr_random_pid(spinlock_t * pid_lock)
13175 +{
13176 +#ifdef CONFIG_GRKERNSEC_RANDPID
13177 +       struct task_struct *p;
13178 +       int pid;
13179 +
13180 +       if (grsec_enable_randpid && current->fs->root) {
13181 +               read_lock(&tasklist_lock);
13182 +               spin_lock(pid_lock);
13183 +
13184 +             repeater:
13185 +
13186 +               pid = 1 + (get_random_long() % PID_MAX);
13187 +
13188 +               for_each_task(p) {
13189 +                       if (p->pid == pid || p->pgrp == pid ||
13190 +                           p->tgid == pid || p->session == pid)
13191 +                               goto repeater;
13192 +               }
13193 +               last_pid = pid;
13194 +               spin_unlock(pid_lock);
13195 +               read_unlock(&tasklist_lock);
13196 +               return pid;
13197 +       }
13198 +#endif
13199 +       return 0;
13200 +}
13201 diff -urN linux-2.4.22.org/grsecurity/grsec_sig.c linux-2.4.22/grsecurity/grsec_sig.c
13202 --- linux-2.4.22.org/grsecurity/grsec_sig.c     1970-01-01 01:00:00.000000000 +0100
13203 +++ linux-2.4.22/grsecurity/grsec_sig.c 2003-11-22 22:14:08.000000000 +0100
13204 @@ -0,0 +1,47 @@
13205 +#include <linux/kernel.h>
13206 +#include <linux/sched.h>
13207 +#include <linux/grinternal.h>
13208 +
13209 +void
13210 +gr_log_signal(const int sig, const struct task_struct *t)
13211 +{
13212 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13213 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
13214 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
13215 +               if (t->pid == current->pid) {
13216 +                       security_alert_good(GR_UNISIGLOG_MSG, sig,
13217 +                                           DEFAULTSECARGS);
13218 +               } else {
13219 +                       security_alert_good(GR_DUALSIGLOG_MSG, sig,
13220 +                                           gr_task_fullpath(t), t->comm,
13221 +                                           t->pid, t->uid, t->euid, t->gid,
13222 +                                           t->egid, gr_parent_task_fullpath(t),
13223 +                                           t->p_pptr->comm,
13224 +                                           t->p_pptr->pid, t->p_pptr->uid,
13225 +                                           t->p_pptr->euid, t->p_pptr->gid,
13226 +                                           t->p_pptr->egid, DEFAULTSECARGS);
13227 +               }
13228 +       }
13229 +#endif
13230 +       return;
13231 +}
13232 +
13233 +int
13234 +gr_handle_signal(const struct task_struct *p, const int sig)
13235 +{
13236 +#ifdef CONFIG_GRKERNSEC
13237 +       if (current->pid > 1 && gr_check_protected_task(p)) {
13238 +               security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath(p),
13239 +                              p->comm, p->pid, p->uid,
13240 +                              p->euid, p->gid, p->egid,
13241 +                              gr_parent_task_fullpath(p), p->p_pptr->comm,
13242 +                              p->p_pptr->pid, p->p_pptr->uid,
13243 +                              p->p_pptr->euid, p->p_pptr->gid,
13244 +                              p->p_pptr->egid, DEFAULTSECARGS);
13245 +               return -EPERM;
13246 +       } else if (gr_pid_is_chrooted(p)) {
13247 +               return -EPERM;
13248 +       }
13249 +#endif
13250 +       return 0;
13251 +}
13252 diff -urN linux-2.4.22.org/grsecurity/grsec_sock.c linux-2.4.22/grsecurity/grsec_sock.c
13253 --- linux-2.4.22.org/grsecurity/grsec_sock.c    1970-01-01 01:00:00.000000000 +0100
13254 +++ linux-2.4.22/grsecurity/grsec_sock.c        2003-11-22 22:14:08.000000000 +0100
13255 @@ -0,0 +1,123 @@
13256 +#include <linux/kernel.h>
13257 +#include <linux/sched.h>
13258 +#include <linux/file.h>
13259 +#include <linux/net.h>
13260 +#include <net/sock.h>
13261 +#include <linux/grsecurity.h>
13262 +#include <linux/grinternal.h>
13263 +#include <linux/gracl.h>
13264 +
13265 +void
13266 +gr_attach_curr_ip(const struct sock *sk)
13267 +{
13268 +#ifdef CONFIG_GRKERNSEC
13269 +       struct task_struct *p;
13270 +       unsigned int i;
13271 +       struct inode *inode;
13272 +       struct file *filp;
13273 +       struct socket *connect_sock;
13274 +
13275 +       if (unlikely(sk->protocol != IPPROTO_TCP))
13276 +               return;
13277 +
13278 +       read_lock(&tasklist_lock);
13279 +       for_each_task(p) {
13280 +               if (!p->used_connect)
13281 +                       continue;
13282 +               task_lock(p);
13283 +               if (unlikely(!p->files)) {
13284 +                       task_unlock(p);
13285 +                       continue;
13286 +               }
13287 +               read_lock(&p->files->file_lock);
13288 +               for (i = 0; i < p->files->max_fds; i++) {
13289 +                       filp = fcheck_files(p->files, i);
13290 +                       if (likely(!filp))
13291 +                               continue;
13292 +                       inode = filp->f_dentry->d_inode;
13293 +                       if (likely(!inode || !inode->i_sock))
13294 +                               continue;
13295 +                       connect_sock = &inode->u.socket_i;
13296 +                       if (unlikely(!connect_sock ||
13297 +                                    connect_sock->sk->protocol != IPPROTO_TCP))
13298 +                               continue;
13299 +                       if (unlikely(sk->rcv_saddr == connect_sock->sk->daddr &&
13300 +                                    sk->daddr == connect_sock->sk->rcv_saddr &&
13301 +                                    ntohs(sk->sport) ==
13302 +                                    ntohs(connect_sock->sk->dport)
13303 +                                    && ntohs(sk->dport) ==
13304 +                                    ntohs(connect_sock->sk->sport))) {
13305 +                               current->curr_ip = p->curr_ip;
13306 +                               current->used_accept = 1;
13307 +                               read_unlock(&p->files->file_lock);
13308 +                               task_unlock(p);
13309 +                               read_unlock(&tasklist_lock);
13310 +                               return;
13311 +                       }
13312 +               }
13313 +               read_unlock(&p->files->file_lock);
13314 +               task_unlock(p);
13315 +       }
13316 +       read_unlock(&tasklist_lock);
13317 +
13318 +       current->curr_ip = sk->daddr;
13319 +       current->used_accept = 1;
13320 +#endif
13321 +       return;
13322 +}
13323 +
13324 +int
13325 +gr_handle_sock_all(const int family, const int type, const int protocol)
13326 +{
13327 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13328 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
13329 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
13330 +               security_alert(GR_SOCK_MSG, family, type, protocol,
13331 +                              DEFAULTSECARGS);
13332 +               return -EACCES;
13333 +       }
13334 +#endif
13335 +       return 0;
13336 +}
13337 +
13338 +int
13339 +gr_handle_sock_server(const struct sockaddr *sck)
13340 +{
13341 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13342 +       if (grsec_enable_socket_server &&
13343 +           in_group_p(grsec_socket_server_gid) &&
13344 +           sck && (sck->sa_family != AF_UNIX) &&
13345 +           (sck->sa_family != AF_LOCAL)) {
13346 +               security_alert(GR_BIND_MSG, DEFAULTSECARGS);
13347 +               return -EACCES;
13348 +       }
13349 +#endif
13350 +       return 0;
13351 +}
13352 +
13353 +int
13354 +gr_handle_sock_client(const struct sockaddr *sck)
13355 +{
13356 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13357 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
13358 +           sck && (sck->sa_family != AF_UNIX) &&
13359 +           (sck->sa_family != AF_LOCAL)) {
13360 +               security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
13361 +               return -EACCES;
13362 +       }
13363 +#endif
13364 +       return 0;
13365 +}
13366 +
13367 +__u32
13368 +gr_cap_rtnetlink(void)
13369 +{
13370 +#ifdef CONFIG_GRKERNSEC
13371 +       if (!gr_acl_is_enabled())
13372 +               return current->cap_effective;
13373 +       else
13374 +               return (current->cap_effective & ~(current->acl->cap_lower));
13375 +#else
13376 +       return current->cap_effective;
13377 +#endif
13378 +}
13379 diff -urN linux-2.4.22.org/grsecurity/grsec_sysctl.c linux-2.4.22/grsecurity/grsec_sysctl.c
13380 --- linux-2.4.22.org/grsecurity/grsec_sysctl.c  1970-01-01 01:00:00.000000000 +0100
13381 +++ linux-2.4.22/grsecurity/grsec_sysctl.c      2003-11-22 22:14:08.000000000 +0100
13382 @@ -0,0 +1,16 @@
13383 +#include <linux/kernel.h>
13384 +#include <linux/sched.h>
13385 +#include <linux/sysctl.h>
13386 +#include <linux/grinternal.h>
13387 +
13388 +int
13389 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
13390 +{
13391 +#ifdef CONFIG_GRKERNSEC_SYSCTL
13392 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
13393 +               security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
13394 +               return -EACCES;
13395 +       }
13396 +#endif
13397 +       return 0;
13398 +}
13399 diff -urN linux-2.4.22.org/grsecurity/grsec_time.c linux-2.4.22/grsecurity/grsec_time.c
13400 --- linux-2.4.22.org/grsecurity/grsec_time.c    1970-01-01 01:00:00.000000000 +0100
13401 +++ linux-2.4.22/grsecurity/grsec_time.c        2003-11-22 22:14:08.000000000 +0100
13402 @@ -0,0 +1,13 @@
13403 +#include <linux/kernel.h>
13404 +#include <linux/sched.h>
13405 +#include <linux/grinternal.h>
13406 +
13407 +void
13408 +gr_log_timechange(void)
13409 +{
13410 +#ifdef CONFIG_GRKERNSEC_TIME
13411 +       if (grsec_enable_time)
13412 +               security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
13413 +#endif
13414 +       return;
13415 +}
13416 diff -urN linux-2.4.22.org/grsecurity/grsec_tpe.c linux-2.4.22/grsecurity/grsec_tpe.c
13417 --- linux-2.4.22.org/grsecurity/grsec_tpe.c     1970-01-01 01:00:00.000000000 +0100
13418 +++ linux-2.4.22/grsecurity/grsec_tpe.c 2003-11-22 22:14:08.000000000 +0100
13419 @@ -0,0 +1,35 @@
13420 +#include <linux/kernel.h>
13421 +#include <linux/sched.h>
13422 +#include <linux/file.h>
13423 +#include <linux/fs.h>
13424 +#include <linux/grinternal.h>
13425 +
13426 +extern int gr_acl_tpe_check(void);
13427 +
13428 +int
13429 +gr_tpe_allow(const struct file *file)
13430 +{
13431 +#ifdef CONFIG_GRKERNSEC
13432 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
13433 +
13434 +       if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
13435 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
13436 +                                               (inode->i_mode & S_IWOTH))))) {
13437 +               security_alert(GR_EXEC_TPE_MSG,
13438 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
13439 +                              DEFAULTSECARGS);
13440 +               return 0;
13441 +       }
13442 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
13443 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
13444 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
13445 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
13446 +               security_alert(GR_EXEC_TPE_MSG,
13447 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
13448 +                              DEFAULTSECARGS);
13449 +               return 0;
13450 +       }
13451 +#endif
13452 +#endif
13453 +       return 1;
13454 +}
13455 diff -urN linux-2.4.22.org/grsecurity/grsum.c linux-2.4.22/grsecurity/grsum.c
13456 --- linux-2.4.22.org/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100
13457 +++ linux-2.4.22/grsecurity/grsum.c     2003-11-22 22:14:08.000000000 +0100
13458 @@ -0,0 +1,59 @@
13459 +#include <linux/kernel.h>
13460 +#include <linux/sched.h>
13461 +#include <linux/mm.h>
13462 +#include <asm/scatterlist.h>
13463 +#include <linux/crypto.h>
13464 +#include <linux/gracl.h>
13465 +
13466 +
13467 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
13468 +#error "crypto and sha256 must be built into the kernel"
13469 +#endif
13470 +
13471 +int
13472 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
13473 +{
13474 +       char *p;
13475 +       struct crypto_tfm *tfm;
13476 +       unsigned char temp_sum[GR_SHA_LEN];
13477 +       struct scatterlist sg[2];
13478 +       volatile int retval = 0;
13479 +       volatile int dummy = 0;
13480 +       unsigned int i;
13481 +
13482 +       tfm = crypto_alloc_tfm("sha256", 0);
13483 +       if (tfm == NULL) {
13484 +               /* should never happen, since sha256 should be built in */
13485 +               return 1;
13486 +       }
13487 +
13488 +       crypto_digest_init(tfm);
13489 +
13490 +       p = salt;
13491 +       sg[0].page = virt_to_page(p);
13492 +       sg[0].offset = ((long) p & ~PAGE_MASK);
13493 +       sg[0].length = GR_SALT_LEN;
13494 +       
13495 +       crypto_digest_update(tfm, sg, 1);
13496 +
13497 +       p = entry->pw;
13498 +       sg[0].page = virt_to_page(p);
13499 +       sg[0].offset = ((long) p & ~PAGE_MASK);
13500 +       sg[0].length = strlen(entry->pw);
13501 +
13502 +       crypto_digest_update(tfm, sg, 1);
13503 +
13504 +       crypto_digest_final(tfm, temp_sum);
13505 +
13506 +       memset(entry->pw, 0, GR_PW_LEN);
13507 +
13508 +       for (i = 0; i < GR_SHA_LEN; i++)
13509 +               if (sum[i] != temp_sum[i])
13510 +                       retval = 1;
13511 +               else
13512 +                       dummy = 1;      // waste a cycle
13513 +
13514 +       crypto_free_tfm(tfm);
13515 +
13516 +       return retval;
13517 +}
13518 diff -urN linux-2.4.22.org/grsecurity/Makefile linux-2.4.22/grsecurity/Makefile
13519 --- linux-2.4.22.org/grsecurity/Makefile        1970-01-01 01:00:00.000000000 +0100
13520 +++ linux-2.4.22/grsecurity/Makefile    2003-11-22 22:14:08.000000000 +0100
13521 @@ -0,0 +1,24 @@
13522 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
13523 +# during 2001, 2002, and 2003 it has been completely redesigned by
13524 +# Brad Spengler
13525 +#
13526 +# All code in this directory and various hooks inserted throughout the kernel
13527 +# are copyright Brad Spengler, and released under the GPL, unless otherwise
13528 +# noted (as in obsd_rand.c)
13529 +
13530 +O_TARGET := grsec.o
13531 +
13532 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
13533 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
13534 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o
13535 +
13536 +ifeq ($(CONFIG_GRKERNSEC),y)
13537 +obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
13538 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
13539 +       gracl_learn.o
13540 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
13541 +else
13542 +obj-y += grsec_disabled.o
13543 +endif
13544 +
13545 +include $(TOPDIR)/Rules.make
13546 diff -urN linux-2.4.22.org/grsecurity/obsd_rand.c linux-2.4.22/grsecurity/obsd_rand.c
13547 --- linux-2.4.22.org/grsecurity/obsd_rand.c     1970-01-01 01:00:00.000000000 +0100
13548 +++ linux-2.4.22/grsecurity/obsd_rand.c 2003-11-22 22:14:08.000000000 +0100
13549 @@ -0,0 +1,195 @@
13550 +
13551 +/*
13552 + * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
13553 + * 
13554 + * Version 1.89, last modified 19-Sep-99
13555 + *    
13556 + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
13557 + * All rights reserved.
13558 + *
13559 + * Copyright 1998 Niels Provos <provos@citi.umich.edu>
13560 + * All rights reserved.
13561 + * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
13562 + * such a mathematical system to generate more random (yet non-repeating)
13563 + * ids to solve the resolver/named problem.  But Niels designed the
13564 + * actual system based on the constraints.
13565 + *
13566 + * Redistribution and use in source and binary forms, with or without
13567 + * modification, are permitted provided that the following conditions
13568 + * are met:
13569 + * 1. Redistributions of source code must retain the above copyright
13570 + *    notice, this list of conditions and the following disclaimer,
13571 + * 2. Redistributions in binary form must reproduce the above copyright
13572 + *    notice, this list of conditions and the following disclaimer in the
13573 + *    documentation and/or other materials provided with the distribution.
13574 + * 3. All advertising materials mentioning features or use of this software
13575 + *    must display the following acknowledgement:
13576 + *    This product includes software developed by Niels Provos.
13577 + * 4. The name of the author may not be used to endorse or promote products
13578 + *    derived from this software without specific prior written permission.
13579 + *
13580 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
13581 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
13582 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
13583 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
13584 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
13585 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
13586 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13587 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13588 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
13589 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13590 + */
13591 +
13592 +#include <linux/kernel.h>
13593 +#include <linux/sched.h>
13594 +#include <linux/timer.h>
13595 +#include <linux/smp_lock.h>
13596 +#include <linux/random.h>
13597 +#include <linux/grsecurity.h>
13598 +
13599 +#define RU_OUT 180
13600 +#define RU_MAX 30000
13601 +#define RU_GEN 2
13602 +#define RU_N 32749
13603 +#define RU_AGEN 7
13604 +#define RU_M 31104
13605 +#define PFAC_N 3
13606 +const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
13607 +
13608 +static __u16 ru_x;
13609 +static __u16 ru_seed, ru_seed2;
13610 +static __u16 ru_a, ru_b;
13611 +static __u16 ru_g;
13612 +static __u16 ru_counter = 0;
13613 +static __u16 ru_msb = 0;
13614 +static unsigned long ru_reseed = 0;
13615 +static __u32 tmp;
13616 +
13617 +#define TCP_RNDISS_ROUNDS      15
13618 +#define TCP_RNDISS_OUT         7200
13619 +#define TCP_RNDISS_MAX         30000
13620 +
13621 +static __u8 tcp_rndiss_sbox[NR_CPUS][128];
13622 +static __u16 tcp_rndiss_msb[NR_CPUS];
13623 +static __u16 tcp_rndiss_cnt[NR_CPUS];
13624 +static unsigned long tcp_rndiss_reseed[NR_CPUS];
13625 +
13626 +static __u16 pmod(__u16, __u16, __u16);
13627 +static void ip_initid(void);
13628 +__u16 ip_randomid(void);
13629 +
13630 +static __u16
13631 +pmod(__u16 gen, __u16 exp, __u16 mod)
13632 +{
13633 +       __u16 s, t, u;
13634 +
13635 +       s = 1;
13636 +       t = gen;
13637 +       u = exp;
13638 +
13639 +       while (u) {
13640 +               if (u & 1)
13641 +                       s = (s * t) % mod;
13642 +               u >>= 1;
13643 +               t = (t * t) % mod;
13644 +       }
13645 +       return (s);
13646 +}
13647 +
13648 +static void
13649 +ip_initid(void)
13650 +{
13651 +       __u16 j, i;
13652 +       int noprime = 1;
13653 +
13654 +       ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
13655 +
13656 +       ru_seed = (tmp >> 16) & 0x7FFF;
13657 +       ru_seed2 = get_random_long() & 0x7FFF;
13658 +
13659 +       ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
13660 +       ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
13661 +       while (ru_b % 3 == 0)
13662 +               ru_b += 2;
13663 +
13664 +       j = (tmp = get_random_long()) % RU_N;
13665 +       tmp = tmp >> 16;
13666 +
13667 +       while (noprime) {
13668 +               for (i = 0; i < PFAC_N; i++)
13669 +                       if (j % pfacts[i] == 0)
13670 +                               break;
13671 +
13672 +               if (i >= PFAC_N)
13673 +                       noprime = 0;
13674 +               else
13675 +                       j = (j + 1) % RU_N;
13676 +       }
13677 +
13678 +       ru_g = pmod(RU_GEN, j, RU_N);
13679 +       ru_counter = 0;
13680 +
13681 +       ru_reseed = xtime.tv_sec + RU_OUT;
13682 +       ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
13683 +}
13684 +
13685 +__u16
13686 +ip_randomid(void)
13687 +{
13688 +       int i, n;
13689 +
13690 +       if (ru_counter >= RU_MAX || time_after(xtime.tv_sec, ru_reseed))
13691 +               ip_initid();
13692 +
13693 +       if (!tmp)
13694 +               tmp = get_random_long();
13695 +
13696 +       n = tmp & 0x3;
13697 +       tmp = tmp >> 2;
13698 +       if (ru_counter + n >= RU_MAX)
13699 +               ip_initid();
13700 +       for (i = 0; i <= n; i++)
13701 +               ru_x = (ru_a * ru_x + ru_b) % RU_M;
13702 +       ru_counter += i;
13703 +
13704 +       return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
13705 +}
13706 +
13707 +__u16
13708 +tcp_rndiss_encrypt(__u16 val)
13709 +{
13710 +       __u16 sum = 0, i;
13711 +       int cpu = smp_processor_id();
13712 +
13713 +       for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
13714 +               sum += 0x79b9;
13715 +               val ^= ((__u16) tcp_rndiss_sbox[cpu][(val ^ sum) ^ 0x7f]) << 7;
13716 +               val = ((val & 0xff) << 7) | (val >> 8);
13717 +       }
13718 +
13719 +       return val;
13720 +}
13721 +
13722 +static void
13723 +tcp_rndiss_init(void)
13724 +{
13725 +       int cpu = smp_processor_id();
13726 +
13727 +       get_random_bytes(tcp_rndiss_sbox[cpu], sizeof (tcp_rndiss_sbox));
13728 +       tcp_rndiss_reseed[cpu] = xtime.tv_sec + TCP_RNDISS_OUT;
13729 +       tcp_rndiss_msb[cpu] = tcp_rndiss_msb[cpu] == 0x8000 ? 0 : 0x8000;
13730 +       tcp_rndiss_cnt[cpu] = 0;
13731 +}
13732 +
13733 +__u32
13734 +ip_randomisn(void)
13735 +{
13736 +       int cpu = smp_processor_id();
13737 +
13738 +       if (tcp_rndiss_cnt[cpu] >= TCP_RNDISS_MAX ||
13739 +           time_after(xtime.tv_sec, tcp_rndiss_reseed[cpu]))
13740 +               tcp_rndiss_init();
13741 +
13742 +       return (((tcp_rndiss_encrypt(tcp_rndiss_cnt[cpu]++) |
13743 +                 tcp_rndiss_msb[cpu]) << 16) | (get_random_long() & 0x7fff));
13744 +}
13745 diff -urN linux-2.4.22.org/include/asm-alpha/a.out.h linux-2.4.22/include/asm-alpha/a.out.h
13746 --- linux-2.4.22.org/include/asm-alpha/a.out.h  2003-11-22 22:09:24.000000000 +0100
13747 +++ linux-2.4.22/include/asm-alpha/a.out.h      2003-11-22 22:14:08.000000000 +0100
13748 @@ -98,7 +98,7 @@
13749         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
13750                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
13751  
13752 -#define STACK_TOP \
13753 +#define __STACK_TOP \
13754    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
13755  
13756  #endif
13757 diff -urN linux-2.4.22.org/include/asm-alpha/elf.h linux-2.4.22/include/asm-alpha/elf.h
13758 --- linux-2.4.22.org/include/asm-alpha/elf.h    2003-11-22 22:09:24.000000000 +0100
13759 +++ linux-2.4.22/include/asm-alpha/elf.h        2003-11-22 22:14:08.000000000 +0100
13760 @@ -41,6 +41,18 @@
13761  
13762  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
13763  
13764 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
13765 +#define PAX_ELF_ET_DYN_BASE(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
13766 +
13767 +#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
13768 +#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
13769 +#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
13770 +#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
13771 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
13772 +#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
13773 +#endif
13774 +
13775 +
13776  /* $0 is set by ld.so to a pointer to a function which might be 
13777     registered using atexit.  This provides a mean for the dynamic
13778     linker to call DT_FINI functions for shared libraries that have
13779 diff -urN linux-2.4.22.org/include/asm-alpha/mman.h linux-2.4.22/include/asm-alpha/mman.h
13780 --- linux-2.4.22.org/include/asm-alpha/mman.h   2003-11-22 22:09:24.000000000 +0100
13781 +++ linux-2.4.22/include/asm-alpha/mman.h       2003-11-22 22:14:08.000000000 +0100
13782 @@ -24,6 +24,10 @@
13783  #define MAP_LOCKED     0x8000          /* lock the mapping */
13784  #define MAP_NORESERVE  0x10000         /* don't check for reservations */
13785  
13786 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
13787 +#define MAP_MIRROR     0x20000
13788 +#endif
13789 +
13790  #define MS_ASYNC       1               /* sync memory asynchronously */
13791  #define MS_SYNC                2               /* synchronous memory sync */
13792  #define MS_INVALIDATE  4               /* invalidate the caches */
13793 diff -urN linux-2.4.22.org/include/asm-alpha/pgtable.h linux-2.4.22/include/asm-alpha/pgtable.h
13794 --- linux-2.4.22.org/include/asm-alpha/pgtable.h        2003-11-22 22:09:24.000000000 +0100
13795 +++ linux-2.4.22/include/asm-alpha/pgtable.h    2003-11-22 22:14:08.000000000 +0100
13796 @@ -96,6 +96,17 @@
13797  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
13798  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
13799  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
13800 +
13801 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
13802 +#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
13803 +#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
13804 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
13805 +#else
13806 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
13807 +#define PAGE_COPY_NOEXEC      PAGE_COPY
13808 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
13809 +#endif
13810 +
13811  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
13812  
13813  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
13814 diff -urN linux-2.4.22.org/include/asm-i386/a.out.h linux-2.4.22/include/asm-i386/a.out.h
13815 --- linux-2.4.22.org/include/asm-i386/a.out.h   2003-11-22 22:09:22.000000000 +0100
13816 +++ linux-2.4.22/include/asm-i386/a.out.h       2003-11-22 22:14:09.000000000 +0100
13817 @@ -19,7 +19,11 @@
13818  
13819  #ifdef __KERNEL__
13820  
13821 -#define STACK_TOP      TASK_SIZE
13822 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
13823 +#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
13824 +#else
13825 +#define __STACK_TOP    TASK_SIZE
13826 +#endif
13827  
13828  #endif
13829  
13830 diff -urN linux-2.4.22.org/include/asm-i386/desc.h linux-2.4.22/include/asm-i386/desc.h
13831 --- linux-2.4.22.org/include/asm-i386/desc.h    2003-11-22 22:09:22.000000000 +0100
13832 +++ linux-2.4.22/include/asm-i386/desc.h        2003-11-22 22:14:09.000000000 +0100
13833 @@ -46,7 +46,8 @@
13834  };
13835  
13836  extern struct desc_struct gdt_table[];
13837 -extern struct desc_struct *idt, *gdt;
13838 +extern struct desc_struct gdt_table2[];
13839 +extern struct desc_struct *idt, *gdt, *gdt2;
13840  
13841  struct Xgt_desc_struct {
13842         unsigned short size;
13843 @@ -55,6 +56,7 @@
13844  
13845  #define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
13846  #define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
13847 +#define gdt_descr2 (*(struct Xgt_desc_struct *)((char *)&gdt2 - 2))
13848  
13849  #define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3))
13850  
13851 @@ -67,6 +69,7 @@
13852  extern struct desc_struct default_ldt[];
13853  extern void set_intr_gate(unsigned int irq, void * addr);
13854  extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
13855 +extern void __set_ldt_desc(unsigned int n, void *addr, unsigned int size);
13856  extern void set_tss_desc(unsigned int n, void *addr);
13857  
13858  static inline void clear_LDT(void)
13859 @@ -94,6 +97,21 @@
13860         __load_LDT(cpu);
13861  }
13862  
13863 +static inline void _load_LDT (struct mm_struct *mm)
13864 +{
13865 +       int cpu = smp_processor_id();
13866 +       void *segments = mm->context.segments;
13867 +       int count = LDT_ENTRIES;
13868 +
13869 +       if (!segments) {
13870 +               segments = &default_ldt[0];
13871 +               count = 5;
13872 +       }
13873 +               
13874 +       __set_ldt_desc(cpu, segments, count);
13875 +       __load_LDT(cpu);
13876 +}
13877 +
13878  #endif /* !__ASSEMBLY__ */
13879  
13880  #endif
13881 diff -urN linux-2.4.22.org/include/asm-i386/elf.h linux-2.4.22/include/asm-i386/elf.h
13882 --- linux-2.4.22.org/include/asm-i386/elf.h     2003-11-22 22:09:22.000000000 +0100
13883 +++ linux-2.4.22/include/asm-i386/elf.h 2003-11-22 22:14:09.000000000 +0100
13884 @@ -55,7 +55,22 @@
13885     the loader.  We need to make sure that it is out of the way of the program
13886     that it will "exec", and that there is sufficient room for the brk.  */
13887  
13888 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
13889 +#define ELF_ET_DYN_BASE                ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2)
13890 +#else
13891  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
13892 +#endif
13893 +
13894 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
13895 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
13896 +
13897 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
13898 +#define PAX_DELTA_MMAP_LEN(tsk)                16
13899 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
13900 +#define PAX_DELTA_EXEC_LEN(tsk)                16
13901 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT  
13902 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
13903 +#endif
13904  
13905  /* Wow, the "main" arch needs arch dependent functions too.. :) */
13906  
13907 diff -urN linux-2.4.22.org/include/asm-i386/hw_irq.h linux-2.4.22/include/asm-i386/hw_irq.h
13908 --- linux-2.4.22.org/include/asm-i386/hw_irq.h  2003-11-22 22:09:21.000000000 +0100
13909 +++ linux-2.4.22/include/asm-i386/hw_irq.h      2003-11-22 22:14:09.000000000 +0100
13910 @@ -128,6 +128,7 @@
13911  asmlinkage void x(void); \
13912  asmlinkage void call_##x(void); \
13913  __asm__( \
13914 +"\n .text" \
13915  "\n"__ALIGN_STR"\n" \
13916  SYMBOL_NAME_STR(x) ":\n\t" \
13917         "pushl $"#v"-256\n\t" \
13918 @@ -141,6 +142,7 @@
13919  asmlinkage void x(struct pt_regs * regs); \
13920  asmlinkage void call_##x(void); \
13921  __asm__( \
13922 +"\n .text" \
13923  "\n"__ALIGN_STR"\n" \
13924  SYMBOL_NAME_STR(x) ":\n\t" \
13925         "pushl $"#v"-256\n\t" \
13926 @@ -155,6 +157,7 @@
13927  #define BUILD_COMMON_IRQ() \
13928  asmlinkage void call_do_IRQ(void); \
13929  __asm__( \
13930 +       "\n .text" \
13931         "\n" __ALIGN_STR"\n" \
13932         "common_interrupt:\n\t" \
13933         SAVE_ALL \
13934 @@ -175,6 +178,7 @@
13935  #define BUILD_IRQ(nr) \
13936  asmlinkage void IRQ_NAME(nr); \
13937  __asm__( \
13938 +"\n .text" \
13939  "\n"__ALIGN_STR"\n" \
13940  SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
13941         "pushl $"#nr"-256\n\t" \
13942 diff -urN linux-2.4.22.org/include/asm-i386/mman.h linux-2.4.22/include/asm-i386/mman.h
13943 --- linux-2.4.22.org/include/asm-i386/mman.h    2003-11-22 22:09:22.000000000 +0100
13944 +++ linux-2.4.22/include/asm-i386/mman.h        2003-11-22 22:14:09.000000000 +0100
13945 @@ -18,6 +18,10 @@
13946  #define MAP_LOCKED     0x2000          /* pages are locked */
13947  #define MAP_NORESERVE  0x4000          /* don't check for reservations */
13948  
13949 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
13950 +#define MAP_MIRROR     0x8000
13951 +#endif
13952 +
13953  #define MS_ASYNC       1               /* sync memory asynchronously */
13954  #define MS_INVALIDATE  2               /* invalidate the caches */
13955  #define MS_SYNC                4               /* synchronous memory sync */
13956 diff -urN linux-2.4.22.org/include/asm-i386/page.h linux-2.4.22/include/asm-i386/page.h
13957 --- linux-2.4.22.org/include/asm-i386/page.h    2003-11-22 22:09:21.000000000 +0100
13958 +++ linux-2.4.22/include/asm-i386/page.h        2003-11-22 22:14:09.000000000 +0100
13959 @@ -78,7 +78,7 @@
13960   * and CONFIG_HIGHMEM64G options in the kernel configuration.
13961   */
13962  
13963 -#define __PAGE_OFFSET          (0xC0000000)
13964 +#include <asm/page_offset.h>
13965  
13966  /*
13967   * This much address space is reserved for vmalloc() and iomap()
13968 diff -urN linux-2.4.22.org/include/asm-i386/page_offset.h linux-2.4.22/include/asm-i386/page_offset.h
13969 --- linux-2.4.22.org/include/asm-i386/page_offset.h     1970-01-01 01:00:00.000000000 +0100
13970 +++ linux-2.4.22/include/asm-i386/page_offset.h 2003-11-22 22:14:09.000000000 +0100
13971 @@ -0,0 +1,2 @@
13972 +#define __KERNEL_TEXT_OFFSET   (0xC0400000)
13973 +#define __PAGE_OFFSET          (0xC0000000)
13974 diff -urN linux-2.4.22.org/include/asm-i386/pgtable.h linux-2.4.22/include/asm-i386/pgtable.h
13975 --- linux-2.4.22.org/include/asm-i386/pgtable.h 2003-11-22 22:09:21.000000000 +0100
13976 +++ linux-2.4.22/include/asm-i386/pgtable.h     2003-11-22 22:14:09.000000000 +0100
13977 @@ -205,6 +205,16 @@
13978  #define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
13979  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
13980  
13981 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
13982 +#define PAGE_SHARED_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
13983 +#define PAGE_COPY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
13984 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) 
13985 +#else
13986 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
13987 +#define PAGE_COPY_NOEXEC      PAGE_COPY
13988 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
13989 +#endif
13990 +
13991  #define __PAGE_KERNEL \
13992         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
13993  #define __PAGE_KERNEL_NOCACHE \
13994 @@ -237,18 +247,18 @@
13995   * This is the closest we can get..
13996   */
13997  #define __P000 PAGE_NONE
13998 -#define __P001 PAGE_READONLY
13999 -#define __P010 PAGE_COPY
14000 -#define __P011 PAGE_COPY
14001 +#define __P001  PAGE_READONLY_NOEXEC
14002 +#define __P010  PAGE_COPY_NOEXEC
14003 +#define __P011  PAGE_COPY_NOEXEC
14004  #define __P100 PAGE_READONLY
14005  #define __P101 PAGE_READONLY
14006  #define __P110 PAGE_COPY
14007  #define __P111 PAGE_COPY
14008  
14009  #define __S000 PAGE_NONE
14010 -#define __S001 PAGE_READONLY
14011 -#define __S010 PAGE_SHARED
14012 -#define __S011 PAGE_SHARED
14013 +#define __S001  PAGE_READONLY_NOEXEC
14014 +#define __S010  PAGE_SHARED_NOEXEC
14015 +#define __S011  PAGE_SHARED_NOEXEC
14016  #define __S100 PAGE_READONLY
14017  #define __S101 PAGE_READONLY
14018  #define __S110 PAGE_SHARED
14019 @@ -324,7 +334,7 @@
14020  ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
14021  
14022  /* to find an entry in a page-table-directory. */
14023 -#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14024 +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14025  
14026  #define __pgd_offset(address) pgd_index(address)
14027  
14028 diff -urN linux-2.4.22.org/include/asm-i386/processor.h linux-2.4.22/include/asm-i386/processor.h
14029 --- linux-2.4.22.org/include/asm-i386/processor.h       2003-11-22 22:09:22.000000000 +0100
14030 +++ linux-2.4.22/include/asm-i386/processor.h   2003-11-22 22:14:09.000000000 +0100
14031 @@ -261,10 +261,19 @@
14032   */
14033  #define TASK_SIZE      (PAGE_OFFSET)
14034  
14035 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14036 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
14037 +#endif
14038 +
14039  /* This decides where the kernel will search for a free chunk of vm
14040   * space during mmap's.
14041   */
14042 +
14043 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14044 +#define TASK_UNMAPPED_BASE     ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3)
14045 +#else
14046  #define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
14047 +#endif
14048  
14049  /*
14050   * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
14051 diff -urN linux-2.4.22.org/include/asm-i386/system.h linux-2.4.22/include/asm-i386/system.h
14052 --- linux-2.4.22.org/include/asm-i386/system.h  2003-11-22 22:09:22.000000000 +0100
14053 +++ linux-2.4.22/include/asm-i386/system.h      2003-11-22 22:14:09.000000000 +0100
14054 @@ -12,6 +12,8 @@
14055  struct task_struct;    /* one of the stranger aspects of C forward declarations.. */
14056  extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
14057  
14058 +void pax_switch_segments(struct task_struct *);
14059 +
14060  #define switch_to(prev,next,last) do {                                 \
14061         asm volatile("pushl %%esi\n\t"                                  \
14062                      "pushl %%edi\n\t"                                  \
14063 diff -urN linux-2.4.22.org/include/asm-parisc/a.out.h linux-2.4.22/include/asm-parisc/a.out.h
14064 --- linux-2.4.22.org/include/asm-parisc/a.out.h 2003-11-22 22:09:51.000000000 +0100
14065 +++ linux-2.4.22/include/asm-parisc/a.out.h     2003-11-22 22:14:09.000000000 +0100
14066 @@ -22,7 +22,7 @@
14067  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
14068   * prumpf */
14069  
14070 -#define STACK_TOP      TASK_SIZE
14071 +#define __STACK_TOP    TASK_SIZE
14072  
14073  #endif
14074  
14075 diff -urN linux-2.4.22.org/include/asm-parisc/elf.h linux-2.4.22/include/asm-parisc/elf.h
14076 --- linux-2.4.22.org/include/asm-parisc/elf.h   2003-11-22 22:09:51.000000000 +0100
14077 +++ linux-2.4.22/include/asm-parisc/elf.h       2003-11-22 22:14:09.000000000 +0100
14078 @@ -135,6 +135,17 @@
14079  
14080  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
14081  
14082 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14083 +#define PAX_ELF_ET_DYN_BASE(tsk)        0x10000UL
14084 +
14085 +#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
14086 +#define PAX_DELTA_MMAP_LEN(tsk)         16
14087 +#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
14088 +#define PAX_DELTA_EXEC_LEN(tsk)         16
14089 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14090 +#define PAX_DELTA_STACK_LEN(tsk)        16
14091 +#endif
14092 +
14093  /* This yields a mask that user programs can use to figure out what
14094     instruction set this CPU supports.  This could be done in user space,
14095     but it's not easy, and we've already done it here.  */
14096 diff -urN linux-2.4.22.org/include/asm-parisc/mman.h linux-2.4.22/include/asm-parisc/mman.h
14097 --- linux-2.4.22.org/include/asm-parisc/mman.h  2003-11-22 22:09:51.000000000 +0100
14098 +++ linux-2.4.22/include/asm-parisc/mman.h      2003-11-22 22:14:09.000000000 +0100
14099 @@ -18,6 +18,10 @@
14100  #define MAP_NORESERVE  0x4000          /* don't check for reservations */
14101  #define MAP_GROWSDOWN  0x8000          /* stack-like segment */
14102  
14103 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14104 +#define MAP_MIRROR     0x0400
14105 +#endif
14106 +
14107  #define MS_SYNC                1               /* synchronous memory sync */
14108  #define MS_ASYNC       2               /* sync memory asynchronously */
14109  #define MS_INVALIDATE  4               /* invalidate the caches */
14110 diff -urN linux-2.4.22.org/include/asm-parisc/pgtable.h linux-2.4.22/include/asm-parisc/pgtable.h
14111 --- linux-2.4.22.org/include/asm-parisc/pgtable.h       2003-11-22 22:09:50.000000000 +0100
14112 +++ linux-2.4.22/include/asm-parisc/pgtable.h   2003-11-22 22:14:09.000000000 +0100
14113 @@ -167,6 +167,17 @@
14114  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
14115  #define PAGE_COPY       PAGE_EXECREAD
14116  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
14117 +
14118 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14119 +#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
14120 +#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14121 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14122 +#else
14123 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14124 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14125 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14126 +#endif
14127 +
14128  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
14129  #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
14130  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
14131 diff -urN linux-2.4.22.org/include/asm-ppc/a.out.h linux-2.4.22/include/asm-ppc/a.out.h
14132 --- linux-2.4.22.org/include/asm-ppc/a.out.h    2003-11-22 22:09:28.000000000 +0100
14133 +++ linux-2.4.22/include/asm-ppc/a.out.h        2003-11-22 22:14:09.000000000 +0100
14134 @@ -2,7 +2,7 @@
14135  #define __PPC_A_OUT_H__
14136  
14137  /* grabbed from the intel stuff  */
14138 -#define STACK_TOP TASK_SIZE
14139 +#define __STACK_TOP TASK_SIZE
14140  
14141  
14142  struct exec
14143 diff -urN linux-2.4.22.org/include/asm-ppc/elf.h linux-2.4.22/include/asm-ppc/elf.h
14144 --- linux-2.4.22.org/include/asm-ppc/elf.h      2003-11-22 22:09:28.000000000 +0100
14145 +++ linux-2.4.22/include/asm-ppc/elf.h  2003-11-22 22:14:09.000000000 +0100
14146 @@ -46,6 +46,17 @@
14147  
14148  #define ELF_ET_DYN_BASE         (0x08000000)
14149  
14150 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14151 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
14152 +
14153 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14154 +#define PAX_DELTA_MMAP_LEN(tsk)                15
14155 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14156 +#define PAX_DELTA_EXEC_LEN(tsk)                15
14157 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
14158 +#define PAX_DELTA_STACK_LEN(tsk)       15
14159 +#endif
14160 +
14161  #define USE_ELF_CORE_DUMP
14162  #define ELF_EXEC_PAGESIZE      4096
14163  
14164 diff -urN linux-2.4.22.org/include/asm-ppc/mman.h linux-2.4.22/include/asm-ppc/mman.h
14165 --- linux-2.4.22.org/include/asm-ppc/mman.h     2003-11-22 22:09:28.000000000 +0100
14166 +++ linux-2.4.22/include/asm-ppc/mman.h 2003-11-22 22:14:09.000000000 +0100
14167 @@ -19,6 +19,10 @@
14168  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14169  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14170  
14171 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14172 +#define MAP_MIRROR     0x0200
14173 +#endif
14174 +
14175  #define MS_ASYNC       1               /* sync memory asynchronously */
14176  #define MS_INVALIDATE  2               /* invalidate the caches */
14177  #define MS_SYNC                4               /* synchronous memory sync */
14178 diff -urN linux-2.4.22.org/include/asm-ppc/pgtable.h linux-2.4.22/include/asm-ppc/pgtable.h
14179 --- linux-2.4.22.org/include/asm-ppc/pgtable.h  2003-11-22 22:09:28.000000000 +0100
14180 +++ linux-2.4.22/include/asm-ppc/pgtable.h      2003-11-22 22:14:09.000000000 +0100
14181 @@ -386,6 +386,16 @@
14182  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
14183  #define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
14184  
14185 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14186 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
14187 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14188 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14189 +#else
14190 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
14191 +# define PAGE_COPY_NOEXEC      PAGE_COPY
14192 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
14193 +#endif
14194 +
14195  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
14196  #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_SHARED)
14197  #define PAGE_KERNEL_CI __pgprot(_PAGE_IO)
14198 @@ -397,21 +407,21 @@
14199   * This is the closest we can get..
14200   */
14201  #define __P000 PAGE_NONE
14202 -#define __P001 PAGE_READONLY_X
14203 -#define __P010 PAGE_COPY
14204 -#define __P011 PAGE_COPY_X
14205 -#define __P100 PAGE_READONLY
14206 +#define __P001 PAGE_READONLY_NOEXEC
14207 +#define __P010 PAGE_COPY_NOEXEC
14208 +#define __P011 PAGE_COPY_NOEXEC
14209 +#define __P100 PAGE_READONLY_X
14210  #define __P101 PAGE_READONLY_X
14211 -#define __P110 PAGE_COPY
14212 +#define __P110 PAGE_COPY_X
14213  #define __P111 PAGE_COPY_X
14214  
14215  #define __S000 PAGE_NONE
14216 -#define __S001 PAGE_READONLY_X
14217 -#define __S010 PAGE_SHARED
14218 -#define __S011 PAGE_SHARED_X
14219 -#define __S100 PAGE_READONLY
14220 +#define __S001 PAGE_READONLY_NOEXEC
14221 +#define __S010 PAGE_SHARED_NOEXEC
14222 +#define __S011 PAGE_SHARED_NOEXEC
14223 +#define __S100 PAGE_READONLY_X
14224  #define __S101 PAGE_READONLY_X
14225 -#define __S110 PAGE_SHARED
14226 +#define __S110 PAGE_SHARED_X
14227  #define __S111 PAGE_SHARED_X
14228  
14229  #ifndef __ASSEMBLY__
14230 diff -urN linux-2.4.22.org/include/asm-sparc/a.out.h linux-2.4.22/include/asm-sparc/a.out.h
14231 --- linux-2.4.22.org/include/asm-sparc/a.out.h  2003-11-22 22:09:26.000000000 +0100
14232 +++ linux-2.4.22/include/asm-sparc/a.out.h      2003-11-22 22:14:09.000000000 +0100
14233 @@ -91,7 +91,7 @@
14234  
14235  #include <asm/page.h>
14236  
14237 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
14238 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
14239  
14240  #endif /* __KERNEL__ */
14241  
14242 diff -urN linux-2.4.22.org/include/asm-sparc/elf.h linux-2.4.22/include/asm-sparc/elf.h
14243 --- linux-2.4.22.org/include/asm-sparc/elf.h    2003-11-22 22:09:26.000000000 +0100
14244 +++ linux-2.4.22/include/asm-sparc/elf.h        2003-11-22 22:14:09.000000000 +0100
14245 @@ -83,6 +83,18 @@
14246  
14247  #define ELF_ET_DYN_BASE         (0x08000000)
14248  
14249 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14250 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
14251 +
14252 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14253 +#define PAX_DELTA_MMAP_LEN(tsk)                16
14254 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14255 +#define PAX_DELTA_EXEC_LEN(tsk)                16
14256 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
14257 +#define PAX_DELTA_STACK_LEN(tsk)       16
14258 +#endif
14259 +
14260 +
14261  /* This yields a mask that user programs can use to figure out what
14262     instruction set this cpu supports.  This can NOT be done in userspace
14263     on Sparc.  */
14264 diff -urN linux-2.4.22.org/include/asm-sparc/mman.h linux-2.4.22/include/asm-sparc/mman.h
14265 --- linux-2.4.22.org/include/asm-sparc/mman.h   2003-11-22 22:09:26.000000000 +0100
14266 +++ linux-2.4.22/include/asm-sparc/mman.h       2003-11-22 22:14:09.000000000 +0100
14267 @@ -24,6 +24,10 @@
14268  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14269  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14270  
14271 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14272 +#define MAP_MIRROR     0x0400
14273 +#endif
14274 +
14275  #define MS_ASYNC       1               /* sync memory asynchronously */
14276  #define MS_INVALIDATE  2               /* invalidate the caches */
14277  #define MS_SYNC                4               /* synchronous memory sync */
14278 diff -urN linux-2.4.22.org/include/asm-sparc/pgtable.h linux-2.4.22/include/asm-sparc/pgtable.h
14279 --- linux-2.4.22.org/include/asm-sparc/pgtable.h        2003-11-22 22:09:26.000000000 +0100
14280 +++ linux-2.4.22/include/asm-sparc/pgtable.h    2003-11-22 22:14:09.000000000 +0100
14281 @@ -97,6 +97,13 @@
14282  BTFIXUPDEF_INT(page_shared)
14283  BTFIXUPDEF_INT(page_copy)
14284  BTFIXUPDEF_INT(page_readonly)
14285 +
14286 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14287 +BTFIXUPDEF_INT(page_shared_noexec)
14288 +BTFIXUPDEF_INT(page_copy_noexec)
14289 +BTFIXUPDEF_INT(page_readonly_noexec)
14290 +#endif
14291 +
14292  BTFIXUPDEF_INT(page_kernel)
14293  
14294  #define PMD_SHIFT              BTFIXUP_SIMM13(pmd_shift)
14295 @@ -118,6 +125,16 @@
14296  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
14297  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
14298  
14299 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14300 +#define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
14301 +#define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
14302 +#define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
14303 +#else
14304 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14305 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14306 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14307 +#endif
14308 +
14309  extern unsigned long page_kernel;
14310  
14311  #ifdef MODULE
14312 diff -urN linux-2.4.22.org/include/asm-sparc/pgtsrmmu.h linux-2.4.22/include/asm-sparc/pgtsrmmu.h
14313 --- linux-2.4.22.org/include/asm-sparc/pgtsrmmu.h       2003-11-22 22:09:26.000000000 +0100
14314 +++ linux-2.4.22/include/asm-sparc/pgtsrmmu.h   2003-11-22 22:14:09.000000000 +0100
14315 @@ -76,6 +76,15 @@
14316                                     SRMMU_EXEC | SRMMU_REF)
14317  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14318                                     SRMMU_EXEC | SRMMU_REF)
14319 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14320 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14321 +                                          SRMMU_WRITE | SRMMU_REF)
14322 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14323 +                                          SRMMU_REF)
14324 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14325 +                                          SRMMU_REF)
14326 +#endif
14327 +
14328  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
14329                                     SRMMU_DIRTY | SRMMU_REF)
14330  
14331 diff -urN linux-2.4.22.org/include/asm-sparc/uaccess.h linux-2.4.22/include/asm-sparc/uaccess.h
14332 --- linux-2.4.22.org/include/asm-sparc/uaccess.h        2003-11-22 22:09:26.000000000 +0100
14333 +++ linux-2.4.22/include/asm-sparc/uaccess.h    2003-11-22 22:14:09.000000000 +0100
14334 @@ -39,7 +39,7 @@
14335   * No one can read/write anything from userland in the kernel space by setting
14336   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
14337   */
14338 -#define __user_ok(addr,size) ((addr) < STACK_TOP)
14339 +#define __user_ok(addr,size) ((addr) < __STACK_TOP)
14340  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
14341  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
14342  #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
14343 diff -urN linux-2.4.22.org/include/asm-sparc64/a.out.h linux-2.4.22/include/asm-sparc64/a.out.h
14344 --- linux-2.4.22.org/include/asm-sparc64/a.out.h        2003-11-22 22:09:29.000000000 +0100
14345 +++ linux-2.4.22/include/asm-sparc64/a.out.h    2003-11-22 22:14:09.000000000 +0100
14346 @@ -95,7 +95,7 @@
14347  
14348  #ifdef __KERNEL__
14349  
14350 -#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14351 +#define __STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14352  
14353  #endif
14354  
14355 diff -urN linux-2.4.22.org/include/asm-sparc64/elf.h linux-2.4.22/include/asm-sparc64/elf.h
14356 --- linux-2.4.22.org/include/asm-sparc64/elf.h  2003-11-22 22:09:28.000000000 +0100
14357 +++ linux-2.4.22/include/asm-sparc64/elf.h      2003-11-22 22:14:09.000000000 +0100
14358 @@ -82,6 +82,17 @@
14359  #define ELF_ET_DYN_BASE         0x0000010000000000UL
14360  #endif
14361  
14362 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14363 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 0x10000UL : 0x100000UL)
14364 +
14365 +#define PAX_DELTA_MMAP_LSB(tsk)         (PAGE_SHIFT + 1)
14366 +#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14367 +#define PAX_DELTA_EXEC_LSB(tsk)         (PAGE_SHIFT + 1)
14368 +#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14369 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14370 +#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 15 : 29 )
14371 +#endif
14372 +
14373  
14374  /* This yields a mask that user programs can use to figure out what
14375     instruction set this cpu supports.  */
14376 diff -urN linux-2.4.22.org/include/asm-sparc64/mman.h linux-2.4.22/include/asm-sparc64/mman.h
14377 --- linux-2.4.22.org/include/asm-sparc64/mman.h 2003-11-22 22:09:28.000000000 +0100
14378 +++ linux-2.4.22/include/asm-sparc64/mman.h     2003-11-22 22:14:09.000000000 +0100
14379 @@ -24,6 +24,10 @@
14380  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14381  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14382  
14383 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14384 +#define MAP_MIRROR     0x0400
14385 +#endif
14386 +
14387  #define MS_ASYNC       1               /* sync memory asynchronously */
14388  #define MS_INVALIDATE  2               /* invalidate the caches */
14389  #define MS_SYNC                4               /* synchronous memory sync */
14390 diff -urN linux-2.4.22.org/include/asm-sparc64/pgtable.h linux-2.4.22/include/asm-sparc64/pgtable.h
14391 --- linux-2.4.22.org/include/asm-sparc64/pgtable.h      2003-11-22 22:09:28.000000000 +0100
14392 +++ linux-2.4.22/include/asm-sparc64/pgtable.h  2003-11-22 22:14:09.000000000 +0100
14393 @@ -122,7 +122,8 @@
14394  #define _PAGE_G                0x0000000000000001      /* Global                             */
14395  
14396  /* Here are the SpitFire software bits we use in the TTE's. */
14397 -#define _PAGE_MODIFIED 0x0000000000000800      /* Modified Page (ie. dirty)          */
14398 +#define _PAGE_MODIFIED 0x0000000000001000      /* Modified Page (ie. dirty)          */
14399 +#define _PAGE_EXEC     0x0000000000000800      /* Executable SW bit                  */
14400  #define _PAGE_ACCESSED 0x0000000000000400      /* Accessed Page (ie. referenced)     */
14401  #define _PAGE_READ     0x0000000000000200      /* Readable SW Bit                    */
14402  #define _PAGE_WRITE    0x0000000000000100      /* Writable SW Bit                    */
14403 @@ -150,16 +151,30 @@
14404  
14405  /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
14406  #define PAGE_SHARED    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14407 -                                 __ACCESS_BITS | _PAGE_WRITE)
14408 +                                 __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
14409  
14410  #define PAGE_COPY      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14411 -                                 __ACCESS_BITS)
14412 +                                 __ACCESS_BITS | _PAGE_EXEC)
14413  
14414  #define PAGE_READONLY  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14415 -                                 __ACCESS_BITS)
14416 +                                 __ACCESS_BITS | _PAGE_EXEC)
14417  
14418  #define PAGE_KERNEL    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14419 -                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
14420 +                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \
14421 +                                 _PAGE_EXEC)
14422 +
14423 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14424 +#define PAGE_SHARED_NOEXEC    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14425 +                                       __ACCESS_BITS | _PAGE_WRITE)
14426 +#define PAGE_COPY_NOEXEC      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14427 +                                       __ACCESS_BITS)
14428 +#define PAGE_READONLY_NOEXEC  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14429 +                                       __ACCESS_BITS)
14430 +#else
14431 +#define PAGE_SHARED_NOEXEC     PAGE_SHARED
14432 +#define PAGE_COPY_NOEXEC       PAGE_COPY
14433 +#define PAGE_READONLY_NOEXEC   PAGE_READONLY
14434 +#endif
14435  
14436  #define PAGE_INVALID   __pgprot (0)
14437  
14438 @@ -170,18 +185,18 @@
14439  #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
14440  
14441  #define __P000 PAGE_NONE
14442 -#define __P001 PAGE_READONLY
14443 -#define __P010 PAGE_COPY
14444 -#define __P011 PAGE_COPY
14445 +#define __P001 PAGE_READONLY_NOEXEC
14446 +#define __P010 PAGE_COPY_NOEXEC
14447 +#define __P011 PAGE_COPY_NOEXEC
14448  #define __P100 PAGE_READONLY
14449  #define __P101 PAGE_READONLY
14450  #define __P110 PAGE_COPY
14451  #define __P111 PAGE_COPY
14452  
14453  #define __S000 PAGE_NONE
14454 -#define __S001 PAGE_READONLY
14455 -#define __S010 PAGE_SHARED
14456 -#define __S011 PAGE_SHARED
14457 +#define __S001 PAGE_READONLY_NOEXEC
14458 +#define __S010 PAGE_SHARED_NOEXEC
14459 +#define __S011 PAGE_SHARED_NOEXEC
14460  #define __S100 PAGE_READONLY
14461  #define __S101 PAGE_READONLY
14462  #define __S110 PAGE_SHARED
14463 diff -urN linux-2.4.22.org/include/linux/a.out.h linux-2.4.22/include/linux/a.out.h
14464 --- linux-2.4.22.org/include/linux/a.out.h      2003-11-22 22:09:16.000000000 +0100
14465 +++ linux-2.4.22/include/linux/a.out.h  2003-11-22 22:14:09.000000000 +0100
14466 @@ -7,6 +7,16 @@
14467  
14468  #include <asm/a.out.h>
14469  
14470 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
14471 +#define __DELTA_STACK (current->mm->delta_stack)
14472 +#else
14473 +#define __DELTA_STACK 0UL
14474 +#endif
14475 +
14476 +#ifndef STACK_TOP
14477 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
14478 +#endif
14479 +
14480  #endif /* __STRUCT_EXEC_OVERRIDE__ */
14481  
14482  /* these go in the N_MACHTYPE field */
14483 @@ -37,6 +47,14 @@
14484    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
14485  };
14486  
14487 +/* Constants for the N_FLAGS field */
14488 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
14489 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
14490 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
14491 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */   
14492 +#define F_PAX_RANDEXEC 16      /* Randomize ET_EXEC base */
14493 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
14494 +
14495  #if !defined (N_MAGIC)
14496  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
14497  #endif
14498 diff -urN linux-2.4.22.org/include/linux/binfmts.h linux-2.4.22/include/linux/binfmts.h
14499 --- linux-2.4.22.org/include/linux/binfmts.h    2003-11-22 22:09:16.000000000 +0100
14500 +++ linux-2.4.22/include/linux/binfmts.h        2003-11-22 22:14:09.000000000 +0100
14501 @@ -61,6 +61,8 @@
14502  extern int do_coredump(long signr, struct pt_regs * regs);
14503  extern void set_binfmt(struct linux_binfmt *new);
14504  
14505 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
14506 +void pax_report_insns(void *pc);
14507  
14508  #if 0
14509  /* this went away now */
14510 diff -urN linux-2.4.22.org/include/linux/elf.h linux-2.4.22/include/linux/elf.h
14511 --- linux-2.4.22.org/include/linux/elf.h        2003-11-22 22:09:15.000000000 +0100
14512 +++ linux-2.4.22/include/linux/elf.h    2003-11-22 22:14:09.000000000 +0100
14513 @@ -117,6 +117,8 @@
14514  #define DT_DEBUG       21
14515  #define DT_TEXTREL     22
14516  #define DT_JMPREL      23
14517 +#define DT_FLAGS       30
14518 +#define DF_TEXTREL     0x00000004
14519  #define DT_LOPROC      0x70000000
14520  #define DT_HIPROC      0x7fffffff
14521  #define DT_MIPS_RLD_VERSION    0x70000001
14522 @@ -255,6 +257,13 @@
14523  #define R_MIPS_LOVENDOR                100
14524  #define R_MIPS_HIVENDOR                127
14525  
14526 +/* Constants for the e_flags field */
14527 +#define EF_PAX_PAGEEXEC               1       /* Paging based non-executable pages */
14528 +#define EF_PAX_EMUTRAMP               2       /* Emulate trampolines */
14529 +#define EF_PAX_MPROTECT               4       /* Restrict mprotect() */
14530 +#define EF_PAX_RANDMMAP               8       /* Randomize mmap() base */ 
14531 +#define EF_PAX_RANDEXEC                      16      /* Randomize ET_EXEC base */
14532 +#define EF_PAX_SEGMEXEC                      32      /* Segmentation based non-executable pages */
14533  
14534  /*
14535   * Sparc ELF relocation types
14536 @@ -550,6 +559,8 @@
14537  #define        EI_VERSION      6
14538  #define        EI_PAD          7
14539  
14540 +#define EI_PAX         14
14541 +
14542  #define        ELFMAG0         0x7f            /* EI_MAG */
14543  #define        ELFMAG1         'E'
14544  #define        ELFMAG2         'L'
14545 @@ -597,6 +608,7 @@
14546  #define elfhdr         elf32_hdr
14547  #define elf_phdr       elf32_phdr
14548  #define elf_note       elf32_note
14549 +#define elf_dyn                Elf32_Dyn
14550  
14551  #else
14552  
14553 @@ -604,6 +616,7 @@
14554  #define elfhdr         elf64_hdr
14555  #define elf_phdr       elf64_phdr
14556  #define elf_note       elf64_note
14557 +#define elf_dyn                Elf64_Dyn
14558  
14559  #endif
14560  
14561 diff -urN linux-2.4.22.org/include/linux/fs.h linux-2.4.22/include/linux/fs.h
14562 --- linux-2.4.22.org/include/linux/fs.h 2003-11-22 22:09:12.000000000 +0100
14563 +++ linux-2.4.22/include/linux/fs.h     2003-11-22 22:14:09.000000000 +0100
14564 @@ -1167,7 +1167,7 @@
14565  
14566  asmlinkage long sys_open(const char *, int, int);
14567  asmlinkage long sys_close(unsigned int);       /* yes, it's really unsigned */
14568 -extern int do_truncate(struct dentry *, loff_t start);
14569 +extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
14570  
14571  extern struct file *filp_open(const char *, int, int);
14572  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
14573 diff -urN linux-2.4.22.org/include/linux/gracl.h linux-2.4.22/include/linux/gracl.h
14574 --- linux-2.4.22.org/include/linux/gracl.h      1970-01-01 01:00:00.000000000 +0100
14575 +++ linux-2.4.22/include/linux/gracl.h  2003-11-22 22:14:09.000000000 +0100
14576 @@ -0,0 +1,212 @@
14577 +#ifndef GR_ACL_H
14578 +#define GR_ACL_H
14579 +#endif
14580 +#include <linux/grdefs.h>
14581 +#include <linux/resource.h>
14582 +
14583 +#include <asm/resource.h>
14584 +
14585 +/* * * * * * * * * * * * * * * * * * * * *
14586 + * grsecurity ACL System
14587 + * Main header file
14588 + * Purpose: define most gracl data structures 
14589 + * * * * * * * * * * * * * * * * * * * * */
14590 +
14591 +/* Major status information */
14592 +
14593 +#define GR_VERSION  "grsecurity 2.0"
14594 +
14595 +enum {
14596 +
14597 +       SHUTDOWN = 0,
14598 +       ENABLE = 1,
14599 +       SPROLE = 2,
14600 +       RELOAD = 3,
14601 +       SEGVMOD = 4,
14602 +       STATUS = 5,
14603 +       UNSPROLE = 6
14604 +};
14605 +
14606 +/* Password setup definitions
14607 + * kernel/grhash.c */
14608 +enum {
14609 +       GR_PW_LEN = 128,
14610 +       GR_SALT_LEN = 16,
14611 +       GR_SHA_LEN = 32,
14612 +};
14613 +
14614 +enum {
14615 +       GR_SPROLE_LEN = 64,
14616 +};
14617 +
14618 +/* Begin Data Structures */
14619 +
14620 +struct sprole_pw {
14621 +       unsigned char *rolename;
14622 +       unsigned char salt[GR_SALT_LEN];
14623 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
14624 +};
14625 +
14626 +struct name_entry {
14627 +       ino_t inode;
14628 +       kdev_t device;
14629 +       char *name;
14630 +       __u16 len;
14631 +};
14632 +
14633 +struct acl_role_db {
14634 +       struct acl_role_label **r_hash;
14635 +       __u32 r_size;
14636 +};
14637 +
14638 +struct name_db {
14639 +       struct name_entry **n_hash;
14640 +       __u32 n_size;
14641 +};
14642 +
14643 +struct crash_uid {
14644 +       uid_t uid;
14645 +       unsigned long expires;
14646 +};
14647 +
14648 +/* Userspace Grsecurity ACL data structures */
14649 +struct acl_subject_label {
14650 +       char *filename;
14651 +       ino_t inode;
14652 +       kdev_t device;
14653 +       __u32 mode;
14654 +       __u32 cap_raise;
14655 +       __u32 cap_lower;
14656 +
14657 +       struct rlimit res[RLIM_NLIMITS + 1];
14658 +       __u16 resmask;
14659 +
14660 +       __u32 ip_proto[8];
14661 +       __u32 ip_type;
14662 +       struct acl_ip_label **ips;
14663 +       __u32 ip_num;
14664 +
14665 +       __u32 crashes;
14666 +       unsigned long expires;
14667 +
14668 +       struct acl_subject_label *parent_subject;
14669 +       struct acl_object_label *proc_object;
14670 +       struct acl_ip_label *ip_object;
14671 +       struct acl_subject_label *prev;
14672 +       struct acl_subject_label *next;
14673 +
14674 +       struct acl_object_label **obj_hash;
14675 +       __u32 obj_hash_size;
14676 +};
14677 +
14678 +struct role_allowed_ip {
14679 +       __u32 addr;
14680 +       __u32 netmask;
14681 +
14682 +       struct role_allowed_ip *prev;
14683 +       struct role_allowed_ip *next;
14684 +};
14685 +
14686 +struct role_transition {
14687 +       char *rolename;
14688 +
14689 +       struct role_transition *prev;
14690 +       struct role_transition *next;
14691 +};
14692 +
14693 +struct acl_role_label {
14694 +       char *rolename;
14695 +       uid_t uidgid;
14696 +       __u16 roletype;
14697 +
14698 +       __u16 auth_attempts;
14699 +       unsigned long expires;
14700 +
14701 +       struct acl_subject_label *root_label;
14702 +       struct acl_subject_label *proc_subject;
14703 +
14704 +       struct acl_role_label *prev;
14705 +       struct acl_role_label *next;
14706 +
14707 +       struct role_transition *transitions;
14708 +       struct role_allowed_ip *allowed_ips;
14709 +       struct acl_subject_label **subj_hash;
14710 +       __u32 subj_hash_size;
14711 +};
14712 +
14713 +struct user_acl_role_db {
14714 +       struct acl_role_label **r_table;
14715 +       __u32 r_entries;        /* number of entries in table */
14716 +       __u32 s_entries;        /* total number of subject acls */
14717 +       __u32 i_entries;        /* total number of ip acls */
14718 +       __u32 o_entries;        /* Total number of object acls */
14719 +       __u32 a_entries;        /* total number of allowed ips */
14720 +       __u32 t_entries;        /* total number of transitions */
14721 +};
14722 +
14723 +struct acl_object_label {
14724 +       char *filename;
14725 +       ino_t inode;
14726 +       kdev_t device;
14727 +       __u32 mode;
14728 +
14729 +       struct acl_subject_label *nested;
14730 +
14731 +       /* next two structures not used */
14732 +
14733 +       struct acl_object_label *prev;
14734 +       struct acl_object_label *next;
14735 +};
14736 +
14737 +struct acl_ip_label {
14738 +       __u32 addr;
14739 +       __u32 netmask;
14740 +       __u16 low, high;
14741 +       __u8 mode;
14742 +       __u32 type;
14743 +       __u32 proto[8];
14744 +
14745 +       /* next two structures not used */
14746 +
14747 +       struct acl_ip_label *prev;
14748 +       struct acl_ip_label *next;
14749 +};
14750 +
14751 +struct gr_arg {
14752 +       struct user_acl_role_db role_db;
14753 +       unsigned char pw[GR_PW_LEN];
14754 +       unsigned char salt[GR_SALT_LEN];
14755 +       unsigned char sum[GR_SHA_LEN];
14756 +       unsigned char sp_role[GR_SPROLE_LEN];
14757 +       struct sprole_pw *sprole_pws;
14758 +       __u16 num_sprole_pws;
14759 +       kdev_t segv_device;
14760 +       ino_t segv_inode;
14761 +       uid_t segv_uid;
14762 +       __u16 mode;
14763 +};
14764 +
14765 +/* End Data Structures Section */
14766 +
14767 +/* Hash functions generated by empirical testing by Brad Spengler
14768 +   Makes good use of the low bits of the inode.  Generally 0-1 times
14769 +   in loop for successful match.  0-3 for unsuccessful match.
14770 +   Shift/add algorithm with modulus of table size and an XOR*/
14771 +
14772 +static __inline__ unsigned long
14773 +rhash(const uid_t uid, const __u16 type, const unsigned long sz)
14774 +{
14775 +       return (((uid << type) + (uid ^ type)) % sz);
14776 +}
14777 +
14778 +static __inline__ unsigned long
14779 +fhash(const ino_t ino, const kdev_t dev, const unsigned long sz)
14780 +{
14781 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
14782 +}
14783 +
14784 +static __inline__ unsigned long
14785 +nhash(const char *name, const __u16 len, const unsigned long sz)
14786 +{
14787 +       return full_name_hash(name, len) % sz;
14788 +}
14789 diff -urN linux-2.4.22.org/include/linux/gralloc.h linux-2.4.22/include/linux/gralloc.h
14790 --- linux-2.4.22.org/include/linux/gralloc.h    1970-01-01 01:00:00.000000000 +0100
14791 +++ linux-2.4.22/include/linux/gralloc.h        2003-11-22 22:14:09.000000000 +0100
14792 @@ -0,0 +1,8 @@
14793 +#ifndef __GRALLOC_H
14794 +#define __GRALLOC_H
14795 +
14796 +void acl_free_all(void);
14797 +int acl_alloc_stack_init(unsigned long size);
14798 +void *acl_alloc(unsigned long len);
14799 +
14800 +#endif
14801 diff -urN linux-2.4.22.org/include/linux/grdefs.h linux-2.4.22/include/linux/grdefs.h
14802 --- linux-2.4.22.org/include/linux/grdefs.h     1970-01-01 01:00:00.000000000 +0100
14803 +++ linux-2.4.22/include/linux/grdefs.h 2003-11-22 22:14:09.000000000 +0100
14804 @@ -0,0 +1,104 @@
14805 +#ifndef GRDEFS_H
14806 +#define GRDEFS_H
14807 +
14808 +/* Begin grsecurity status declarations */
14809 +
14810 +enum {
14811 +       GR_READY = 0x01,
14812 +       GR_STATUS_INIT = 0x00   // disabled state
14813 +};
14814 +
14815 +/* Begin  ACL declarations */
14816 +
14817 +/* Role flags */
14818 +
14819 +enum {
14820 +       GR_ROLE_USER = 0x0001,
14821 +       GR_ROLE_GROUP = 0x0002,
14822 +       GR_ROLE_DEFAULT = 0x0004,
14823 +       GR_ROLE_SPECIAL = 0x0008,
14824 +       GR_ROLE_AUTH = 0x0010,
14825 +       GR_ROLE_NOPW = 0x0020,
14826 +       GR_ROLE_GOD = 0x0040,
14827 +       GR_ROLE_LEARN = 0x0080,
14828 +       GR_ROLE_TPE = 0x0100
14829 +};
14830 +
14831 +/* ACL Subject and Object mode flags */
14832 +enum {
14833 +       GR_DELETED = 0x00000080
14834 +};
14835 +
14836 +/* ACL Object-only mode flags */
14837 +enum {
14838 +       GR_READ = 0x00000001,
14839 +       GR_APPEND = 0x00000002,
14840 +       GR_WRITE = 0x00000004,
14841 +       GR_EXEC = 0x00000008,
14842 +       GR_FIND = 0x00000010,
14843 +       GR_INHERIT = 0x00000040,
14844 +       GR_PTRACERD = 0x00000100,
14845 +       GR_SETID = 0x00000200,
14846 +       GR_CREATE = 0x00000400,
14847 +       GR_DELETE = 0x00000800,
14848 +       GR_AUDIT_READ = 0x00001000,
14849 +       GR_AUDIT_APPEND = 0x00002000,
14850 +       GR_AUDIT_WRITE = 0x0004000,
14851 +       GR_AUDIT_EXEC = 0x00008000,
14852 +       GR_AUDIT_FIND = 0x00010000,
14853 +       GR_AUDIT_INHERIT = 0x00020000,
14854 +       GR_AUDIT_SETID = 0x00400000,
14855 +       GR_AUDIT_CREATE = 0x00800000,
14856 +       GR_AUDIT_DELETE = 0x01000000,
14857 +       GR_SUPPRESS = 0x02000000,
14858 +       GR_NOLEARN = 0x04000000
14859 +};
14860 +
14861 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
14862 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
14863 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE)
14864 +
14865 +/* ACL subject-only mode flags */
14866 +enum {
14867 +       GR_KILL = 0x00000001,
14868 +       GR_VIEW = 0x00000002,
14869 +       GR_PROTECTED = 0x00000100,
14870 +       GR_LEARN = 0x00000200,
14871 +       GR_OVERRIDE = 0x00000400,
14872 +       /* just a placeholder, this mode is only used in userspace */
14873 +       GR_DUMMY = 0x00000800,
14874 +
14875 +       GR_PAXPAGE = 0x00001000,
14876 +       GR_PAXSEGM = 0x00002000,
14877 +       GR_PAXGCC = 0x00004000,
14878 +       GR_PAXRANDMMAP = 0x00008000,
14879 +       GR_PAXRANDEXEC = 0x00010000,
14880 +       GR_PAXMPROTECT = 0x00020000,
14881 +       GR_PROTSHM = 0x00040000,
14882 +       GR_KILLPROC = 0x00080000,
14883 +       GR_KILLIPPROC = 0x00100000,
14884 +       /* just a placeholder, this mode is only used in userspace */
14885 +       GR_NOTROJAN = 0x00200000,
14886 +       GR_PROTPROCFD = 0x00400000,
14887 +       GR_PROCACCT = 0x00800000
14888 +};
14889 +
14890 +#define GR_CRASH_RES   11
14891 +#define GR_UIDTABLE_MAX 500
14892 +
14893 +/* begin resource learning section */
14894 +enum {
14895 +       GR_RLIM_CPU_BUMP = 60,
14896 +       GR_RLIM_FSIZE_BUMP = 50000,
14897 +       GR_RLIM_DATA_BUMP = 10000,
14898 +       GR_RLIM_STACK_BUMP = 1000,
14899 +       GR_RLIM_CORE_BUMP = 10000,
14900 +       GR_RLIM_RSS_BUMP = 500000,
14901 +       GR_RLIM_NPROC_BUMP = 1,
14902 +       GR_RLIM_NOFILE_BUMP = 5,
14903 +       GR_RLIM_MEMLOCK_BUMP = 50000,
14904 +       GR_RLIM_AS_BUMP = 500000,
14905 +       GR_RLIM_LOCKS_BUMP = 2
14906 +};
14907 +
14908 +#endif
14909 diff -urN linux-2.4.22.org/include/linux/grinternal.h linux-2.4.22/include/linux/grinternal.h
14910 --- linux-2.4.22.org/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100
14911 +++ linux-2.4.22/include/linux/grinternal.h     2003-11-22 22:14:09.000000000 +0100
14912 @@ -0,0 +1,193 @@
14913 +#ifndef __GRINTERNAL_H
14914 +#define __GRINTERNAL_H
14915 +
14916 +#ifdef CONFIG_GRKERNSEC
14917 +
14918 +#include <linux/grdefs.h>
14919 +#include <linux/grmsg.h>
14920 +
14921 +extern void gr_add_learn_entry(const char *fmt, ...);
14922 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
14923 +                           const struct vfsmount *mnt);
14924 +extern __u32 gr_check_create(const struct dentry *new_dentry,
14925 +                            const struct dentry *parent,
14926 +                            const struct vfsmount *mnt, const __u32 mode);
14927 +extern int gr_check_protected_task(const struct task_struct *task);
14928 +extern __inline__ __u32 to_gr_audit(const __u32 reqmode);
14929 +extern int gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14930 +                           struct dentry *old_dentry,
14931 +                           struct dentry *new_dentry,
14932 +                           struct vfsmount *mnt, const __u8 replace);
14933 +extern int gr_set_acls(const int type);
14934 +
14935 +extern void gr_handle_alertkill(void);
14936 +extern char *gr_to_filename(const struct dentry *dentry,
14937 +                           const struct vfsmount *mnt);
14938 +extern char *gr_to_filename1(const struct dentry *dentry,
14939 +                           const struct vfsmount *mnt);
14940 +extern char *gr_to_filename2(const struct dentry *dentry,
14941 +                           const struct vfsmount *mnt);
14942 +extern char *gr_to_filename3(const struct dentry *dentry,
14943 +                           const struct vfsmount *mnt);
14944 +
14945 +extern int grsec_enable_link;
14946 +extern int grsec_enable_fifo;
14947 +extern int grsec_enable_execve;
14948 +extern int grsec_enable_forkbomb;
14949 +extern int grsec_forkbomb_gid;
14950 +extern int grsec_forkbomb_sec;
14951 +extern int grsec_forkbomb_max;
14952 +extern int grsec_enable_execlog;
14953 +extern int grsec_enable_signal;
14954 +extern int grsec_enable_forkfail;
14955 +extern int grsec_enable_time;
14956 +extern int grsec_enable_chroot_shmat;
14957 +extern int grsec_enable_chroot_findtask;
14958 +extern int grsec_enable_chroot_mount;
14959 +extern int grsec_enable_chroot_double;
14960 +extern int grsec_enable_chroot_pivot;
14961 +extern int grsec_enable_chroot_chdir;
14962 +extern int grsec_enable_chroot_chmod;
14963 +extern int grsec_enable_chroot_mknod;
14964 +extern int grsec_enable_chroot_fchdir;
14965 +extern int grsec_enable_chroot_nice;
14966 +extern int grsec_enable_chroot_execlog;
14967 +extern int grsec_enable_chroot_caps;
14968 +extern int grsec_enable_chroot_sysctl;
14969 +extern int grsec_enable_chroot_unix;
14970 +extern int grsec_enable_tpe;
14971 +extern int grsec_tpe_gid;
14972 +extern int grsec_enable_tpe_all;
14973 +extern int grsec_enable_sidcaps;
14974 +extern int grsec_enable_randpid;
14975 +extern int grsec_enable_socket_all;
14976 +extern int grsec_socket_all_gid;
14977 +extern int grsec_enable_socket_client;
14978 +extern int grsec_socket_client_gid;
14979 +extern int grsec_enable_socket_server;
14980 +extern int grsec_socket_server_gid;
14981 +extern int grsec_audit_gid;
14982 +extern int grsec_enable_group;
14983 +extern int grsec_enable_audit_ipc;
14984 +extern int grsec_enable_mount;
14985 +extern int grsec_enable_chdir;
14986 +extern int grsec_lock;
14987 +
14988 +extern struct task_struct *child_reaper;
14989 +
14990 +extern spinlock_t grsec_alert_lock;
14991 +extern unsigned long grsec_alert_wtime;
14992 +extern unsigned long grsec_alert_fyet;
14993 +
14994 +extern spinlock_t grsec_alertgood_lock;
14995 +extern unsigned long grsec_alertgood_wtime;
14996 +extern unsigned long grsec_alertgood_fyet;
14997 +
14998 +extern spinlock_t grsec_audit_lock;
14999 +
15000 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
15001 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
15002 +                       tsk->exec_file->f_vfsmnt) : "/")
15003 +
15004 +#define gr_parent_task_fullpath(tsk) (tsk->p_pptr->exec_file ? \
15005 +                       gr_to_filename3(tsk->p_pptr->exec_file->f_dentry, \
15006 +                       tsk->p_pptr->exec_file->f_vfsmnt) : "/")
15007 +
15008 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && \
15009 +                         ((tsk_a->fs->root->d_inode->i_dev != \
15010 +                         child_reaper->fs->root->d_inode->i_dev) || \
15011 +                         (tsk_a->fs->root->d_inode->i_ino != \
15012 +                         child_reaper->fs->root->d_inode->i_ino)))
15013 +
15014 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_dev == \
15015 +                         tsk_b->fs->root->d_inode->i_dev) && \
15016 +                         (tsk_a->fs->root->d_inode->i_ino == \
15017 +                         tsk_b->fs->root->d_inode->i_ino))
15018 +
15019 +#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
15020 +                      current->pid, current->uid, \
15021 +                      current->euid, current->gid, current->egid, \
15022 +                      gr_parent_task_fullpath(current), \
15023 +                      current->p_pptr->comm, current->p_pptr->pid, \
15024 +                      current->p_pptr->uid, current->p_pptr->euid, \
15025 +                      current->p_pptr->gid, current->p_pptr->egid
15026 +
15027 +#define GR_CHROOT_CAPS ( \
15028 +       CAP_TO_MASK(CAP_FOWNER) | \
15029 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
15030 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
15031 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
15032 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
15033 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
15034 +       CAP_TO_MASK(CAP_IPC_OWNER))
15035 +
15036 +#define security_alert_good(normal_msg,args...) \
15037 +({ \
15038 +       spin_lock(&grsec_alertgood_lock); \
15039 +       \
15040 +       if (!grsec_alertgood_wtime || jiffies - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15041 +           grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet = 0; \
15042 +           if (current->curr_ip) \
15043 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15044 +           else \
15045 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15046 +       } else if((jiffies - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15047 +           grsec_alertgood_fyet++; \
15048 +           if (current->curr_ip) \
15049 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15050 +           else \
15051 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15052 +       } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15053 +           grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet++; \
15054 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15055 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15056 +       } \
15057 +       \
15058 +       spin_unlock(&grsec_alertgood_lock); \
15059 +})
15060 +
15061 +#define security_alert(normal_msg,args...) \
15062 +({ \
15063 +       spin_lock(&grsec_alert_lock); \
15064 +       \
15065 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15066 +           grsec_alert_wtime = jiffies; grsec_alert_fyet = 0; \
15067 +           if (current->curr_ip) \
15068 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15069 +           else \
15070 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15071 +       } else if((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15072 +           grsec_alert_fyet++; \
15073 +           if (current->curr_ip) \
15074 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15075 +           else \
15076 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15077 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15078 +           grsec_alert_wtime = jiffies; grsec_alert_fyet++; \
15079 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15080 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15081 +       } \
15082 +       \
15083 +       gr_handle_alertkill(); \
15084 +       spin_unlock(&grsec_alert_lock); \
15085 +})
15086 +
15087 +#define security_audit(normal_msg,args...) \
15088 +({ \
15089 +       spin_lock(&grsec_audit_lock); \
15090 +       if (current->curr_ip) \
15091 +               printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
15092 +                      NIPQUAD(current->curr_ip) , ## args); \
15093 +       else \
15094 +               printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
15095 +       spin_unlock(&grsec_audit_lock); \
15096 +})
15097 +
15098 +#define security_learn(normal_msg,args...) \
15099 +({ \
15100 +       gr_add_learn_entry(normal_msg "\n", ## args); \
15101 +})
15102 +
15103 +#endif
15104 +
15105 +#endif
15106 diff -urN linux-2.4.22.org/include/linux/grmsg.h linux-2.4.22/include/linux/grmsg.h
15107 --- linux-2.4.22.org/include/linux/grmsg.h      1970-01-01 01:00:00.000000000 +0100
15108 +++ linux-2.4.22/include/linux/grmsg.h  2003-11-22 22:14:09.000000000 +0100
15109 @@ -0,0 +1,104 @@
15110 +#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"
15111 +#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"
15112 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
15113 +#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
15114 +#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
15115 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
15116 +#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
15117 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
15118 +#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
15119 +#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
15120 +#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
15121 +#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
15122 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
15123 +#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"
15124 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
15125 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
15126 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
15127 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
15128 +#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
15129 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
15130 +#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
15131 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
15132 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
15133 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
15134 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
15135 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
15136 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
15137 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
15138 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
15139 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
15140 +#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
15141 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
15142 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
15143 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
15144 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution of [%.16s:%lu] for %lu seconds"
15145 +#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
15146 +#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
15147 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
15148 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
15149 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
15150 +#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
15151 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
15152 +#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
15153 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
15154 +#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
15155 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
15156 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
15157 +#define GR_INITF_ACL_MSG "init_variables() failed %s"
15158 +#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"
15159 +#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
15160 +#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
15161 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
15162 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
15163 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
15164 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
15165 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
15166 +#define GR_ENABLE_ACL_MSG "Loaded %s"
15167 +#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
15168 +#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
15169 +#define GR_RELOAD_ACL_MSG "Reloaded %s"
15170 +#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
15171 +#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
15172 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
15173 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
15174 +#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
15175 +#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
15176 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
15177 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
15178 +#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
15179 +#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
15180 +#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
15181 +#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
15182 +#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
15183 +#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
15184 +#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
15185 +#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
15186 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
15187 +#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
15188 +#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
15189 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
15190 +#define GR_TIME_MSG "time set by " DEFAULTSECMSG
15191 +#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
15192 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
15193 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
15194 +#define GR_SOCK_MSG "attempted socket(%d,%d,%d) by " DEFAULTSECMSG
15195 +#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
15196 +#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
15197 +#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15198 +#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15199 +#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"
15200 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
15201 +#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
15202 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
15203 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
15204 +#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
15205 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
15206 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
15207 +#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
15208 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
15209 +#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
15210 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
15211 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
15212 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
15213 +#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
15214 diff -urN linux-2.4.22.org/include/linux/grsecurity.h linux-2.4.22/include/linux/grsecurity.h
15215 --- linux-2.4.22.org/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100
15216 +++ linux-2.4.22/include/linux/grsecurity.h     2003-11-22 22:14:09.000000000 +0100
15217 @@ -0,0 +1,174 @@
15218 +#ifndef GR_SECURITY_H
15219 +#define GR_SECURITY_H
15220 +
15221 +extern int gr_pid_is_chrooted(const struct task_struct *p);
15222 +extern int gr_handle_chroot_nice(void);
15223 +extern int gr_handle_chroot_sysctl(const int op);
15224 +extern int gr_handle_chroot_capset(const struct task_struct *target);
15225 +extern int gr_handle_chroot_setpriority(const struct task_struct *p,
15226 +                                       const int niceval);
15227 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
15228 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
15229 +                                  const struct vfsmount *mnt);
15230 +extern void gr_handle_chroot_caps(struct task_struct *task);
15231 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
15232 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
15233 +                                 const struct vfsmount *mnt, const int mode);
15234 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
15235 +                                 const struct vfsmount *mnt, const int mode);
15236 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
15237 +                                 const struct vfsmount *mnt,
15238 +                                 const char *dev_name);
15239 +extern int gr_handle_chroot_pivot(void);
15240 +extern int gr_handle_chroot_unix(const pid_t pid);
15241 +
15242 +extern int gr_handle_rawio(const struct inode *inode);
15243 +extern int gr_handle_nproc(void);
15244 +
15245 +extern void gr_handle_ioperm(void);
15246 +extern void gr_handle_iopl(void);
15247 +
15248 +extern int gr_tpe_allow(const struct file *file);
15249 +
15250 +extern int gr_random_pid(spinlock_t * pid_lock);
15251 +
15252 +extern void gr_log_forkfail(const int retval);
15253 +extern void gr_log_timechange(void);
15254 +extern void gr_log_signal(const int sig, const struct task_struct *t);
15255 +extern void gr_log_chdir(const struct dentry *dentry,
15256 +                        const struct vfsmount *mnt);
15257 +extern void gr_log_chroot_exec(const struct dentry *dentry,
15258 +                              const struct vfsmount *mnt);
15259 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
15260 +extern void gr_log_remount(const char *devname, const int retval);
15261 +extern void gr_log_unmount(const char *devname, const int retval);
15262 +extern void gr_log_mount(const char *from, const char *to, const int retval);
15263 +extern void gr_log_msgget(const int ret, const int msgflg);
15264 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
15265 +extern void gr_log_semget(const int err, const int semflg);
15266 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
15267 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
15268 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
15269 +
15270 +extern int gr_handle_follow_link(const struct inode *parent,
15271 +                                const struct inode *inode,
15272 +                                const struct dentry *dentry,
15273 +                                const struct vfsmount *mnt);
15274 +extern int gr_handle_fifo(const struct dentry *dentry,
15275 +                         const struct vfsmount *mnt,
15276 +                         const struct dentry *dir, const int flag,
15277 +                         const int acc_mode);
15278 +extern int gr_handle_hardlink(const struct dentry *dentry,
15279 +                             const struct vfsmount *mnt,
15280 +                             struct inode *inode,
15281 +                             const int mode, const char *to);
15282 +
15283 +extern int gr_is_capable(const int cap);
15284 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
15285 +                             const unsigned long wanted);
15286 +extern void gr_copy_label(struct task_struct *tsk);
15287 +extern void gr_handle_crash(struct task_struct *task, const int sig);
15288 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
15289 +extern int gr_check_crash_uid(const uid_t uid);
15290 +extern int gr_check_protected_task(const struct task_struct *task);
15291 +extern int gr_acl_handle_mmap(const struct file *file,
15292 +                             const unsigned long prot);
15293 +extern int gr_acl_handle_mprotect(const struct file *file,
15294 +                                 const unsigned long prot);
15295 +extern int gr_check_hidden_task(const struct task_struct *tsk);
15296 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
15297 +                                   const struct vfsmount *mnt);
15298 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
15299 +                                const struct vfsmount *mnt);
15300 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
15301 +                                 const struct vfsmount *mnt, const int fmode);
15302 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
15303 +                                 const struct vfsmount *mnt, mode_t mode);
15304 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
15305 +                                const struct vfsmount *mnt, mode_t mode);
15306 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
15307 +                                const struct vfsmount *mnt);
15308 +extern int gr_handle_ptrace_exec(const struct dentry *dentry,
15309 +                                const struct vfsmount *mnt);
15310 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
15311 +extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
15312 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
15313 +                                 const struct vfsmount *mnt);
15314 +extern int gr_check_crash_exec(const struct file *filp);
15315 +extern int gr_acl_is_enabled(void);
15316 +extern void gr_set_kernel_label(struct task_struct *task);
15317 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
15318 +                             const gid_t gid);
15319 +extern void gr_set_proc_label(const struct dentry *dentry,
15320 +                             const struct vfsmount *mnt);
15321 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
15322 +                                      const struct vfsmount *mnt);
15323 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
15324 +                               const struct vfsmount *mnt, const int fmode);
15325 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
15326 +                                const struct dentry *p_dentry,
15327 +                                const struct vfsmount *p_mnt, const int fmode,
15328 +                                const int imode);
15329 +extern void gr_handle_create(const struct dentry *dentry,
15330 +                            const struct vfsmount *mnt);
15331 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
15332 +                                const struct dentry *parent_dentry,
15333 +                                const struct vfsmount *parent_mnt,
15334 +                                const int mode);
15335 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
15336 +                                const struct dentry *parent_dentry,
15337 +                                const struct vfsmount *parent_mnt);
15338 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
15339 +                                const struct vfsmount *mnt);
15340 +extern void gr_handle_delete(const ino_t ino, const kdev_t dev);
15341 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
15342 +                                 const struct vfsmount *mnt);
15343 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
15344 +                                  const struct dentry *parent_dentry,
15345 +                                  const struct vfsmount *parent_mnt,
15346 +                                  const char *from);
15347 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
15348 +                               const struct dentry *parent_dentry,
15349 +                               const struct vfsmount *parent_mnt,
15350 +                               const struct dentry *old_dentry,
15351 +                               const struct vfsmount *old_mnt, const char *to);
15352 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
15353 +                               struct dentry *parent_dentry,
15354 +                               const struct vfsmount *parent_mnt,
15355 +                               struct dentry *old_dentry,
15356 +                               struct inode *old_parent_inode,
15357 +                               struct vfsmount *old_mnt, const char *newname);
15358 +extern __u32 gr_check_link(const struct dentry *new_dentry,
15359 +                          const struct dentry *parent_dentry,
15360 +                          const struct vfsmount *parent_mnt,
15361 +                          const struct dentry *old_dentry,
15362 +                          const struct vfsmount *old_mnt);
15363 +extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
15364 +                                  const struct vfsmount *mnt, const ino_t ino);
15365 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
15366 +                               const struct vfsmount *mnt);
15367 +extern void gr_set_pax_flags(struct task_struct *task);
15368 +extern void gr_acl_handle_exit(void);
15369 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
15370 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
15371 +extern __u32 gr_cap_rtnetlink(void);
15372 +
15373 +#ifdef CONFIG_GRKERNSEC
15374 +extern void gr_handle_mem_write(void);
15375 +extern void gr_handle_kmem_write(void);
15376 +extern void gr_handle_open_port(void);
15377 +extern int gr_handle_mem_mmap(const unsigned long offset,
15378 +                             struct vm_area_struct *vma);
15379 +
15380 +extern __u16 ip_randomid(void);
15381 +extern __u32 ip_randomisn(void);
15382 +extern unsigned long get_random_long(void);
15383 +
15384 +extern int grsec_enable_dmesg;
15385 +extern int grsec_enable_randid;
15386 +extern int grsec_enable_randisn;
15387 +extern int grsec_enable_randsrc;
15388 +extern int grsec_enable_randrpc;
15389 +#endif
15390 +
15391 +#endif
15392 diff -urN linux-2.4.22.org/include/linux/kernel.h linux-2.4.22/include/linux/kernel.h
15393 --- linux-2.4.22.org/include/linux/kernel.h     2003-11-22 22:09:15.000000000 +0100
15394 +++ linux-2.4.22/include/linux/kernel.h 2003-11-22 22:14:09.000000000 +0100
15395 @@ -71,14 +71,17 @@
15396  extern long long simple_strtoll(const char *,char **,unsigned int);
15397  extern int sprintf(char * buf, const char * fmt, ...)
15398         __attribute__ ((format (printf, 2, 3)));
15399 -extern int vsprintf(char *buf, const char *, va_list);
15400 +extern int vsprintf(char *buf, const char *, va_list)
15401 +       __attribute__ ((format (printf, 2, 0)));
15402  extern int snprintf(char * buf, size_t size, const char * fmt, ...)
15403         __attribute__ ((format (printf, 3, 4)));
15404 -extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
15405 +extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
15406 +       __attribute__ ((format (printf, 3, 0)));
15407  
15408  extern int sscanf(const char *, const char *, ...)
15409         __attribute__ ((format (scanf,2,3)));
15410 -extern int vsscanf(const char *, const char *, va_list);
15411 +extern int vsscanf(const char *, const char *, va_list)
15412 +       __attribute__ ((format (scanf, 2, 0)));
15413  
15414  extern void qsort(void *, size_t, size_t, int (*)(const void *,const void *));
15415  
15416 diff -urN linux-2.4.22.org/include/linux/mm.h linux-2.4.22/include/linux/mm.h
15417 --- linux-2.4.22.org/include/linux/mm.h 2003-11-22 22:09:12.000000000 +0100
15418 +++ linux-2.4.22/include/linux/mm.h     2003-11-22 22:14:10.000000000 +0100
15419 @@ -22,9 +22,13 @@
15420  extern struct list_head active_list;
15421  extern struct list_head inactive_list;
15422  
15423 +extern void gr_learn_resource(const struct task_struct * task, const int limit,
15424 +                             const unsigned long wanted);
15425 +
15426  #include <asm/page.h>
15427  #include <asm/pgtable.h>
15428  #include <asm/atomic.h>
15429 +#include <asm/mman.h>
15430  
15431  /*
15432   * Linux kernel virtual memory manager primitives.
15433 @@ -104,6 +108,33 @@
15434  #define VM_DONTEXPAND  0x00040000      /* Cannot expand with mremap() */
15435  #define VM_RESERVED    0x00080000      /* Don't unmap it from swap_out */
15436  
15437 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
15438 +#define VM_MIRROR      0x00100000      /* vma is mirroring another */
15439 +#endif
15440 +
15441 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
15442 +#define VM_MAYNOTWRITE 0x00200000      /* vma cannot be granted VM_WRITE any more */
15443 +#endif
15444 +
15445 +#ifdef ARCH_STACK_GROWSUP
15446 +#define __VM_STACK_FLAGS       0x00000233
15447 +#else
15448 +#define __VM_STACK_FLAGS       0x00000133
15449 +#endif
15450 +
15451 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
15452 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
15453 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | \
15454 +                       ((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15455 +                       ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
15456 +#else
15457 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_MAYEXEC | \
15458 +                       ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
15459 +#endif
15460 +#else
15461 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_EXEC | VM_MAYEXEC)
15462 +#endif
15463 +
15464  #ifndef VM_STACK_FLAGS
15465  #define VM_STACK_FLAGS 0x00000177
15466  #endif
15467 @@ -570,22 +601,50 @@
15468                                    unsigned long prot, unsigned long flag,
15469                                    unsigned long pgoff);
15470  
15471 +extern int do_munmap(struct mm_struct *, unsigned long, size_t);
15472 +
15473  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
15474         unsigned long len, unsigned long prot,
15475         unsigned long flag, unsigned long offset)
15476  {
15477         unsigned long ret = -EINVAL;
15478 +
15479 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
15480 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
15481 +          (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
15482 +               goto out;
15483 +#endif
15484 +
15485         if ((offset + PAGE_ALIGN(len)) < offset)
15486                 goto out;
15487         if (!(offset & ~PAGE_MASK))
15488                 ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
15489                                     offset >> PAGE_SHIFT);
15490 +
15491 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
15492 +#define BAD_ADDR(x)    ((unsigned long)(x) > TASK_SIZE)
15493 +       if ((current->flags & PF_PAX_SEGMEXEC) && !BAD_ADDR(ret) &&
15494 +           (prot & PROT_EXEC) && ((flag & MAP_TYPE) == MAP_PRIVATE)
15495 +
15496 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
15497 +           && (!(current->flags & PF_PAX_MPROTECT) || (file && !(prot & PROT_WRITE)))
15498 +#endif
15499 +          )
15500 +       {
15501 +               unsigned long ret_m;
15502 +               ret_m = do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flag | MAP_MIRROR | MAP_FIXED, ret);
15503 +               if (BAD_ADDR(ret_m)) {
15504 +                       do_munmap(current->mm, ret, len);
15505 +                       ret = ret_m;
15506 +               }
15507 +       }
15508 +#undef BAD_ADDR
15509 +#endif
15510 +
15511  out:
15512         return ret;
15513  }
15514  
15515 -extern int do_munmap(struct mm_struct *, unsigned long, size_t);
15516 -
15517  extern unsigned long do_brk(unsigned long, unsigned long);
15518  
15519  static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev)
15520 @@ -598,6 +657,12 @@
15521  
15522  static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
15523  {
15524 +
15525 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
15526 +       if ((vma->vm_flags | vm_flags) & VM_MIRROR)
15527 +               return 0;
15528 +#endif
15529 +
15530         if (!vma->vm_file && vma->vm_flags == vm_flags)
15531                 return 1;
15532         else
15533 @@ -651,7 +716,12 @@
15534  
15535         return gfp_mask;
15536  }
15537 -       
15538 +
15539 +/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
15540 +extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
15541 +extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
15542 +                                            struct vm_area_struct **pprev);
15543 +
15544  /* vma is the first one with  address < vma->vm_end,
15545   * and even  address < vma->vm_start. Have to extend vma. */
15546  static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
15547 @@ -666,11 +736,51 @@
15548         address &= PAGE_MASK;
15549         spin_lock(&vma->vm_mm->page_table_lock);
15550         grow = (vma->vm_start - address) >> PAGE_SHIFT;
15551 +
15552 +       gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address);
15553 +       gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT);
15554 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT);
15555 +
15556 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
15557 +       if (vma->vm_flags & VM_MIRROR) {
15558 +               struct vm_area_struct * vma_m;
15559 +               unsigned long address_m;
15560 +
15561 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
15562 +               vma_m = find_vma(vma->vm_mm, address_m);
15563 +               if (!vma_m || vma_m->vm_start != address_m || !(vma_m->vm_flags & VM_MIRROR) ||
15564 +                   vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start) {
15565 +                       spin_unlock(&vma->vm_mm->page_table_lock);
15566 +                       printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
15567 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
15568 +                       return -ENOMEM;
15569 +               }
15570 +
15571 +               address_m = address + (unsigned long)vma->vm_private_data;
15572 +               if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
15573 +                   ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
15574 +                   ((vma_m->vm_flags & VM_LOCKED) && ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
15575 +                    current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
15576 +                       spin_unlock(&vma->vm_mm->page_table_lock);
15577 +                       return -ENOMEM;
15578 +               }
15579 +
15580 +               vma_m->vm_start = address_m;
15581 +               vma_m->vm_pgoff -= grow;
15582 +               vma_m->vm_mm->total_vm += grow;
15583 +               if (vma_m->vm_flags & VM_LOCKED)
15584 +                       vma_m->vm_mm->locked_vm += grow;
15585 +       } else
15586 +#endif
15587 +
15588         if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
15589 -           ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
15590 +           ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
15591 +           ((vma->vm_flags & VM_LOCKED) && ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
15592 +            current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
15593                 spin_unlock(&vma->vm_mm->page_table_lock);
15594                 return -ENOMEM;
15595         }
15596 +
15597         vma->vm_start = address;
15598         vma->vm_pgoff -= grow;
15599         vma->vm_mm->total_vm += grow;
15600 @@ -680,11 +790,6 @@
15601         return 0;
15602  }
15603  
15604 -/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
15605 -extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
15606 -extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
15607 -                                            struct vm_area_struct **pprev);
15608 -
15609  /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
15610     NULL if none.  Assume start_addr < end_addr. */
15611  static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
15612 diff -urN linux-2.4.22.org/include/linux/proc_fs.h linux-2.4.22/include/linux/proc_fs.h
15613 --- linux-2.4.22.org/include/linux/proc_fs.h    2003-11-22 22:09:15.000000000 +0100
15614 +++ linux-2.4.22/include/linux/proc_fs.h        2003-11-22 22:14:10.000000000 +0100
15615 @@ -143,6 +143,9 @@
15616  extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
15617                 struct proc_dir_entry *,kdev_t);
15618  extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
15619 +#ifdef CONFIG_GRKERNSEC_PROC
15620 +extern struct proc_dir_entry *proc_priv_mkdir(const char *, struct proc_dir_entry *);
15621 +#endif
15622  
15623  static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
15624         mode_t mode, struct proc_dir_entry *base, 
15625 diff -urN linux-2.4.22.org/include/linux/sched.h linux-2.4.22/include/linux/sched.h
15626 --- linux-2.4.22.org/include/linux/sched.h      2003-11-22 22:09:12.000000000 +0100
15627 +++ linux-2.4.22/include/linux/sched.h  2003-11-22 22:14:10.000000000 +0100
15628 @@ -28,6 +28,9 @@
15629  #include <linux/securebits.h>
15630  #include <linux/fs_struct.h>
15631  
15632 +extern int gr_is_capable(const int cap);
15633 +extern int gr_pid_is_chrooted(const struct task_struct *p);
15634 +
15635  struct exec_domain;
15636  
15637  /*
15638 @@ -250,6 +253,20 @@
15639         unsigned long cpu_vm_mask;
15640         unsigned long swap_address;
15641  
15642 +#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
15643 +       unsigned long call_dl_resolve;
15644 +#endif
15645 +
15646 +#if defined(CONFIG_PPC32) && defined(CONFIG_GRKERNSEC_PAX_EMUSIGRT)
15647 +       unsigned long call_syscall;
15648 +#endif
15649 +
15650 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
15651 +       unsigned long delta_mmap;               /* PaX: randomized offset */
15652 +       unsigned long delta_exec;               /* PaX: randomized offset */
15653 +       unsigned long delta_stack;              /* PaX: randomized offset */
15654 +#endif
15655
15656         unsigned dumpable:1;
15657  
15658         /* Architecture-specific MM context */
15659 @@ -422,7 +439,7 @@
15660         int (*notifier)(void *priv);
15661         void *notifier_data;
15662         sigset_t *notifier_mask;
15663 -       
15664 +
15665  /* Thread group tracking */
15666         u32 parent_exec_id;
15667         u32 self_exec_id;
15668 @@ -433,6 +450,19 @@
15669  
15670  /* journalling filesystem info */
15671         void *journal_info;
15672 +
15673 +#ifdef CONFIG_GRKERNSEC
15674 +/* added by grsecurity's ACL system */ 
15675 +       struct acl_subject_label *acl;
15676 +       struct acl_role_label *role;
15677 +       struct file *exec_file;
15678 +       u32 curr_ip;
15679 +       u16 acl_role_id;        
15680 +       u8 acl_sp_role:1;       
15681 +       u8 used_accept:1;       
15682 +       u8 used_connect:1;      
15683 +       u8 is_writable:1;
15684 +#endif
15685  };
15686  
15687  /*
15688 @@ -453,6 +483,13 @@
15689  
15690  #define PF_USEDFPU     0x00100000      /* task used FPU this quantum (SMP) */
15691  
15692 +#define PF_PAX_PAGEEXEC       0x01000000      /* Paging based non-executable pages */
15693 +#define PF_PAX_EMUTRAMP       0x02000000      /* Emulate trampolines */
15694 +#define PF_PAX_MPROTECT       0x04000000      /* Restrict mprotect() */
15695 +#define PF_PAX_RANDMMAP       0x08000000      /* Randomize mmap() base */
15696 +#define PF_PAX_RANDEXEC              0x10000000      /* Randomize ET_EXEC base */
15697 +#define PF_PAX_SEGMEXEC              0x20000000      /* Segmentation based non-executable pages */
15698 +
15699  /*
15700   * Ptrace flags
15701   */
15702 @@ -573,6 +610,8 @@
15703         *p->pidhash_pprev = p->pidhash_next;
15704  }
15705  
15706 +#include <asm/current.h>
15707 +
15708  static inline task_t *find_task_by_pid(int pid)
15709  {
15710         task_t *p, **htable = &pidhash[pid_hashfn(pid)];
15711 @@ -580,6 +619,8 @@
15712         for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
15713                 ;
15714  
15715 +       if(gr_pid_is_chrooted(p)) p = NULL;
15716 +
15717         return p;
15718  }
15719  
15720 @@ -588,8 +629,6 @@
15721  extern void free_uid(struct user_struct *);
15722  extern void switch_uid(struct user_struct *);
15723  
15724 -#include <asm/current.h>
15725 -
15726  extern unsigned long volatile jiffies;
15727  extern unsigned long itimer_ticks;
15728  extern unsigned long itimer_next;
15729 @@ -756,7 +795,7 @@
15730  static inline int capable(int cap)
15731  {
15732  #if 1 /* ok now */
15733 -       if (cap_raised(current->cap_effective, cap))
15734 +       if (cap_raised(current->cap_effective, cap) && gr_is_capable(cap))
15735  #else
15736         if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
15737  #endif
15738 diff -urN linux-2.4.22.org/include/linux/sysctl.h linux-2.4.22/include/linux/sysctl.h
15739 --- linux-2.4.22.org/include/linux/sysctl.h     2003-11-22 22:09:11.000000000 +0100
15740 +++ linux-2.4.22/include/linux/sysctl.h 2003-11-22 22:45:25.000000000 +0100
15741 @@ -128,6 +128,7 @@
15742         KERN_PPC_L3CR=57,       /* l3cr register on PPC */
15743         KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
15744         KERN_CORE_SETUID=59,    /* int: set to allow core dumps of setuid apps */
15745 +       KERN_GRSECURITY=68,     /* grsecurity */
15746  };
15747  
15748  
15749 diff -urN linux-2.4.22.org/include/net/inetpeer.h linux-2.4.22/include/net/inetpeer.h
15750 --- linux-2.4.22.org/include/net/inetpeer.h     2003-11-22 22:09:27.000000000 +0100
15751 +++ linux-2.4.22/include/net/inetpeer.h 2003-11-22 22:14:10.000000000 +0100
15752 @@ -13,6 +13,7 @@
15753  #include <linux/init.h>
15754  #include <linux/sched.h>
15755  #include <linux/spinlock.h>
15756 +
15757  #include <asm/atomic.h>
15758  
15759  struct inet_peer
15760 @@ -34,6 +35,11 @@
15761  /* can be called with or without local BH being disabled */
15762  struct inet_peer       *inet_getpeer(__u32 daddr, int create);
15763  
15764 +#ifdef CONFIG_GRKERNSEC_RANDID
15765 +extern int grsec_enable_randid;
15766 +extern __u16 ip_randomid(void);
15767 +#endif
15768 +
15769  extern spinlock_t inet_peer_unused_lock;
15770  extern struct inet_peer *inet_peer_unused_head;
15771  extern struct inet_peer **inet_peer_unused_tailp;
15772 @@ -58,7 +64,14 @@
15773         __u16 id;
15774  
15775         spin_lock_bh(&inet_peer_idlock);
15776 -       id = p->ip_id_count++;
15777 +
15778 +#ifdef CONFIG_GRKERNSEC_RANDID
15779 +       if(grsec_enable_randid)
15780 +               id = htons(ip_randomid());
15781 +       else
15782 +#endif
15783 +               id = p->ip_id_count++;
15784 +
15785         spin_unlock_bh(&inet_peer_idlock);
15786         return id;
15787  }
15788 diff -urN linux-2.4.22.org/include/net/ip.h linux-2.4.22/include/net/ip.h
15789 --- linux-2.4.22.org/include/net/ip.h   2003-11-22 22:09:27.000000000 +0100
15790 +++ linux-2.4.22/include/net/ip.h       2003-11-22 22:14:10.000000000 +0100
15791 @@ -64,6 +64,11 @@
15792         void                    (*destructor)(struct sock *);
15793  };
15794  
15795 +#ifdef CONFIG_GRKERNSEC_RANDID
15796 +extern int grsec_enable_randid;
15797 +extern __u16 ip_randomid(void);
15798 +#endif
15799 +
15800  extern struct ip_ra_chain *ip_ra_chain;
15801  extern rwlock_t ip_ra_lock;
15802  
15803 @@ -197,7 +202,13 @@
15804                  * does not change, they drop every other packet in
15805                  * a TCP stream using header compression.
15806                  */
15807 -               iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
15808 +
15809 +#ifdef CONFIG_GRKERNSEC_RANDID
15810 +               if(grsec_enable_randid)
15811 +                       iph->id = htons(ip_randomid());
15812 +               else
15813 +#endif
15814 +                       iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
15815         } else
15816                 __ip_select_ident(iph, dst);
15817  }
15818 diff -urN linux-2.4.22.org/init/main.c linux-2.4.22/init/main.c
15819 --- linux-2.4.22.org/init/main.c        2003-11-22 22:09:07.000000000 +0100
15820 +++ linux-2.4.22/init/main.c    2003-11-22 22:14:10.000000000 +0100
15821 @@ -28,6 +28,7 @@
15822  #include <linux/bootmem.h>
15823  #include <linux/file.h>
15824  #include <linux/tty.h>
15825 +#include <linux/grsecurity.h>
15826  
15827  #include <asm/io.h>
15828  #include <asm/bugs.h>
15829 @@ -113,6 +114,8 @@
15830  extern void ipc_init(void);
15831  #endif
15832  
15833 +extern void grsecurity_init(void);
15834 +
15835  /*
15836   * Boot command-line arguments
15837   */
15838 @@ -568,6 +571,7 @@
15839         do_basic_setup();
15840  
15841         prepare_namespace();
15842 +       grsecurity_init();
15843  
15844         /*
15845          * Ok, we have completed the initial bootup, and
15846 diff -urN linux-2.4.22.org/ipc/msg.c linux-2.4.22/ipc/msg.c
15847 --- linux-2.4.22.org/ipc/msg.c  2003-11-22 22:10:06.000000000 +0100
15848 +++ linux-2.4.22/ipc/msg.c      2003-11-22 22:14:10.000000000 +0100
15849 @@ -22,6 +22,7 @@
15850  #include <linux/init.h>
15851  #include <linux/proc_fs.h>
15852  #include <linux/list.h>
15853 +#include <linux/grsecurity.h>
15854  #include <asm/uaccess.h>
15855  #include "util.h"
15856  
15857 @@ -326,6 +327,9 @@
15858                 msg_unlock(id);
15859         }
15860         up(&msg_ids.sem);
15861 +
15862 +       gr_log_msgget(ret, msgflg);
15863 +
15864         return ret;
15865  }
15866  
15867 @@ -560,6 +564,8 @@
15868                 break;
15869         }
15870         case IPC_RMID:
15871 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
15872 +
15873                 freeque (msqid); 
15874                 break;
15875         }
15876 diff -urN linux-2.4.22.org/ipc/sem.c linux-2.4.22/ipc/sem.c
15877 --- linux-2.4.22.org/ipc/sem.c  2003-11-22 22:10:06.000000000 +0100
15878 +++ linux-2.4.22/ipc/sem.c      2003-11-22 22:14:10.000000000 +0100
15879 @@ -63,6 +63,7 @@
15880  #include <linux/init.h>
15881  #include <linux/proc_fs.h>
15882  #include <linux/time.h>
15883 +#include <linux/grsecurity.h>
15884  #include <asm/uaccess.h>
15885  #include "util.h"
15886  
15887 @@ -182,6 +183,9 @@
15888         }
15889  
15890         up(&sem_ids.sem);
15891 +
15892 +       gr_log_semget(err, semflg);
15893 +
15894         return err;
15895  }
15896  
15897 @@ -724,6 +728,8 @@
15898  
15899         switch(cmd){
15900         case IPC_RMID:
15901 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
15902 +
15903                 freeary(semid);
15904                 err = 0;
15905                 break;
15906 diff -urN linux-2.4.22.org/ipc/shm.c linux-2.4.22/ipc/shm.c
15907 --- linux-2.4.22.org/ipc/shm.c  2003-11-22 22:10:06.000000000 +0100
15908 +++ linux-2.4.22/ipc/shm.c      2003-11-22 22:14:10.000000000 +0100
15909 @@ -23,6 +23,7 @@
15910  #include <linux/mman.h>
15911  #include <linux/proc_fs.h>
15912  #include <asm/uaccess.h>
15913 +#include <linux/grsecurity.h>
15914  
15915  #include "util.h"
15916  
15917 @@ -38,8 +39,21 @@
15918         time_t                  shm_ctim;
15919         pid_t                   shm_cprid;
15920         pid_t                   shm_lprid;
15921 +
15922 +#ifdef CONFIG_GRKERNSEC
15923 +       time_t                  shm_createtime;
15924 +       pid_t                   shm_lapid;
15925 +#endif
15926  };
15927  
15928 +#ifdef CONFIG_GRKERNSEC
15929 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
15930 +                           const time_t shm_createtime, const uid_t cuid,
15931 +                           const int shmid);
15932 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
15933 +                    const time_t shm_createtime);
15934 +#endif
15935 +
15936  #define shm_flags      shm_perm.mode
15937  
15938  static struct file_operations shm_file_operations;
15939 @@ -209,6 +223,9 @@
15940         shp->shm_lprid = 0;
15941         shp->shm_atim = shp->shm_dtim = 0;
15942         shp->shm_ctim = CURRENT_TIME;
15943 +#ifdef CONFIG_GRKERNSEC
15944 +       shp->shm_createtime = CURRENT_TIME;
15945 +#endif
15946         shp->shm_segsz = size;
15947         shp->shm_nattch = 0;
15948         shp->id = shm_buildid(id,shp->shm_perm.seq);
15949 @@ -254,6 +271,9 @@
15950                 shm_unlock(id);
15951         }
15952         up(&shm_ids.sem);
15953 +
15954 +       gr_log_shmget(err, shmflg, size);
15955 +
15956         return err;
15957  }
15958  
15959 @@ -509,6 +529,9 @@
15960                         err=-EPERM;
15961                         goto out_unlock_up;
15962                 }
15963 +
15964 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
15965 +
15966                 if (shp->shm_nattch){
15967                         shp->shm_flags |= SHM_DEST;
15968                         /* Do not find it any more */
15969 @@ -622,9 +645,28 @@
15970                 shm_unlock(shmid);
15971                 return -EACCES;
15972         }
15973 +
15974 +#ifdef CONFIG_GRKERNSEC
15975 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
15976 +                            shp->shm_perm.cuid, shmid)) {
15977 +               shm_unlock(shmid);
15978 +               return -EACCES;
15979 +       }
15980 +
15981 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
15982 +               shm_unlock(shmid);
15983 +               return -EACCES;
15984 +       }
15985 +#endif
15986 +
15987         file = shp->shm_file;
15988         size = file->f_dentry->d_inode->i_size;
15989         shp->shm_nattch++;
15990 +
15991 +#ifdef CONFIG_GRKERNSEC
15992 +       shp->shm_lapid = current->pid;
15993 +#endif
15994 +
15995         shm_unlock(shmid);
15996  
15997         down_write(&current->mm->mmap_sem);
15998 diff -urN linux-2.4.22.org/kernel/capability.c linux-2.4.22/kernel/capability.c
15999 --- linux-2.4.22.org/kernel/capability.c        2003-11-22 22:09:08.000000000 +0100
16000 +++ linux-2.4.22/kernel/capability.c    2003-11-22 22:14:10.000000000 +0100
16001 @@ -7,6 +7,7 @@
16002  
16003  #include <linux/mm.h>
16004  #include <asm/uaccess.h>
16005 +#include <linux/grsecurity.h>
16006  
16007  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
16008  
16009 @@ -170,6 +171,10 @@
16010               target = current;
16011       }
16012  
16013 +     if (gr_handle_chroot_capset(target)) {
16014 +            error = -ESRCH;
16015 +            goto out;
16016 +     }
16017  
16018       /* verify restrictions on target's new Inheritable set */
16019       if (!cap_issubset(inheritable,
16020 diff -urN linux-2.4.22.org/kernel/exit.c linux-2.4.22/kernel/exit.c
16021 --- linux-2.4.22.org/kernel/exit.c      2003-11-22 22:09:07.000000000 +0100
16022 +++ linux-2.4.22/kernel/exit.c  2003-11-22 22:14:10.000000000 +0100
16023 @@ -7,6 +7,7 @@
16024  #include <linux/config.h>
16025  #include <linux/slab.h>
16026  #include <linux/interrupt.h>
16027 +#include <linux/file.h>
16028  #include <linux/smp_lock.h>
16029  #include <linux/module.h>
16030  #include <linux/completion.h>
16031 @@ -16,6 +17,7 @@
16032  #ifdef CONFIG_BSD_PROCESS_ACCT
16033  #include <linux/acct.h>
16034  #endif
16035 +#include <linux/grsecurity.h>
16036  
16037  #include <asm/uaccess.h>
16038  #include <asm/pgtable.h>
16039 @@ -139,12 +141,21 @@
16040  {
16041         write_lock_irq(&tasklist_lock);
16042  
16043 +#ifdef CONFIG_GRKERNSEC
16044 +       if (current->exec_file) {
16045 +               fput(current->exec_file);
16046 +               current->exec_file = NULL;
16047 +       }
16048 +#endif
16049 +
16050         /* Reparent to init */
16051         REMOVE_LINKS(current);
16052         current->p_pptr = child_reaper;
16053         current->p_opptr = child_reaper;
16054         SET_LINKS(current);
16055  
16056 +       gr_set_kernel_label(current);
16057 +
16058         /* Set the exit signal to SIGCHLD so we signal init on exit */
16059         current->exit_signal = SIGCHLD;
16060  
16061 @@ -485,6 +496,11 @@
16062  #ifdef CONFIG_BSD_PROCESS_ACCT
16063         acct_process(code);
16064  #endif
16065 +#include <linux/grsecurity.h>
16066 +
16067 +       gr_acl_handle_psacct(tsk, code);
16068 +       gr_acl_handle_exit();
16069 +
16070         __exit_mm(tsk);
16071  
16072         lock_kernel();
16073 diff -urN linux-2.4.22.org/kernel/fork.c linux-2.4.22/kernel/fork.c
16074 --- linux-2.4.22.org/kernel/fork.c      2003-11-22 22:09:08.000000000 +0100
16075 +++ linux-2.4.22/kernel/fork.c  2003-11-22 22:14:10.000000000 +0100
16076 @@ -22,6 +22,7 @@
16077  #include <linux/namespace.h>
16078  #include <linux/personality.h>
16079  #include <linux/compiler.h>
16080 +#include <linux/grsecurity.h>
16081  
16082  #include <asm/pgtable.h>
16083  #include <asm/pgalloc.h>
16084 @@ -94,6 +95,10 @@
16085         if (flags & CLONE_PID)
16086                 return current->pid;
16087  
16088 +       pid = gr_random_pid(&lastpid_lock);
16089 +       if (pid)
16090 +               return pid;
16091 +
16092         spin_lock(&lastpid_lock);
16093         beginpid = last_pid;
16094         if((++last_pid) & 0xffff8000) {
16095 @@ -670,6 +675,9 @@
16096          * friends to set the per-user process limit to something lower
16097          * than the amount of processes root is running. -- Rik
16098          */
16099 +
16100 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes));
16101 +
16102         if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
16103                       && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
16104                 goto bad_fork_free;
16105 @@ -753,6 +761,7 @@
16106         retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
16107         if (retval)
16108                 goto bad_fork_cleanup_namespace;
16109 +       gr_copy_label(p);
16110         p->semundo = NULL;
16111         
16112         /* Our parent execution domain becomes current domain
16113 @@ -855,6 +864,9 @@
16114         free_uid(p->user);
16115  bad_fork_free:
16116         free_task_struct(p);
16117 +
16118 +       gr_log_forkfail(retval);
16119 +
16120         goto fork_out;
16121  }
16122  
16123 diff -urN linux-2.4.22.org/kernel/ksyms.c linux-2.4.22/kernel/ksyms.c
16124 --- linux-2.4.22.org/kernel/ksyms.c     2003-11-22 22:09:08.000000000 +0100
16125 +++ linux-2.4.22/kernel/ksyms.c 2003-11-22 22:45:48.000000000 +0100
16126 @@ -51,6 +51,7 @@
16127  #include <linux/dnotify.h>
16128  #include <linux/crc32.h>
16129  #include <linux/firmware.h>
16130 +#include <linux/grsecurity.h>
16131  #include <asm/checksum.h>
16132  
16133  #if defined(CONFIG_PROC_FS)
16134 @@ -632,3 +633,9 @@
16135  /* To match ksyms with System.map */
16136  extern const char _end[];
16137  EXPORT_SYMBOL(_end);
16138 +
16139 +/* grsecurity */
16140 +EXPORT_SYMBOL(gr_is_capable);
16141 +EXPORT_SYMBOL(gr_pid_is_chrooted);
16142 +EXPORT_SYMBOL(gr_learn_resource);
16143 +EXPORT_SYMBOL(gr_set_kernel_label);
16144 diff -urN linux-2.4.22.org/kernel/module.c linux-2.4.22/kernel/module.c
16145 --- linux-2.4.22.org/kernel/module.c    2003-11-22 22:09:07.000000000 +0100
16146 +++ linux-2.4.22/kernel/module.c        2003-11-22 22:14:10.000000000 +0100
16147 @@ -900,6 +900,11 @@
16148         struct module *mod;
16149         int err;
16150  
16151 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16152 +       if (!capable(CAP_SYS_MODULE))
16153 +               return -EPERM;
16154 +#endif
16155 +
16156         lock_kernel();
16157         if (name_user == NULL)
16158                 mod = &kernel_module;
16159 @@ -969,6 +974,11 @@
16160         int i;
16161         struct kernel_sym ksym;
16162  
16163 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16164 +       if (!capable(CAP_SYS_MODULE))
16165 +               return 0;
16166 +#endif
16167 +
16168         lock_kernel();
16169         for (mod = module_list, i = 0; mod; mod = mod->next) {
16170                 /* include the count for the module name! */
16171 diff -urN linux-2.4.22.org/kernel/printk.c linux-2.4.22/kernel/printk.c
16172 --- linux-2.4.22.org/kernel/printk.c    2003-11-22 22:09:07.000000000 +0100
16173 +++ linux-2.4.22/kernel/printk.c        2003-11-22 22:14:10.000000000 +0100
16174 @@ -27,6 +27,7 @@
16175  #include <linux/interrupt.h>                   /* For in_interrupt() */
16176  #include <linux/config.h>
16177  #include <linux/delay.h>
16178 +#include <linux/grsecurity.h>
16179  
16180  #include <asm/uaccess.h>
16181  
16182 @@ -299,6 +300,11 @@
16183  
16184  asmlinkage long sys_syslog(int type, char * buf, int len)
16185  {
16186 +#ifdef CONFIG_GRKERNSEC_DMESG
16187 +       if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
16188 +               return -EPERM;
16189 +       else
16190 +#endif
16191         if ((type != 3) && !capable(CAP_SYS_ADMIN))
16192                 return -EPERM;
16193         return do_syslog(type, buf, len);
16194 diff -urN linux-2.4.22.org/kernel/sched.c linux-2.4.22/kernel/sched.c
16195 --- linux-2.4.22.org/kernel/sched.c     2003-11-22 22:09:08.000000000 +0100
16196 +++ linux-2.4.22/kernel/sched.c 2003-11-22 22:14:10.000000000 +0100
16197 @@ -25,6 +25,7 @@
16198  #include <asm/mmu_context.h>
16199  #include <linux/kernel_stat.h>
16200  #include <linux/completion.h>
16201 +#include <linux/grsecurity.h>
16202  
16203  /*
16204   * Convert user-nice values [ -20 ... 0 ... 19 ]
16205 @@ -1192,6 +1193,9 @@
16206                         return -EPERM;
16207                 if (increment < -40)
16208                         increment = -40;
16209 +
16210 +               if (gr_handle_chroot_nice())
16211 +                       return -EPERM;
16212         }
16213         if (increment > 40)
16214                 increment = 40;
16215 diff -urN linux-2.4.22.org/kernel/signal.c linux-2.4.22/kernel/signal.c
16216 --- linux-2.4.22.org/kernel/signal.c    2003-11-22 22:09:08.000000000 +0100
16217 +++ linux-2.4.22/kernel/signal.c        2003-11-22 22:14:10.000000000 +0100
16218 @@ -13,6 +13,8 @@
16219  #include <linux/smp_lock.h>
16220  #include <linux/init.h>
16221  #include <linux/sched.h>
16222 +#include <linux/fs.h>
16223 +#include <linux/grsecurity.h>
16224  
16225  #include <asm/uaccess.h>
16226  
16227 @@ -553,6 +555,8 @@
16228         if (!sig || !t->sig)
16229                 goto out_nolock;
16230  
16231 +       gr_log_signal(sig, t);
16232 +
16233         spin_lock_irqsave(&t->sigmask_lock, flags);
16234         handle_stop_signal(sig, t);
16235  
16236 @@ -602,6 +606,8 @@
16237         recalc_sigpending(t);
16238         spin_unlock_irqrestore(&t->sigmask_lock, flags);
16239  
16240 +       gr_handle_crash(t, sig);
16241 +
16242         return send_sig_info(sig, info, t);
16243  }
16244  
16245 @@ -621,9 +627,13 @@
16246                 read_lock(&tasklist_lock);
16247                 for_each_task(p) {
16248                         if (p->pgrp == pgrp && thread_group_leader(p)) {
16249 -                               int err = send_sig_info(sig, info, p);
16250 -                               if (retval)
16251 -                                       retval = err;
16252 +                               if (gr_handle_signal(p, sig))
16253 +                                       retval = -EPERM;
16254 +                               else {
16255 +                                       int err = send_sig_info(sig, info, p);
16256 +                                       if (retval)
16257 +                                               retval = err;
16258 +                               }
16259                         }
16260                 }
16261                 read_unlock(&tasklist_lock);
16262 @@ -674,7 +684,10 @@
16263                         if (tg)
16264                                 p = tg;
16265                  }
16266 -               error = send_sig_info(sig, info, p);
16267 +               if (gr_handle_signal(p, sig))
16268 +                       error = -EPERM;
16269 +               else
16270 +                       error = send_sig_info(sig, info, p);
16271         }
16272         read_unlock(&tasklist_lock);
16273         return error;
16274 @@ -699,10 +712,14 @@
16275                 read_lock(&tasklist_lock);
16276                 for_each_task(p) {
16277                         if (p->pid > 1 && p != current && thread_group_leader(p)) {
16278 -                               int err = send_sig_info(sig, info, p);
16279 -                               ++count;
16280 -                               if (err != -EPERM)
16281 -                                       retval = err;
16282 +                               if (gr_handle_signal(p, sig))
16283 +                                       retval = -EPERM;
16284 +                               else {
16285 +                                       int err = send_sig_info(sig, info, p);
16286 +                                       ++count;
16287 +                                       if (err != -EPERM)
16288 +                                               retval = err;
16289 +                               }
16290                         }
16291                 }
16292                 read_unlock(&tasklist_lock);
16293 diff -urN linux-2.4.22.org/kernel/sys.c linux-2.4.22/kernel/sys.c
16294 --- linux-2.4.22.org/kernel/sys.c       2003-11-22 22:09:07.000000000 +0100
16295 +++ linux-2.4.22/kernel/sys.c   2003-11-22 22:14:10.000000000 +0100
16296 @@ -4,6 +4,7 @@
16297   *  Copyright (C) 1991, 1992  Linus Torvalds
16298   */
16299  
16300 +#include <linux/config.h>
16301  #include <linux/module.h>
16302  #include <linux/mm.h>
16303  #include <linux/utsname.h>
16304 @@ -14,6 +15,7 @@
16305  #include <linux/prctl.h>
16306  #include <linux/init.h>
16307  #include <linux/highuid.h>
16308 +#include <linux/grsecurity.h>
16309  
16310  #include <asm/uaccess.h>
16311  #include <asm/io.h>
16312 @@ -239,6 +241,12 @@
16313                 }
16314                 if (error == -ESRCH)
16315                         error = 0;
16316 +
16317 +               if (gr_handle_chroot_setpriority(p, niceval)) {
16318 +                       read_unlock(&tasklist_lock);
16319 +                       return -ESRCH;
16320 +               }
16321 +
16322                 if (niceval < task_nice(p) && !capable(CAP_SYS_NICE))
16323                         error = -EACCES;
16324                 else
16325 @@ -425,6 +433,9 @@
16326         if (rgid != (gid_t) -1 ||
16327             (egid != (gid_t) -1 && egid != old_rgid))
16328                 current->sgid = new_egid;
16329 +
16330 +       gr_set_role_label(current, current->uid, new_rgid);
16331 +
16332         current->fsgid = new_egid;
16333         current->egid = new_egid;
16334         current->gid = new_rgid;
16335 @@ -447,6 +458,9 @@
16336                         current->mm->dumpable=0;
16337                         wmb();
16338                 }
16339 +
16340 +               gr_set_role_label(current, current->uid, gid);
16341 +
16342                 current->gid = current->egid = current->sgid = current->fsgid = gid;
16343         }
16344         else if ((gid == current->gid) || (gid == current->sgid))
16345 @@ -523,6 +537,9 @@
16346                 current->mm->dumpable = 0;
16347                 wmb();
16348         }
16349 +
16350 +       gr_set_role_label(current, new_ruid, current->gid);
16351 +
16352         current->uid = new_ruid;
16353         return 0;
16354  }
16355 @@ -617,6 +634,9 @@
16356         } else if ((uid != current->uid) && (uid != new_suid))
16357                 return -EPERM;
16358  
16359 +       if (gr_check_crash_uid(uid))
16360 +               return -EPERM;
16361 +
16362         if (old_euid != uid)
16363         {
16364                 current->mm->dumpable = 0;
16365 @@ -713,8 +733,10 @@
16366                 current->egid = egid;
16367         }
16368         current->fsgid = current->egid;
16369 -       if (rgid != (gid_t) -1)
16370 +       if (rgid != (gid_t) -1) {
16371 +               gr_set_role_label(current, current->uid, rgid);
16372                 current->gid = rgid;
16373 +       }
16374         if (sgid != (gid_t) -1)
16375                 current->sgid = sgid;
16376         return 0;
16377 @@ -1137,6 +1159,10 @@
16378         if (new_rlim.rlim_cur > new_rlim.rlim_max)
16379                 return -EINVAL;
16380         old_rlim = current->rlim + resource;
16381 +
16382 +       if (old_rlim->rlim_max < old_rlim->rlim_cur)
16383 +               return -EINVAL;
16384 +
16385         if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
16386              (new_rlim.rlim_max > old_rlim->rlim_max)) &&
16387             !capable(CAP_SYS_RESOURCE))
16388 diff -urN linux-2.4.22.org/kernel/sysctl.c linux-2.4.22/kernel/sysctl.c
16389 --- linux-2.4.22.org/kernel/sysctl.c    2003-11-22 22:09:08.000000000 +0100
16390 +++ linux-2.4.22/kernel/sysctl.c        2003-11-22 22:14:10.000000000 +0100
16391 @@ -39,6 +39,15 @@
16392  #endif
16393  
16394  #if defined(CONFIG_SYSCTL)
16395 +#include <linux/grsecurity.h>
16396 +#include <linux/grinternal.h>
16397 +
16398 +extern int gr_proc_handler(ctl_table * table, int write, struct file * filp,
16399 +                          void * buffer, size_t * lenp);
16400 +extern __u32 gr_handle_sysctl(const ctl_table * table, const void *oldval,
16401 +                             const void *newval);
16402 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op);
16403 +extern int gr_handle_chroot_sysctl(const int op);
16404  
16405  /* External variables not in a header file. */
16406  extern int panic_timeout;
16407 @@ -130,6 +139,8 @@
16408  static ctl_table dev_table[];
16409  extern ctl_table random_table[];
16410  
16411 +static ctl_table grsecurity_table[];
16412 +
16413  /* /proc declarations: */
16414  
16415  #ifdef CONFIG_PROC_FS
16416 @@ -278,8 +289,191 @@
16417         {KERN_EXCEPTION_TRACE,"exception-trace",
16418          &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
16419  #endif 
16420 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16421 +       {KERN_GRSECURITY, "grsecurity", NULL, 0, 0500, grsecurity_table},
16422 +#endif
16423 +       {0}
16424 +};
16425 +
16426 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16427 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL, 
16428 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
16429 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
16430 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS, 
16431 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS, 
16432 +GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
16433 +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
16434 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
16435 +GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
16436 +GS_FINDTASK, GS_LOCK};
16437 +
16438 +static ctl_table grsecurity_table[] = {
16439 +#ifdef CONFIG_GRKERNSEC_LINK
16440 +       {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int),
16441 +        0600, NULL, &proc_dointvec}, 
16442 +#endif
16443 +#ifdef CONFIG_GRKERNSEC_FIFO
16444 +       {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int),
16445 +        0600, NULL, &proc_dointvec},
16446 +#endif
16447 +#ifdef CONFIG_GRKERNSEC_EXECVE
16448 +       {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int),
16449 +        0600, NULL, &proc_dointvec},
16450 +#endif
16451 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16452 +       {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int),
16453 +        0600, NULL, &proc_dointvec},
16454 +#endif
16455 +#ifdef CONFIG_GRKERNSEC_SIGNAL
16456 +       {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int),
16457 +        0600, NULL, &proc_dointvec},
16458 +#endif
16459 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16460 +       {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int),
16461 +        0600, NULL, &proc_dointvec},
16462 +#endif
16463 +#ifdef CONFIG_GRKERNSEC_TIME
16464 +       {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int),
16465 +        0600, NULL, &proc_dointvec},
16466 +#endif
16467 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16468 +       {GS_CHROOT_SHMAT, "chroot_deny_shmat", &grsec_enable_chroot_shmat, sizeof (int),
16469 +        0600, NULL, &proc_dointvec},
16470 +#endif
16471 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16472 +       {GS_CHROOT_UNIX, "chroot_deny_unix", &grsec_enable_chroot_unix, sizeof(int),
16473 +        0600, NULL, &proc_dointvec},
16474 +#endif
16475 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16476 +       {GS_CHROOT_MNT, "chroot_deny_mount", &grsec_enable_chroot_mount, sizeof (int),
16477 +        0600, NULL, &proc_dointvec},
16478 +#endif
16479 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16480 +       {GS_CHROOT_FCHDIR, "chroot_deny_fchdir", &grsec_enable_chroot_fchdir, sizeof (int),
16481 +        0600, NULL, &proc_dointvec},
16482 +#endif
16483 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16484 +       {GS_CHROOT_DBL, "chroot_deny_chroot", &grsec_enable_chroot_double, sizeof (int),
16485 +        0600, NULL, &proc_dointvec},
16486 +#endif
16487 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16488 +       {GS_CHROOT_PVT, "chroot_deny_pivot", &grsec_enable_chroot_pivot, sizeof (int),
16489 +        0600, NULL, &proc_dointvec},
16490 +#endif
16491 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16492 +       {GS_CHROOT_CD, "chroot_enforce_chdir", &grsec_enable_chroot_chdir, sizeof (int),
16493 +        0600, NULL, &proc_dointvec},
16494 +#endif
16495 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16496 +       {GS_CHROOT_CM, "chroot_deny_chmod", &grsec_enable_chroot_chmod, sizeof (int),
16497 +        0600, NULL, &proc_dointvec},
16498 +#endif
16499 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16500 +       {GS_CHROOT_MK, "chroot_deny_mknod", &grsec_enable_chroot_mknod, sizeof (int),
16501 +        0600, NULL, &proc_dointvec},
16502 +#endif
16503 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16504 +       {GS_CHROOT_NI, "chroot_restrict_nice", &grsec_enable_chroot_nice, sizeof (int),
16505 +        0600, NULL, &proc_dointvec},
16506 +#endif
16507 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16508 +       {GS_CHROOT_EXECLOG, "chroot_execlog",
16509 +        &grsec_enable_chroot_execlog, sizeof (int),
16510 +         0600, NULL, &proc_dointvec},
16511 +#endif
16512 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16513 +       {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int),
16514 +        0600, NULL, &proc_dointvec},
16515 +#endif
16516 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16517 +       {GS_CHROOT_SYSCTL, "chroot_deny_sysctl", &grsec_enable_chroot_sysctl, sizeof (int),
16518 +        0600, NULL, &proc_dointvec},
16519 +#endif
16520 +#ifdef CONFIG_GRKERNSEC_TPE
16521 +       {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int),
16522 +        0600, NULL, &proc_dointvec},
16523 +       {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int),
16524 +        0600, NULL, &proc_dointvec},
16525 +#endif
16526 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16527 +       {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int),
16528 +        0600, NULL, &proc_dointvec},
16529 +#endif
16530 +#ifdef CONFIG_GRKERNSEC_RANDPID
16531 +       {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int),
16532 +        0600, NULL, &proc_dointvec},
16533 +#endif
16534 +#ifdef CONFIG_GRKERNSEC_RANDID
16535 +       {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int),
16536 +        0600, NULL, &proc_dointvec},
16537 +#endif
16538 +#ifdef CONFIG_GRKERNSEC_RANDSRC
16539 +       {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int),
16540 +        0600, NULL, &proc_dointvec},
16541 +#endif
16542 +#ifdef CONFIG_GRKERNSEC_RANDISN
16543 +       {GS_RANDISN, "rand_isns", &grsec_enable_randisn, sizeof (int),
16544 +        0600, NULL, &proc_dointvec},
16545 +#endif
16546 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
16547 +       {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int),
16548 +        0600, NULL, &proc_dointvec},
16549 +       {GS_SOCKET_ALL_GID, "socket_all_gid",
16550 +        &grsec_socket_all_gid, sizeof (int),
16551 +        0600, NULL, &proc_dointvec},
16552 +#endif
16553 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16554 +       {GS_SOCKET_CLIENT, "socket_client", 
16555 +        &grsec_enable_socket_client, sizeof (int),
16556 +        0600, NULL, &proc_dointvec},
16557 +       {GS_SOCKET_CLIENT_GID, "socket_client_gid", 
16558 +        &grsec_socket_client_gid, sizeof (int),
16559 +        0600, NULL, &proc_dointvec},
16560 +#endif
16561 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16562 +       {GS_SOCKET_SERVER, "socket_server", 
16563 +        &grsec_enable_socket_server, sizeof (int),
16564 +        0600, NULL, &proc_dointvec},
16565 +       {GS_SOCKET_SERVER_GID, "socket_server_gid",
16566 +        &grsec_socket_server_gid, sizeof (int),
16567 +        0600, NULL, &proc_dointvec},
16568 +#endif
16569 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
16570 +       {GS_GROUP, "audit_group", &grsec_enable_group, sizeof (int),
16571 +        0600, NULL, &proc_dointvec},
16572 +       {GS_GID, "audit_gid",
16573 +        &grsec_audit_gid, sizeof (int),
16574 +        0600, NULL, &proc_dointvec},
16575 +#endif
16576 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16577 +       {GS_ACHDIR, "audit_chdir", &grsec_enable_chdir, sizeof (int),
16578 +        0600, NULL, &proc_dointvec},
16579 +#endif
16580 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16581 +       {GS_AMOUNT, "audit_mount", &grsec_enable_mount, sizeof (int),
16582 +        0600, NULL, &proc_dointvec},
16583 +#endif
16584 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16585 +       {GS_AIPC, "audit_ipc", &grsec_enable_audit_ipc, sizeof (int),
16586 +        0600, NULL, &proc_dointvec},
16587 +#endif
16588 +#ifdef CONFIG_GRKERNSEC_DMESG
16589 +       {GS_AIPC, "dmesg", &grsec_enable_dmesg, sizeof (int),
16590 +        0600, NULL, &proc_dointvec},
16591 +#endif
16592 +#ifdef CONFIG_GRKERNSEC_RANDRPC
16593 +       {GS_RANDRPC, "rand_rpc", &grsec_enable_randrpc, sizeof (int),
16594 +        0600, NULL, &proc_dointvec},
16595 +#endif
16596 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16597 +       {GS_FINDTASK, "chroot_findtask", &grsec_enable_chroot_findtask, 
16598 +        sizeof (int), 0600, NULL, &proc_dointvec},
16599 +#endif
16600 +       {GS_LOCK, "grsec_lock", &grsec_lock, sizeof (int), 0600, NULL,
16601 +        &proc_dointvec},
16602         {0}
16603  };
16604 +#endif
16605  
16606  static ctl_table vm_table[] = {
16607         {VM_GFP_DEBUG, "vm_gfp_debug", 
16608 @@ -432,6 +626,11 @@
16609  
16610  static inline int ctl_perm(ctl_table *table, int op)
16611  {
16612 +       if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
16613 +               return -EACCES;
16614 +       if (gr_handle_chroot_sysctl(op))
16615 +               return -EACCES;
16616 +
16617         return test_perm(table->mode, op);
16618  }
16619  
16620 @@ -465,6 +664,10 @@
16621                                 table = table->child;
16622                                 goto repeat;
16623                         }
16624 +
16625 +                       if (!gr_handle_sysctl(table, oldval, newval))
16626 +                               return -EACCES;
16627 +
16628                         error = do_sysctl_strategy(table, name, nlen,
16629                                                    oldval, oldlenp,
16630                                                    newval, newlen, context);
16631 diff -urN linux-2.4.22.org/kernel/time.c linux-2.4.22/kernel/time.c
16632 --- linux-2.4.22.org/kernel/time.c      2003-11-22 22:09:07.000000000 +0100
16633 +++ linux-2.4.22/kernel/time.c  2003-11-22 22:14:11.000000000 +0100
16634 @@ -27,6 +27,7 @@
16635  #include <linux/mm.h>
16636  #include <linux/timex.h>
16637  #include <linux/smp_lock.h>
16638 +#include <linux/grsecurity.h>
16639  
16640  #include <asm/uaccess.h>
16641  
16642 @@ -89,6 +90,9 @@
16643         time_maxerror = NTP_PHASE_LIMIT;
16644         time_esterror = NTP_PHASE_LIMIT;
16645         write_unlock_irq(&xtime_lock);
16646 +
16647 +       gr_log_timechange();
16648 +
16649         return 0;
16650  }
16651  
16652 @@ -167,6 +171,8 @@
16653                  * globally block out interrupts when it runs.
16654                  */
16655                 do_settimeofday(tv);
16656 +
16657 +               gr_log_timechange();
16658         }
16659         return 0;
16660  }
16661 diff -urN linux-2.4.22.org/kernel/timer.c linux-2.4.22/kernel/timer.c
16662 --- linux-2.4.22.org/kernel/timer.c     2003-11-22 22:09:08.000000000 +0100
16663 +++ linux-2.4.22/kernel/timer.c 2003-11-22 22:14:11.000000000 +0100
16664 @@ -565,6 +565,9 @@
16665  
16666         psecs = (p->times.tms_utime += user);
16667         psecs += (p->times.tms_stime += system);
16668 +
16669 +       gr_learn_resource(p, RLIMIT_CPU, psecs / HZ);
16670 +
16671         if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
16672                 /* Send SIGXCPU every second.. */
16673                 if (!(psecs % HZ))
16674 diff -urN linux-2.4.22.org/Makefile linux-2.4.22/Makefile
16675 --- linux-2.4.22.org/Makefile   2003-11-22 22:13:00.000000000 +0100
16676 +++ linux-2.4.22/Makefile       2003-11-22 22:14:06.000000000 +0100
16677 @@ -134,9 +134,10 @@
16678  
16679  CORE_FILES     =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
16680  NETWORKS       =net/network.o
16681 +GRSECURITY     =grsecurity/grsec.o
16682  
16683  LIBS           =$(TOPDIR)/lib/lib.a
16684 -SUBDIRS                =kernel drivers mm fs net ipc lib crypto
16685 +SUBDIRS                =kernel drivers mm fs net ipc lib crypto grsecurity
16686  
16687  DRIVERS-n :=
16688  DRIVERS-y :=
16689 @@ -280,7 +281,7 @@
16690  
16691  export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
16692  
16693 -export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
16694 +export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS GRSECURITY
16695  
16696  .S.s:
16697         $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
16698 @@ -299,6 +300,7 @@
16699                 $(CORE_FILES) \
16700                 $(DRIVERS) \
16701                 $(NETWORKS) \
16702 +               $(GRSECURITY) \
16703                 $(LIBS) \
16704                 --end-group \
16705                 -o vmlinux
16706 diff -urN linux-2.4.22.org/mm/filemap.c linux-2.4.22/mm/filemap.c
16707 --- linux-2.4.22.org/mm/filemap.c       2003-11-22 22:09:09.000000000 +0100
16708 +++ linux-2.4.22/mm/filemap.c   2003-11-22 22:14:11.000000000 +0100
16709 @@ -2316,6 +2316,12 @@
16710         }
16711         if (!mapping->a_ops->readpage)
16712                 return -ENOEXEC;
16713 +
16714 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
16715 +       if (current->flags & PF_PAX_PAGEEXEC)
16716 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
16717 +#endif
16718 +
16719         UPDATE_ATIME(inode);
16720         vma->vm_ops = &generic_file_vm_ops;
16721         return 0;
16722 @@ -2600,6 +2606,7 @@
16723         error = -EIO;
16724         rlim_rss = current->rlim ?  current->rlim[RLIMIT_RSS].rlim_cur :
16725                                 LONG_MAX; /* default: see resource.h */
16726 +       gr_learn_resource(current, RLIMIT_RSS, vma->vm_mm->rss + (end - start));
16727         if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
16728                 return error;
16729  
16730 @@ -3083,6 +3090,7 @@
16731         err = -EFBIG;
16732         
16733         if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
16734 +               gr_learn_resource(current, RLIMIT_FSIZE, pos);
16735                 if (pos >= limit) {
16736                         send_sig(SIGXFSZ, current, 0);
16737                         goto out;
16738 @@ -3118,6 +3126,7 @@
16739          */
16740          
16741         if (!S_ISBLK(inode->i_mode)) {
16742 +               gr_learn_resource(current, RLIMIT_FSIZE, *count + (u32)pos);
16743                 if (pos >= inode->i_sb->s_maxbytes)
16744                 {
16745                         if (*count || pos > inode->i_sb->s_maxbytes) {
16746 diff -urN linux-2.4.22.org/mm/memory.c linux-2.4.22/mm/memory.c
16747 --- linux-2.4.22.org/mm/memory.c        2003-11-22 22:09:09.000000000 +0100
16748 +++ linux-2.4.22/mm/memory.c    2003-11-22 22:14:11.000000000 +0100
16749 @@ -925,6 +925,65 @@
16750         establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
16751  }
16752  
16753 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16754 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
16755 + *
16756 + * mm->page_table_lock is held on entry and is not released on exit or inside
16757 + * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
16758 + */
16759 +static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
16760 +       unsigned long address, pte_t *pte)
16761 +{
16762 +       unsigned long address_m;
16763 +       struct vm_area_struct * vma_m = NULL;
16764 +       pte_t * pte_m, entry_m;
16765 +       struct page * page_m;
16766 +
16767 +       if (!(vma->vm_flags & VM_MIRROR))
16768 +               return;
16769 +
16770 +       address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16771 +       vma_m = find_vma(mm, address_m);
16772 +       if (!vma_m || vma_m->vm_start != address_m)
16773 +               return;
16774 +
16775 +       address_m = address + (unsigned long)vma->vm_private_data;
16776 +
16777 +       {
16778 +               pgd_t *pgd_m;
16779 +               pmd_t *pmd_m;
16780 +
16781 +               pgd_m = pgd_offset(mm, address_m);
16782 +               pmd_m = pmd_offset(pgd_m, address_m);
16783 +               pte_m = pte_offset(pmd_m, address_m);
16784 +       }
16785 +
16786 +       if (pte_present(*pte_m)) {
16787 +               flush_cache_page(vma_m, address_m);
16788 +               flush_icache_page(vma_m, pte_page(*pte_m));
16789 +       }
16790 +       entry_m = ptep_get_and_clear(pte_m);
16791 +       if (pte_present(entry_m))
16792 +               flush_tlb_page(vma_m, address_m);  
16793 +
16794 +       if (pte_none(entry_m)) {
16795 +               ++mm->rss;
16796 +       } else if (pte_present(entry_m)) {
16797 +               page_cache_release(pte_page(entry_m));
16798 +       } else {
16799 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
16800 +               ++mm->rss;
16801 +       }
16802 +
16803 +       page_m = pte_page(*pte);
16804 +       page_cache_get(page_m);
16805 +       entry_m = mk_pte(page_m, vma_m->vm_page_prot);
16806 +       if (pte_write(*pte))
16807 +               entry_m = pte_mkdirty(pte_mkwrite(entry_m));
16808 +       establish_pte(vma_m, address_m, pte_m, entry_m);  
16809 +}                      
16810 +#endif
16811 +
16812  /*
16813   * This routine handles present pages, when users try to write
16814   * to a shared page. It is done by copying the page to a new address
16815 @@ -988,6 +1047,11 @@
16816  
16817                 /* Free the old page.. */
16818                 new_page = old_page;
16819 +
16820 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16821 +               pax_mirror_fault(mm, vma, address, page_table);
16822 +#endif
16823 +
16824         }
16825         spin_unlock(&mm->page_table_lock);
16826         page_cache_release(new_page);
16827 @@ -1065,6 +1129,7 @@
16828  
16829  do_expand:
16830         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
16831 +       gr_learn_resource(current, RLIMIT_FSIZE, offset);
16832         if (limit != RLIM_INFINITY && offset > limit)
16833                 goto out_sig;
16834         if (offset > inode->i_sb->s_maxbytes)
16835 @@ -1178,6 +1243,11 @@
16836  
16837         /* No need to invalidate - it was non-present before */
16838         update_mmu_cache(vma, address, pte);
16839 +
16840 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16841 +       pax_mirror_fault(mm, vma, address, page_table);
16842 +#endif
16843 +
16844         spin_unlock(&mm->page_table_lock);
16845         return ret;
16846  }
16847 @@ -1223,6 +1293,11 @@
16848  
16849         /* No need to invalidate - it was non-present before */
16850         update_mmu_cache(vma, addr, entry);
16851 +
16852 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16853 +       pax_mirror_fault(mm, vma, addr, page_table);
16854 +#endif
16855 +
16856         spin_unlock(&mm->page_table_lock);
16857         return 1;       /* Minor fault */
16858  
16859 @@ -1304,6 +1379,11 @@
16860  
16861         /* no need to invalidate: a not-present page shouldn't be cached */
16862         update_mmu_cache(vma, address, entry);
16863 +
16864 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16865 +       pax_mirror_fault(mm, vma, address, page_table);
16866 +#endif
16867 +
16868         spin_unlock(&mm->page_table_lock);
16869         return 2;       /* Major fault */
16870  }
16871 @@ -1368,6 +1448,11 @@
16872         pgd_t *pgd;
16873         pmd_t *pmd;
16874  
16875 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16876 +       unsigned long address_m = 0UL;
16877 +       struct vm_area_struct * vma_m = NULL;
16878 +#endif
16879 +
16880         current->state = TASK_RUNNING;
16881         pgd = pgd_offset(mm, address);
16882  
16883 @@ -1376,6 +1461,47 @@
16884          * and the SMP-safe atomic PTE updates.
16885          */
16886         spin_lock(&mm->page_table_lock);
16887 +
16888 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16889 +       if (vma->vm_flags & VM_MIRROR) {
16890 +               pgd_t *pgd_m;
16891 +               pmd_t *pmd_m;
16892 +               pte_t *pte_m;
16893 +
16894 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16895 +               vma_m = find_vma(mm, address_m);
16896 +
16897 +               /* PaX: sanity checks */
16898 +               if (!vma_m) {
16899 +                       spin_unlock(&mm->page_table_lock);
16900 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
16901 +                              address, vma, address_m, vma_m);
16902 +                       return 0;
16903 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
16904 +                          vma_m->vm_start != address_m ||
16905 +                          vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
16906 +               {
16907 +                       spin_unlock(&mm->page_table_lock);
16908 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
16909 +                               address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
16910 +                       return 0;
16911 +               }
16912 +
16913 +               address_m = address + (unsigned long)vma->vm_private_data;
16914 +               pgd_m = pgd_offset(mm, address_m);
16915 +               pmd_m = pmd_alloc(mm, pgd_m, address_m);
16916 +               if (!pmd_m) {
16917 +                       spin_unlock(&mm->page_table_lock);
16918 +                       return -1;
16919 +               }
16920 +               pte_m = pte_alloc(mm, pmd_m, address_m);
16921 +               if (!pte_m) {
16922 +                       spin_unlock(&mm->page_table_lock);
16923 +                       return -1;
16924 +               }
16925 +       }                       
16926 +#endif
16927 +
16928         pmd = pmd_alloc(mm, pgd, address);
16929  
16930         if (pmd) {
16931 diff -urN linux-2.4.22.org/mm/mlock.c linux-2.4.22/mm/mlock.c
16932 --- linux-2.4.22.org/mm/mlock.c 2003-11-22 22:09:09.000000000 +0100
16933 +++ linux-2.4.22/mm/mlock.c     2003-11-22 22:14:11.000000000 +0100
16934 @@ -114,9 +114,35 @@
16935         return 0;
16936  }
16937  
16938 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16939 +static int __mlock_fixup(struct vm_area_struct * vma,
16940 +       unsigned long start, unsigned long end, unsigned int newflags);
16941  static int mlock_fixup(struct vm_area_struct * vma, 
16942         unsigned long start, unsigned long end, unsigned int newflags)
16943  {
16944 +       if (vma->vm_flags & VM_MIRROR) {
16945 +               struct vm_area_struct * vma_m;
16946 +               unsigned long start_m, end_m;
16947 +
16948 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16949 +               vma_m = find_vma(vma->vm_mm, start_m);
16950 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
16951 +                       start_m = start + (unsigned long)vma->vm_private_data;
16952 +                       end_m = end + (unsigned long)vma->vm_private_data;
16953 +                       __mlock_fixup(vma_m, start_m, end_m, newflags);
16954 +               } else
16955 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
16956 +       }
16957 +       return __mlock_fixup(vma, start, end, newflags);
16958 +}
16959 +
16960 +static int __mlock_fixup(struct vm_area_struct * vma,
16961 +       unsigned long start, unsigned long end, unsigned int newflags)
16962 +#else
16963 +static int mlock_fixup(struct vm_area_struct * vma,
16964 +       unsigned long start, unsigned long end, unsigned int newflags)
16965 +#endif
16966 +{
16967         int pages, retval;
16968  
16969         if (newflags == vma->vm_flags)
16970 @@ -209,6 +235,7 @@
16971         lock_limit >>= PAGE_SHIFT;
16972  
16973         /* check against resource limits */
16974 +       gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
16975         if (locked > lock_limit)
16976                 goto out;
16977  
16978 @@ -276,6 +303,7 @@
16979         lock_limit >>= PAGE_SHIFT;
16980  
16981         ret = -ENOMEM;
16982 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm);
16983         if (current->mm->total_vm > lock_limit)
16984                 goto out;
16985  
16986 diff -urN linux-2.4.22.org/mm/mmap.c linux-2.4.22/mm/mmap.c
16987 --- linux-2.4.22.org/mm/mmap.c  2003-11-22 22:09:09.000000000 +0100
16988 +++ linux-2.4.22/mm/mmap.c      2003-11-22 22:14:11.000000000 +0100
16989 @@ -14,6 +14,8 @@
16990  #include <linux/file.h>
16991  #include <linux/fs.h>
16992  #include <linux/personality.h>
16993 +#include <linux/random.h>
16994 +#include <linux/grsecurity.h>
16995  
16996  #include <asm/uaccess.h>
16997  #include <asm/pgalloc.h>
16998 @@ -168,6 +170,7 @@
16999  
17000         /* Check against rlimit.. */
17001         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
17002 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data);
17003         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
17004                 goto out;
17005  
17006 @@ -205,6 +208,11 @@
17007                 _trans(prot, PROT_WRITE, VM_WRITE) |
17008                 _trans(prot, PROT_EXEC, VM_EXEC);
17009         flag_bits =
17010 +
17011 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17012 +               _trans(flags, MAP_MIRROR, VM_MIRROR) |
17013 +#endif
17014 +
17015                 _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
17016                 _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
17017                 _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
17018 @@ -401,6 +409,28 @@
17019         int error;
17020         rb_node_t ** rb_link, * rb_parent;
17021  
17022 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17023 +       struct vm_area_struct * vma_m = NULL;
17024 +       
17025 +       if (flags & MAP_MIRROR) {
17026 +               /* PaX: sanity checks, to be removed when proved to be stable */
17027 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
17028 +                       return -EINVAL;
17029 +
17030 +               vma_m = find_vma(mm, pgoff);
17031 +
17032 +               if (!vma_m ||
17033 +                   vma_m->vm_start != pgoff ||
17034 +                   (vma_m->vm_flags & VM_MIRROR) ||
17035 +                   (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
17036 +                       return -EINVAL;
17037 +
17038 +               file = vma_m->vm_file;
17039 +               pgoff = vma_m->vm_pgoff;
17040 +               len = vma_m->vm_end - vma_m->vm_start;
17041 +       }
17042 +#endif
17043 +
17044         if (file && (!file->f_op || !file->f_op->mmap))
17045                 return -ENODEV;
17046  
17047 @@ -433,10 +463,32 @@
17048          */
17049         vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
17050  
17051 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
17052 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
17053 +
17054 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17055 +               if (current->flags & PF_PAX_MPROTECT) {
17056 +                       if (!file || (prot & PROT_WRITE))
17057 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
17058 +                       else
17059 +                               vm_flags &= ~VM_MAYWRITE;
17060 +
17061 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
17062 +                       if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
17063 +                               vma_m->vm_flags &= ~VM_MAYWRITE;
17064 +#endif
17065 +
17066 +               }
17067 +#endif
17068 +
17069 +       }
17070 +#endif
17071 +
17072         /* mlock MCL_FUTURE? */
17073         if (vm_flags & VM_LOCKED) {
17074                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
17075                 locked += len;
17076 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
17077                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
17078                         return -EAGAIN;
17079         }
17080 @@ -481,6 +533,9 @@
17081                 }
17082         }
17083  
17084 +       if (!gr_acl_handle_mmap(file, prot))
17085 +               return -EACCES;
17086 +
17087         /* Clear old maps */
17088  munmap_back:
17089         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
17090 @@ -491,10 +546,16 @@
17091         }
17092  
17093         /* Check against address space limit. */
17094 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17095 +       if (!(vm_flags & VM_MIRROR)) {
17096 +#endif
17097 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
17098         if ((mm->total_vm << PAGE_SHIFT) + len
17099             > current->rlim[RLIMIT_AS].rlim_cur)
17100                 return -ENOMEM;
17101 -
17102 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17103 +       }
17104 +#endif
17105         /* Private writable mapping? Check memory availability.. */
17106         if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
17107             !(flags & MAP_NORESERVE)                             &&
17108 @@ -518,6 +579,13 @@
17109         vma->vm_start = addr;
17110         vma->vm_end = addr + len;
17111         vma->vm_flags = vm_flags;
17112 +
17113 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17114 +       if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
17115 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
17116 +       else
17117 +#endif
17118 +
17119         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
17120         vma->vm_ops = NULL;
17121         vma->vm_pgoff = pgoff;
17122 @@ -546,6 +614,14 @@
17123                         goto free_vma;
17124         }
17125  
17126 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17127 +       if (flags & MAP_MIRROR) {
17128 +               vma_m->vm_flags |= VM_MIRROR;
17129 +               vma_m->vm_private_data = (void *)(vma->vm_start - vma_m->vm_start);
17130 +               vma->vm_private_data = (void *)(vma_m->vm_start - vma->vm_start);
17131 +       }
17132 +#endif
17133 +
17134         /* Can addr have changed??
17135          *
17136          * Answer: Yes, several device drivers can do it in their
17137 @@ -581,6 +657,9 @@
17138                 atomic_inc(&file->f_dentry->d_inode->i_writecount);
17139  
17140  out:   
17141 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17142 +       if (!(flags & MAP_MIRROR))
17143 +#endif
17144         mm->total_vm += len >> PAGE_SHIFT;
17145         if (vm_flags & VM_LOCKED) {
17146                 mm->locked_vm += len >> PAGE_SHIFT;
17147 @@ -617,20 +696,49 @@
17148  {
17149         struct vm_area_struct *vma;
17150  
17151 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17152 +       if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE)
17153 +               return -ENOMEM;
17154 +       else
17155 +#endif
17156 +
17157         if (len > TASK_SIZE)
17158                 return -ENOMEM;
17159  
17160 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
17161 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
17162 +#endif
17163 +
17164         if (addr) {
17165                 addr = PAGE_ALIGN(addr);
17166                 vma = find_vma(current->mm, addr);
17167 +
17168 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17169 +               if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)                
17170 +                       return -ENOMEM;
17171 +#endif
17172 +
17173                 if (TASK_SIZE - len >= addr &&
17174                     (!vma || addr + len <= vma->vm_start))
17175                         return addr;
17176         }
17177         addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
17178  
17179 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
17180 +       /* PaX: randomize base address if requested */
17181 +       if (current->flags & PF_PAX_RANDMMAP)
17182 +               addr += current->mm->delta_mmap;
17183 +#endif
17184 +
17185         for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
17186                 /* At this point:  (!vma || addr < vma->vm_end). */
17187 +
17188 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17189 +               if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)
17190 +                       return -ENOMEM;
17191 +               else
17192 +#endif
17193 +
17194                 if (TASK_SIZE - len < addr)
17195                         return -ENOMEM;
17196                 if (!vma || addr + len <= vma->vm_start)
17197 @@ -792,6 +900,9 @@
17198         struct vm_area_struct *mpnt;
17199         unsigned long end = addr + len;
17200  
17201 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17202 +       if (!(area->vm_flags & VM_MIRROR))
17203 +#endif
17204         area->vm_mm->total_vm -= len >> PAGE_SHIFT;
17205         if (area->vm_flags & VM_LOCKED)
17206                 area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
17207 @@ -917,6 +1028,83 @@
17208         }
17209  }
17210  
17211 +static inline struct vm_area_struct *unmap_vma(struct mm_struct *mm,
17212 +       unsigned long addr, size_t len, struct vm_area_struct *mpnt,
17213 +       struct vm_area_struct *extra)
17214 +{
17215 +       unsigned long st, end, size;
17216 +       struct file *file = NULL;
17217 +
17218 +       st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
17219 +       end = addr+len;
17220 +       end = end > mpnt->vm_end ? mpnt->vm_end : end;
17221 +       size = end - st;
17222 +
17223 +       if (mpnt->vm_flags & VM_DENYWRITE &&
17224 +           (st != mpnt->vm_start || end != mpnt->vm_end) &&
17225 +           (file = mpnt->vm_file) != NULL) {
17226 +               atomic_dec(&file->f_dentry->d_inode->i_writecount);
17227 +       }
17228 +       remove_shared_vm_struct(mpnt);
17229 +       zap_page_range(mm, st, size);
17230 +
17231 +       /*
17232 +        * Fix the mapping, and free the old area if it wasn't reused.
17233 +        */
17234 +       extra = unmap_fixup(mm, mpnt, st, size, extra);
17235 +       if (file)
17236 +               atomic_inc(&file->f_dentry->d_inode->i_writecount);
17237 +       return extra;
17238 +}
17239 +       
17240 +static struct vm_area_struct *unmap_vma_list(struct mm_struct *mm,
17241 +       unsigned long addr, size_t len, struct vm_area_struct *free,
17242 +       struct vm_area_struct *extra, struct vm_area_struct *prev)
17243 +{
17244 +       struct vm_area_struct *mpnt;
17245 +
17246 +       /* Ok - we have the memory areas we should free on the 'free' list,
17247 +        * so release them, and unmap the page range..
17248 +        * If the one of the segments is only being partially unmapped,
17249 +        * it will put new vm_area_struct(s) into the address space.
17250 +        * In that case we have to be careful with VM_DENYWRITE.
17251 +        */
17252 +       while ((mpnt = free) != NULL) {
17253 +               free = free->vm_next;
17254 +               extra = unmap_vma(mm, addr, len, mpnt, extra);
17255 +       }
17256 +
17257 +       free_pgtables(mm, prev, addr, addr+len);
17258 +
17259 +       return extra;
17260 +}
17261 +
17262 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17263 +static struct vm_area_struct *unmap_vma_mirror_list(struct mm_struct *mm,
17264 +       unsigned long addr, size_t len, struct vm_area_struct *free_m,
17265 +       struct vm_area_struct *extra_m)
17266 +{
17267 +       struct vm_area_struct *mpnt, *prev;
17268 +
17269 +       while ((mpnt = free_m) != NULL) {
17270 +               unsigned long addr_m, start, end;
17271 +
17272 +               free_m = free_m->vm_next;
17273 +
17274 +               addr_m = addr - (unsigned long)mpnt->vm_private_data;
17275 +               start = addr_m < mpnt->vm_start ? mpnt->vm_start : addr_m;
17276 +               end = addr_m+len;
17277 +               end = end > mpnt->vm_end ? mpnt->vm_end : end;
17278 +               find_vma_prev(mm, mpnt->vm_start, &prev);
17279 +               extra_m = unmap_vma(mm, addr_m, len, mpnt, extra_m);
17280 +
17281 +               free_pgtables(mm, prev, start, end);
17282 +       }               
17283 +
17284 +       return extra_m;
17285 +}
17286 +#endif
17287 +
17288  /* Munmap is split into 2 main parts -- this part which finds
17289   * what needs doing, and the areas themselves, which do the
17290   * work.  This now handles partial unmappings.
17291 @@ -926,6 +1114,10 @@
17292  {
17293         struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
17294  
17295 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17296 +       struct vm_area_struct *free_m, *extra_m;
17297 +#endif
17298 +
17299         if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr)
17300                 return -EINVAL;
17301  
17302 @@ -958,60 +1150,69 @@
17303         if (!extra)
17304                 return -ENOMEM;
17305  
17306 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17307 +       if (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) { 
17308 +               extra_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
17309 +               if (!extra_m) {
17310 +                       kmem_cache_free(vm_area_cachep, extra);
17311 +                       return -ENOMEM;
17312 +               }
17313 +       } else
17314 +               extra_m = NULL;
17315 +
17316 +       free_m = NULL;
17317 +#endif
17318 +
17319         npp = (prev ? &prev->vm_next : &mm->mmap);
17320         free = NULL;
17321         spin_lock(&mm->page_table_lock);
17322         for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) {
17323 +               mm->map_count--;
17324                 *npp = mpnt->vm_next;
17325                 mpnt->vm_next = free;
17326                 free = mpnt;
17327                 rb_erase(&mpnt->vm_rb, &mm->mm_rb);
17328 +
17329 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17330 +               if (free->vm_flags & VM_MIRROR) {
17331 +                       struct vm_area_struct *mpnt_m, *prev_m, **npp_m;
17332 +                       unsigned long addr_m = free->vm_start + (unsigned long)free->vm_private_data;
17333 +
17334 +                       mm->mmap_cache = NULL;  /* Kill the cache. */
17335 +                       mpnt_m = find_vma_prev(mm, addr_m, &prev_m);
17336 +                       if (mpnt_m && mpnt_m->vm_start == addr_m && (mpnt_m->vm_flags & VM_MIRROR)) {
17337 +                               mm->map_count--;
17338 +                               npp_m = (prev_m ? &prev_m->vm_next : &mm->mmap);
17339 +                               *npp_m = mpnt_m->vm_next;
17340 +                               mpnt_m->vm_next = free_m;
17341 +                               free_m = mpnt_m;
17342 +                               rb_erase(&mpnt_m->vm_rb, &mm->mm_rb);
17343 +                       } else
17344 +                               printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, free->vm_start);
17345 +               }
17346 +#endif
17347 +
17348         }
17349         mm->mmap_cache = NULL;  /* Kill the cache. */
17350         spin_unlock(&mm->page_table_lock);
17351  
17352 -       /* Ok - we have the memory areas we should free on the 'free' list,
17353 -        * so release them, and unmap the page range..
17354 -        * If the one of the segments is only being partially unmapped,
17355 -        * it will put new vm_area_struct(s) into the address space.
17356 -        * In that case we have to be careful with VM_DENYWRITE.
17357 -        */
17358 -       while ((mpnt = free) != NULL) {
17359 -               unsigned long st, end, size;
17360 -               struct file *file = NULL;
17361 -
17362 -               free = free->vm_next;
17363 +       extra = unmap_vma_list(mm, addr, len, free, extra, prev);
17364  
17365 -               st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
17366 -               end = addr+len;
17367 -               end = end > mpnt->vm_end ? mpnt->vm_end : end;
17368 -               size = end - st;
17369 -
17370 -               if (mpnt->vm_flags & VM_DENYWRITE &&
17371 -                   (st != mpnt->vm_start || end != mpnt->vm_end) &&
17372 -                   (file = mpnt->vm_file) != NULL) {
17373 -                       atomic_dec(&file->f_dentry->d_inode->i_writecount);
17374 -               }
17375 -               remove_shared_vm_struct(mpnt);
17376 -               mm->map_count--;
17377 -
17378 -               zap_page_range(mm, st, size);
17379 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17380 +       extra_m = unmap_vma_mirror_list(mm, addr, len, free_m, extra_m);
17381 +#endif
17382  
17383 -               /*
17384 -                * Fix the mapping, and free the old area if it wasn't reused.
17385 -                */
17386 -               extra = unmap_fixup(mm, mpnt, st, size, extra);
17387 -               if (file)
17388 -                       atomic_inc(&file->f_dentry->d_inode->i_writecount);
17389 -       }
17390         validate_mm(mm);
17391  
17392 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17393 +       if (extra_m)
17394 +               kmem_cache_free(vm_area_cachep, extra_m);
17395 +#endif
17396 +
17397         /* Release the extra vma struct if it wasn't used */
17398         if (extra)
17399                 kmem_cache_free(vm_area_cachep, extra);
17400  
17401 -       free_pgtables(mm, prev, addr, addr+len);
17402 -
17403         return 0;
17404  }
17405  
17406 @@ -1020,8 +1221,15 @@
17407         int ret;
17408         struct mm_struct *mm = current->mm;
17409  
17410 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17411 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
17412 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
17413 +               return -EINVAL;
17414 +#endif
17415 +
17416         down_write(&mm->mmap_sem);
17417         ret = do_munmap(mm, addr, len);
17418 +
17419         up_write(&mm->mmap_sem);
17420         return ret;
17421  }
17422 @@ -1051,6 +1259,7 @@
17423         if (mm->def_flags & VM_LOCKED) {
17424                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
17425                 locked += len;
17426 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
17427                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
17428                         return -EAGAIN;
17429         }
17430 @@ -1067,6 +1276,7 @@
17431         }
17432  
17433         /* Check against address space limits *after* clearing old maps... */
17434 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
17435         if ((mm->total_vm << PAGE_SHIFT) + len
17436             > current->rlim[RLIMIT_AS].rlim_cur)
17437                 return -ENOMEM;
17438 @@ -1079,6 +1289,17 @@
17439  
17440         flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
17441  
17442 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
17443 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
17444 +               flags &= ~VM_EXEC;
17445 +
17446 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17447 +               if (current->flags & PF_PAX_MPROTECT)
17448 +                       flags &= ~VM_MAYEXEC;
17449 +#endif
17450 +
17451 +       }
17452 +#endif
17453         /* Can we just expand an old anonymous mapping? */
17454         if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
17455                 goto out;
17456 @@ -1094,6 +1315,12 @@
17457         vma->vm_start = addr;
17458         vma->vm_end = addr + len;
17459         vma->vm_flags = flags;
17460 +
17461 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17462 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
17463 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
17464 +       else
17465 +#endif
17466         vma->vm_page_prot = protection_map[flags & 0x0f];
17467         vma->vm_ops = NULL;
17468         vma->vm_pgoff = 0;
17469 diff -urN linux-2.4.22.org/mm/mprotect.c linux-2.4.22/mm/mprotect.c
17470 --- linux-2.4.22.org/mm/mprotect.c      2003-11-22 22:09:09.000000000 +0100
17471 +++ linux-2.4.22/mm/mprotect.c  2003-11-22 22:14:11.000000000 +0100
17472 @@ -7,6 +7,12 @@
17473  #include <linux/smp_lock.h>
17474  #include <linux/shm.h>
17475  #include <linux/mman.h>
17476 +#include <linux/grsecurity.h>
17477 +
17478 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17479 +#include <linux/elf.h>
17480 +#include <linux/fs.h>
17481 +#endif
17482  
17483  #include <asm/uaccess.h>
17484  #include <asm/pgalloc.h>
17485 @@ -236,9 +242,40 @@
17486         return 0;
17487  }
17488  
17489 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17490 +static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17491 +       unsigned long start, unsigned long end, unsigned int newflags);
17492 +
17493  static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17494         unsigned long start, unsigned long end, unsigned int newflags)
17495  {
17496 +       if (vma->vm_flags & VM_MIRROR) {
17497 +               struct vm_area_struct * vma_m, * prev_m;
17498 +               unsigned long start_m, end_m;
17499 +
17500 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17501 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
17502 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
17503 +                       start_m = start + (unsigned long)vma->vm_private_data;
17504 +                       end_m = end + (unsigned long)vma->vm_private_data;
17505 +                       if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
17506 +                               __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
17507 +                       else
17508 +                               __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
17509 +               } else
17510 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
17511 +       }
17512 +
17513 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
17514 +}
17515 +
17516 +static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17517 +       unsigned long start, unsigned long end, unsigned int newflags)
17518 +#else
17519 +static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17520 +       unsigned long start, unsigned long end, unsigned int newflags)
17521 +#endif
17522 +{
17523         pgprot_t newprot;
17524         int error;
17525  
17526 @@ -246,6 +283,12 @@
17527                 *pprev = vma;
17528                 return 0;
17529         }
17530 +
17531 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17532 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
17533 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
17534 +       else
17535 +#endif
17536         newprot = protection_map[newflags & 0xf];
17537         if (start == vma->vm_start) {
17538                 if (end == vma->vm_end)
17539 @@ -264,6 +307,68 @@
17540         return 0;
17541  }
17542  
17543 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17544 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
17545 + * therefore we'll grant them VM_MAYWRITE once during their life.
17546 + *
17547 + * The checks favor ld-linux.so behaviour which operates on a per ELF segment
17548 + * basis because we want to allow the common case and not the special ones.
17549 + */
17550 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
17551 +{
17552 +       struct elfhdr elf_h;
17553 +       struct elf_phdr elf_p, p_dyn;
17554 +       elf_dyn dyn;
17555 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
17556 +
17557 +#ifndef CONFIG_GRKERNSEC_PAX_NOELFRELOCS
17558 +       if ((vma->vm_start != start) ||
17559 +           !vma->vm_file ||
17560 +           !(vma->vm_flags & VM_MAYEXEC) ||
17561 +           (vma->vm_flags & VM_MAYNOTWRITE))
17562 +#endif
17563 +
17564 +               return;
17565 +
17566 +       if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
17567 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
17568 +
17569 +#ifdef CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
17570 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
17571 +#else
17572 +           elf_h.e_type != ET_DYN ||
17573 +#endif
17574 +
17575 +           !elf_check_arch(&elf_h) ||
17576 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
17577 +           elf_h.e_phnum > j)
17578 +               return;
17579 +
17580 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
17581 +               if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
17582 +                       return;
17583 +               if (elf_p.p_type == PT_DYNAMIC) {
17584 +                       p_dyn = elf_p;
17585 +                       j = i;
17586 +               }
17587 +       }
17588 +       if (elf_h.e_phnum <= j)
17589 +               return;
17590 +
17591 +       i = 0UL;
17592 +       do {
17593 +               if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
17594 +                       return;
17595 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
17596 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
17597 +                       return;
17598 +               }
17599 +               i++;
17600 +       } while (dyn.d_tag != DT_NULL);
17601 +       return;
17602 +}
17603 +#endif
17604 +
17605  long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
17606                  unsigned long prot)
17607  {
17608 @@ -289,6 +394,16 @@
17609         if (!vma || vma->vm_start > start)
17610                 goto out;
17611  
17612 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
17613 +               error = -EACCES;
17614 +               goto out;
17615 +       }
17616 +
17617 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17618 +       if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
17619 +               pax_handle_maywrite(vma, start);
17620 +#endif
17621 +
17622         for (nstart = start ; ; ) {
17623                 unsigned int newflags;
17624                 int last = 0;
17625 @@ -306,6 +421,13 @@
17626                         if (error < 0)
17627                                 goto out;
17628                 }
17629 +
17630 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17631 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
17632 +               if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
17633 +                       newflags &= ~VM_MAYWRITE;
17634 +#endif
17635 +
17636                 if (vma->vm_end > end) {
17637                         error = mprotect_fixup(vma, &prev, nstart, end, newflags);
17638                         goto out;
17639 diff -urN linux-2.4.22.org/mm/mremap.c linux-2.4.22/mm/mremap.c
17640 --- linux-2.4.22.org/mm/mremap.c        2003-11-22 22:09:09.000000000 +0100
17641 +++ linux-2.4.22/mm/mremap.c    2003-11-22 22:14:11.000000000 +0100
17642 @@ -193,7 +193,9 @@
17643                 }
17644  
17645                 do_munmap(current->mm, addr, old_len);
17646 -
17647 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17648 +               if (!(new_vma->vm_flags & VM_MIRROR))
17649 +#endif
17650                 current->mm->total_vm += new_len >> PAGE_SHIFT;
17651                 if (vm_locked) {
17652                         current->mm->locked_vm += new_len >> PAGE_SHIFT;
17653 @@ -232,6 +234,13 @@
17654         old_len = PAGE_ALIGN(old_len);
17655         new_len = PAGE_ALIGN(new_len);
17656  
17657 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17658 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
17659 +           (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
17660 +            old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len))
17661 +               goto out;
17662 +#endif
17663 +
17664         /* new_addr is only valid if MREMAP_FIXED is specified */
17665         if (flags & MREMAP_FIXED) {
17666                 if (new_addr & ~PAGE_MASK)
17667 @@ -242,6 +251,12 @@
17668                 if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
17669                         goto out;
17670  
17671 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17672 +               if ((current->flags & PF_PAX_SEGMEXEC) &&
17673 +                   (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len))
17674 +                       goto out;
17675 +#endif
17676 +
17677                 /* Check if the location we're moving into overlaps the
17678                  * old location at all, and fail if it does.
17679                  */
17680 @@ -272,6 +287,13 @@
17681         vma = find_vma(current->mm, addr);
17682         if (!vma || vma->vm_start > addr)
17683                 goto out;
17684 +
17685 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17686 +       if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
17687 +           (vma->vm_flags & VM_MIRROR))
17688 +               return -EINVAL;
17689 +#endif
17690 +
17691         /* We can't remap across vm area boundaries */
17692         if (old_len > vma->vm_end - addr)
17693                 goto out;
17694 @@ -283,13 +305,22 @@
17695                 unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
17696                 locked += new_len - old_len;
17697                 ret = -EAGAIN;
17698 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
17699                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
17700                         goto out;
17701         }
17702         ret = -ENOMEM;
17703 +
17704 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17705 +       if (!(vma->vm_flags & VM_MIRROR)) {
17706 +#endif   
17707 +       gr_learn_resource(current, RLIMIT_AS, (current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len));
17708         if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
17709             > current->rlim[RLIMIT_AS].rlim_cur)
17710                 goto out;
17711 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17712 +       }
17713 +#endif
17714         /* Private writable mapping? Check memory availability.. */
17715         if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
17716             !(flags & MAP_NORESERVE)                             &&
17717 @@ -311,6 +342,9 @@
17718                         spin_lock(&vma->vm_mm->page_table_lock);
17719                         vma->vm_end = addr + new_len;
17720                         spin_unlock(&vma->vm_mm->page_table_lock);
17721 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17722 +                       if (!(vma->vm_flags & VM_MIRROR))
17723 +#endif   
17724                         current->mm->total_vm += pages;
17725                         if (vma->vm_flags & VM_LOCKED) {
17726                                 current->mm->locked_vm += pages;
17727 diff -urN linux-2.4.22.org/net/ipv4/af_inet.c linux-2.4.22/net/ipv4/af_inet.c
17728 --- linux-2.4.22.org/net/ipv4/af_inet.c 2003-11-22 22:10:02.000000000 +0100
17729 +++ linux-2.4.22/net/ipv4/af_inet.c     2003-11-22 22:14:11.000000000 +0100
17730 @@ -83,6 +83,7 @@
17731  #include <linux/init.h>
17732  #include <linux/poll.h>
17733  #include <linux/netfilter_ipv4.h>
17734 +#include <linux/grsecurity.h>
17735  
17736  #include <asm/uaccess.h>
17737  #include <asm/system.h>
17738 @@ -374,7 +375,12 @@
17739         else
17740                 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
17741  
17742 -       sk->protinfo.af_inet.id = 0;
17743 +#ifdef CONFIG_GRKERNSEC_RANDID
17744 +       if(grsec_enable_randid)
17745 +               sk->protinfo.af_inet.id = htons(ip_randomid());
17746 +       else
17747 +#endif
17748 +               sk->protinfo.af_inet.id = 0;
17749  
17750         sock_init_data(sock,sk);
17751  
17752 diff -urN linux-2.4.22.org/net/ipv4/icmp.c linux-2.4.22/net/ipv4/icmp.c
17753 --- linux-2.4.22.org/net/ipv4/icmp.c    2003-11-22 22:09:53.000000000 +0100
17754 +++ linux-2.4.22/net/ipv4/icmp.c        2003-11-22 22:14:11.000000000 +0100
17755 @@ -87,6 +87,8 @@
17756  #include <linux/errno.h>
17757  #include <linux/timer.h>
17758  #include <linux/init.h>
17759 +#include <linux/grsecurity.h>
17760 +
17761  #include <asm/system.h>
17762  #include <asm/uaccess.h>
17763  #include <net/checksum.h>
17764 @@ -723,6 +725,7 @@
17765  
17766                 icmp_param.data.icmph=*skb->h.icmph;
17767                 icmp_param.data.icmph.type=ICMP_ECHOREPLY;
17768 +
17769                 icmp_param.skb=skb;
17770                 icmp_param.offset=0;
17771                 icmp_param.data_len=skb->len;
17772 diff -urN linux-2.4.22.org/net/ipv4/ip_output.c linux-2.4.22/net/ipv4/ip_output.c
17773 --- linux-2.4.22.org/net/ipv4/ip_output.c       2003-11-22 22:10:02.000000000 +0100
17774 +++ linux-2.4.22/net/ipv4/ip_output.c   2003-11-22 22:14:11.000000000 +0100
17775 @@ -77,6 +77,7 @@
17776  #include <linux/netfilter_ipv4.h>
17777  #include <linux/mroute.h>
17778  #include <linux/netlink.h>
17779 +#include <linux/grsecurity.h>
17780  
17781  /*
17782   *      Shall we try to damage output packets if routing dev changes?
17783 @@ -514,7 +515,13 @@
17784          *      Begin outputting the bytes.
17785          */
17786  
17787 -       id = sk->protinfo.af_inet.id++;
17788 +#ifdef CONFIG_GRKERNSEC_RANDID
17789 +       if(grsec_enable_randid) { 
17790 +               id = htons(ip_randomid());      
17791 +               sk->protinfo.af_inet.id = htons(ip_randomid());
17792 +       } else
17793 +#endif
17794 +               id = sk->protinfo.af_inet.id++;
17795  
17796         do {
17797                 char *data;
17798 diff -urN linux-2.4.22.org/net/ipv4/netfilter/Config.in linux-2.4.22/net/ipv4/netfilter/Config.in
17799 --- linux-2.4.22.org/net/ipv4/netfilter/Config.in       2003-11-22 22:10:02.000000000 +0100
17800 +++ linux-2.4.22/net/ipv4/netfilter/Config.in   2003-11-22 22:14:11.000000000 +0100
17801 @@ -69,6 +69,7 @@
17802    dep_tristate '  TTL match support' CONFIG_IP_NF_MATCH_TTL $CONFIG_IP_NF_IPTABLES
17803    dep_tristate '  address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES
17804    dep_tristate '  tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES
17805 +  dep_tristate '  stealth match support' CONFIG_IP_NF_MATCH_STEALTH $CONFIG_IP_NF_IPTABLES
17806    dep_tristate '  realm match support' CONFIG_IP_NF_MATCH_REALM $CONFIG_IP_NF_IPTABLES
17807    if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
17808      dep_tristate '  Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES
17809 diff -urN linux-2.4.22.org/net/ipv4/netfilter/ipt_stealth.c linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c
17810 --- linux-2.4.22.org/net/ipv4/netfilter/ipt_stealth.c   1970-01-01 01:00:00.000000000 +0100
17811 +++ linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c       2003-11-22 22:14:11.000000000 +0100
17812 @@ -0,0 +1,109 @@
17813 +/* Kernel module to add stealth support.
17814 + *
17815 + * Copyright (C) 2002 Brad Spengler  <spender@grsecurity.net>
17816 + *
17817 + */
17818 +
17819 +#include <linux/kernel.h>
17820 +#include <linux/module.h>
17821 +#include <linux/skbuff.h>
17822 +#include <linux/net.h>
17823 +#include <linux/sched.h>
17824 +#include <linux/inet.h>
17825 +#include <linux/stddef.h>
17826 +
17827 +#include <net/ip.h>
17828 +#include <net/sock.h>
17829 +#include <net/tcp.h>
17830 +#include <net/udp.h>
17831 +#include <net/route.h>
17832 +#include <net/inet_common.h>
17833 +
17834 +#include <linux/netfilter_ipv4/ip_tables.h>
17835 +
17836 +MODULE_LICENSE("GPL");
17837 +
17838 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
17839 +
17840 +static int
17841 +match(const struct sk_buff *skb,
17842 +      const struct net_device *in,
17843 +      const struct net_device *out,
17844 +      const void *matchinfo,
17845 +      int offset,
17846 +      const void *hdr,
17847 +      u_int16_t datalen,
17848 +      int *hotdrop)
17849 +{
17850 +       struct iphdr *ip = skb->nh.iph;
17851 +       struct tcphdr *th = (struct tcphdr *) hdr;
17852 +       struct udphdr *uh = (struct udphdr *) hdr;
17853 +       struct sock *sk = NULL;
17854 +
17855 +       if (!ip || !hdr || offset) return 0;
17856 +
17857 +       switch(ip->protocol) {
17858 +       case IPPROTO_TCP:
17859 +               if (datalen < sizeof(struct tcphdr)) {
17860 +                       *hotdrop = 1;
17861 +                       return 0;
17862 +               }
17863 +               if (!(th->syn && !th->ack)) return 0;
17864 +               sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th->dest), ((struct rtable*)skb->dst)->rt_iif);    
17865 +               break;
17866 +       case IPPROTO_UDP:
17867 +               if (datalen < sizeof(struct udphdr)) {
17868 +                       *hotdrop = 1;
17869 +                       return 0;
17870 +               }
17871 +               sk = udp_v4_lookup(ip->saddr, uh->source, ip->daddr, uh->dest, skb->dev->ifindex);
17872 +               break;
17873 +       default:
17874 +               return 0;
17875 +       }
17876 +
17877 +       if(!sk) // port is being listened on, match this
17878 +               return 1;
17879 +       else {
17880 +               sock_put(sk);
17881 +               return 0;
17882 +       }
17883 +}
17884 +
17885 +/* Called when user tries to insert an entry of this type. */
17886 +static int
17887 +checkentry(const char *tablename,
17888 +           const struct ipt_ip *ip,
17889 +           void *matchinfo,
17890 +           unsigned int matchsize,
17891 +           unsigned int hook_mask)
17892 +{
17893 +        if (matchsize != IPT_ALIGN(0))
17894 +                return 0;
17895 +
17896 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
17897 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
17898 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
17899 +                       return 1;
17900 +
17901 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
17902 +
17903 +        return 0;
17904 +}
17905 +
17906 +
17907 +static struct ipt_match stealth_match
17908 += { { NULL, NULL }, "stealth", &match, &checkentry, NULL, THIS_MODULE };
17909 +
17910 +static int __init init(void)
17911 +{
17912 +       return ipt_register_match(&stealth_match);
17913 +}
17914 +
17915 +static void __exit fini(void)
17916 +{
17917 +       ipt_unregister_match(&stealth_match);
17918 +}
17919 +
17920 +module_init(init);
17921 +module_exit(fini);
17922 diff -urN linux-2.4.22.org/net/ipv4/netfilter/Makefile linux-2.4.22/net/ipv4/netfilter/Makefile
17923 --- linux-2.4.22.org/net/ipv4/netfilter/Makefile        2003-11-22 22:10:02.000000000 +0100
17924 +++ linux-2.4.22/net/ipv4/netfilter/Makefile    2003-11-22 22:14:11.000000000 +0100
17925 @@ -176,6 +176,7 @@
17926  obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
17927  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
17928  obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
17929 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
17930  
17931  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
17932  
17933 diff -urN linux-2.4.22.org/net/ipv4/tcp_ipv4.c linux-2.4.22/net/ipv4/tcp_ipv4.c
17934 --- linux-2.4.22.org/net/ipv4/tcp_ipv4.c        2003-11-22 22:09:53.000000000 +0100
17935 +++ linux-2.4.22/net/ipv4/tcp_ipv4.c    2003-11-22 22:14:11.000000000 +0100
17936 @@ -67,6 +67,7 @@
17937  #include <linux/inet.h>
17938  #include <linux/stddef.h>
17939  #include <linux/ipsec.h>
17940 +#include <linux/grsecurity.h>
17941  
17942  extern int sysctl_ip_dynaddr;
17943  extern int sysctl_ip_default_ttl;
17944 @@ -223,9 +224,18 @@
17945  
17946                 spin_lock(&tcp_portalloc_lock);
17947                 rover = tcp_port_rover;
17948 -               do {    rover++;
17949 -                       if ((rover < low) || (rover > high))
17950 -                               rover = low;
17951 +                do {
17952 +#ifdef CONFIG_GRKERNSEC_RANDSRC
17953 +                       if (grsec_enable_randsrc && (high > low)) {
17954 +                               rover = low + (get_random_long() % (high - low));
17955 +                       } else
17956 +#endif
17957 +                       {
17958 +                               rover++;
17959 +                               if ((rover < low) || (rover > high))
17960 +                                       rover = low;
17961 +                       }
17962 +
17963                         head = &tcp_bhash[tcp_bhashfn(rover)];
17964                         spin_lock(&head->lock);
17965                         for (tb = head->chain; tb; tb = tb->next)
17966 @@ -548,6 +558,11 @@
17967  
17968  static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
17969  {
17970 +#ifdef CONFIG_GRKERNSEC_RANDISN
17971 +       if (likely(grsec_enable_randisn))
17972 +               return ip_randomisn();
17973 +       else
17974 +#endif
17975         return secure_tcp_sequence_number(skb->nh.iph->daddr,
17976                                           skb->nh.iph->saddr,
17977                                           skb->h.th->dest,
17978 @@ -683,9 +698,16 @@
17979                 rover = tcp_port_rover;
17980  
17981                 do {
17982 -                       rover++;
17983 -                       if ((rover < low) || (rover > high))
17984 -                               rover = low;
17985 +#ifdef CONFIG_GRKERNSEC_RANDSRC
17986 +                       if(grsec_enable_randsrc && (high > low)) {
17987 +                               rover = low + (get_random_long() % (high - low));
17988 +                       } else
17989 +#endif
17990 +                       {
17991 +                               rover++;
17992 +                               if ((rover < low) || (rover > high))
17993 +                                       rover = low;
17994 +                       }
17995                         head = &tcp_bhash[tcp_bhashfn(rover)];
17996                         spin_lock(&head->lock);         
17997  
17998 @@ -846,11 +868,22 @@
17999         if (err)
18000                 goto failure;
18001  
18002 -       if (!tp->write_seq)
18003 +       if (!tp->write_seq) {
18004 +#ifdef CONFIG_GRKERNSEC_RANDISN
18005 +               if (likely(grsec_enable_randisn))
18006 +                       tp->write_seq = ip_randomisn();
18007 +               else
18008 +#endif
18009                 tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
18010                                                            sk->sport, usin->sin_port);
18011 +       }
18012  
18013 -       sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18014 +#ifdef CONFIG_GRKERNSEC_RANDID
18015 +       if(grsec_enable_randid)
18016 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18017 +       else
18018 +#endif
18019 +               sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18020  
18021         err = tcp_connect(sk);
18022         if (err)
18023 @@ -1572,7 +1605,13 @@
18024         newtp->ext_header_len = 0;
18025         if (newsk->protinfo.af_inet.opt)
18026                 newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen;
18027 -       newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18028 +
18029 +#ifdef CONFIG_GRKERNSEC_RANDID
18030 +       if(grsec_enable_randid)
18031 +               newsk->protinfo.af_inet.id = htons(ip_randomid());
18032 +       else
18033 +#endif
18034 +               newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18035  
18036         tcp_sync_mss(newsk, dst->pmtu);
18037         newtp->advmss = dst->advmss;
18038 diff -urN linux-2.4.22.org/net/ipv4/udp.c linux-2.4.22/net/ipv4/udp.c
18039 --- linux-2.4.22.org/net/ipv4/udp.c     2003-11-22 22:09:53.000000000 +0100
18040 +++ linux-2.4.22/net/ipv4/udp.c 2003-11-22 22:14:11.000000000 +0100
18041 @@ -91,6 +91,7 @@
18042  #include <net/ipv6.h>
18043  #include <net/protocol.h>
18044  #include <linux/skbuff.h>
18045 +#include <linux/grsecurity.h>
18046  #include <net/sock.h>
18047  #include <net/udp.h>
18048  #include <net/icmp.h>
18049 @@ -98,6 +99,11 @@
18050  #include <net/inet_common.h>
18051  #include <net/checksum.h>
18052  
18053 +extern int gr_search_udp_recvmsg(const struct sock *sk,
18054 +                                       const struct sk_buff *skb);
18055 +extern int gr_search_udp_sendmsg(const struct sock *sk,
18056 +                                       const struct sockaddr_in *addr);
18057 +
18058  /*
18059   *     Snmp MIB for the UDP layer
18060   */
18061 @@ -480,9 +486,16 @@
18062                 ufh.uh.dest = usin->sin_port;
18063                 if (ufh.uh.dest == 0)
18064                         return -EINVAL;
18065 +
18066 +               if (!gr_search_udp_sendmsg(sk, usin))
18067 +                       return -EPERM;
18068         } else {
18069                 if (sk->state != TCP_ESTABLISHED)
18070                         return -EDESTADDRREQ;
18071 +
18072 +               if (!gr_search_udp_sendmsg(sk, NULL))
18073 +                       return -EPERM;
18074 +
18075                 ufh.daddr = sk->daddr;
18076                 ufh.uh.dest = sk->dport;
18077                 /* Open fast path for connected socket.
18078 @@ -490,6 +503,7 @@
18079                  */
18080                 connected = 1;
18081         }
18082 +
18083         ipc.addr = sk->saddr;
18084         ufh.uh.source = sk->sport;
18085  
18086 @@ -661,6 +675,11 @@
18087         if (!skb)
18088                 goto out;
18089    
18090 +       if (!gr_search_udp_recvmsg(sk, skb)) {
18091 +               err = -EPERM;
18092 +               goto out_free;
18093 +       }
18094 +
18095         copied = skb->len - sizeof(struct udphdr);
18096         if (copied > len) {
18097                 copied = len;
18098 @@ -765,7 +784,13 @@
18099         sk->daddr = rt->rt_dst;
18100         sk->dport = usin->sin_port;
18101         sk->state = TCP_ESTABLISHED;
18102 -       sk->protinfo.af_inet.id = jiffies;
18103 +
18104 +#ifdef CONFIG_GRKERNSEC_RANDID
18105 +       if(grsec_enable_randid)
18106 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18107 +       else
18108 +#endif
18109 +               sk->protinfo.af_inet.id = jiffies;
18110  
18111         sk_dst_set(sk, &rt->u.dst);
18112         return(0);
18113 diff -urN linux-2.4.22.org/net/netlink/af_netlink.c linux-2.4.22/net/netlink/af_netlink.c
18114 --- linux-2.4.22.org/net/netlink/af_netlink.c   2003-11-22 22:10:04.000000000 +0100
18115 +++ linux-2.4.22/net/netlink/af_netlink.c       2003-11-22 22:14:11.000000000 +0100
18116 @@ -40,6 +40,7 @@
18117  #include <linux/proc_fs.h>
18118  #include <linux/smp_lock.h>
18119  #include <linux/notifier.h>
18120 +#include <linux/grsecurity.h>
18121  #include <net/sock.h>
18122  #include <net/scm.h>
18123  
18124 @@ -625,7 +626,8 @@
18125            check them, when this message will be delivered
18126            to corresponding kernel module.   --ANK (980802)
18127          */
18128 -       NETLINK_CB(skb).eff_cap = current->cap_effective;
18129 +
18130 +       NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
18131  
18132         err = -EFAULT;
18133         if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
18134 diff -urN linux-2.4.22.org/net/netsyms.c linux-2.4.22/net/netsyms.c
18135 --- linux-2.4.22.org/net/netsyms.c      2003-11-22 22:10:06.000000000 +0100
18136 +++ linux-2.4.22/net/netsyms.c  2003-11-22 22:14:11.000000000 +0100
18137 @@ -25,6 +25,7 @@
18138  #include <net/checksum.h>
18139  #include <linux/etherdevice.h>
18140  #include <net/route.h>
18141 +#include <linux/grsecurity.h>
18142  #ifdef CONFIG_HIPPI
18143  #include <linux/hippidevice.h>
18144  #endif
18145 @@ -614,6 +615,49 @@
18146  
18147  EXPORT_SYMBOL(softnet_data);
18148  
18149 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
18150 +#if !defined (CONFIG_IPV6_MODULE) && !defined (CONFIG_KHTTPD) && !defined (CONFIG_KHTTPD_MODULE)
18151 +EXPORT_SYMBOL(tcp_v4_lookup_listener);
18152 +#endif
18153 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
18154 +EXPORT_SYMBOL(udp_v4_lookup);
18155 +#endif
18156 +
18157 +#if defined(CONFIG_GRKERNSEC_RANDID)
18158 +EXPORT_SYMBOL(ip_randomid);
18159 +#endif
18160 +#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
18161 +EXPORT_SYMBOL(get_random_long);
18162 +#endif
18163 +#ifdef CONFIG_GRKERNSEC_RANDISN
18164 +EXPORT_SYMBOL(ip_randomisn);
18165 +EXPORT_SYMBOL(grsec_enable_randisn);
18166 +#endif
18167 +#ifdef CONFIG_GRKERNSEC_RANDID
18168 +EXPORT_SYMBOL(grsec_enable_randid);
18169 +#endif
18170 +#ifdef CONFIG_GRKERNSEC_RANDSRC
18171 +EXPORT_SYMBOL(grsec_enable_randsrc);
18172 +#endif
18173 +#ifdef CONFIG_GRKERNSEC_RANDRPC
18174 +EXPORT_SYMBOL(grsec_enable_randrpc);
18175 +#endif
18176 +
18177 +EXPORT_SYMBOL(gr_cap_rtnetlink);
18178 +
18179 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
18180 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
18181 +
18182 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
18183 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
18184 +
18185 +#ifdef CONFIG_UNIX_MODULE
18186 +EXPORT_SYMBOL(gr_acl_handle_unix);
18187 +EXPORT_SYMBOL(gr_acl_handle_mknod);
18188 +EXPORT_SYMBOL(gr_handle_chroot_unix);
18189 +EXPORT_SYMBOL(gr_handle_create);
18190 +#endif
18191 +
18192  #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
18193  #include <net/iw_handler.h>
18194  EXPORT_SYMBOL(wireless_send_event);
18195 diff -urN linux-2.4.22.org/net/socket.c linux-2.4.22/net/socket.c
18196 --- linux-2.4.22.org/net/socket.c       2003-11-22 22:09:53.000000000 +0100
18197 +++ linux-2.4.22/net/socket.c   2003-11-22 22:14:11.000000000 +0100
18198 @@ -85,6 +85,18 @@
18199  #include <net/scm.h>
18200  #include <linux/netfilter.h>
18201  
18202 +extern void gr_attach_curr_ip(const struct sock *sk);
18203 +extern int gr_handle_sock_all(const int family, const int type,
18204 +                             const int protocol);
18205 +extern int gr_handle_sock_server(const struct sockaddr *sck);  
18206 +extern int gr_handle_sock_client(const struct sockaddr *sck);
18207 +extern int gr_search_connect(const struct socket * sock,
18208 +                            const struct sockaddr_in * addr);  
18209 +extern int gr_search_bind(const struct socket * sock,
18210 +                         const struct sockaddr_in * addr);
18211 +extern int gr_search_socket(const int domain, const int type,
18212 +                           const int protocol);
18213 +
18214  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
18215  static ssize_t sock_read(struct file *file, char *buf,
18216                          size_t size, loff_t *ppos);
18217 @@ -699,6 +711,7 @@
18218  
18219  int sock_close(struct inode *inode, struct file *filp)
18220  {
18221 +       struct socket *sock;
18222         /*
18223          *      It was possible the inode is NULL we were 
18224          *      closing an unfinished socket. 
18225 @@ -709,8 +722,21 @@
18226                 printk(KERN_DEBUG "sock_close: NULL inode\n");
18227                 return 0;
18228         }
18229 +       sock = socki_lookup(inode);
18230 +
18231         sock_fasync(-1, filp, 0);
18232 +
18233 +#ifdef CONFIG_GRKERNSEC
18234 +       if (unlikely(current->used_accept && sock->sk &&
18235 +                    (sock->sk->protocol == IPPROTO_TCP) &&
18236 +                    (sock->sk->daddr == current->curr_ip))) {
18237 +               current->used_accept = 0;
18238 +               current->curr_ip = 0;
18239 +       }
18240 +#endif
18241 +
18242         sock_release(socki_lookup(inode));
18243 +
18244         return 0;
18245  }
18246  
18247 @@ -903,6 +929,16 @@
18248         int retval;
18249         struct socket *sock;
18250  
18251 +       if(!gr_search_socket(family, type, protocol)) {
18252 +               retval = -EACCES;
18253 +               goto out;
18254 +       }
18255 +
18256 +       if (gr_handle_sock_all(family, type, protocol)) {
18257 +               retval = -EACCES;
18258 +               goto out;
18259 +       }
18260 +
18261         retval = sock_create(family, type, protocol, &sock);
18262         if (retval < 0)
18263                 goto out;
18264 @@ -998,12 +1034,26 @@
18265  {
18266         struct socket *sock;
18267         char address[MAX_SOCK_ADDR];
18268 +       struct sockaddr * sck;
18269         int err;
18270  
18271         if((sock = sockfd_lookup(fd,&err))!=NULL)
18272         {
18273 -               if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
18274 +               if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
18275 +                       sck = (struct sockaddr *) address;
18276 +
18277 +                       if(!gr_search_bind(sock, (struct sockaddr_in *) sck)) {
18278 +                               sockfd_put(sock);
18279 +                               return -EACCES;
18280 +                       }
18281 +
18282 +                       if (gr_handle_sock_server(sck)) {
18283 +                               sockfd_put(sock);
18284 +                               return -EACCES;
18285 +                       }
18286 +
18287                         err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
18288 +               }
18289                 sockfd_put(sock);
18290         }                       
18291         return err;
18292 @@ -1079,6 +1129,8 @@
18293         if ((err = sock_map_fd(newsock)) < 0)
18294                 goto out_release;
18295  
18296 +       gr_attach_curr_ip(newsock->sk);
18297 +
18298  out_put:
18299         sockfd_put(sock);
18300  out:
18301 @@ -1106,6 +1158,7 @@
18302  {
18303         struct socket *sock;
18304         char address[MAX_SOCK_ADDR];
18305 +       struct sockaddr * sck;
18306         int err;
18307  
18308         sock = sockfd_lookup(fd, &err);
18309 @@ -1114,6 +1167,24 @@
18310         err = move_addr_to_kernel(uservaddr, addrlen, address);
18311         if (err < 0)
18312                 goto out_put;
18313 +
18314 +       sck = (struct sockaddr *) address;
18315 +
18316 +       if (!gr_search_connect(sock, (struct sockaddr_in *) sck)) {
18317 +               err = -EACCES;
18318 +               goto out_put;
18319 +       }
18320 +
18321 +       if (gr_handle_sock_client(sck)) {
18322 +               err = -EACCES;
18323 +               goto out_put;
18324 +       }
18325 +
18326 +#ifdef CONFIG_GRKERNSEC
18327 +       if (sock->sk->protocol == IPPROTO_TCP)
18328 +               current->used_connect = 1;
18329 +#endif
18330 +
18331         err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
18332                                  sock->file->f_flags);
18333  out_put:
18334 @@ -1333,6 +1404,14 @@
18335                 err=sock->ops->shutdown(sock, how);
18336                 sockfd_put(sock);
18337         }
18338 +
18339 +#ifdef CONFIG_GRKERNSEC
18340 +       if (likely(!err && current->used_accept)) {
18341 +               current->used_accept = 0;
18342 +               current->curr_ip = 0;
18343 +       }
18344 +#endif
18345 +
18346         return err;
18347  }
18348  
18349 diff -urN linux-2.4.22.org/net/sunrpc/xprt.c linux-2.4.22/net/sunrpc/xprt.c
18350 --- linux-2.4.22.org/net/sunrpc/xprt.c  2003-11-22 22:10:03.000000000 +0100
18351 +++ linux-2.4.22/net/sunrpc/xprt.c      2003-11-22 22:14:11.000000000 +0100
18352 @@ -59,6 +59,7 @@
18353  #include <linux/unistd.h>
18354  #include <linux/sunrpc/clnt.h>
18355  #include <linux/file.h>
18356 +#include <linux/grsecurity.h>
18357  
18358  #include <net/sock.h>
18359  #include <net/checksum.h>
18360 @@ -1297,6 +1298,12 @@
18361         }
18362         ret = xid++;
18363         spin_unlock(&xid_lock);
18364 +
18365 +#ifdef CONFIG_GRKERNSEC_RANDRPC
18366 +       if (grsec_enable_randrpc)
18367 +               ret = (u32) get_random_long();
18368 +#endif
18369 +
18370         return ret;
18371  }
18372  
18373 diff -urN linux-2.4.22.org/net/unix/af_unix.c linux-2.4.22/net/unix/af_unix.c
18374 --- linux-2.4.22.org/net/unix/af_unix.c 2003-11-22 22:09:53.000000000 +0100
18375 +++ linux-2.4.22/net/unix/af_unix.c     2003-11-22 22:14:11.000000000 +0100
18376 @@ -109,6 +109,7 @@
18377  #include <linux/poll.h>
18378  #include <linux/smp_lock.h>
18379  #include <linux/rtnetlink.h>
18380 +#include <linux/grsecurity.h>
18381  
18382  #include <asm/checksum.h>
18383  
18384 @@ -599,6 +600,11 @@
18385                 if (err)
18386                         goto put_fail;
18387  
18388 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
18389 +                       err = -EACCES;
18390 +                       goto put_fail;
18391 +               }
18392 +               
18393                 err = -ECONNREFUSED;
18394                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
18395                         goto put_fail;
18396 @@ -622,6 +628,13 @@
18397                 if (u) {
18398                         struct dentry *dentry;
18399                         dentry = u->protinfo.af_unix.dentry;
18400 +
18401 +                       if (!gr_handle_chroot_unix(u->peercred.pid)) {
18402 +                               err = -EPERM;
18403 +                               sock_put(u);
18404 +                               goto fail;
18405 +                       }
18406 +
18407                         if (dentry)
18408                                 UPDATE_ATIME(dentry->d_inode);
18409                 } else
18410 @@ -720,9 +733,19 @@
18411                  * All right, let's create it.
18412                  */
18413                 mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask);
18414 +       
18415 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
18416 +                       err = -EACCES;
18417 +                       goto out_mknod_dput;
18418 +               }       
18419 +
18420                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
18421 +
18422                 if (err)
18423                         goto out_mknod_dput;
18424 +
18425 +               gr_handle_create(dentry, nd.mnt);
18426 +
18427                 up(&nd.dentry->d_inode->i_sem);
18428                 dput(nd.dentry);
18429                 nd.dentry = dentry;
18430 @@ -740,6 +763,10 @@
18431                         goto out_unlock;
18432                 }
18433  
18434 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
18435 +               sk->peercred.pid = current->pid;
18436 +#endif
18437 +
18438                 list = &unix_socket_table[addr->hash];
18439         } else {
18440                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
18441 @@ -866,6 +893,9 @@
18442         int st;
18443         int err;
18444         long timeo;
18445 +#ifdef CONFIG_GRKERNSEC
18446 +       struct task_struct *p, **htable;
18447 +#endif
18448  
18449         err = unix_mkname(sunaddr, addr_len, &hash);
18450         if (err < 0)
18451 @@ -989,6 +1019,17 @@
18452         /* Set credentials */
18453         sk->peercred = other->peercred;
18454  
18455 +#ifdef CONFIG_GRKERNSEC
18456 +       read_lock(&tasklist_lock);
18457 +       htable = &pidhash[pid_hashfn(other->peercred.pid)];
18458 +       for (p = *htable; p && p->pid != other->peercred.pid; p = p->pidhash_next);
18459 +       if (p) {
18460 +               p->curr_ip = current->curr_ip;
18461 +               p->used_accept = 1;
18462 +       }
18463 +       read_unlock(&tasklist_lock);
18464 +#endif
18465 +
18466         sock_hold(newsk);
18467         unix_peer(sk)=newsk;
18468         sock->state=SS_CONNECTED;
This page took 1.703203 seconds and 3 git commands to generate.