]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.0-rc4-2.4.25-O1.patch
- replaced by linux-2.4-sfq.patch
[packages/kernel.git] / grsecurity-2.0-rc4-2.4.25-O1.patch
1 diff -urN linux-2.4.24.org/arch/alpha/config.in linux-2.4.24/arch/alpha/config.in
2 --- linux-2.4.24.org/arch/alpha/config.in       2004-02-04 23:08:41.480547776 +0100
3 +++ linux-2.4.24/arch/alpha/config.in   2004-02-04 23:11:31.558184277 +0100
4 @@ -468,3 +468,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.24.org/arch/alpha/kernel/osf_sys.c linux-2.4.24/arch/alpha/kernel/osf_sys.c
18 --- linux-2.4.24.org/arch/alpha/kernel/osf_sys.c        2004-02-04 23:08:43.094212241 +0100
19 +++ linux-2.4.24/arch/alpha/kernel/osf_sys.c    2004-02-04 23:11:31.562183446 +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.24.org/arch/alpha/kernel/ptrace.c linux-2.4.24/arch/alpha/kernel/ptrace.c
84 --- linux-2.4.24.org/arch/alpha/kernel/ptrace.c 2004-02-04 23:08:43.047222012 +0100
85 +++ linux-2.4.24/arch/alpha/kernel/ptrace.c     2004-02-04 23:11:31.566182614 +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.24.org/arch/alpha/mm/fault.c linux-2.4.24/arch/alpha/mm/fault.c
106 --- linux-2.4.24.org/arch/alpha/mm/fault.c      2004-02-04 23:08:42.636307455 +0100
107 +++ linux-2.4.24/arch/alpha/mm/fault.c  2004-02-04 23:11:31.571181575 +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.24.org/arch/arm/config.in linux-2.4.24/arch/arm/config.in
283 --- linux-2.4.24.org/arch/arm/config.in 2004-02-04 23:09:27.053071717 +0100
284 +++ linux-2.4.24/arch/arm/config.in     2004-02-04 23:11:31.577180328 +0100
285 @@ -736,3 +736,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.24.org/arch/cris/config.in linux-2.4.24/arch/cris/config.in
298 --- linux-2.4.24.org/arch/cris/config.in        2004-02-04 23:09:52.816714594 +0100
299 +++ linux-2.4.24/arch/cris/config.in    2004-02-04 23:11:31.579179912 +0100
300 @@ -276,3 +276,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.24.org/arch/i386/boot/bootsect.S linux-2.4.24/arch/i386/boot/bootsect.S
314 --- linux-2.4.24.org/arch/i386/boot/bootsect.S  2004-02-04 23:08:37.059467067 +0100
315 +++ linux-2.4.24/arch/i386/boot/bootsect.S      2004-02-04 23:11:31.582179288 +0100
316 @@ -237,7 +237,7 @@
317  #ifdef __BIG_KERNEL__
318                                         # look in setup.S for bootsect_kludge
319         bootsect_kludge = 0x220         # 0x200 + 0x20 which is the size of the
320 -       lcall   bootsect_kludge         # bootsector + bootsect_kludge offset
321 +       lcall   *bootsect_kludge        # bootsector + bootsect_kludge offset
322  #else
323         movw    %es, %ax
324         subw    $SYSSEG, %ax
325 diff -urN linux-2.4.24.org/arch/i386/boot/setup.S linux-2.4.24/arch/i386/boot/setup.S
326 --- linux-2.4.24.org/arch/i386/boot/setup.S     2004-02-04 23:08:37.024474343 +0100
327 +++ linux-2.4.24/arch/i386/boot/setup.S 2004-02-04 23:11:31.587178249 +0100
328 @@ -637,7 +637,7 @@
329         cmpw    $0, %cs:realmode_swtch
330         jz      rmodeswtch_normal
331  
332 -       lcall   %cs:realmode_swtch
333 +       lcall   *%cs:realmode_swtch
334  
335         jmp     rmodeswtch_end
336  
337 diff -urN linux-2.4.24.org/arch/i386/config.in linux-2.4.24/arch/i386/config.in
338 --- linux-2.4.24.org/arch/i386/config.in        2004-02-04 23:08:41.317581662 +0100
339 +++ linux-2.4.24/arch/i386/config.in    2004-02-04 23:11:31.602175131 +0100
340 @@ -99,6 +99,7 @@
341  fi
342  if [ "$CONFIG_M686" = "y" ]; then
343     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
344 +   define_bool CONFIG_X86_ALIGNMENT_16 y
345     define_bool CONFIG_X86_HAS_TSC y
346     define_bool CONFIG_X86_GOOD_APIC y
347     bool 'PGE extensions (not for Cyrix/Transmeta)' CONFIG_X86_PGE
348 @@ -108,6 +109,7 @@
349  fi
350  if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
351     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
352 +   define_bool CONFIG_X86_ALIGNMENT_16 y
353     define_bool CONFIG_X86_HAS_TSC y
354     define_bool CONFIG_X86_GOOD_APIC y
355     define_bool CONFIG_X86_PGE y
356 @@ -117,6 +119,7 @@
357  fi
358  if [ "$CONFIG_MPENTIUM4" = "y" ]; then
359     define_int  CONFIG_X86_L1_CACHE_SHIFT 7
360 +   define_bool CONFIG_X86_ALIGNMENT_16 y
361     define_bool CONFIG_X86_HAS_TSC y
362     define_bool CONFIG_X86_GOOD_APIC y
363     define_bool CONFIG_X86_PGE y
364 @@ -139,6 +142,7 @@
365  fi
366  if [ "$CONFIG_MK7" = "y" ]; then
367     define_int  CONFIG_X86_L1_CACHE_SHIFT 6
368 +   define_bool CONFIG_X86_ALIGNMENT_16 y
369     define_bool CONFIG_X86_HAS_TSC y
370     define_bool CONFIG_X86_GOOD_APIC y
371     define_bool CONFIG_X86_USE_3DNOW y
372 @@ -493,3 +497,11 @@
373  
374  source crypto/Config.in
375  source lib/Config.in
376 +
377 +mainmenu_option next_comment
378 +comment 'Grsecurity'
379 +bool 'Grsecurity' CONFIG_GRKERNSEC
380 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
381 +       source grsecurity/Config.in
382 +fi
383 +endmenu
384 diff -urN linux-2.4.24.org/arch/i386/kernel/apm.c linux-2.4.24/arch/i386/kernel/apm.c
385 --- linux-2.4.24.org/arch/i386/kernel/apm.c     2004-02-04 23:08:39.082046505 +0100
386 +++ linux-2.4.24/arch/i386/kernel/apm.c 2004-02-04 23:11:31.609173676 +0100
387 @@ -614,7 +614,7 @@
388         __asm__ __volatile__(APM_DO_ZERO_SEGS
389                 "pushl %%edi\n\t"
390                 "pushl %%ebp\n\t"
391 -               "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
392 +               "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
393                 "setc %%al\n\t"
394                 "popl %%ebp\n\t"
395                 "popl %%edi\n\t"
396 @@ -666,7 +666,7 @@
397                 __asm__ __volatile__(APM_DO_ZERO_SEGS
398                         "pushl %%edi\n\t"
399                         "pushl %%ebp\n\t"
400 -                       "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
401 +                       "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
402                         "setc %%bl\n\t"
403                         "popl %%ebp\n\t"
404                         "popl %%edi\n\t"
405 @@ -1985,6 +1985,12 @@
406                  __va((unsigned long)0x40 << 4));
407         _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4));
408  
409 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
410 +       set_base(gdt2[APM_40 >> 3],
411 +               __va((unsigned long)0x40 << 4));
412 +       _set_limit((char *)&gdt2[APM_40 >> 3], 4095 - (0x40 << 4));
413 +#endif
414 +
415         apm_bios_entry.offset = apm_info.bios.offset;
416         apm_bios_entry.segment = APM_CS;
417         set_base(gdt[APM_CS >> 3],
418 @@ -1993,6 +1999,16 @@
419                  __va((unsigned long)apm_info.bios.cseg_16 << 4));
420         set_base(gdt[APM_DS >> 3],
421                  __va((unsigned long)apm_info.bios.dseg << 4));
422 +
423 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
424 +       set_base(gdt2[APM_CS >> 3],
425 +               __va((unsigned long)apm_info.bios.cseg << 4));
426 +       set_base(gdt2[APM_CS_16 >> 3],
427 +               __va((unsigned long)apm_info.bios.cseg_16 << 4));
428 +       set_base(gdt2[APM_DS >> 3],
429 +               __va((unsigned long)apm_info.bios.dseg << 4));
430 +#endif
431 +
432  #ifndef APM_RELAX_SEGMENTS
433         if (apm_info.bios.version == 0x100) {
434  #endif
435 @@ -2002,6 +2018,13 @@
436                 _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
437                 /* For the DEC Hinote Ultra CT475 (and others?) */
438                 _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
439 +
440 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
441 +               _set_limit((char *)&gdt2[APM_CS >> 3], 64 * 1024 - 1);
442 +               _set_limit((char *)&gdt2[APM_CS_16 >> 3], 64 * 1024 - 1);
443 +               _set_limit((char *)&gdt2[APM_DS >> 3], 64 * 1024 - 1);
444 +#endif
445 +
446  #ifndef APM_RELAX_SEGMENTS
447         } else {
448                 _set_limit((char *)&gdt[APM_CS >> 3],
449 @@ -2010,6 +2033,16 @@
450                         (apm_info.bios.cseg_16_len - 1) & 0xffff);
451                 _set_limit((char *)&gdt[APM_DS >> 3],
452                         (apm_info.bios.dseg_len - 1) & 0xffff);
453 +
454 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
455 +               _set_limit((char *)&gdt2[APM_CS >> 3],
456 +                       (apm_info.bios.cseg_len - 1) & 0xffff);
457 +               _set_limit((char *)&gdt2[APM_CS_16 >> 3],
458 +                       (apm_info.bios.cseg_16_len - 1) & 0xffff);
459 +               _set_limit((char *)&gdt2[APM_DS >> 3],
460 +                       (apm_info.bios.dseg_len - 1) & 0xffff);
461 +#endif
462 +
463         }
464  #endif
465  
466 diff -urN linux-2.4.24.org/arch/i386/kernel/entry.S linux-2.4.24/arch/i386/kernel/entry.S
467 --- linux-2.4.24.org/arch/i386/kernel/entry.S   2004-02-04 23:08:39.261009293 +0100
468 +++ linux-2.4.24/arch/i386/kernel/entry.S       2004-02-04 23:11:31.628169726 +0100
469 @@ -211,6 +211,17 @@
470         jae badsys
471         call *SYMBOL_NAME(sys_call_table)(,%eax,4)
472         movl %eax,EAX(%esp)             # save the return value
473 +
474 +#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
475 +       cli                             # need_resched and signals atomic test
476 +       cmpl $0,need_resched(%ebx)
477 +       jne reschedule
478 +       cmpl $0,sigpending(%ebx)
479 +       jne signal_return
480 +       call SYMBOL_NAME(pax_randomize_kstack)
481 +       jmp restore_all
482 +#endif
483 +
484  ENTRY(ret_from_sys_call)
485         cli                             # need_resched and signals atomic test
486         cmpl $0,need_resched(%ebx)
487 @@ -391,8 +402,56 @@
488         jmp error_code
489  
490  ENTRY(page_fault)
491 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
492 +       ALIGN
493 +       pushl $ SYMBOL_NAME(pax_do_page_fault)
494 +#else
495         pushl $ SYMBOL_NAME(do_page_fault)
496 +#endif
497 +
498 +#ifndef CONFIG_GRKERNSEC_PAX_EMUTRAMP
499         jmp error_code
500 +#else
501 +       pushl %ds
502 +       pushl %eax
503 +       xorl %eax,%eax
504 +       pushl %ebp
505 +       pushl %edi
506 +       pushl %esi
507 +       pushl %edx
508 +       decl %eax                       # eax = -1
509 +       pushl %ecx
510 +       pushl %ebx
511 +       cld
512 +       movl %es,%ecx
513 +       movl ORIG_EAX(%esp), %esi       # get the error code
514 +       movl ES(%esp), %edi             # get the function address
515 +       movl %eax, ORIG_EAX(%esp)
516 +       movl %ecx, ES(%esp)
517 +       movl %esp,%edx
518 +       pushl %esi                      # push the error code
519 +       pushl %edx                      # push the pt_regs pointer
520 +       movl $(__KERNEL_DS),%edx
521 +       movl %edx,%ds
522 +       movl %edx,%es
523 +       GET_CURRENT(%ebx)
524 +       call *%edi
525 +       addl $8,%esp
526 +       decl %eax
527 +       jnz ret_from_exception
528 +
529 +       popl %ebx
530 +       popl %ecx
531 +       popl %edx
532 +       popl %esi
533 +       popl %edi
534 +       popl %ebp
535 +       popl %eax
536 +       popl %ds
537 +       popl %es
538 +       addl $4,%esp
539 +       jmp system_call
540 +#endif
541  
542  ENTRY(machine_check)
543         pushl $0
544 @@ -404,7 +463,7 @@
545         pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
546         jmp error_code
547  
548 -.data
549 +.section .rodata, "a"
550  ENTRY(sys_call_table)
551         .long SYMBOL_NAME(sys_ni_syscall)       /* 0  -  old "setup()" system call*/
552         .long SYMBOL_NAME(sys_exit)
553 diff -urN linux-2.4.24.org/arch/i386/kernel/head.S linux-2.4.24/arch/i386/kernel/head.S
554 --- linux-2.4.24.org/arch/i386/kernel/head.S    2004-02-04 23:08:38.925079144 +0100
555 +++ linux-2.4.24/arch/i386/kernel/head.S        2004-02-04 23:11:31.661162867 +0100
556 @@ -41,6 +41,7 @@
557   *
558   * On entry, %esi points to the real-mode code as a 32-bit pointer.
559   */
560 +.global startup_32
561  startup_32:
562  /*
563   * Set segments to known values
564 @@ -86,7 +87,7 @@
565                                    PRESENT+RW+USER */
566  2:     stosl
567         add $0x1000,%eax
568 -       cmp $empty_zero_page-__PAGE_OFFSET,%edi
569 +       cmp $0x00c00007,%eax
570         jne 2b
571  
572  /*
573 @@ -100,9 +101,19 @@
574         movl %eax,%cr0          /* ..and set paging (PG) bit */
575         jmp 1f                  /* flush the prefetch-queue */
576  1:
577 +
578 +#if !defined(CONFIG_GRKERNSEC_PAX_KERNEXEC) || defined(CONFIG_SMP)
579 +
580 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
581 +       orw  %bx,%bx
582 +       jz  1f
583 +#endif
584 +
585         movl $1f,%eax
586         jmp *%eax               /* make sure eip is relocated */
587  1:
588 +#endif
589 +
590         /* Set up the stack pointer */
591         lss stack_start,%esp
592  
593 @@ -121,7 +132,7 @@
594   */
595         xorl %eax,%eax
596         movl $ SYMBOL_NAME(__bss_start),%edi
597 -       movl $ SYMBOL_NAME(_end),%ecx
598 +       movl $ SYMBOL_NAME(__bss_end),%ecx
599         subl %edi,%ecx
600         rep
601         stosb
602 @@ -272,8 +283,6 @@
603         jmp L6                  # main should never return here, but
604                                 # just in case, we know what happens.
605  
606 -ready: .byte 0
607 -
608  /*
609   * We depend on ET to be correct. This checks for 287/387.
610   */
611 @@ -319,13 +328,6 @@
612         jne rp_sidt
613         ret
614  
615 -ENTRY(stack_start)
616 -       .long SYMBOL_NAME(init_task_union)+8192
617 -       .long __KERNEL_DS
618 -
619 -/* This is the default interrupt "handler" :-) */
620 -int_msg:
621 -       .asciz "Unknown interrupt\n"
622         ALIGN
623  ignore_int:
624         cld
625 @@ -347,6 +349,18 @@
626         popl %eax
627         iret
628  
629 +.data
630 +ready: .byte 0
631 +
632 +ENTRY(stack_start)
633 +       .long SYMBOL_NAME(init_task_union)+8192
634 +       .long __KERNEL_DS
635 +
636 +.section .rodata,"a"
637 +/* This is the default interrupt "handler" :-) */
638 +int_msg:
639 +       .asciz "Unknown interrupt\n"
640 +
641  /*
642   * The interrupt descriptor table has room for 256 idt's,
643   * the global descriptor table is dependent on the number
644 @@ -372,41 +386,58 @@
645  SYMBOL_NAME(gdt):
646         .long SYMBOL_NAME(gdt_table)
647  
648 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
649 +.globl SYMBOL_NAME(gdt2)
650 +       .word 0
651 +gdt_descr2:
652 +       .word GDT_ENTRIES*8-1
653 +SYMBOL_NAME(gdt2):
654 +       .long SYMBOL_NAME(gdt_table2)
655 +#endif
656 +
657  /*
658   * This is initialized to create an identity-mapping at 0-8M (for bootup
659   * purposes) and another mapping of the 0-8M area at virtual address
660   * PAGE_OFFSET.
661   */
662 -.org 0x1000
663 +.section .data.swapper_pg_dir,"a"
664  ENTRY(swapper_pg_dir)
665 -       .long 0x00102007
666 -       .long 0x00103007
667 -       .fill BOOT_USER_PGD_PTRS-2,4,0
668 +       .long pg0-__PAGE_OFFSET+7
669 +       .long pg1-__PAGE_OFFSET+7
670 +       .long pg2-__PAGE_OFFSET+7
671 +       .fill BOOT_USER_PGD_PTRS-3,4,0
672         /* default: 766 entries */
673 -       .long 0x00102007
674 -       .long 0x00103007
675 +       .long pg0-__PAGE_OFFSET+7
676 +       .long pg1-__PAGE_OFFSET+7
677 +       .long pg2-__PAGE_OFFSET+7
678         /* default: 254 entries */
679 -       .fill BOOT_KERNEL_PGD_PTRS-2,4,0
680 +       .fill BOOT_KERNEL_PGD_PTRS-3,4,0
681  
682  /*
683   * The page tables are initialized to only 8MB here - the final page
684   * tables are set up later depending on memory size.
685   */
686 -.org 0x2000
687 +.section .data.pg0,"a"
688  ENTRY(pg0)
689 +       .fill 1024,4,0
690  
691 -.org 0x3000
692 +.section .data.pg1,"a"
693  ENTRY(pg1)
694 +       .fill 1024,4,0
695 +
696 +.section .data.pg2,"a"
697 +ENTRY(pg2)
698 +       .fill 1024,4,0
699  
700  /*
701   * empty_zero_page must immediately follow the page tables ! (The
702   * initialization loop counts until empty_zero_page)
703   */
704 -
705 -.org 0x4000
706 +.section .data.empty_zero_page,"a"
707  ENTRY(empty_zero_page)
708 +       .fill 1024,4,0
709  
710 -.org 0x5000
711 +.text
712  
713  /*
714   * Real beginning of normal "text" segment
715 @@ -419,7 +450,7 @@
716   * in the text section because it has alignment requirements
717   * that we cannot fulfill any other way.
718   */
719 -.data
720 +.section .rodata,"a"
721  
722  ALIGN
723  /*
724 @@ -430,19 +461,55 @@
725   */
726  ENTRY(gdt_table)
727         .quad 0x0000000000000000        /* NULL descriptor */
728 -       .quad 0x0000000000000000        /* not used */
729 -       .quad 0x00cf9a000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
730 -       .quad 0x00cf92000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
731 -       .quad 0x00cffa000000ffff        /* 0x23 user   4GB code at 0x00000000 */
732 -       .quad 0x00cff2000000ffff        /* 0x2b user   4GB data at 0x00000000 */
733 +
734 +#if defined(CONFIG_GRKERNSEC_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
735 +       .quad 0x00cf9b000000ffff        /* 0x08 kernel 4GB code at 0x00000000 */
736 +       .quad 0xc0cf9b400000ffff        /* 0x10 kernel 4GB code at 0xc0400000 */
737 +#else
738 +       .quad 0x0000000000000000        /* not used */
739 +       .quad 0x00cf9b000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
740 +#endif
741 +
742 +       .quad 0x00cf93000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
743 +       .quad 0x00cffb000000ffff        /* 0x23 user   4GB code at 0x00000000 */
744 +       .quad 0x00cff3000000ffff        /* 0x2b user   4GB data at 0x00000000 */
745 +       .quad 0x0000000000000000        /* not used */
746 +       .quad 0x0000000000000000        /* not used */
747 +       /*
748 +        * The APM segments have byte granularity and their bases
749 +        * and limits are set at run time.
750 +        */
751 +       .quad 0x0040930000000000        /* 0x40 APM set up for bad BIOS's */
752 +       .quad 0x00409b0000000000        /* 0x48 APM CS    code */
753 +       .quad 0x00009b0000000000        /* 0x50 APM CS 16 code (16 bit) */
754 +       .quad 0x0040930000000000        /* 0x58 APM DS    data */
755 +       .fill NR_CPUS*4,8,0             /* space for TSS's and LDT's */
756 +
757 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
758 +ENTRY(gdt_table2)
759 +       .quad 0x0000000000000000        /* NULL descriptor */
760 +
761 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
762 +       .quad 0x00cf9b000000ffff        /* 0x08 kernel 4GB code at 0x00000000 */
763 +       .quad 0xc0cf9b400000ffff        /* 0x10 kernel 4GB code at 0xc0400000 */
764 +#else
765 +       .quad 0x0000000000000000        /* not used */
766 +       .quad 0x00cf9b000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
767 +#endif
768 +
769 +       .quad 0x00cf93000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
770 +       .quad 0x60c5fb000000ffff        /* 0x23 user 1.5GB code at 0x60000000 */
771 +       .quad 0x00c5f3000000ffff        /* 0x2b user 1.5GB data at 0x00000000 */
772 +
773         .quad 0x0000000000000000        /* not used */
774         .quad 0x0000000000000000        /* not used */
775         /*
776          * The APM segments have byte granularity and their bases
777          * and limits are set at run time.
778          */
779 -       .quad 0x0040920000000000        /* 0x40 APM set up for bad BIOS's */
780 -       .quad 0x00409a0000000000        /* 0x48 APM CS    code */
781 -       .quad 0x00009a0000000000        /* 0x50 APM CS 16 code (16 bit) */
782 -       .quad 0x0040920000000000        /* 0x58 APM DS    data */
783 +       .quad 0x0040930000000000        /* 0x40 APM set up for bad BIOS's */
784 +       .quad 0x00409b0000000000        /* 0x48 APM CS    code */
785 +       .quad 0x00009b0000000000        /* 0x50 APM CS 16 code (16 bit) */
786 +       .quad 0x0040930000000000        /* 0x58 APM DS    data */
787         .fill NR_CPUS*4,8,0             /* space for TSS's and LDT's */
788 +#endif
789 diff -urN linux-2.4.24.org/arch/i386/kernel/i386_ksyms.c linux-2.4.24/arch/i386/kernel/i386_ksyms.c
790 --- linux-2.4.24.org/arch/i386/kernel/i386_ksyms.c      2004-02-04 23:08:38.903083717 +0100
791 +++ linux-2.4.24/arch/i386/kernel/i386_ksyms.c  2004-02-04 23:11:31.666161827 +0100
792 @@ -74,6 +74,9 @@
793  EXPORT_SYMBOL(get_cmos_time);
794  EXPORT_SYMBOL(apm_info);
795  EXPORT_SYMBOL(gdt);
796 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
797 +EXPORT_SYMBOL(gdt2);
798 +#endif
799  EXPORT_SYMBOL(empty_zero_page);
800  
801  #ifdef CONFIG_DEBUG_IOVIRT
802 diff -urN linux-2.4.24.org/arch/i386/kernel/ioport.c linux-2.4.24/arch/i386/kernel/ioport.c
803 --- linux-2.4.24.org/arch/i386/kernel/ioport.c  2004-02-04 23:08:39.226016569 +0100
804 +++ linux-2.4.24/arch/i386/kernel/ioport.c      2004-02-04 23:11:31.669161204 +0100
805 @@ -14,6 +14,7 @@
806  #include <linux/smp.h>
807  #include <linux/smp_lock.h>
808  #include <linux/stddef.h>
809 +#include <linux/grsecurity.h>
810  
811  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
812  static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
813 @@ -59,8 +60,16 @@
814  
815         if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
816                 return -EINVAL;
817 +#ifdef CONFIG_GRKERNSEC_IO
818 +       if (turn_on) {
819 +               gr_handle_ioperm();
820 +#else
821         if (turn_on && !capable(CAP_SYS_RAWIO))
822 +#endif
823                 return -EPERM;
824 +#ifdef CONFIG_GRKERNSEC_IO
825 +       }
826 +#endif
827         /*
828          * If it's the first ioperm() call in this thread's lifetime, set the
829          * IO bitmap up. ioperm() is much less timing critical than clone(),
830 @@ -109,8 +118,13 @@
831                 return -EINVAL;
832         /* Trying to gain more privileges? */
833         if (level > old) {
834 +#ifdef CONFIG_GRKERNSEC_IO
835 +               gr_handle_iopl();
836 +               return -EPERM;
837 +#else
838                 if (!capable(CAP_SYS_RAWIO))
839                         return -EPERM;
840 +#endif
841         }
842         regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
843         return 0;
844 diff -urN linux-2.4.24.org/arch/i386/kernel/ldt.c linux-2.4.24/arch/i386/kernel/ldt.c
845 --- linux-2.4.24.org/arch/i386/kernel/ldt.c     2004-02-04 23:08:40.766696210 +0100
846 +++ linux-2.4.24/arch/i386/kernel/ldt.c 2004-02-04 23:11:31.675159956 +0100
847 @@ -151,7 +151,7 @@
848  {
849         int err;
850         unsigned long size;
851 -       void *address;
852 +       const void *address;
853  
854         err = 0;
855         address = &default_ldt[0];
856 @@ -214,6 +214,13 @@
857                 }
858         }
859  
860 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
861 +       if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
862 +               error = -EINVAL;
863 +               goto out_unlock;
864 +       }
865 +#endif
866 +
867         entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
868                   (ldt_info.limit & 0x0ffff);
869         entry_2 = (ldt_info.base_addr & 0xff000000) |
870 @@ -224,7 +231,7 @@
871                   ((ldt_info.seg_not_present ^ 1) << 15) |
872                   (ldt_info.seg_32bit << 22) |
873                   (ldt_info.limit_in_pages << 23) |
874 -                 0x7000;
875 +                 0x7100;
876         if (!oldmode)
877                 entry_2 |= (ldt_info.useable << 20);
878  
879 diff -urN linux-2.4.24.org/arch/i386/kernel/pci-pc.c linux-2.4.24/arch/i386/kernel/pci-pc.c
880 --- linux-2.4.24.org/arch/i386/kernel/pci-pc.c  2004-02-04 23:08:38.793106585 +0100
881 +++ linux-2.4.24/arch/i386/kernel/pci-pc.c      2004-02-04 23:11:31.678159333 +0100
882 @@ -17,6 +17,7 @@
883  #include <asm/io.h>
884  #include <asm/smp.h>
885  #include <asm/smpboot.h>
886 +#include <asm/desc.h>
887  
888  #include "pci-i386.h"
889  
890 @@ -575,10 +576,16 @@
891   * the array there.
892   */
893  
894 +#if defined(CONFIG_GRKERNSEC_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
895 +#define __FLAT_KERNEL_CS 0x08
896 +#else
897 +#define __FLAT_KERNEL_CS __KERNEL_CS
898 +#endif
899 +
900  static struct {
901         unsigned long address;
902         unsigned short segment;
903 -} bios32_indirect = { 0, __KERNEL_CS };
904 +} bios32_indirect = { 0, __FLAT_KERNEL_CS };
905  
906  /*
907   * Returns the entry point for the given service, NULL on error
908 @@ -619,7 +626,9 @@
909  static struct {
910         unsigned long address;
911         unsigned short segment;
912 -} pci_indirect = { 0, __KERNEL_CS };
913 +} pci_indirect = { 0, __FLAT_KERNEL_CS };
914 +
915 +#undef __FLAT_KERNEL_CS
916  
917  static int pci_bios_present;
918  
919 @@ -1457,6 +1466,7 @@
920         if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
921                 pcibios_sort();
922  #endif
923 +
924  }
925  
926  char * __devinit  pcibios_setup(char *str)
927 diff -urN linux-2.4.24.org/arch/i386/kernel/process.c linux-2.4.24/arch/i386/kernel/process.c
928 --- linux-2.4.24.org/arch/i386/kernel/process.c 2004-02-04 23:08:38.761113238 +0100
929 +++ linux-2.4.24/arch/i386/kernel/process.c     2004-02-04 23:11:31.683158294 +0100
930 @@ -549,7 +549,11 @@
931  {
932         struct pt_regs * childregs;
933  
934 +#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
935 +       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p - sizeof(unsigned long))) - 1;
936 +#else
937         childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
938 +#endif
939         struct_cpy(childregs, regs);
940         childregs->eax = 0;
941         childregs->esp = esp;
942 @@ -610,6 +614,16 @@
943         dump->u_fpvalid = dump_fpu (regs, &dump->i387);
944  }
945  
946 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
947 +void pax_switch_segments(struct task_struct * tsk)
948 +{
949 +       if (tsk->flags & PF_PAX_SEGMEXEC)
950 +               __asm__ __volatile__("lgdt %0": "=m" (gdt_descr2));
951 +       else
952 +               __asm__ __volatile__("lgdt %0": "=m" (gdt_descr));
953 +}
954 +#endif
955 +
956  /*
957   * This special macro can be used to load a debugging register
958   */
959 @@ -649,6 +663,10 @@
960  
961         unlazy_fpu(prev_p);
962  
963 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
964 +       pax_switch_segments(next_p);
965 +#endif
966 +
967         /*
968          * Reload esp0, LDT and the page table pointer:
969          */
970 @@ -791,3 +809,25 @@
971  }
972  #undef last_sched
973  #undef first_sched
974 +
975 +#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
976 +asmlinkage void pax_randomize_kstack(void)
977 +{
978 +       struct tss_struct *tss = init_tss + smp_processor_id();
979 +       unsigned long time;
980 +
981 +       rdtscl(time);
982 +
983 +       /* P4 seems to return a 0 LSB, ignore it */
984 +#ifdef CONFIG_MPENTIUM4
985 +       time &= 0x3EUL;
986 +       time <<= 1;
987 +#else
988 +       time &= 0x1FUL;
989 +       time <<= 2;
990 +#endif
991 +
992 +       current->thread.esp0 ^= time;
993 +       tss->esp0 = current->thread.esp0;
994 +}
995 +#endif
996 diff -urN linux-2.4.24.org/arch/i386/kernel/ptrace.c linux-2.4.24/arch/i386/kernel/ptrace.c
997 --- linux-2.4.24.org/arch/i386/kernel/ptrace.c  2004-02-04 23:08:40.647720949 +0100
998 +++ linux-2.4.24/arch/i386/kernel/ptrace.c      2004-02-04 23:11:31.686157670 +0100
999 @@ -13,6 +13,7 @@
1000  #include <linux/errno.h>
1001  #include <linux/ptrace.h>
1002  #include <linux/user.h>
1003 +#include <linux/grsecurity.h>
1004  
1005  #include <asm/uaccess.h>
1006  #include <asm/pgtable.h>
1007 @@ -177,6 +178,9 @@
1008         if (pid == 1)           /* you may not mess with init */
1009                 goto out_tsk;
1010  
1011 +       if(gr_handle_ptrace(child, request))
1012 +               goto out_tsk;
1013 +
1014         if (request == PTRACE_ATTACH) {
1015                 ret = ptrace_attach(child);
1016                 goto out_tsk;
1017 @@ -256,6 +260,17 @@
1018                           if(addr < (long) &dummy->u_debugreg[4] &&
1019                              ((unsigned long) data) >= TASK_SIZE-3) break;
1020                           
1021 +#ifdef CONFIG_GRKERNSEC
1022 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
1023 +                            addr <= (long) &dummy->u_debugreg[3]){
1024 +                                 long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
1025 +                                 long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
1026 +                                 long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
1027 +                                 if((type & 1) && (data & align))
1028 +                                       break;
1029 +                         }
1030 +#endif
1031 +
1032                           if(addr == (long) &dummy->u_debugreg[7]) {
1033                                   data &= ~DR_CONTROL_RESERVED;
1034                                   for(i=0; i<4; i++)
1035 diff -urN linux-2.4.24.org/arch/i386/kernel/setup.c linux-2.4.24/arch/i386/kernel/setup.c
1036 --- linux-2.4.24.org/arch/i386/kernel/setup.c   2004-02-04 23:08:38.752115109 +0100
1037 +++ linux-2.4.24/arch/i386/kernel/setup.c       2004-02-04 23:13:40.129452734 +0100
1038 @@ -3191,7 +3191,7 @@
1039         set_tss_desc(nr,t);
1040         gdt_table[__TSS(nr)].b &= 0xfffffdff;
1041         load_TR(nr);
1042 -       load_LDT(&init_mm.context);
1043 +       _load_LDT(&init_mm.context);
1044  
1045         /* Clear %fs and %gs. */
1046         asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
1047 diff -urN linux-2.4.24.org/arch/i386/kernel/sys_i386.c linux-2.4.24/arch/i386/kernel/sys_i386.c
1048 --- linux-2.4.24.org/arch/i386/kernel/sys_i386.c        2004-02-04 23:08:39.036056068 +0100
1049 +++ linux-2.4.24/arch/i386/kernel/sys_i386.c    2004-02-04 23:16:10.926100220 +0100
1050 @@ -18,6 +18,7 @@
1051  #include <linux/mman.h>
1052  #include <linux/file.h>
1053  #include <linux/utsname.h>
1054 +#include <linux/grsecurity.h>
1055  
1056  #include <asm/uaccess.h>
1057  #include <asm/ipc.h>
1058 @@ -48,6 +49,11 @@
1059         int error = -EBADF;
1060         struct file * file = NULL;
1061  
1062 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
1063 +       if (flags & MAP_MIRROR)
1064 +               return -EINVAL;
1065 +#endif
1066 +
1067         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1068         if (!(flags & MAP_ANONYMOUS)) {
1069                 file = fget(fd);
1070 @@ -55,8 +61,14 @@
1071                         goto out;
1072         }
1073  
1074 +       if(gr_handle_mmap(file, prot)) {
1075 +               fput(file);
1076 +               error = -EACCES;
1077 +               goto out;
1078 +       }
1079 +       
1080         down_write(&current->mm->mmap_sem);
1081 -       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1082 +       error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
1083         up_write(&current->mm->mmap_sem);
1084  
1085         if (file)
1086 diff -urN linux-2.4.24.org/arch/i386/kernel/trampoline.S linux-2.4.24/arch/i386/kernel/trampoline.S
1087 --- linux-2.4.24.org/arch/i386/kernel/trampoline.S      2004-02-04 23:08:40.609728849 +0100
1088 +++ linux-2.4.24/arch/i386/kernel/trampoline.S  2004-02-04 23:11:31.719150810 +0100
1089 @@ -54,7 +54,7 @@
1090         lmsw    %ax             # into protected mode
1091         jmp     flush_instr
1092  flush_instr:
1093 -       ljmpl   $__KERNEL_CS, $0x00100000
1094 +       ljmpl   $__KERNEL_CS, $SYMBOL_NAME(startup_32)-__PAGE_OFFSET
1095                         # jump to startup_32 in arch/i386/kernel/head.S
1096  
1097  idt_48:
1098 diff -urN linux-2.4.24.org/arch/i386/kernel/traps.c linux-2.4.24/arch/i386/kernel/traps.c
1099 --- linux-2.4.24.org/arch/i386/kernel/traps.c   2004-02-04 23:08:39.329994948 +0100
1100 +++ linux-2.4.24/arch/i386/kernel/traps.c       2004-02-04 23:11:31.723149979 +0100
1101 @@ -54,7 +54,7 @@
1102  asmlinkage void lcall7(void);
1103  asmlinkage void lcall27(void);
1104  
1105 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1106 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1107                 { 0, 0 }, { 0, 0 } };
1108  
1109  /*
1110 @@ -228,14 +228,23 @@
1111                 show_stack((unsigned long*)esp);
1112  
1113                 printk("\nCode: ");
1114 +
1115 +#ifndef CONFIG_GRKERNSEC_PAX_KERNEXEC
1116                 if(regs->eip < PAGE_OFFSET)
1117                         goto bad;
1118 +#endif
1119  
1120                 for(i=0;i<20;i++)
1121                 {
1122                         unsigned char c;
1123 +
1124 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1125 +                       if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) {
1126 +#else
1127                         if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
1128  bad:
1129 +#endif
1130 +
1131                                 printk(" Bad EIP value.");
1132                                 break;
1133                         }
1134 @@ -258,8 +267,13 @@
1135  
1136         eip = regs->eip;
1137  
1138 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1139 +       eip += __KERNEL_TEXT_OFFSET;
1140 +#else
1141         if (eip < PAGE_OFFSET)
1142                 goto no_bug;
1143 +#endif
1144 +
1145         if (__get_user(ud2, (unsigned short *)eip))
1146                 goto no_bug;
1147         if (ud2 != 0x0b0f)
1148 @@ -267,7 +281,13 @@
1149         if (__get_user(line, (unsigned short *)(eip + 2)))
1150                 goto bug;
1151         if (__get_user(file, (char **)(eip + 4)) ||
1152 +
1153 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1154 +               __get_user(c, file + __KERNEL_TEXT_OFFSET))
1155 +#else
1156                 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
1157 +#endif
1158 +
1159                 file = "<bad filename>";
1160  
1161         printk("kernel BUG at %s:%d!\n", file, line);
1162 @@ -422,6 +442,13 @@
1163                         regs->eip = fixup;
1164                         return;
1165                 }
1166 +
1167 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1168 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
1169 +                               die("PAX: suspicious general protection fault", regs, error_code);
1170 +               else
1171 +#endif
1172 +
1173                 die("general protection fault", regs, error_code);
1174         }
1175  }
1176 @@ -527,13 +554,12 @@
1177  {
1178         unsigned int condition;
1179         struct task_struct *tsk = current;
1180 -       unsigned long eip = regs->eip;
1181         siginfo_t info;
1182  
1183         __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
1184  
1185         /* If the user set TF, it's simplest to clear it right away. */
1186 -       if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
1187 +       if (!(regs->xcs & 3) && (regs->eflags & TF_MASK) && !(regs->eflags & VM_MASK))
1188                 goto clear_TF;
1189  
1190         /* Mask out spurious debug traps due to lazy DR7 setting */
1191 @@ -826,7 +852,7 @@
1192         _set_gate(idt_table+n,15,3,addr);
1193  }
1194  
1195 -static void __init set_call_gate(void *a, void *addr)
1196 +static void __init set_call_gate(const void *a, void *addr)
1197  {
1198         _set_gate(a,12,3,addr);
1199  }
1200 @@ -852,14 +878,58 @@
1201         "rorl $16,%%eax" \
1202         : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
1203  
1204 -void set_tss_desc(unsigned int n, void *addr)
1205 +void set_tss_desc(unsigned int n, const void *addr)
1206  {
1207         _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
1208 +
1209 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1210 +       _set_tssldt_desc(gdt_table2+__TSS(n), (int)addr, 235, 0x89);
1211 +#endif
1212 +
1213  }
1214  
1215 -void set_ldt_desc(unsigned int n, void *addr, unsigned int size)
1216 +void __set_ldt_desc(unsigned int n, const void *addr, unsigned int size)
1217  {
1218         _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1219 +
1220 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1221 +       _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1222 +#endif
1223 +
1224 +}
1225 +
1226 +void set_ldt_desc(unsigned int n, const void *addr, unsigned int size)
1227 +{
1228 +
1229 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1230 +       unsigned long temp, cr3;
1231 +       pgd_t* pgd;
1232 +       pmd_t* pmd;
1233 +
1234 +       asm("movl %%cr3,%0":"=r" (cr3));
1235 +       for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
1236 +               pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
1237 +               pmd = pmd_offset(pgd, temp);
1238 +               set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_RW));
1239 +       }
1240 +       __flush_tlb_all();
1241 +#endif
1242 +
1243 +       _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1244 +
1245 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1246 +       _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1247 +#endif
1248 +
1249 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1250 +       for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
1251 +               pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
1252 +               pmd = pmd_offset(pgd, temp);
1253 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1254 +       }
1255 +       flush_tlb_all();
1256 +#endif
1257 +
1258  }
1259  
1260  #ifdef CONFIG_X86_VISWS_APIC
1261 diff -urN linux-2.4.24.org/arch/i386/Makefile linux-2.4.24/arch/i386/Makefile
1262 --- linux-2.4.24.org/arch/i386/Makefile 2004-02-04 23:08:36.996480164 +0100
1263 +++ linux-2.4.24/arch/i386/Makefile     2004-02-04 23:11:31.727149147 +0100
1264 @@ -114,6 +114,9 @@
1265  
1266  MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
1267  
1268 +arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE
1269 +       $(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
1270 +
1271  vmlinux: arch/i386/vmlinux.lds
1272  
1273  FORCE: ;
1274 @@ -150,6 +153,7 @@
1275         @$(MAKEBOOT) clean
1276  
1277  archmrproper:
1278 +       rm -f arch/i386/vmlinux.lds
1279  
1280  archdep:
1281         @$(MAKEBOOT) dep
1282 diff -urN linux-2.4.24.org/arch/i386/mm/fault.c linux-2.4.24/arch/i386/mm/fault.c
1283 --- linux-2.4.24.org/arch/i386/mm/fault.c       2004-02-04 23:08:37.895293271 +0100
1284 +++ linux-2.4.24/arch/i386/mm/fault.c   2004-02-04 23:11:31.733147900 +0100
1285 @@ -4,6 +4,7 @@
1286   *  Copyright (C) 1995  Linus Torvalds
1287   */
1288  
1289 +#include <linux/config.h>
1290  #include <linux/signal.h>
1291  #include <linux/sched.h>
1292  #include <linux/kernel.h>
1293 @@ -19,6 +20,8 @@
1294  #include <linux/init.h>
1295  #include <linux/tty.h>
1296  #include <linux/vt_kern.h>             /* For unblank_screen() */
1297 +#include <linux/unistd.h>
1298 +#include <linux/compiler.h>
1299  
1300  #include <asm/system.h>
1301  #include <asm/uaccess.h>
1302 @@ -123,6 +126,10 @@
1303  asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
1304  extern unsigned long idt;
1305  
1306 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
1307 +static int pax_handle_fetch_fault(struct pt_regs *regs);
1308 +#endif
1309 +
1310  /*
1311   * This routine handles page faults.  It determines the address,
1312   * and the problem, and then passes it off to one of the appropriate
1313 @@ -133,23 +140,31 @@
1314   *     bit 1 == 0 means read, 1 means write
1315   *     bit 2 == 0 means kernel, 1 means user-mode
1316   */
1317 -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
1318 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1319 +static int do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
1320 +#else
1321 +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long error_code)
1322 +#endif
1323  {
1324         struct task_struct *tsk;
1325         struct mm_struct *mm;
1326         struct vm_area_struct * vma;
1327 +#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1328         unsigned long address;
1329 +#endif
1330         unsigned long page;
1331         unsigned long fixup;
1332         int write;
1333         siginfo_t info;
1334  
1335 +#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1336         /* get the address */
1337         __asm__("movl %%cr2,%0":"=r" (address));
1338  
1339         /* It's safe to allow irq's after cr2 has been saved */
1340         if (regs->eflags & X86_EFLAGS_IF)
1341                 local_irq_enable();
1342 +#endif
1343  
1344         tsk = current;
1345  
1346 @@ -256,7 +271,7 @@
1347         }
1348         up_read(&mm->mmap_sem);
1349         tsk->in_page_fault = 0;
1350 -       return;
1351 +       return 0;
1352  
1353  /*
1354   * Something tried to access memory that isn't in our memory map..
1355 @@ -268,6 +283,39 @@
1356  
1357         /* User mode accesses just cause a SIGSEGV */
1358         if (error_code & 4) {
1359 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1360 +               if (current->flags & PF_PAX_SEGMEXEC) {
1361 +
1362 +#if defined(CONFIG_GRKERNSEC_PAX_EMUTRAMP) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
1363 +               if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
1364 +                       switch (pax_handle_fetch_fault(regs)) {
1365 +
1366 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1367 +                       case 5:
1368 +                               return 0;
1369 +#endif
1370 +
1371 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1372 +                       case 4:
1373 +                               return 0;
1374 +                       case 3:
1375 +                       case 2:
1376 +                               return 1;
1377 +#endif
1378 +
1379 +                       case 1:
1380 +                       default:
1381 +                       }
1382 +               }
1383 +#endif
1384 +
1385 +                       if (address >= SEGMEXEC_TASK_SIZE) {
1386 +                               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1387 +                               do_exit(SIGKILL);
1388 +                       }
1389 +               }
1390 +#endif
1391 +
1392                 tsk->thread.cr2 = address;
1393                 /* Kernel addresses are always protection faults */
1394                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
1395 @@ -277,7 +325,7 @@
1396                 /* info.si_code has been set above */
1397                 info.si_addr = (void *)address;
1398                 force_sig_info(SIGSEGV, &info, tsk);
1399 -               return;
1400 +               return 0;
1401         }
1402  
1403         /*
1404 @@ -290,7 +338,7 @@
1405  
1406                 if (nr == 6) {
1407                         do_invalid_op(regs, 0);
1408 -                       return;
1409 +                       return 0;
1410                 }
1411         }
1412  
1413 @@ -298,7 +346,7 @@
1414         /* Are we prepared to handle this kernel fault?  */
1415         if ((fixup = search_exception_table(regs->eip)) != 0) {
1416                 regs->eip = fixup;
1417 -               return;
1418 +               return 0;
1419         }
1420  
1421  /*
1422 @@ -311,6 +359,18 @@
1423  
1424         if (address < PAGE_SIZE)
1425                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
1426 +
1427 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1428 +       else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET) {
1429 +               if (tsk->curr_ip)
1430 +                       printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1431 +                                        NIPQUAD(tsk->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1432 +               else
1433 +                       printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1434 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1435 +       }
1436 +#endif
1437 +
1438         else
1439                 printk(KERN_ALERT "Unable to handle kernel paging request");
1440         printk(" at virtual address %08lx\n",address);
1441 @@ -365,7 +425,7 @@
1442         /* Kernel mode? Handle exceptions or die */
1443         if (!(error_code & 4))
1444                 goto no_context;
1445 -       return;
1446 +       return 0;
1447  
1448  vmalloc_fault:
1449         {
1450 @@ -398,6 +458,448 @@
1451                 pte_k = pte_offset(pmd_k, address);
1452                 if (!pte_present(*pte_k))
1453                         goto no_context;
1454 -               return;
1455 +               return 0;
1456         }
1457  }
1458 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1459 +/* PaX: called with the page_table_lock spinlock held */
1460 +static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
1461 +{
1462 +       pgd_t *pgd;
1463 +       pmd_t *pmd;
1464 +
1465 +       pgd = pgd_offset(mm, address);
1466 +       if (!pgd || !pgd_present(*pgd))
1467 +               return 0;
1468 +       pmd = pmd_offset(pgd, address);
1469 +       if (!pmd || !pmd_present(*pmd))
1470 +               return 0;
1471 +       return pte_offset(pmd, address);
1472 +}
1473 +#endif
1474 +
1475 +/*
1476 + * PaX: decide what to do with offenders (regs->eip = fault address)
1477 + *
1478 + * returns 1 when task should be killed
1479 + *         2 when sigreturn trampoline was detected
1480 + *         3 when rt_sigreturn trampoline was detected
1481 + *         4 when gcc trampoline was detected
1482 + *        5 when legitimate ET_EXEC was detected
1483 + */
1484 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
1485 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1486 +{
1487 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1488 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
1489 +#endif
1490 +       int err;
1491 +       
1492 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1493 +       if (current->flags & PF_PAX_RANDEXEC) {
1494 +               unsigned long esp_4;
1495 +               if (regs->eip >= current->mm->start_code &&
1496 +                   regs->eip < current->mm->end_code)
1497 +               {
1498 +                       err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
1499 +                       if (err || esp_4 == regs->eip)
1500 +                               return 1;
1501 +                       regs->eip += current->mm->delta_exec;
1502 +                       return 5;
1503 +               }
1504 +       }
1505 +#endif
1506 +
1507 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1508 +
1509 +#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1510 +       if (!(current->flags & PF_PAX_EMUTRAMP))
1511 +               return 1;
1512 +#endif
1513 +
1514 +       do { /* PaX: sigreturn emulation */
1515 +               unsigned char pop, mov;
1516 +               unsigned short sys;
1517 +               unsigned long nr;
1518 +
1519 +               err = get_user(pop, (unsigned char *)(regs->eip));
1520 +               err |= get_user(mov, (unsigned char *)(regs->eip + 1));
1521 +               err |= get_user(nr, (unsigned long *)(regs->eip + 2));
1522 +               err |= get_user(sys, (unsigned short *)(regs->eip + 6));
1523 +
1524 +               if (err)
1525 +                       break;
1526 +
1527 +               if (pop == 0x58 &&
1528 +                   mov == 0xb8 &&
1529 +                   nr == __NR_sigreturn &&
1530 +                   sys == 0x80cd)
1531 +               {
1532 +
1533 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1534 +                       int sig;
1535 +                       struct k_sigaction *ka;
1536 +                       __sighandler_t handler;
1537 +
1538 +                       if (get_user(sig, (int *)regs->esp))
1539 +                               return 1;
1540 +                       if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
1541 +                               return 1;
1542 +                       ka = &current->sig->action[sig-1];
1543 +                       handler = ka->sa.sa_handler;
1544 +                       if (handler == SIG_DFL || handler == SIG_IGN) {
1545 +                               if (!(current->flags & PF_PAX_EMUTRAMP))
1546 +                                       return 1;
1547 +                       } else if (ka->sa.sa_flags & SA_SIGINFO)
1548 +                               return 1;
1549 +#endif
1550 +
1551 +                       regs->esp += 4;
1552 +                       regs->eax = nr;
1553 +                       regs->eip += 8;
1554 +                       return 2;
1555 +               }
1556 +       } while (0);
1557 +
1558 +       do { /* PaX: rt_sigreturn emulation */
1559 +               unsigned char mov;
1560 +               unsigned short sys;
1561 +               unsigned long nr;
1562 +
1563 +               err = get_user(mov, (unsigned char *)(regs->eip));
1564 +               err |= get_user(nr, (unsigned long *)(regs->eip + 1));
1565 +               err |= get_user(sys, (unsigned short *)(regs->eip + 5));
1566 +
1567 +               if (err)
1568 +                       break;
1569 +
1570 +               if (mov == 0xb8 &&
1571 +                   nr == __NR_rt_sigreturn &&
1572 +                   sys == 0x80cd)
1573 +               {
1574 +
1575 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1576 +                       int sig;
1577 +                       struct k_sigaction *ka;
1578 +                       __sighandler_t handler;
1579 +
1580 +                       if (get_user(sig, (int *)regs->esp))
1581 +                               return 1;
1582 +                       if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
1583 +                               return 1;
1584 +                       ka = &current->sig->action[sig-1];
1585 +                       handler = ka->sa.sa_handler;
1586 +                       if (handler == SIG_DFL || handler == SIG_IGN) {
1587 +                               if (!(current->flags & PF_PAX_EMUTRAMP))
1588 +                                       return 1;
1589 +                       } else if (!(ka->sa.sa_flags & SA_SIGINFO))
1590 +                               return 1;
1591 +#endif
1592 +
1593 +                       regs->eax = nr;
1594 +                       regs->eip += 7;
1595 +                       return 3;
1596 +               }
1597 +       } while (0);
1598 +
1599 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1600 +       if (!(current->flags & PF_PAX_EMUTRAMP))
1601 +               return 1;
1602 +#endif
1603 +
1604 +       do { /* PaX: gcc trampoline emulation #1 */
1605 +               unsigned char mov1, mov2;
1606 +               unsigned short jmp;
1607 +               unsigned long addr1, addr2, ret;
1608 +               unsigned short call;
1609 +
1610 +               err = get_user(mov1, (unsigned char *)regs->eip);
1611 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1612 +               err |= get_user(mov2, (unsigned char *)(regs->eip + 5));
1613 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1614 +               err |= get_user(jmp, (unsigned short *)(regs->eip + 10));
1615 +               err |= get_user(ret, (unsigned long *)regs->esp);
1616 +
1617 +               if (err)
1618 +                       break;
1619 +
1620 +               err = get_user(call, (unsigned short *)(ret-2));
1621 +               if (err)
1622 +                       break;
1623 +
1624 +               if ((mov1 & 0xF8) == 0xB8 &&
1625 +                   (mov2 & 0xF8) == 0xB8 &&
1626 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
1627 +                   (jmp & 0xF8FF) == 0xE0FF &&
1628 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
1629 +                   (call & 0xF8FF) == 0xD0FF &&
1630 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1631 +               {
1632 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
1633 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
1634 +                       regs->eip = addr2;
1635 +                       return 4;
1636 +               }
1637 +       } while (0);
1638 +
1639 +       do { /* PaX: gcc trampoline emulation #2 */
1640 +               unsigned char mov, jmp;
1641 +               unsigned long addr1, addr2, ret;
1642 +               unsigned short call;
1643 +
1644 +               err = get_user(mov, (unsigned char *)regs->eip);
1645 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1646 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1647 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1648 +               err |= get_user(ret, (unsigned long *)regs->esp);
1649 +
1650 +               if (err)
1651 +                       break;
1652 +
1653 +               err = get_user(call, (unsigned short *)(ret-2));
1654 +               if (err)
1655 +                       break;
1656 +
1657 +               if ((mov & 0xF8) == 0xB8 &&
1658 +                   jmp == 0xE9 &&
1659 +                   (call & 0xF8FF) == 0xD0FF &&
1660 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1661 +               {
1662 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1663 +                       regs->eip += addr2 + 10;
1664 +                       return 4;
1665 +               }
1666 +       } while (0);
1667 +
1668 +       do { /* PaX: gcc trampoline emulation #3 */
1669 +               unsigned char mov, jmp;
1670 +               char offset;
1671 +               unsigned long addr1, addr2, ret;
1672 +               unsigned short call;
1673 +
1674 +               err = get_user(mov, (unsigned char *)regs->eip);
1675 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1676 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1677 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1678 +               err |= get_user(ret, (unsigned long *)regs->esp);
1679 +
1680 +               if (err)
1681 +                       break;
1682 +
1683 +               err = get_user(call, (unsigned short *)(ret-3));
1684 +               err |= get_user(offset, (char *)(ret-1));
1685 +               if (err)
1686 +                       break;
1687 +
1688 +               if ((mov & 0xF8) == 0xB8 &&
1689 +                   jmp == 0xE9 &&
1690 +                   call == 0x55FF)
1691 +               {
1692 +                       unsigned long addr;
1693 +
1694 +                       err = get_user(addr, (unsigned long*)(regs->ebp + (unsigned long)(long)offset));
1695 +                       if (err || regs->eip != addr)
1696 +                               break;
1697 +
1698 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1699 +                       regs->eip += addr2 + 10;
1700 +                       return 4;
1701 +               }
1702 +       } while (0);
1703 +
1704 +       do { /* PaX: gcc trampoline emulation #4 */
1705 +               unsigned char mov, jmp, sib;
1706 +               char offset;
1707 +               unsigned long addr1, addr2, ret;
1708 +               unsigned short call;
1709 +
1710 +               err = get_user(mov, (unsigned char *)regs->eip);
1711 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1712 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1713 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1714 +               err |= get_user(ret, (unsigned long *)regs->esp);
1715 +
1716 +               if (err)
1717 +                       break;
1718 +
1719 +               err = get_user(call, (unsigned short *)(ret-4));
1720 +               err |= get_user(sib, (unsigned char *)(ret-2));
1721 +               err |= get_user(offset, (char *)(ret-1));
1722 +               if (err)
1723 +                       break;
1724 +
1725 +               if ((mov & 0xF8) == 0xB8 &&
1726 +                   jmp == 0xE9 &&
1727 +                   call == 0x54FF &&
1728 +                   sib == 0x24)
1729 +               {
1730 +                       unsigned long addr;
1731 +
1732 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + (unsigned long)(long)offset));
1733 +                       if (err || regs->eip != addr)
1734 +                               break;
1735 +
1736 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1737 +                       regs->eip += addr2 + 10;
1738 +                       return 4;
1739 +               }
1740 +       } while (0);
1741 +
1742 +       do { /* PaX: gcc trampoline emulation #5 */
1743 +               unsigned char mov, jmp, sib;
1744 +               unsigned long addr1, addr2, ret, offset;
1745 +               unsigned short call;
1746 +
1747 +               err = get_user(mov, (unsigned char *)regs->eip);
1748 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1749 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1750 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1751 +               err |= get_user(ret, (unsigned long *)regs->esp);
1752 +
1753 +               if (err)
1754 +                       break;
1755 +
1756 +               err = get_user(call, (unsigned short *)(ret-7));
1757 +               err |= get_user(sib, (unsigned char *)(ret-5));
1758 +               err |= get_user(offset, (unsigned long *)(ret-4));
1759 +               if (err)
1760 +                       break;
1761 +
1762 +               if ((mov & 0xF8) == 0xB8 &&
1763 +                   jmp == 0xE9 &&
1764 +                   call == 0x94FF &&
1765 +                   sib == 0x24)
1766 +               {
1767 +                       unsigned long addr;
1768 +
1769 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + offset));
1770 +                       if (err || regs->eip != addr)
1771 +                               break;
1772 +
1773 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1774 +                       regs->eip += addr2 + 10;
1775 +                       return 4;
1776 +               }
1777 +       } while (0);
1778 +#endif
1779 +
1780 +       return 1; /* PaX in action */
1781 +}
1782 +
1783 +void pax_report_insns(void *pc)
1784 +{
1785 +       unsigned long i;
1786 +
1787 +       printk(KERN_ERR "PAX: bytes at PC: ");
1788 +       for (i = 0; i < 20; i++) {
1789 +               unsigned char c;
1790 +               if (get_user(c, (unsigned char*)pc+i)) {
1791 +                       printk("<invalid address>.");
1792 +                       break;
1793 +               }
1794 +               printk("%02x ", c);
1795 +       }
1796 +       printk("\n");
1797 +}
1798 +#endif
1799 +
1800 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1801 +/*
1802 + * PaX: handle the extra page faults or pass it down to the original handler
1803 + *
1804 + * returns 0 when nothing special was detected
1805 + *         1 when sigreturn trampoline (syscall) has to be emulated
1806 + */
1807 +asmlinkage int pax_do_page_fault(struct pt_regs *regs, unsigned long error_code)
1808 +{
1809 +       struct mm_struct *mm = current->mm;
1810 +       unsigned long address;
1811 +       pte_t *pte;
1812 +       unsigned char pte_mask;
1813 +       int ret;
1814 +
1815 +       __asm__("movl %%cr2,%0":"=r" (address));
1816 +
1817 +       /* It's safe to allow irq's after cr2 has been saved */
1818 +       if (likely(regs->eflags & X86_EFLAGS_IF))
1819 +               local_irq_enable();
1820 +
1821 +       if (unlikely((error_code & 5) != 5 ||
1822 +                    address >= TASK_SIZE ||
1823 +                    !(current->flags & PF_PAX_PAGEEXEC)))
1824 +               return do_page_fault(regs, error_code, address);
1825 +
1826 +       /* PaX: it's our fault, let's handle it if we can */
1827 +
1828 +       /* PaX: take a look at read faults before acquiring any locks */
1829 +       if (unlikely((error_code == 5) && (regs->eip == address))) { 
1830 +               /* instruction fetch attempt from a protected page in user mode */
1831 +               ret = pax_handle_fetch_fault(regs);
1832 +               switch (ret) {
1833 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1834 +               case 5:
1835 +                       return 0;
1836 +#endif
1837 +
1838 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1839 +               case 4:
1840 +                       return 0;
1841 +               case 3:
1842 +               case 2:
1843 +                       return 1;
1844 +#endif
1845 +               case 1:
1846 +               default:
1847 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1848 +                       do_exit(SIGKILL);
1849 +               }
1850 +       }
1851 +
1852 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
1853 +
1854 +       spin_lock(&mm->page_table_lock);
1855 +       pte = pax_get_pte(mm, address);
1856 +       if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
1857 +               spin_unlock(&mm->page_table_lock);
1858 +               do_page_fault(regs, error_code, address);
1859 +               return 0;
1860 +       }
1861 +
1862 +       if (unlikely((error_code == 7) && !pte_write(*pte))) {
1863 +               /* write attempt to a protected page in user mode */
1864 +               spin_unlock(&mm->page_table_lock);
1865 +               do_page_fault(regs, error_code, address);
1866 +               return 0;
1867 +       }
1868 +
1869 +       /*
1870 +        * PaX: fill DTLB with user rights and retry
1871 +        */
1872 +       __asm__ __volatile__ (
1873 +               "orb %2,%1\n"
1874 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
1875 +/*   
1876 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's   
1877 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
1878 + * page fault when examined during a TLB load attempt. this is true not only
1879 + * for PTEs holding a non-present entry but also present entries that will
1880 + * raise a page fault (such as those set up by PaX, or the copy-on-write
1881 + * mechanism). in effect it means that we do *not* need to flush the TLBs
1882 + * for our target pages since their PTEs are simply not in the TLBs at all.
1883 + * the best thing in omitting it is that we gain around 15-20% speed in the
1884 + * fast path of the page fault handler and can get rid of tracing since we
1885 + * can no longer flush unintended entries.
1886 + */
1887 +
1888 +               "invlpg %0\n"
1889 +#endif
1890 +
1891 +               "testb $0,%0\n"
1892 +               "xorb %3,%1\n"
1893 +               :
1894 +               : "m" (*(char*)address), "m" (*(char*)pte) , "q" (pte_mask) , "i" (_PAGE_USER)
1895 +               : "memory", "cc");
1896 +       spin_unlock(&mm->page_table_lock);
1897 +       return 0;
1898 +}
1899 +#endif
1900 diff -urN linux-2.4.24.org/arch/i386/mm/init.c linux-2.4.24/arch/i386/mm/init.c
1901 --- linux-2.4.24.org/arch/i386/mm/init.c        2004-02-04 23:08:37.831306576 +0100
1902 +++ linux-2.4.24/arch/i386/mm/init.c    2004-02-04 23:11:31.738146861 +0100
1903 @@ -37,6 +37,8 @@
1904  #include <asm/e820.h>
1905  #include <asm/apic.h>
1906  #include <asm/tlb.h>
1907 +#include <asm/page_offset.h>
1908 +#include <asm/desc.h>
1909  
1910  mmu_gather_t mmu_gathers[NR_CPUS];
1911  unsigned long highstart_pfn, highend_pfn;
1912 @@ -122,7 +124,7 @@
1913  
1914  /* References to section boundaries */
1915  
1916 -extern char _text, _etext, _edata, __bss_start, _end;
1917 +extern char _text, _etext, _data, _edata, __bss_start, _end;
1918  extern char __init_begin, __init_end;
1919  
1920  static inline void set_pte_phys (unsigned long vaddr,
1921 @@ -514,7 +516,7 @@
1922         reservedpages = free_pages_init();
1923  
1924         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
1925 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
1926 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
1927         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
1928  
1929         printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
1930 @@ -582,6 +584,38 @@
1931                 totalram_pages++;
1932         }
1933         printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
1934 +
1935 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1936 +       /* PaX: limit KERNEL_CS to actual size */
1937 +       {
1938 +               unsigned long limit;
1939 +
1940 +               limit = (unsigned long)&_etext >> PAGE_SHIFT;
1941 +               gdt_table[2].a = (gdt_table[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1942 +               gdt_table[2].b = (gdt_table[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1943 +
1944 +#ifdef CONFIG_PCI_BIOS
1945 +               printk(KERN_INFO "PAX: warning, PCI BIOS might still be in use, keeping flat KERNEL_CS.\n");
1946 +#endif
1947 +
1948 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1949 +               gdt_table2[2].a = (gdt_table2[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1950 +               gdt_table2[2].b = (gdt_table2[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1951 +#endif
1952 +
1953 +       /* PaX: make KERNEL_CS read-only */
1954 +               for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
1955 +                       pgd_t *pgd;
1956 +                       pmd_t *pmd;
1957 +
1958 +                       pgd = pgd_offset_k(addr);
1959 +                       pmd = pmd_offset(pgd, addr);
1960 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1961 +               }
1962 +               flush_tlb_all();
1963 +       }
1964 +#endif
1965 +
1966  }
1967  
1968  #ifdef CONFIG_BLK_DEV_INITRD
1969 diff -urN linux-2.4.24.org/arch/i386/vmlinux.lds linux-2.4.24/arch/i386/vmlinux.lds
1970 --- linux-2.4.24.org/arch/i386/vmlinux.lds      2004-02-04 23:08:41.186608896 +0100
1971 +++ linux-2.4.24/arch/i386/vmlinux.lds  1970-01-01 01:00:00.000000000 +0100
1972 @@ -1,82 +0,0 @@
1973 -/* ld script to make i386 Linux kernel
1974 - * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1975 - */
1976 -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1977 -OUTPUT_ARCH(i386)
1978 -ENTRY(_start)
1979 -SECTIONS
1980 -{
1981 -  . = 0xC0000000 + 0x100000;
1982 -  _text = .;                   /* Text and read-only data */
1983 -  .text : {
1984 -       *(.text)
1985 -       *(.fixup)
1986 -       *(.gnu.warning)
1987 -       } = 0x9090
1988 -
1989 -  _etext = .;                  /* End of text section */
1990 -
1991 -  .rodata : { *(.rodata) *(.rodata.*) }
1992 -  .kstrtab : { *(.kstrtab) }
1993 -
1994 -  . = ALIGN(16);               /* Exception table */
1995 -  __start___ex_table = .;
1996 -  __ex_table : { *(__ex_table) }
1997 -  __stop___ex_table = .;
1998 -
1999 -  __start___ksymtab = .;       /* Kernel symbol table */
2000 -  __ksymtab : { *(__ksymtab) }
2001 -  __stop___ksymtab = .;
2002 -
2003 -  .data : {                    /* Data */
2004 -       *(.data)
2005 -       CONSTRUCTORS
2006 -       }
2007 -
2008 -  _edata = .;                  /* End of data section */
2009 -
2010 -  . = ALIGN(8192);             /* init_task */
2011 -  .data.init_task : { *(.data.init_task) }
2012 -
2013 -  . = ALIGN(4096);             /* Init code and data */
2014 -  __init_begin = .;
2015 -  .text.init : { *(.text.init) }
2016 -  .data.init : { *(.data.init) }
2017 -  . = ALIGN(16);
2018 -  __setup_start = .;
2019 -  .setup.init : { *(.setup.init) }
2020 -  __setup_end = .;
2021 -  __initcall_start = .;
2022 -  .initcall.init : { *(.initcall.init) }
2023 -  __initcall_end = .;
2024 -  . = ALIGN(4096);
2025 -  __init_end = .;
2026 -
2027 -  . = ALIGN(4096);
2028 -  .data.page_aligned : { *(.data.idt) }
2029 -
2030 -  . = ALIGN(32);
2031 -  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
2032 -
2033 -  __bss_start = .;             /* BSS */
2034 -  .bss : {
2035 -       *(.bss)
2036 -       }
2037 -  _end = . ;
2038 -
2039 -  /* Sections to be discarded */
2040 -  /DISCARD/ : {
2041 -       *(.text.exit)
2042 -       *(.data.exit)
2043 -       *(.exitcall.exit)
2044 -       }
2045 -
2046 -  /* Stabs debugging sections.  */
2047 -  .stab 0 : { *(.stab) }
2048 -  .stabstr 0 : { *(.stabstr) }
2049 -  .stab.excl 0 : { *(.stab.excl) }
2050 -  .stab.exclstr 0 : { *(.stab.exclstr) }
2051 -  .stab.index 0 : { *(.stab.index) }
2052 -  .stab.indexstr 0 : { *(.stab.indexstr) }
2053 -  .comment 0 : { *(.comment) }
2054 -}
2055 diff -urN linux-2.4.24.org/arch/i386/vmlinux.lds.S linux-2.4.24/arch/i386/vmlinux.lds.S
2056 --- linux-2.4.24.org/arch/i386/vmlinux.lds.S    1970-01-01 01:00:00.000000000 +0100
2057 +++ linux-2.4.24/arch/i386/vmlinux.lds.S        2004-02-04 23:11:31.761142080 +0100
2058 @@ -0,0 +1,136 @@
2059 +/* ld script to make i386 Linux kernel
2060 + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
2061 + */
2062 +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2063 +OUTPUT_ARCH(i386)
2064 +ENTRY(_start)
2065 +SECTIONS
2066 +{
2067 +  . = __PAGE_OFFSET + 0x100000;
2068 +  .text.startup : {
2069 +       BYTE(0xEA) /* jmp far */
2070 +
2071 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
2072 +       LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
2073 +#else
2074 +       LONG(startup_32 - __PAGE_OFFSET)
2075 +#endif
2076 +
2077 +       SHORT(__KERNEL_CS)
2078 +       }
2079 +
2080 +  . = ALIGN(32);
2081 +  _data = .;
2082 +  .data : {                    /* Data */
2083 +       *(.data)
2084 +       CONSTRUCTORS
2085 +       }
2086 +
2087 +  . = ALIGN(32);
2088 +  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
2089 +
2090 +  . = ALIGN(8192);
2091 +  .data.init_task : { *(.data.init_task) }
2092 +
2093 +  . = ALIGN(4096);
2094 +  .data.page_aligned : { *(.data.swapper_pg_dir) }
2095 +
2096 +  _edata = .;                  /* End of data section */
2097 +
2098 +  __bss_start = .;             /* BSS */
2099 +  .bss : {
2100 +       *(.bss)
2101 +       LONG(0)
2102 +       } 
2103 +  __bss_end = . ;
2104 +
2105 +  . = ALIGN(4096);             /* Init code and data */
2106 +  __init_begin = .;
2107 +
2108 +  .data.init : {
2109 +       *(.data.pg0)
2110 +       *(.data.pg1)
2111 +       *(.data.pg2)
2112 +       *(.data.init)
2113 +       }
2114 +  . = ALIGN(16);
2115 +  __setup_start = .;
2116 +  .setup.init : { *(.setup.init) }
2117 +  __setup_end = .;
2118 +  __initcall_start = .;
2119 +  .initcall.init : { *(.initcall.init) }
2120 +  __initcall_end = .;
2121 +
2122 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
2123 +  __text_init_start = .;
2124 +  .text.init (. - __KERNEL_TEXT_OFFSET) : AT (__text_init_start) {
2125 +       *(.text.init)
2126 +       . = ALIGN(4*1024*1024) - 1;
2127 +       BYTE(0)
2128 +       }
2129 +  __init_end = . + __KERNEL_TEXT_OFFSET;
2130 +
2131 +/*
2132 + * PaX: this must be kept in synch with the KERNEL_CS base
2133 + * in the GDTs in arch/i386/kernel/head.S
2134 + */
2135 +  _text = .;                   /* Text and read-only data */
2136 +  .text : AT (. + __KERNEL_TEXT_OFFSET) {
2137 +#else
2138 +  .text.init : { *(.text.init) }
2139 +  . = ALIGN(4096);
2140 +  __init_end = .;
2141 +  _text = .;                   /* Text and read-only data */
2142 +  .text : {
2143 +#endif
2144 +
2145 +       *(.text)
2146 +       *(.fixup)
2147 +       *(.gnu.warning)
2148 +       } = 0x9090
2149 +
2150 +  _etext = .;                  /* End of text section */
2151 +  . = ALIGN(4096);
2152 +
2153 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
2154 +  . += __KERNEL_TEXT_OFFSET;
2155 +#endif
2156 +
2157 +  .rodata.page_aligned : {
2158 +       *(.data.empty_zero_page)
2159 +       *(.data.idt)
2160 +       }
2161 +  .rodata : { *(.rodata) *(.rodata.*) }
2162 +  .kstrtab : { *(.kstrtab) }
2163 +
2164 +  . = ALIGN(16);               /* Exception table */
2165 +  __start___ex_table = .;
2166 +  __ex_table : { *(__ex_table) }
2167 +  __stop___ex_table = .;
2168 +
2169 +  __start___ksymtab = .;       /* Kernel symbol table */
2170 +  __ksymtab : { *(__ksymtab) }
2171 +  __stop___ksymtab = .;
2172 +
2173 +#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
2174 +  _end = ALIGN(4*1024*1024);
2175 +#else
2176 +  _end = .;
2177 +#endif
2178 +
2179 +  /* Sections to be discarded */
2180 +  /DISCARD/ : {
2181 +       *(.text.exit)
2182 +       *(.data.exit)
2183 +       *(.exitcall.exit)
2184 +       }
2185 +
2186 +  /* Stabs debugging sections.  */
2187 +  .stab 0 : { *(.stab) }
2188 +  .stabstr 0 : { *(.stabstr) }
2189 +  .stab.excl 0 : { *(.stab.excl) }
2190 +  .stab.exclstr 0 : { *(.stab.exclstr) }
2191 +  .stab.index 0 : { *(.stab.index) }
2192 +  .stab.indexstr 0 : { *(.stab.indexstr) }
2193 +  .comment 0 : { *(.comment) }
2194 +}
2195 diff -urN linux-2.4.24.org/arch/ia64/config.in linux-2.4.24/arch/ia64/config.in
2196 --- linux-2.4.24.org/arch/ia64/config.in        2004-02-04 23:09:38.875613414 +0100
2197 +++ linux-2.4.24/arch/ia64/config.in    2004-02-04 23:11:31.763141664 +0100
2198 @@ -319,3 +319,12 @@
2199  int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
2200  
2201  endmenu
2202 +
2203 +mainmenu_option next_comment
2204 +comment 'Grsecurity'
2205 +bool 'Grsecurity' CONFIG_GRKERNSEC
2206 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2207 +    source grsecurity/Config.in
2208 +fi
2209 +endmenu
2210 +
2211 diff -urN linux-2.4.24.org/arch/ia64/kernel/ptrace.c linux-2.4.24/arch/ia64/kernel/ptrace.c
2212 --- linux-2.4.24.org/arch/ia64/kernel/ptrace.c  2004-02-04 23:09:40.382300123 +0100
2213 +++ linux-2.4.24/arch/ia64/kernel/ptrace.c      2004-02-04 23:11:31.770140209 +0100
2214 @@ -16,6 +16,7 @@
2215  #include <linux/ptrace.h>
2216  #include <linux/smp_lock.h>
2217  #include <linux/user.h>
2218 +#include <linux/grsecurity.h>
2219  
2220  #include <asm/pgtable.h>
2221  #include <asm/processor.h>
2222 @@ -1273,6 +1274,9 @@
2223         if (pid == 1)           /* no messing around with init! */
2224                 goto out_tsk;
2225  
2226 +       if (gr_handle_ptrace(child, request))
2227 +               goto out_tsk;
2228 +
2229         if (request == PTRACE_ATTACH) {
2230                 ret = ptrace_attach(child);
2231                 goto out_tsk;
2232 diff -urN linux-2.4.24.org/arch/ia64/kernel/sys_ia64.c linux-2.4.24/arch/ia64/kernel/sys_ia64.c
2233 --- linux-2.4.24.org/arch/ia64/kernel/sys_ia64.c        2004-02-04 23:09:41.018167905 +0100
2234 +++ linux-2.4.24/arch/ia64/kernel/sys_ia64.c    2004-02-04 23:17:00.969695516 +0100
2235 @@ -16,6 +16,7 @@
2236  #include <linux/smp_lock.h>
2237  #include <linux/highuid.h>
2238  #include <linux/hugetlb.h>
2239 +#include <linux/grsecurity.h>
2240  
2241  #include <asm/shmparam.h>
2242  #include <asm/uaccess.h>
2243 @@ -211,6 +212,11 @@
2244                 goto out;
2245         }
2246  
2247 +       if (gr_handle_mmap(file, prot)) {
2248 +               addr = -EACCES;
2249 +               goto out;
2250 +       }
2251 +
2252         down_write(&current->mm->mmap_sem);
2253         addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
2254         up_write(&current->mm->mmap_sem);
2255 diff -urN linux-2.4.24.org/arch/m68k/config.in linux-2.4.24/arch/m68k/config.in
2256 --- linux-2.4.24.org/arch/m68k/config.in        2004-02-04 23:09:17.818991792 +0100
2257 +++ linux-2.4.24/arch/m68k/config.in    2004-02-04 23:11:31.781137922 +0100
2258 @@ -557,3 +557,11 @@
2259  
2260  source crypto/Config.in
2261  source lib/Config.in
2262 +
2263 +mainmenu_option next_comment
2264 +comment 'Grsecurity'
2265 +bool 'Grsecurity' CONFIG_GRKERNSEC
2266 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2267 +       source grsecurity/Config.in
2268 +fi
2269 +endmenu
2270 diff -urN linux-2.4.24.org/arch/mips/config.in linux-2.4.24/arch/mips/config.in
2271 --- linux-2.4.24.org/arch/mips/config.in        2004-02-04 23:08:53.415066189 +0100
2272 +++ linux-2.4.24/arch/mips/config.in    2004-02-04 23:11:31.783137507 +0100
2273 @@ -7,3 +7,11 @@
2274  define_bool CONFIG_MIPS64 n
2275  
2276  source arch/mips/config-shared.in
2277 +
2278 +mainmenu_option next_comment
2279 +comment 'Grsecurity'
2280 +bool 'Grsecurity' CONFIG_GRKERNSEC
2281 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2282 +        source grsecurity/Config.in
2283 +fi
2284 +endmenu
2285 diff -urN linux-2.4.24.org/arch/mips64/config.in linux-2.4.24/arch/mips64/config.in
2286 --- linux-2.4.24.org/arch/mips64/config.in      2004-02-04 23:09:44.133520119 +0100
2287 +++ linux-2.4.24/arch/mips64/config.in  2004-02-04 23:11:31.786136883 +0100
2288 @@ -7,3 +7,11 @@
2289  define_bool CONFIG_MIPS64 y
2290  
2291  source arch/mips/config-shared.in
2292 +
2293 +mainmenu_option next_comment
2294 +comment 'Grsecurity'
2295 +bool 'Grsecurity' CONFIG_GRKERNSEC
2296 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2297 +        source grsecurity/Config.in
2298 +fi
2299 +endmenu
2300 diff -urN linux-2.4.24.org/arch/parisc/config.in linux-2.4.24/arch/parisc/config.in
2301 --- linux-2.4.24.org/arch/parisc/config.in      2004-02-04 23:09:48.698570893 +0100
2302 +++ linux-2.4.24/arch/parisc/config.in  2004-02-04 23:11:31.789136259 +0100
2303 @@ -204,3 +204,11 @@
2304  
2305  source crypto/Config.in
2306  source lib/Config.in
2307 +
2308 +mainmenu_option next_comment
2309 +comment 'Grsecurity'
2310 +bool 'Grsecurity' CONFIG_GRKERNSEC
2311 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2312 +       source grsecurity/Config.in
2313 +fi
2314 +endmenu
2315 diff -urN linux-2.4.24.org/arch/parisc/kernel/ioctl32.c linux-2.4.24/arch/parisc/kernel/ioctl32.c
2316 --- linux-2.4.24.org/arch/parisc/kernel/ioctl32.c       2004-02-04 23:09:51.399009382 +0100
2317 +++ linux-2.4.24/arch/parisc/kernel/ioctl32.c   2004-02-04 23:11:31.796134804 +0100
2318 @@ -1435,7 +1435,11 @@
2319          * To have permissions to do most of the vt ioctls, we either have
2320          * to be the owner of the tty, or super-user.
2321          */
2322 +#ifdef CONFIG_GRKERNSEC
2323 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
2324 +#else
2325         if (current->tty == tty || suser())
2326 +#endif
2327                 return 1;
2328         return 0;                                                    
2329  }
2330 diff -urN linux-2.4.24.org/arch/parisc/kernel/ptrace.c linux-2.4.24/arch/parisc/kernel/ptrace.c
2331 --- linux-2.4.24.org/arch/parisc/kernel/ptrace.c        2004-02-04 23:09:52.194843901 +0100
2332 +++ linux-2.4.24/arch/parisc/kernel/ptrace.c    2004-02-04 23:11:31.801133765 +0100
2333 @@ -15,7 +15,7 @@
2334  #include <linux/ptrace.h>
2335  #include <linux/user.h>
2336  #include <linux/personality.h>
2337 -
2338 +#include <linux/grsecurity.h>
2339  #include <asm/uaccess.h>
2340  #include <asm/pgtable.h>
2341  #include <asm/system.h>
2342 @@ -119,6 +119,9 @@
2343         if (pid == 1)           /* no messing around with init! */
2344                 goto out_tsk;
2345  
2346 +       if (gr_handle_ptrace(child, request))
2347 +               goto out_tsk;
2348 +
2349         if (request == PTRACE_ATTACH) {
2350                 ret = ptrace_attach(child);
2351                 goto out_tsk;
2352 diff -urN linux-2.4.24.org/arch/parisc/kernel/sys_parisc32.c linux-2.4.24/arch/parisc/kernel/sys_parisc32.c
2353 --- linux-2.4.24.org/arch/parisc/kernel/sys_parisc32.c  2004-02-04 23:09:51.577972169 +0100
2354 +++ linux-2.4.24/arch/parisc/kernel/sys_parisc32.c      2004-02-04 23:11:31.807132518 +0100
2355 @@ -50,6 +50,7 @@
2356  #include <linux/highmem.h>
2357  #include <linux/highuid.h>
2358  #include <linux/mman.h>
2359 +#include <linux/grsecurity.h>
2360  
2361  #include <asm/types.h>
2362  #include <asm/uaccess.h>
2363 @@ -177,6 +178,11 @@
2364         struct file *file;
2365         int retval;
2366         int i;
2367 +#ifdef CONFIG_GRKERNSEC
2368 +       struct file *old_exec_file;
2369 +       struct acl_subject_label *old_acl;
2370 +       struct rlimit old_rlim[RLIM_NLIMITS];
2371 +#endif
2372  
2373         file = open_exec(filename);
2374  
2375 @@ -184,7 +190,26 @@
2376         if (IS_ERR(file))
2377                 return retval;
2378  
2379 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
2380 +
2381 +       if (gr_handle_nproc()) {
2382 +               allow_write_access(file);
2383 +               fput(file);
2384 +               return -EAGAIN;
2385 +       }
2386 +
2387 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
2388 +               allow_write_access(file);
2389 +               fput(file);
2390 +               return -EACCES;
2391 +       }
2392 +
2393         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
2394 +
2395 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
2396 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
2397 +#endif
2398 +
2399         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
2400  
2401         DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs));
2402 @@ -209,11 +234,24 @@
2403         if (retval < 0)
2404                 goto out;
2405         
2406 +       if (!gr_tpe_allow(file)) {
2407 +               retval = -EACCES;
2408 +               goto out;
2409 +       }
2410 +
2411 +       if (gr_check_crash_exec(file)) {
2412 +               retval = -EACCES;
2413 +               goto out;
2414 +       }
2415 +
2416         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
2417         if (retval < 0)
2418                 goto out;
2419  
2420         bprm.exec = bprm.p;
2421 +
2422 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
2423 +
2424         retval = copy_strings32(bprm.envc, envp, &bprm);
2425         if (retval < 0)
2426                 goto out;
2427 @@ -222,11 +260,32 @@
2428         if (retval < 0)
2429                 goto out;
2430  
2431 +#ifdef CONFIG_GRKERNSEC
2432 +       old_acl = current->acl;
2433 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
2434 +       old_exec_file = current->exec_file;
2435 +       get_file(file);
2436 +       current->exec_file = file;
2437 +#endif
2438 +
2439 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
2440 +
2441         retval = search_binary_handler(&bprm,regs);
2442 -       if (retval >= 0)
2443 +       if (retval >= 0) {
2444 +#ifdef CONFIG_GRKERNSEC
2445 +               if (old_exec_file)
2446 +                       fput(old_exec_file);
2447 +#endif
2448                 /* execve success */
2449                 return retval;
2450 +       }
2451  
2452 +#ifdef CONFIG_GRKERNSEC
2453 +       current->acl = old_acl;
2454 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
2455 +       fput(current->exec_file);
2456 +       current->exec_file = old_exec_file;
2457 +#endif
2458  out:
2459         /* Something went wrong, return the inode and free the argument pages*/
2460         allow_write_access(bprm.file);
2461 diff -urN linux-2.4.24.org/arch/parisc/kernel/sys_parisc.c linux-2.4.24/arch/parisc/kernel/sys_parisc.c
2462 --- linux-2.4.24.org/arch/parisc/kernel/sys_parisc.c    2004-02-04 23:09:52.087866145 +0100
2463 +++ linux-2.4.24/arch/parisc/kernel/sys_parisc.c        2004-02-04 23:11:31.813131271 +0100
2464 @@ -12,6 +12,7 @@
2465  #include <linux/mman.h>
2466  #include <linux/shm.h>
2467  #include <linux/smp_lock.h>
2468 +#include <linux/grsecurity.h>
2469  
2470  int sys_pipe(int *fildes)
2471  {
2472 @@ -90,6 +91,11 @@
2473                 inode = filp->f_dentry->d_inode;
2474         }
2475  
2476 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2477 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
2478 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
2479 +#endif
2480 +
2481         if (inode && (flags & MAP_SHARED) && (inode->i_mapping->i_mmap_shared)) {
2482                 addr = get_shared_area(inode, addr, len, pgoff);
2483         } else {
2484 @@ -104,12 +110,23 @@
2485  {
2486         struct file * file = NULL;
2487         unsigned long error = -EBADF;
2488 +
2489 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2490 +       if (flags & MAP_MIRROR)
2491 +               return -EINVAL;
2492 +#endif
2493 +
2494         if (!(flags & MAP_ANONYMOUS)) {
2495                 file = fget(fd);
2496                 if (!file)
2497                         goto out;
2498         }
2499  
2500 +       if (gr_handle_mmap(file, prot)) {
2501 +               fput(file);
2502 +               return -EACCES;
2503 +       }
2504 +
2505         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2506  
2507         down_write(&current->mm->mmap_sem);
2508 diff -urN linux-2.4.24.org/arch/parisc/kernel/traps.c linux-2.4.24/arch/parisc/kernel/traps.c
2509 --- linux-2.4.24.org/arch/parisc/kernel/traps.c 2004-02-04 23:09:51.088074036 +0100
2510 +++ linux-2.4.24/arch/parisc/kernel/traps.c     2004-02-04 23:11:31.817130439 +0100
2511 @@ -637,9 +637,7 @@
2512  
2513                         down_read(&current->mm->mmap_sem);
2514                         vma = find_vma(current->mm,regs->iaoq[0]);
2515 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
2516 -                               && (vma->vm_flags & VM_EXEC)) {
2517 -
2518 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
2519                                 fault_address = regs->iaoq[0];
2520                                 fault_space = regs->iasq[0];
2521  
2522 diff -urN linux-2.4.24.org/arch/parisc/mm/fault.c linux-2.4.24/arch/parisc/mm/fault.c
2523 --- linux-2.4.24.org/arch/parisc/mm/fault.c     2004-02-04 23:09:52.460788602 +0100
2524 +++ linux-2.4.24/arch/parisc/mm/fault.c 2004-02-04 23:11:31.822129400 +0100
2525 @@ -15,6 +15,7 @@
2526  #include <linux/ptrace.h>
2527  #include <linux/sched.h>
2528  #include <linux/interrupt.h>
2529 +#include <linux/unistd.h>
2530  
2531  #include <asm/uaccess.h>
2532  #include <asm/traps.h>
2533 @@ -53,7 +54,7 @@
2534  static unsigned long
2535  parisc_acctyp(unsigned long code, unsigned int inst)
2536  {
2537 -       if (code == 6 || code == 16)
2538 +       if (code == 6 || code == 7 || code == 16)
2539             return VM_EXEC;
2540  
2541         switch (inst & 0xf0000000) {
2542 @@ -139,6 +140,136 @@
2543                         }
2544  #endif
2545  
2546 +/*
2547 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
2548 + *
2549 + * returns 1 when task should be killed 
2550 + *        2 when rt_sigreturn trampoline was detected
2551 + *        3 when unpatched PLT trampoline was detected
2552 + *        4 when legitimate ET_EXEC was detected
2553 + */
2554 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC  
2555 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2556 +{
2557 +       int err;
2558 +
2559 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2560 +       if (current->flags & PF_PAX_RANDEXEC) {
2561 +               if (instruction_pointer(regs) >= current->mm->start_code &&
2562 +                   instruction_pointer(regs) < current->mm->end_code)
2563 +               {
2564 +#if 0
2565 +                       /* PaX: this needs fixing */
2566 +                       if ((regs->gr[2] & ~3UL) == instruction_pointer(regs))
2567 +                               return 1;
2568 +#endif
2569 +                       regs->iaoq[0] += current->mm->delta_exec;
2570 +                       if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code &&
2571 +                           (regs->iaoq[1] & ~3UL) < current->mm->end_code)
2572 +                               regs->iaoq[1] += current->mm->delta_exec;
2573 +                       return 4;
2574 +               }
2575 +       }
2576 +#endif
2577 +
2578 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2579 +       do { /* PaX: unpatched PLT emulation */
2580 +               unsigned int bl, depwi;
2581 +
2582 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
2583 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
2584 +
2585 +               if (err)
2586 +                       break;
2587 +
2588 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
2589 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
2590 +
2591 +                       err = get_user(ldw, (unsigned int*)addr);
2592 +                       err |= get_user(bv, (unsigned int*)(addr+4));
2593 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
2594 +
2595 +                       if (err)
2596 +                               break;
2597 +
2598 +                       if (ldw == 0x0E801096U &&
2599 +                           bv == 0xEAC0C000U &&
2600 +                           ldw2 == 0x0E881095U)
2601 +                       {
2602 +                               unsigned int resolver, map;
2603 +
2604 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
2605 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
2606 +                               if (err)
2607 +                                       break;
2608 +
2609 +                               regs->gr[20] = instruction_pointer(regs)+8;
2610 +                               regs->gr[21] = map;
2611 +                               regs->gr[22] = resolver;
2612 +                               regs->iaoq[0] = resolver | 3UL;
2613 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
2614 +                               return 3;
2615 +                       }
2616 +               }
2617 +       } while (0);
2618 +#endif
2619
2620 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2621 +
2622 +#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2623 +       if (!(current->flags & PF_PAX_EMUTRAMP))
2624 +               return 1;
2625 +#endif
2626 +
2627 +       do { /* PaX: rt_sigreturn emulation */
2628 +               unsigned int ldi1, ldi2, bel, nop;
2629 +
2630 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
2631 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
2632 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
2633 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
2634 +
2635 +               if (err)
2636 +                       break;
2637 +
2638 +                if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
2639 +                   ldi2 == 0x3414015AU &&
2640 +                   bel == 0xE4008200U &&
2641 +                   nop == 0x08000240U)
2642 +               {
2643 +                       regs->gr[25] = (ldi1 & 2) >> 1;
2644 +                       regs->gr[20] = __NR_rt_sigreturn;
2645 +                       regs->gr[31] = regs->iaoq[1] + 16;
2646 +                       regs->sr[0] = regs->iasq[1];
2647 +                       regs->iaoq[0] = 0x100UL;
2648 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
2649 +                       regs->iasq[0] = regs->sr[2];
2650 +                       regs->iasq[1] = regs->sr[2];
2651 +                       return 2;
2652 +               }
2653 +       } while (0);
2654 +#endif
2655 +
2656 +       return 1;
2657 +}
2658 +
2659 +void pax_report_insns(void *pc)
2660 +{
2661 +       unsigned long i;
2662 +
2663 +       printk(KERN_ERR "PAX: bytes at PC: ");
2664 +       for (i = 0; i < 5; i++) {
2665 +               unsigned int c;
2666 +               if (get_user(c, (unsigned int*)pc+i)) {
2667 +                       printk("<invalid address>.");
2668 +                       break;
2669 +               }
2670 +               printk("%08x ", c);
2671 +       }
2672 +       printk("\n");
2673 +}
2674 +#endif
2675 +
2676  void do_page_fault(struct pt_regs *regs, unsigned long code,
2677                               unsigned long address)
2678  {
2679 @@ -164,8 +295,38 @@
2680  
2681         acc_type = parisc_acctyp(code,regs->iir);
2682  
2683 -       if ((vma->vm_flags & acc_type) != acc_type)
2684 +       if ((vma->vm_flags & acc_type) != acc_type) {
2685 +
2686 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2687 +               if ((current->flags & PF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
2688 +                   (address & ~3UL) == instruction_pointer(regs))
2689 +                  {
2690 +                       up_read(&mm->mmap_sem);
2691 +                       switch(pax_handle_fetch_fault(regs)) {
2692 +
2693 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2694 +                       case 4:
2695 +                               return;
2696 +#endif
2697 +
2698 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2699 +                       case 3:
2700 +                               return;
2701 +#endif
2702 +
2703 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2704 +                       case 2:
2705 +                               return;
2706 +#endif
2707 +
2708 +                       }
2709 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
2710 +                       do_exit(SIGKILL);
2711 +               }
2712 +#endif
2713 +
2714                 goto bad_area;
2715 +       }
2716  
2717         /*
2718          * If for any reason at all we couldn't handle the fault, make
2719 diff -urN linux-2.4.24.org/arch/ppc/config.in linux-2.4.24/arch/ppc/config.in
2720 --- linux-2.4.24.org/arch/ppc/config.in 2004-02-04 23:09:08.164999182 +0100
2721 +++ linux-2.4.24/arch/ppc/config.in     2004-02-04 23:11:31.843125035 +0100
2722 @@ -634,3 +634,12 @@
2723  int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
2724  
2725  endmenu
2726 +
2727 +mainmenu_option next_comment
2728 +comment 'Grsecurity'
2729 +bool 'Grsecurity' CONFIG_GRKERNSEC
2730 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2731 +    source grsecurity/Config.in
2732 +fi
2733 +endmenu
2734 +
2735 diff -urN linux-2.4.24.org/arch/ppc/kernel/ptrace.c linux-2.4.24/arch/ppc/kernel/ptrace.c
2736 --- linux-2.4.24.org/arch/ppc/kernel/ptrace.c   2004-02-04 23:09:11.614281960 +0100
2737 +++ linux-2.4.24/arch/ppc/kernel/ptrace.c       2004-02-04 23:11:31.846124411 +0100
2738 @@ -24,6 +24,7 @@
2739  #include <linux/errno.h>
2740  #include <linux/ptrace.h>
2741  #include <linux/user.h>
2742 +#include <linux/grsecurity.h>
2743  
2744  #include <asm/uaccess.h>
2745  #include <asm/page.h>
2746 @@ -195,6 +196,9 @@
2747         if (pid == 1)           /* you may not mess with init */
2748                 goto out_tsk;
2749  
2750 +       if (gr_handle_ptrace(child, request))
2751 +               goto out_tsk;
2752 +
2753         if (request == PTRACE_ATTACH) {
2754                 ret = ptrace_attach(child);
2755                 goto out_tsk;
2756 diff -urN linux-2.4.24.org/arch/ppc/kernel/syscalls.c linux-2.4.24/arch/ppc/kernel/syscalls.c
2757 --- linux-2.4.24.org/arch/ppc/kernel/syscalls.c 2004-02-04 23:09:11.135381539 +0100
2758 +++ linux-2.4.24/arch/ppc/kernel/syscalls.c     2004-02-04 23:20:05.148402372 +0100
2759 @@ -35,6 +35,7 @@
2760  #include <linux/ipc.h>
2761  #include <linux/utsname.h>
2762  #include <linux/file.h>
2763 +#include <linux/grsecurity.h>
2764  
2765  #include <asm/uaccess.h>
2766  #include <asm/ipc.h>
2767 @@ -191,6 +192,11 @@
2768         struct file * file = NULL;
2769         int ret = -EBADF;
2770  
2771 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2772 +       if (flags & MAP_MIRROR)
2773 +               return -EINVAL;
2774 +#endif
2775 +           
2776         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2777         if (!(flags & MAP_ANONYMOUS)) {
2778                 if (!(file = fget(fd)))
2779 @@ -200,9 +206,15 @@
2780         ret = -EINVAL;
2781         if ((! allow_mmap_address(addr)) && (flags & MAP_FIXED))
2782                 goto out;
2783 -       
2784 +
2785 +       if (gr_handle_mmap(file, prot)) {
2786 +               fput(file);
2787 +               ret = -EACCES;
2788 +               goto out;
2789 +       }
2790 +
2791         down_write(&current->mm->mmap_sem);
2792 -       ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
2793 +       ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
2794         up_write(&current->mm->mmap_sem);
2795         if (file)
2796                 fput(file);
2797 diff -urN linux-2.4.24.org/arch/ppc/mm/fault.c linux-2.4.24/arch/ppc/mm/fault.c
2798 --- linux-2.4.24.org/arch/ppc/mm/fault.c        2004-02-04 23:09:11.050399210 +0100
2799 +++ linux-2.4.24/arch/ppc/mm/fault.c    2004-02-04 23:11:31.875118383 +0100
2800 @@ -26,6 +26,9 @@
2801  #include <linux/mman.h>
2802  #include <linux/mm.h>
2803  #include <linux/interrupt.h>
2804 +#include <linux/slab.h>
2805 +#include <linux/pagemap.h>
2806 +#include <linux/compiler.h>
2807  
2808  #include <asm/page.h>
2809  #include <asm/pgtable.h>
2810 @@ -52,6 +55,360 @@
2811  void bad_page_fault(struct pt_regs *, unsigned long, int sig);
2812  void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
2813  
2814 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2815 +void pax_syscall_close(struct vm_area_struct * vma)
2816 +{
2817 +       vma->vm_mm->call_syscall = 0UL;
2818 +}
2819 +
2820 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
2821 +{
2822 +       struct page* page;
2823 +       unsigned int *kaddr;
2824 +
2825 +       page = alloc_page(GFP_HIGHUSER);
2826 +       if (!page)
2827 +               return page;
2828 +
2829 +       kaddr = kmap(page);
2830 +       memset(kaddr, 0, PAGE_SIZE);
2831 +       kaddr[0] = 0x44000002U; /* sc */
2832 +       __flush_dcache_icache(kaddr);
2833 +       kunmap(page);
2834 +       return page;
2835 +}
2836 +
2837 +static struct vm_operations_struct pax_vm_ops = {
2838 +       close:          pax_syscall_close,
2839 +       nopage:         pax_syscall_nopage,
2840 +};
2841 +
2842 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2843 +{
2844 +       vma->vm_mm = current->mm;
2845 +       vma->vm_start = addr;
2846 +       vma->vm_end = addr + PAGE_SIZE;
2847 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2848 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
2849 +       vma->vm_ops = &pax_vm_ops;
2850 +       vma->vm_pgoff = 0UL;
2851 +       vma->vm_file = NULL;
2852 +       vma->vm_private_data = NULL;
2853 +       insert_vm_struct(current->mm, vma);
2854 +       ++current->mm->total_vm;
2855 +}
2856 +#endif
2857 +
2858 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2859 +/*
2860 + * PaX: decide what to do with offenders (regs->nip = fault address)
2861 + *
2862 + * returns 1 when task should be killed
2863 + *         2 when patched GOT trampoline was detected
2864 + *         3 when patched PLT trampoline was detected
2865 + *         4 when unpatched PLT trampoline was detected
2866 + *         5 when legitimate ET_EXEC was detected
2867 + *         6 when sigreturn trampoline was detected
2868 + *         7 when rt_sigreturn trampoline was detected
2869 + */
2870 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2871 +{
2872 +       int err;
2873 +
2874 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2875 +       if (current->flags & PF_PAX_RANDEXEC) {
2876 +               if (regs->nip >= current->mm->start_code &&
2877 +                   regs->nip < current->mm->end_code)
2878 +               {
2879 +                       if (regs->link == regs->nip)
2880 +                               return 1;
2881 +
2882 +                       regs->nip += current->mm->delta_exec;
2883 +                       return 5;
2884 +               }
2885 +       }
2886 +#endif
2887 +
2888 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2889 +       do { /* PaX: patched GOT emulation */
2890 +               unsigned int blrl;
2891 +
2892 +               err = get_user(blrl, (unsigned int*)regs->nip);
2893 +
2894 +               if (!err && blrl == 0x4E800021U) {
2895 +                       unsigned long temp = regs->nip;
2896 +
2897 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
2898 +                       regs->link = temp + 4UL;
2899 +                       return 2;
2900 +               }
2901 +       } while (0);
2902 +
2903 +       do { /* PaX: patched PLT emulation #1 */
2904 +               unsigned int b;
2905 +
2906 +               err = get_user(b, (unsigned int *)regs->nip);
2907 +
2908 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
2909 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
2910 +                       return 3;
2911 +               }
2912 +       } while (0);
2913 +
2914 +       do { /* PaX: unpatched PLT emulation #1 */
2915 +               unsigned int li, b;
2916 +
2917 +               err = get_user(li, (unsigned int *)regs->nip);
2918 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2919 +
2920 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2921 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2922 +                        unsigned long addr = b | 0xFC000000UL;
2923 +
2924 +                        addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2925 +                       err = get_user(rlwinm, (unsigned int*)addr);
2926 +                       err |= get_user(add, (unsigned int*)(addr+4));
2927 +                       err |= get_user(li2, (unsigned int*)(addr+8));
2928 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
2929 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
2930 +                       err |= get_user(li3, (unsigned int*)(addr+20));
2931 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
2932 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
2933 +
2934 +                       if (err)
2935 +                               break;
2936 +
2937 +                       if (rlwinm == 0x556C083CU &&
2938 +                           add == 0x7D6C5A14U &&
2939 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2940 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2941 +                           mtctr == 0x7D8903A6U &&
2942 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2943 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2944 +                           bctr == 0x4E800420U)
2945 +                       {
2946 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2947 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2948 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2949 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2950 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2951 +                               regs->nip = regs->ctr;
2952 +                               return 4;
2953 +                       }
2954 +               }
2955 +       } while (0);
2956 +
2957 +#if 0
2958 +       do { /* PaX: unpatched PLT emulation #2 */
2959 +               unsigned int lis, lwzu, b, bctr;
2960 +
2961 +               err = get_user(lis, (unsigned int *)regs->nip);
2962 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
2963 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
2964 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
2965 +
2966 +               if (err)
2967 +                       break;
2968 +
2969 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
2970 +                   (lwzu & 0xU) == 0xU &&
2971 +                   (b & 0xFC000003U) == 0x48000000U &&
2972 +                   bctr == 0x4E800420U)
2973 +               {
2974 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2975 +                        unsigned long addr = b | 0xFC000000UL;
2976 +
2977 +                        addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2978 +                       err = get_user(addis, (unsigned int*)addr);
2979 +                       err |= get_user(addi, (unsigned int*)(addr+4));
2980 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
2981 +                       err |= get_user(add, (unsigned int*)(addr+12));
2982 +                       err |= get_user(li2, (unsigned int*)(addr+16));
2983 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
2984 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
2985 +                       err |= get_user(li3, (unsigned int*)(addr+28));
2986 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
2987 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
2988 +
2989 +                       if (err)
2990 +                               break;
2991 +
2992 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2993 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
2994 +                           rlwinm == 0x556C083CU &&
2995 +                           add == 0x7D6C5A14U &&
2996 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2997 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2998 +                           mtctr == 0x7D8903A6U &&
2999 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
3000 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3001 +                           bctr == 0x4E800420U)
3002 +                       {
3003 +                               regs->gpr[PT_R11] = 
3004 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3005 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3006 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3007 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3008 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
3009 +                               regs->nip = regs->ctr;
3010 +                               return 4;
3011 +                       }
3012 +               }
3013 +       } while (0);
3014 +#endif
3015 +
3016 +       do { /* PaX: unpatched PLT emulation #3 */
3017 +               unsigned int li, b;
3018 +
3019 +               err = get_user(li, (unsigned int *)regs->nip);
3020 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
3021 +
3022 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3023 +                       unsigned int addis, lwz, mtctr, bctr;
3024 +                       unsigned long addr = b | 0xFC000000UL;
3025 +
3026 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3027 +                       err = get_user(addis, (unsigned int*)addr);
3028 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
3029 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
3030 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
3031 +
3032 +                       if (err)
3033 +                               break;
3034 +
3035 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3036 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
3037 +                           mtctr == 0x7D6903A6U &&
3038 +                           bctr == 0x4E800420U)
3039 +                       {
3040 +                               unsigned int r11;
3041 +
3042 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3043 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3044 +
3045 +                               err = get_user(r11, (unsigned int*)addr);
3046 +                               if (err)
3047 +                                       break;
3048 +
3049 +                               regs->gpr[PT_R11] = r11;
3050 +                               regs->ctr = r11;
3051 +                               regs->nip = r11;
3052 +                               return 4;
3053 +                       }
3054 +               }
3055 +       } while (0);
3056 +#endif
3057 +
3058 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
3059 +       do { /* PaX: sigreturn emulation */
3060 +               unsigned int li, sc;
3061 +
3062 +               err = get_user(li, (unsigned int *)regs->nip);
3063 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
3064 +
3065 +               if (!err && li == 0x38007777U && sc == 0x44000002U) {
3066 +                       struct vm_area_struct *vma;
3067 +                       unsigned long call_syscall;
3068 +
3069 +                       down_read(&current->mm->mmap_sem);
3070 +                       call_syscall = current->mm->call_syscall;
3071 +                       up_read(&current->mm->mmap_sem);
3072 +                       if (likely(call_syscall))
3073 +                               goto emulate;
3074 +
3075 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3076 +
3077 +                       down_write(&current->mm->mmap_sem);
3078 +                       if (current->mm->call_syscall) {
3079 +                               call_syscall = current->mm->call_syscall;
3080 +                               up_write(&current->mm->mmap_sem);
3081 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3082 +                               goto emulate;
3083 +                       }
3084 +
3085 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3086 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
3087 +                               up_write(&current->mm->mmap_sem);
3088 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3089 +                               return 1;
3090 +                       }
3091 +
3092 +                       pax_insert_vma(vma, call_syscall);
3093 +                       current->mm->call_syscall = call_syscall;
3094 +                       up_write(&current->mm->mmap_sem);
3095 +
3096 +emulate:
3097 +                       regs->gpr[PT_R0] = 0x7777UL;
3098 +                       regs->nip = call_syscall;
3099 +                       return 6;
3100 +               }
3101 +       } while (0);
3102 +
3103 +       do { /* PaX: rt_sigreturn emulation */
3104 +               unsigned int li, sc;
3105 +
3106 +               err = get_user(li, (unsigned int *)regs->nip);
3107 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
3108 +
3109 +               if (!err && li == 0x38006666U && sc == 0x44000002U) {
3110 +                       struct vm_area_struct *vma;
3111 +                       unsigned int call_syscall;
3112 +
3113 +                       down_read(&current->mm->mmap_sem);
3114 +                       call_syscall = current->mm->call_syscall;
3115 +                       up_read(&current->mm->mmap_sem);
3116 +                       if (likely(call_syscall))
3117 +                               goto rt_emulate;
3118 +
3119 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3120 +
3121 +                       down_write(&current->mm->mmap_sem);
3122 +                       if (current->mm->call_syscall) {
3123 +                               call_syscall = current->mm->call_syscall;
3124 +                               up_write(&current->mm->mmap_sem);
3125 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3126 +                               goto rt_emulate;
3127 +                       }
3128 +
3129 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3130 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
3131 +                               up_write(&current->mm->mmap_sem);
3132 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3133 +                               return 1;
3134 +                       }
3135 +
3136 +                       pax_insert_vma(vma, call_syscall);
3137 +                       current->mm->call_syscall = call_syscall;
3138 +                       up_write(&current->mm->mmap_sem);
3139 +
3140 +rt_emulate:
3141 +                       regs->gpr[PT_R0] = 0x6666UL;
3142 +                       regs->nip = call_syscall;
3143 +                       return 7;
3144 +               }
3145 +       } while (0);
3146 +#endif
3147 +
3148 +        return 1;
3149 +}
3150 +
3151 +void pax_report_insns(void *pc)
3152 +{
3153 +       unsigned long i;
3154 +
3155 +       printk(KERN_ERR "PAX: bytes at PC: ");
3156 +       for (i = 0; i < 5; i++) {
3157 +               unsigned int c;
3158 +               if (get_user(c, (unsigned int*)pc+i)) {
3159 +                       printk("<invalid address>.");
3160 +                       break;
3161 +               }
3162 +               printk("%08x ", c);
3163 +       }
3164 +       printk("\n");
3165 +}
3166 +#endif
3167 +
3168  /*
3169   * Check whether the instruction at regs->nip is a store using
3170   * an update addressing form which will update r1.
3171 @@ -112,7 +469,7 @@
3172          * indicate errors in DSISR but can validly be set in SRR1.
3173          */
3174         if (regs->trap == 0x400)
3175 -               error_code &= 0x48200000;
3176 +               error_code &= 0x58200000;
3177         else
3178                 is_write = error_code & 0x02000000;
3179  #endif /* CONFIG_4xx || CONFIG_BOOKE */
3180 @@ -245,6 +602,38 @@
3181  
3182         /* User mode accesses cause a SIGSEGV */
3183         if (user_mode(regs)) {
3184 +
3185 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3186 +               if (current->flags & PF_PAX_PAGEEXEC) {
3187 +                       if ((regs->trap == 0x400) && (regs->nip == address)) {
3188 +                               switch (pax_handle_fetch_fault(regs)) {
3189 +
3190 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3191 +                               case 2:
3192 +                               case 3:
3193 +                               case 4:
3194 +                                       return;
3195 +#endif
3196 +
3197 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3198 +                               case 5:
3199 +                                       return;
3200 +#endif
3201 +
3202 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
3203 +                               case 6:
3204 +                               case 7:
3205 +                                       return;
3206 +#endif
3207 +
3208 +                               }
3209 +
3210 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
3211 +                               do_exit(SIGKILL);
3212 +                       }
3213 +               }
3214 +#endif
3215 +
3216                 info.si_signo = SIGSEGV;
3217                 info.si_errno = 0;
3218                 info.si_code = code;
3219 diff -urN linux-2.4.24.org/arch/ppc64/kernel/ioctl32.c linux-2.4.24/arch/ppc64/kernel/ioctl32.c
3220 --- linux-2.4.24.org/arch/ppc64/kernel/ioctl32.c        2004-02-04 23:08:33.624181379 +0100
3221 +++ linux-2.4.24/arch/ppc64/kernel/ioctl32.c    2004-02-04 23:11:31.883116720 +0100
3222 @@ -1825,7 +1825,11 @@
3223          * To have permissions to do most of the vt ioctls, we either have
3224          * to be the owner of the tty, or super-user.
3225          */
3226 +#ifdef CONFIG_GRKERNSEC
3227 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3228 +#else
3229         if (current->tty == tty || suser())
3230 +#endif
3231                 return 1;
3232         return 0;                                                    
3233  }
3234 diff -urN linux-2.4.24.org/arch/s390/config.in linux-2.4.24/arch/s390/config.in
3235 --- linux-2.4.24.org/arch/s390/config.in        2004-02-04 23:09:47.685781486 +0100
3236 +++ linux-2.4.24/arch/s390/config.in    2004-02-04 23:11:31.887115888 +0100
3237 @@ -87,3 +87,11 @@
3238  
3239  source crypto/Config.in
3240  source lib/Config.in
3241 +
3242 +mainmenu_option next_comment
3243 +comment 'Grsecurity'
3244 +bool 'Grsecurity' CONFIG_GRKERNSEC
3245 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3246 +       source grsecurity/Config.in
3247 +fi
3248 +endmenu
3249 diff -urN linux-2.4.24.org/arch/s390x/config.in linux-2.4.24/arch/s390x/config.in
3250 --- linux-2.4.24.org/arch/s390x/config.in       2004-02-04 23:09:56.955853928 +0100
3251 +++ linux-2.4.24/arch/s390x/config.in   2004-02-04 23:11:31.892114849 +0100
3252 @@ -91,3 +91,11 @@
3253  
3254  source crypto/Config.in
3255  source lib/Config.in
3256 +
3257 +mainmenu_option next_comment
3258 +comment 'Grsecurity'
3259 +bool 'Grsecurity' CONFIG_GRKERNSEC
3260 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3261 +       source grsecurity/Config.in
3262 +fi
3263 +endmenu
3264 diff -urN linux-2.4.24.org/arch/sh/config.in linux-2.4.24/arch/sh/config.in
3265 --- linux-2.4.24.org/arch/sh/config.in  2004-02-04 23:09:34.998419612 +0100
3266 +++ linux-2.4.24/arch/sh/config.in      2004-02-04 23:11:31.913110484 +0100
3267 @@ -493,3 +493,11 @@
3268  
3269  source crypto/Config.in
3270  source lib/Config.in
3271 +
3272 +mainmenu_option next_comment
3273 +comment 'Grsecurity'
3274 +bool 'Grsecurity' CONFIG_GRKERNSEC
3275 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3276 +       source grsecurity/Config.in
3277 +fi
3278 +endmenu
3279 diff -urN linux-2.4.24.org/arch/sparc/boot/Makefile linux-2.4.24/arch/sparc/boot/Makefile
3280 --- linux-2.4.24.org/arch/sparc/boot/Makefile   2004-02-04 23:08:45.792651145 +0100
3281 +++ linux-2.4.24/arch/sparc/boot/Makefile       2004-02-04 23:11:31.915110068 +0100
3282 @@ -24,7 +24,7 @@
3283  
3284  BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o
3285  BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
3286 -       $(DRIVERS) $(NETWORKS)
3287 +       $(DRIVERS) $(NETWORKS) $(GRSECURITY)
3288  
3289  # I wanted to make this depend upon BTOBJS so that a parallel
3290  # build would work, but this fails because $(HEAD) cannot work
3291 diff -urN linux-2.4.24.org/arch/sparc/config.in linux-2.4.24/arch/sparc/config.in
3292 --- linux-2.4.24.org/arch/sparc/config.in       2004-02-04 23:08:44.885839701 +0100
3293 +++ linux-2.4.24/arch/sparc/config.in   2004-02-04 23:11:31.920109029 +0100
3294 @@ -282,3 +282,11 @@
3295  
3296  source crypto/Config.in
3297  source lib/Config.in
3298 +
3299 +mainmenu_option next_comment
3300 +comment 'Grsecurity'
3301 +bool 'Grsecurity' CONFIG_GRKERNSEC
3302 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3303 +       source grsecurity/Config.in
3304 +fi
3305 +endmenu
3306 diff -urN linux-2.4.24.org/arch/sparc/kernel/ptrace.c linux-2.4.24/arch/sparc/kernel/ptrace.c
3307 --- linux-2.4.24.org/arch/sparc/kernel/ptrace.c 2004-02-04 23:08:46.429518719 +0100
3308 +++ linux-2.4.24/arch/sparc/kernel/ptrace.c     2004-02-04 23:11:31.926107781 +0100
3309 @@ -17,6 +17,7 @@
3310  #include <linux/user.h>
3311  #include <linux/smp.h>
3312  #include <linux/smp_lock.h>
3313 +#include <linux/grsecurity.h>
3314  
3315  #include <asm/pgtable.h>
3316  #include <asm/system.h>
3317 @@ -310,6 +311,9 @@
3318                 goto out;
3319         }
3320  
3321 +       if(gr_handle_ptrace(child, request))
3322 +               goto out_tsk;
3323 +
3324         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3325             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3326                 if (ptrace_attach(child)) {
3327 diff -urN linux-2.4.24.org/arch/sparc/kernel/sys_sparc.c linux-2.4.24/arch/sparc/kernel/sys_sparc.c
3328 --- linux-2.4.24.org/arch/sparc/kernel/sys_sparc.c      2004-02-04 23:08:45.953617674 +0100
3329 +++ linux-2.4.24/arch/sparc/kernel/sys_sparc.c  2004-02-04 23:11:31.929107158 +0100
3330 @@ -20,6 +20,7 @@
3331  #include <linux/utsname.h>
3332  #include <linux/smp.h>
3333  #include <linux/smp_lock.h>
3334 +#include <linux/grsecurity.h>
3335  
3336  #include <asm/uaccess.h>
3337  #include <asm/ipc.h>
3338 @@ -54,6 +55,13 @@
3339                 return -ENOMEM;
3340         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
3341                 return -ENOMEM;
3342 +
3343 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3344 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3345 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3346 +       else
3347 +#endif
3348 +
3349         if (!addr)
3350                 addr = TASK_UNMAPPED_BASE;
3351  
3352 @@ -225,6 +233,11 @@
3353         struct file * file = NULL;
3354         unsigned long retval = -EBADF;
3355  
3356 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3357 +       if (flags & MAP_MIRROR)
3358 +               return -EINVAL;
3359 +#endif
3360 +
3361         if (!(flags & MAP_ANONYMOUS)) {
3362                 file = fget(fd);
3363                 if (!file)
3364 @@ -243,6 +256,12 @@
3365         if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
3366                 goto out_putf;
3367  
3368 +       if (gr_handle_mmap(file, prot)) {
3369 +               fput(file);
3370 +               retval = -EACCES;
3371 +               goto out;
3372 +       }
3373 +
3374         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3375  
3376         down_write(&current->mm->mmap_sem);
3377 diff -urN linux-2.4.24.org/arch/sparc/kernel/sys_sunos.c linux-2.4.24/arch/sparc/kernel/sys_sunos.c
3378 --- linux-2.4.24.org/arch/sparc/kernel/sys_sunos.c      2004-02-04 23:08:45.866635761 +0100
3379 +++ linux-2.4.24/arch/sparc/kernel/sys_sunos.c  2004-02-04 23:11:31.934106118 +0100
3380 @@ -68,6 +68,11 @@
3381         struct file * file = NULL;
3382         unsigned long retval, ret_type;
3383  
3384 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3385 +       if (flags & MAP_MIRROR)
3386 +               return -EINVAL;
3387 +#endif
3388 +
3389         if(flags & MAP_NORESERVE) {
3390                 static int cnt;
3391                 if (cnt++ < 10)
3392 diff -urN linux-2.4.24.org/arch/sparc/mm/fault.c linux-2.4.24/arch/sparc/mm/fault.c
3393 --- linux-2.4.24.org/arch/sparc/mm/fault.c      2004-02-04 23:08:47.679258856 +0100
3394 +++ linux-2.4.24/arch/sparc/mm/fault.c  2004-02-04 23:11:31.939105079 +0100
3395 @@ -19,6 +19,9 @@
3396  #include <linux/smp.h>
3397  #include <linux/smp_lock.h>
3398  #include <linux/interrupt.h>
3399 +#include <linux/slab.h>
3400 +#include <linux/pagemap.h>
3401 +#include <linux/compiler.h>
3402  
3403  #include <asm/system.h>
3404  #include <asm/segment.h>
3405 @@ -200,6 +203,264 @@
3406         return 0;
3407  }
3408  
3409 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3410 +void pax_emuplt_close(struct vm_area_struct * vma)
3411 +{
3412 +       vma->vm_mm->call_dl_resolve = 0UL;
3413 +}
3414 +
3415 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
3416 +{
3417 +       struct page* page;
3418 +       unsigned int *kaddr;
3419 +
3420 +       page = alloc_page(GFP_HIGHUSER);
3421 +       if (!page)
3422 +               return page;
3423 +
3424 +       kaddr = kmap(page);
3425 +       memset(kaddr, 0, PAGE_SIZE);
3426 +       kaddr[0] = 0x9DE3BFA8U; /* save */
3427 +       flush_dcache_page(page);
3428 +       kunmap(page);
3429 +       return page;
3430 +}
3431 +
3432 +static struct vm_operations_struct pax_vm_ops = {
3433 +       close:          pax_emuplt_close,
3434 +       nopage:         pax_emuplt_nopage,
3435 +};
3436 +
3437 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3438 +{
3439 +       vma->vm_mm = current->mm;
3440 +       vma->vm_start = addr;
3441 +       vma->vm_end = addr + PAGE_SIZE;
3442 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3443 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3444 +       vma->vm_ops = &pax_vm_ops;
3445 +       vma->vm_pgoff = 0UL;
3446 +       vma->vm_file = NULL;
3447 +       vma->vm_private_data = NULL;
3448 +       insert_vm_struct(current->mm, vma);
3449 +       ++current->mm->total_vm;
3450 +}
3451 +
3452 +/*
3453 + * PaX: decide what to do with offenders (regs->pc = fault address)
3454 + *
3455 + * returns 1 when task should be killed
3456 + *         2 when patched PLT trampoline was detected
3457 + *         3 when unpatched PLT trampoline was detected
3458 + *        4 when legitimate ET_EXEC was detected
3459 + */
3460 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3461 +{
3462 +       int err;
3463 +
3464 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3465 +       if (current->flags & PF_PAX_RANDEXEC) {
3466 +               if (regs->pc >= current->mm->start_code &&
3467 +                   regs->pc < current->mm->end_code)
3468 +               {
3469 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
3470 +                               return 1;
3471 +
3472 +                       regs->pc += current->mm->delta_exec;
3473 +                       if (regs->npc >= current->mm->start_code &&
3474 +                           regs->npc < current->mm->end_code)
3475 +                               regs->npc += current->mm->delta_exec;
3476 +                       return 4;
3477 +               }
3478 +               if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
3479 +                   regs->pc < current->mm->end_code + current->mm->delta_exec)
3480 +               {
3481 +                       regs->pc -= current->mm->delta_exec;
3482 +                       if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
3483 +                           regs->npc < current->mm->end_code + current->mm->delta_exec)
3484 +                               regs->npc -= current->mm->delta_exec;
3485 +               }
3486 +       }
3487 +#endif
3488 +
3489 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3490 +       do { /* PaX: patched PLT emulation #1 */
3491 +               unsigned int sethi1, sethi2, jmpl;
3492 +
3493 +               err = get_user(sethi1, (unsigned int *)regs->pc);
3494 +               err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
3495 +               err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
3496 +
3497 +               if (err)
3498 +                       break;
3499 +
3500 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3501 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
3502 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
3503 +               {
3504 +                       unsigned int addr;
3505 +
3506 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3507 +                       addr = regs->u_regs[UREG_G1];
3508 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3509 +                       regs->pc = addr;
3510 +                       regs->npc = addr+4;
3511 +                       return 2;
3512 +               }
3513 +       } while (0);
3514 +
3515 +       { /* PaX: patched PLT emulation #2 */
3516 +               unsigned int ba;
3517 +
3518 +               err = get_user(ba, (unsigned int *)regs->pc);
3519 +
3520 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3521 +                       unsigned int addr;
3522 +
3523 +                       addr = regs->pc + 4 + (((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U);
3524 +                       regs->pc = addr;
3525 +                       regs->npc = addr+4;
3526 +                       return 2;
3527 +               }
3528 +       }
3529 +
3530 +       do { /* PaX: patched PLT emulation #3 */
3531 +               unsigned int sethi, jmpl, nop;
3532 +
3533 +               err = get_user(sethi, (unsigned int*)regs->pc);
3534 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
3535 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
3536 +
3537 +               if (err)
3538 +                       break;
3539 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3540 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3541 +                   nop == 0x01000000U)
3542 +               {
3543 +                       unsigned int addr;
3544 +
3545 +                       addr = (sethi & 0x003FFFFFU) << 10;
3546 +                       regs->u_regs[UREG_G1] = addr;
3547 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3548 +                       regs->pc = addr;
3549 +                       regs->npc = addr+4;
3550 +                       return 2;
3551 +               }
3552 +       } while (0);
3553 +
3554 +       do { /* PaX: unpatched PLT emulation step 1 */
3555 +               unsigned int sethi, ba, nop;
3556 +
3557 +               err = get_user(sethi, (unsigned int *)regs->pc);
3558 +               err |= get_user(ba, (unsigned int *)(regs->pc+4));
3559 +               err |= get_user(nop, (unsigned int *)(regs->pc+8));
3560 +
3561 +               if (err)
3562 +                       break;
3563 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3564 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3565 +                   nop == 0x01000000U)
3566 +               {
3567 +                       unsigned int addr, save, call;
3568 +
3569 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
3570 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3571 +                       else
3572 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
3573 +
3574 +                       err = get_user(save, (unsigned int *)addr);
3575 +                       err |= get_user(call, (unsigned int *)(addr+4));
3576 +                       err |= get_user(nop, (unsigned int *)(addr+8)); 
3577 +                       if (err)
3578 +                               break;
3579 +
3580 +                       if (save == 0x9DE3BFA8U &&
3581 +                           (call & 0xC0000000U) == 0x40000000U &&
3582 +                           nop == 0x01000000U)
3583 +                       {
3584 +                               struct vm_area_struct *vma;
3585 +                               unsigned long call_dl_resolve;
3586 +
3587 +                               down_read(&current->mm->mmap_sem);
3588 +                               call_dl_resolve = current->mm->call_dl_resolve;
3589 +                               up_read(&current->mm->mmap_sem);
3590 +                               if (likely(call_dl_resolve))
3591 +                                       goto emulate;
3592 +
3593 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3594 +
3595 +                               down_write(&current->mm->mmap_sem);
3596 +                               if (current->mm->call_dl_resolve) {
3597 +                                       call_dl_resolve = current->mm->call_dl_resolve;
3598 +                                       up_write(&current->mm->mmap_sem);
3599 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3600 +                                       goto emulate;
3601 +                               }
3602 +
3603 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3604 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3605 +                                       up_write(&current->mm->mmap_sem);
3606 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3607 +                                       return 1;
3608 +                               }
3609 +
3610 +                               pax_insert_vma(vma, call_dl_resolve);
3611 +                               current->mm->call_dl_resolve = call_dl_resolve;
3612 +                               up_write(&current->mm->mmap_sem);
3613 +
3614 +emulate:
3615 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3616 +                               regs->pc = call_dl_resolve;
3617 +                               regs->npc = addr+4;
3618 +                               return 3;
3619 +                       }
3620 +               }
3621 +       } while (0);
3622 +
3623 +       do { /* PaX: unpatched PLT emulation step 2 */
3624 +               unsigned int save, call, nop;
3625 +
3626 +               err = get_user(save, (unsigned int*)(regs->pc-4));
3627 +               err |= get_user(call, (unsigned int*)regs->pc);
3628 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
3629 +               if (err)
3630 +                       break;
3631 +
3632 +               if (save == 0x9DE3BFA8U &&
3633 +                   (call & 0xC0000000U) == 0x40000000U &&
3634 +                   nop == 0x01000000U)
3635 +               {
3636 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
3637 +
3638 +                       regs->u_regs[UREG_RETPC] = regs->pc;
3639 +                       regs->pc = dl_resolve;
3640 +                       regs->npc = dl_resolve+4;
3641 +                       return 3;
3642 +               }
3643 +       } while (0);
3644 +
3645 +#endif
3646 +
3647 +       return 1;
3648 +}
3649 +
3650 +void pax_report_insns(void *pc)
3651 +{
3652 +       unsigned long i;
3653 +
3654 +       printk(KERN_ERR "PAX: bytes at PC: ");
3655 +       for (i = 0; i < 5; i++) {
3656 +               unsigned int c;
3657 +               if (get_user(c, (unsigned int*)pc+i)) {
3658 +                       printk("<invalid address>.");
3659 +                       break;
3660 +               }
3661 +               printk("%08x ", c);
3662 +       }
3663 +       printk("\n");
3664 +}
3665 +#endif
3666 +
3667  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
3668                                unsigned long address)
3669  {
3670 @@ -263,6 +524,29 @@
3671                 if(!(vma->vm_flags & VM_WRITE))
3672                         goto bad_area;
3673         } else {
3674 +
3675 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3676 +               if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
3677 +                       up_read(&mm->mmap_sem);
3678 +                       switch (pax_handle_fetch_fault(regs)) {
3679 +
3680 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3681 +                       case 2:
3682 +                       case 3:
3683 +                               return;
3684 +#endif
3685 +
3686 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3687 +                       case 4:
3688 +                               return;
3689 +#endif
3690 +
3691 +                       }
3692 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
3693 +                       do_exit(SIGKILL);
3694 +               }
3695 +#endif
3696 +
3697                 /* Allow reads even for write-only mappings */
3698                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
3699                         goto bad_area;
3700 diff -urN linux-2.4.24.org/arch/sparc/mm/init.c linux-2.4.24/arch/sparc/mm/init.c
3701 --- linux-2.4.24.org/arch/sparc/mm/init.c       2004-02-04 23:08:47.685257608 +0100
3702 +++ linux-2.4.24/arch/sparc/mm/init.c   2004-02-04 23:11:31.945103832 +0100
3703 @@ -350,17 +350,17 @@
3704  
3705         /* Initialize the protection map with non-constant, MMU dependent values. */
3706         protection_map[0] = PAGE_NONE;
3707 -       protection_map[1] = PAGE_READONLY;
3708 -       protection_map[2] = PAGE_COPY;
3709 -       protection_map[3] = PAGE_COPY;
3710 +       protection_map[1] = PAGE_READONLY_NOEXEC;
3711 +       protection_map[2] = PAGE_COPY_NOEXEC;
3712 +       protection_map[3] = PAGE_COPY_NOEXEC;
3713         protection_map[4] = PAGE_READONLY;
3714         protection_map[5] = PAGE_READONLY;
3715         protection_map[6] = PAGE_COPY;
3716         protection_map[7] = PAGE_COPY;
3717         protection_map[8] = PAGE_NONE;
3718 -       protection_map[9] = PAGE_READONLY;
3719 -       protection_map[10] = PAGE_SHARED;
3720 -       protection_map[11] = PAGE_SHARED;
3721 +       protection_map[9] = PAGE_READONLY_NOEXEC;
3722 +       protection_map[10] = PAGE_SHARED_NOEXEC;
3723 +       protection_map[11] = PAGE_SHARED_NOEXEC;
3724         protection_map[12] = PAGE_READONLY;
3725         protection_map[13] = PAGE_READONLY;
3726         protection_map[14] = PAGE_SHARED;
3727 diff -urN linux-2.4.24.org/arch/sparc/mm/srmmu.c linux-2.4.24/arch/sparc/mm/srmmu.c
3728 --- linux-2.4.24.org/arch/sparc/mm/srmmu.c      2004-02-04 23:08:47.649265092 +0100
3729 +++ linux-2.4.24/arch/sparc/mm/srmmu.c  2004-02-04 23:11:31.951102585 +0100
3730 @@ -2047,6 +2047,13 @@
3731         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
3732         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
3733         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
3734 +
3735 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3736 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
3737 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
3738 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
3739 +#endif
3740 +
3741         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
3742         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
3743         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
3744 diff -urN linux-2.4.24.org/arch/sparc64/config.in linux-2.4.24/arch/sparc64/config.in
3745 --- linux-2.4.24.org/arch/sparc64/config.in     2004-02-04 23:09:27.003082111 +0100
3746 +++ linux-2.4.24/arch/sparc64/config.in 2004-02-04 23:11:31.955101753 +0100
3747 @@ -319,3 +319,11 @@
3748  
3749  source crypto/Config.in
3750  source lib/Config.in
3751 +
3752 +mainmenu_option next_comment
3753 +comment 'Grsecurity'
3754 +bool 'Grsecurity' CONFIG_GRKERNSEC
3755 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3756 +       source grsecurity/Config.in
3757 +fi
3758 +endmenu
3759 diff -urN linux-2.4.24.org/arch/sparc64/kernel/ioctl32.c linux-2.4.24/arch/sparc64/kernel/ioctl32.c
3760 --- linux-2.4.24.org/arch/sparc64/kernel/ioctl32.c      2004-02-04 23:09:23.656777920 +0100
3761 +++ linux-2.4.24/arch/sparc64/kernel/ioctl32.c  2004-02-04 23:11:31.967099259 +0100
3762 @@ -2047,7 +2047,11 @@
3763          * To have permissions to do most of the vt ioctls, we either have
3764          * to be the owner of the tty, or super-user.
3765          */
3766 +#ifdef CONFIG_GRKERNSEC
3767 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3768 +#else
3769         if (current->tty == tty || suser())
3770 +#endif
3771                 return 1;
3772         return 0;                                                    
3773  }
3774 diff -urN linux-2.4.24.org/arch/sparc64/kernel/itlb_base.S linux-2.4.24/arch/sparc64/kernel/itlb_base.S
3775 --- linux-2.4.24.org/arch/sparc64/kernel/itlb_base.S    2004-02-04 23:09:23.933720335 +0100
3776 +++ linux-2.4.24/arch/sparc64/kernel/itlb_base.S        2004-02-04 23:11:31.970098635 +0100
3777 @@ -41,7 +41,9 @@
3778         CREATE_VPTE_OFFSET2(%g4, %g6)                   ! Create VPTE offset
3779         ldxa            [%g3 + %g6] ASI_P, %g5          ! Load VPTE
3780  1:     brgez,pn        %g5, 3f                         ! Not valid, branch out
3781 -        nop                                            ! Delay-slot
3782 +       and             %g5, _PAGE_EXEC, %g4
3783 +       brz,pn          %g4, 3f                         ! Not executable, branch out
3784 +       nop                                             ! Delay-slot
3785  2:     stxa            %g5, [%g0] ASI_ITLB_DATA_IN     ! Load PTE into TLB
3786         retry                                           ! Trap return
3787  3:     rdpr            %pstate, %g4                    ! Move into alternate globals
3788 @@ -74,8 +76,6 @@
3789         nop
3790         nop
3791         nop
3792 -       nop
3793 -       nop
3794         CREATE_VPTE_NOP
3795  
3796  #undef CREATE_VPTE_OFFSET1
3797 diff -urN linux-2.4.24.org/arch/sparc64/kernel/ptrace.c linux-2.4.24/arch/sparc64/kernel/ptrace.c
3798 --- linux-2.4.24.org/arch/sparc64/kernel/ptrace.c       2004-02-04 23:09:23.965713682 +0100
3799 +++ linux-2.4.24/arch/sparc64/kernel/ptrace.c   2004-02-04 23:11:31.975097596 +0100
3800 @@ -18,6 +18,7 @@
3801  #include <linux/user.h>
3802  #include <linux/smp.h>
3803  #include <linux/smp_lock.h>
3804 +#include <linux/grsecurity.h>
3805  
3806  #include <asm/asi.h>
3807  #include <asm/pgtable.h>
3808 @@ -161,6 +162,11 @@
3809                 goto out;
3810         }
3811  
3812 +       if (gr_handle_ptrace(child, (long)request)) {
3813 +               pt_error_return(regs, EPERM);
3814 +               goto out_tsk;
3815 +       }
3816 +
3817         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3818             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3819                 if (ptrace_attach(child)) {
3820 diff -urN linux-2.4.24.org/arch/sparc64/kernel/sys_sparc32.c linux-2.4.24/arch/sparc64/kernel/sys_sparc32.c
3821 --- linux-2.4.24.org/arch/sparc64/kernel/sys_sparc32.c  2004-02-04 23:09:24.185667946 +0100
3822 +++ linux-2.4.24/arch/sparc64/kernel/sys_sparc32.c      2004-02-04 23:11:31.983095933 +0100
3823 @@ -52,6 +52,8 @@
3824  #include <linux/sysctl.h>
3825  #include <linux/dnotify.h>
3826  #include <linux/netfilter_ipv4/ip_tables.h>
3827 +#include <linux/random.h>
3828 +#include <linux/grsecurity.h>
3829  
3830  #include <asm/types.h>
3831  #include <asm/ipc.h>
3832 @@ -3235,8 +3237,18 @@
3833         struct file * file;
3834         int retval;
3835         int i;
3836 +#ifdef CONFIG_GRKERNSEC
3837 +       struct file *old_exec_file;
3838 +       struct acl_subject_label *old_acl;
3839 +       struct rlimit old_rlim[RLIM_NLIMITS];
3840 +#endif
3841  
3842         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3843 +
3844 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
3845 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
3846 +#endif
3847 +
3848         memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3849  
3850         file = open_exec(filename);
3851 @@ -3245,6 +3257,20 @@
3852         if (IS_ERR(file))
3853                 return retval;
3854  
3855 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
3856 +
3857 +       if (gr_handle_nproc()) {
3858 +               allow_write_access(file);
3859 +               fput(file);
3860 +               return -EAGAIN;
3861 +       }
3862 +
3863 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
3864 +               allow_write_access(file);
3865 +               fput(file);
3866 +               return -EACCES;
3867 +       }
3868 +
3869         bprm.file = file;
3870         bprm.filename = filename;
3871         bprm.sh_bang = 0;
3872 @@ -3265,11 +3291,24 @@
3873         if (retval < 0)
3874                 goto out;
3875         
3876 +       if(!gr_tpe_allow(file)) {
3877 +               retval = -EACCES;
3878 +               goto out;
3879 +       }
3880 +
3881 +       if (gr_check_crash_exec(file)) {
3882 +               retval = -EACCES;
3883 +               goto out;
3884 +       }
3885 +
3886         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3887         if (retval < 0)
3888                 goto out;
3889  
3890         bprm.exec = bprm.p;
3891 +
3892 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
3893 +
3894         retval = copy_strings32(bprm.envc, envp, &bprm);
3895         if (retval < 0)
3896                 goto out;
3897 @@ -3278,11 +3317,32 @@
3898         if (retval < 0)
3899                 goto out;
3900  
3901 +#ifdef CONFIG_GRKERNSEC
3902 +       old_acl = current->acl;
3903 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
3904 +       old_exec_file = current->exec_file;
3905 +       get_file(file);
3906 +       current->exec_file = file;
3907 +#endif
3908 +
3909 +        gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
3910 +
3911         retval = search_binary_handler(&bprm, regs);
3912 -       if (retval >= 0)
3913 +       if (retval >= 0) {
3914 +#ifdef CONFIG_GRKERNSEC
3915 +               if (old_exec_file)
3916 +                       fput(old_exec_file);
3917 +#endif
3918                 /* execve success */
3919                 return retval;
3920 +       }
3921  
3922 +#ifdef CONFIG_GRKERNSEC
3923 +       current->acl = old_acl;
3924 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
3925 +       fput(current->exec_file);
3926 +       current->exec_file = old_exec_file;
3927 +#endif
3928  out:
3929         /* Something went wrong, return the inode and free the argument pages*/
3930         allow_write_access(bprm.file);
3931 diff -urN linux-2.4.24.org/arch/sparc64/kernel/sys_sparc.c linux-2.4.24/arch/sparc64/kernel/sys_sparc.c
3932 --- linux-2.4.24.org/arch/sparc64/kernel/sys_sparc.c    2004-02-04 23:09:23.780752142 +0100
3933 +++ linux-2.4.24/arch/sparc64/kernel/sys_sparc.c        2004-02-04 23:11:31.988094894 +0100
3934 @@ -24,6 +24,7 @@
3935  #include <linux/slab.h>
3936  #include <linux/ipc.h>
3937  #include <linux/personality.h>
3938 +#include <linux/grsecurity.h>
3939  
3940  #include <asm/uaccess.h>
3941  #include <asm/ipc.h>
3942 @@ -63,6 +64,13 @@
3943                 task_size = 0xf0000000UL;
3944         if (len > task_size || len > -PAGE_OFFSET)
3945                 return -ENOMEM;
3946 +
3947 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3948 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3949 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3950 +       else
3951 +#endif
3952 +
3953         if (!addr)
3954                 addr = TASK_UNMAPPED_BASE;
3955  
3956 @@ -289,11 +297,22 @@
3957         struct file * file = NULL;
3958         unsigned long retval = -EBADF;
3959  
3960 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3961 +       if (flags & MAP_MIRROR)
3962 +               return -EINVAL;
3963 +#endif
3964 +
3965         if (!(flags & MAP_ANONYMOUS)) {
3966                 file = fget(fd);
3967                 if (!file)
3968                         goto out;
3969         }
3970 +
3971 +       if (gr_handle_mmap(file, prot)) {
3972 +               retval = -EACCES;
3973 +               goto out_putf;
3974 +       }
3975 +
3976         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3977         len = PAGE_ALIGN(len);
3978         retval = -EINVAL;
3979 diff -urN linux-2.4.24.org/arch/sparc64/kernel/sys_sunos32.c linux-2.4.24/arch/sparc64/kernel/sys_sunos32.c
3980 --- linux-2.4.24.org/arch/sparc64/kernel/sys_sunos32.c  2004-02-04 23:09:23.420826982 +0100
3981 +++ linux-2.4.24/arch/sparc64/kernel/sys_sunos32.c      2004-02-04 23:11:31.994093646 +0100
3982 @@ -68,6 +68,11 @@
3983         struct file *file = NULL;
3984         unsigned long retval, ret_type;
3985  
3986 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3987 +       if (flags & MAP_MIRROR)
3988 +               return -EINVAL;
3989 +#endif
3990 +
3991         if(flags & MAP_NORESERVE) {
3992                 static int cnt;
3993                 if (cnt++ < 10)
3994 diff -urN linux-2.4.24.org/arch/sparc64/mm/fault.c linux-2.4.24/arch/sparc64/mm/fault.c
3995 --- linux-2.4.24.org/arch/sparc64/mm/fault.c    2004-02-04 23:09:26.150259442 +0100
3996 +++ linux-2.4.24/arch/sparc64/mm/fault.c        2004-02-04 23:11:31.999092607 +0100
3997 @@ -16,6 +16,9 @@
3998  #include <linux/smp_lock.h>
3999  #include <linux/init.h>
4000  #include <linux/interrupt.h>
4001 +#include <linux/slab.h>
4002 +#include <linux/pagemap.h>
4003 +#include <linux/compiler.h>
4004  
4005  #include <asm/page.h>
4006  #include <asm/pgtable.h>
4007 @@ -299,6 +302,360 @@
4008         unhandled_fault (address, current, regs);
4009  }
4010  
4011 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
4012 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4013 +static void pax_emuplt_close(struct vm_area_struct * vma)
4014 +{
4015 +       vma->vm_mm->call_dl_resolve = 0UL;
4016 +}
4017 +
4018 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
4019 +{
4020 +       struct page* page;
4021 +       unsigned int *kaddr;
4022 +
4023 +       page = alloc_page(GFP_HIGHUSER);
4024 +       if (!page)
4025 +               return page;
4026 +
4027 +       kaddr = kmap(page);
4028 +       memset(kaddr, 0, PAGE_SIZE);
4029 +       kaddr[0] = 0x9DE3BFA8U; /* save */
4030 +       flush_dcache_page(page);
4031 +       kunmap(page);
4032 +       return page;
4033 +}
4034 +
4035 +static struct vm_operations_struct pax_vm_ops = {
4036 +       close:          pax_emuplt_close,
4037 +       nopage:         pax_emuplt_nopage,
4038 +};
4039 +
4040 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4041 +{
4042 +       vma->vm_mm = current->mm;
4043 +       vma->vm_start = addr;
4044 +       vma->vm_end = addr + PAGE_SIZE;
4045 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4046 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
4047 +       vma->vm_ops = &pax_vm_ops;
4048 +       vma->vm_pgoff = 0UL; 
4049 +       vma->vm_file = NULL;
4050 +       vma->vm_private_data = NULL;
4051 +       insert_vm_struct(current->mm, vma);
4052 +       ++current->mm->total_vm;
4053 +}
4054 +#endif
4055 +
4056 +/*
4057 + * PaX: decide what to do with offenders (regs->tpc = fault address)
4058 + *
4059 + * returns 1 when task should be killed
4060 + *         2 when patched PLT trampoline was detected
4061 + *         3 when unpatched PLT trampoline was detected
4062 + *        4 when legitimate ET_EXEC was detected
4063 + */
4064 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4065 +{
4066 +       int err;
4067 +
4068 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4069 +       if (current->flags & PF_PAX_RANDEXEC) {
4070 +               if (regs->tpc >= current->mm->start_code &&
4071 +                   regs->tpc < current->mm->end_code)
4072 +               {
4073 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
4074 +                               return 1;
4075 +
4076 +                       regs->tpc += current->mm->delta_exec;
4077 +                       if (regs->tnpc >= current->mm->start_code &&
4078 +                           regs->tnpc < current->mm->end_code)
4079 +                               regs->tnpc += current->mm->delta_exec;
4080 +                       return 4;
4081 +               }
4082 +               if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
4083 +                   regs->tpc < current->mm->end_code + current->mm->delta_exec)
4084 +               {
4085 +                       regs->tpc -= current->mm->delta_exec;
4086 +                       if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
4087 +                           regs->tnpc < current->mm->end_code + current->mm->delta_exec)
4088 +                               regs->tnpc -= current->mm->delta_exec;
4089 +               }
4090 +       }
4091 +#endif
4092 +
4093 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4094 +       do { /* PaX: patched PLT emulation #1 */
4095 +               unsigned int sethi1, sethi2, jmpl;
4096 +
4097 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4098 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4099 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
4100 +
4101 +               if (err)
4102 +                       break;
4103 +
4104 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4105 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
4106 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
4107 +               {
4108 +                       unsigned long addr;
4109 +
4110 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4111 +                       addr = regs->u_regs[UREG_G1];
4112 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4113 +                       regs->tpc = addr;
4114 +                       regs->tnpc = addr+4;
4115 +                       return 2;
4116 +               }
4117 +       } while (0);
4118 +
4119 +       { /* PaX: patched PLT emulation #2 */
4120 +               unsigned int ba;
4121 +
4122 +               err = get_user(ba, (unsigned int*)regs->tpc);
4123 +
4124 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4125 +                       unsigned long addr;
4126 +
4127 +                       addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL);
4128 +                       regs->tpc = addr;
4129 +                       regs->tnpc = addr+4;
4130 +                       return 2;
4131 +               }
4132 +       }
4133 +
4134 +       do { /* PaX: patched PLT emulation #3 */
4135 +               unsigned int sethi, jmpl, nop;
4136 +
4137 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4138 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
4139 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4140 +
4141 +               if (err)
4142 +                       break;
4143 +
4144 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4145 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4146 +                   nop == 0x01000000U)
4147 +               {
4148 +                       unsigned long addr;
4149 +
4150 +                       addr = (sethi & 0x003FFFFFU) << 10;
4151 +                       regs->u_regs[UREG_G1] = addr;
4152 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4153 +                       regs->tpc = addr;
4154 +                       regs->tnpc = addr+4;
4155 +                       return 2;
4156 +               }
4157 +       } while (0);
4158 +
4159 +       do { /* PaX: patched PLT emulation #4 */
4160 +               unsigned int mov1, call, mov2;
4161 +
4162 +               err = get_user(mov1, (unsigned int*)regs->tpc);
4163 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
4164 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
4165 +
4166 +               if (err)
4167 +                       break;
4168 +
4169 +               if (mov1 == 0x8210000FU &&
4170 +                   (call & 0xC0000000U) == 0x40000000U &&
4171 +                   mov2 == 0x9E100001U)
4172 +               {
4173 +                       unsigned long addr;
4174 +
4175 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4176 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4177 +                       regs->tpc = addr;
4178 +                       regs->tnpc = addr+4;
4179 +                       return 2;
4180 +               }
4181 +       } while (0);
4182 +
4183 +       do { /* PaX: patched PLT emulation #5 */
4184 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4185 +
4186 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4187 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4188 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
4189 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
4190 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
4191 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
4192 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
4193 +
4194 +               if (err)
4195 +                       break;
4196 +
4197 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4198 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4199 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
4200 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
4201 +                   sllx == 0x83287020 &&
4202 +                   jmpl == 0x81C04005U &&
4203 +                   nop == 0x01000000U)
4204 +               {
4205 +                       unsigned long addr;
4206 +
4207 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4208 +                       regs->u_regs[UREG_G1] <<= 32;
4209 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4210 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4211 +                       regs->tpc = addr;
4212 +                       regs->tnpc = addr+4;
4213 +                       return 2;
4214 +               }
4215 +       } while (0);
4216 +
4217 +       do { /* PaX: patched PLT emulation #6 */
4218 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
4219 +
4220 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4221 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4222 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
4223 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
4224 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
4225 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
4226 +
4227 +               if (err)
4228 +                       break;
4229 +
4230 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4231 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4232 +                   sllx == 0x83287020 &&
4233 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
4234 +                   jmpl == 0x81C04005U &&
4235 +                   nop == 0x01000000U)
4236 +               {
4237 +                       unsigned long addr;
4238 +
4239 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
4240 +                       regs->u_regs[UREG_G1] <<= 32;
4241 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
4242 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4243 +                       regs->tpc = addr;
4244 +                       regs->tnpc = addr+4;
4245 +                       return 2;
4246 +               }
4247 +       } while (0);
4248 +
4249 +       do { /* PaX: unpatched PLT emulation step 1 */
4250 +               unsigned int sethi, ba, nop;
4251 +
4252 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4253 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
4254 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4255 +
4256 +               if (err)
4257 +                       break;
4258 +
4259 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4260 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4261 +                   nop == 0x01000000U)
4262 +               {
4263 +                       unsigned long addr;
4264 +                       unsigned int save, call;
4265 +
4266 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
4267 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4268 +                       else
4269 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4270 +
4271 +                       err = get_user(save, (unsigned int*)addr);
4272 +                       err |= get_user(call, (unsigned int*)(addr+4));
4273 +                       err |= get_user(nop, (unsigned int*)(addr+8));
4274 +
4275 +                       if (err)
4276 +                               break;
4277 +
4278 +                       if (save == 0x9DE3BFA8U &&
4279 +                           (call & 0xC0000000U) == 0x40000000U &&
4280 +                           nop == 0x01000000U)
4281 +                       {
4282 +                               struct vm_area_struct *vma;
4283 +                               unsigned long call_dl_resolve;
4284 +
4285 +                               down_read(&current->mm->mmap_sem);
4286 +                               call_dl_resolve = current->mm->call_dl_resolve;
4287 +                               up_read(&current->mm->mmap_sem);
4288 +                               if (likely(call_dl_resolve))
4289 +                                       goto emulate;
4290 +
4291 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4292 +
4293 +                               down_write(&current->mm->mmap_sem);
4294 +                               if (current->mm->call_dl_resolve) {
4295 +                                       call_dl_resolve = current->mm->call_dl_resolve;
4296 +                                       up_write(&current->mm->mmap_sem);
4297 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4298 +                                       goto emulate;
4299 +                               }
4300 +
4301 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4302 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4303 +                                       up_write(&current->mm->mmap_sem);
4304 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4305 +                                       return 1;
4306 +                               }
4307 +
4308 +                               pax_insert_vma(vma, call_dl_resolve);
4309 +                               current->mm->call_dl_resolve = call_dl_resolve;
4310 +                               up_write(&current->mm->mmap_sem);
4311 +
4312 +emulate:
4313 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4314 +                               regs->tpc = call_dl_resolve;
4315 +                               regs->tnpc = addr+4;
4316 +                               return 3;
4317 +                       }
4318 +               }
4319 +       } while (0);
4320 +
4321 +       do { /* PaX: unpatched PLT emulation step 2 */
4322 +               unsigned int save, call, nop;
4323 +
4324 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
4325 +               err |= get_user(call, (unsigned int*)regs->tpc);
4326 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
4327 +               if (err)
4328 +                       break;
4329 +
4330 +               if (save == 0x9DE3BFA8U &&
4331 +                   (call & 0xC0000000U) == 0x40000000U &&
4332 +                   nop == 0x01000000U)
4333 +               {
4334 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4335 +
4336 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
4337 +                       regs->tpc = dl_resolve;
4338 +                       regs->tnpc = dl_resolve+4;
4339 +                       return 3;
4340 +               }
4341 +       } while (0);
4342 +#endif
4343 +
4344 +       return 1;
4345 +}
4346 +
4347 +void pax_report_insns(void *pc)
4348 +{
4349 +       unsigned long i;
4350 +
4351 +       printk(KERN_ERR "PAX: bytes at PC: ");
4352 +       for (i = 0; i < 5; i++) {
4353 +               unsigned int c;
4354 +               if (get_user(c, (unsigned int*)pc+i)) {
4355 +                       printk("<invalid address>.");
4356 +                       break;
4357 +               }
4358 +               printk("%08x ", c);
4359 +       }
4360 +       printk("\n");
4361 +}
4362 +#endif  
4363 +
4364 +
4365  asmlinkage void do_sparc64_fault(struct pt_regs *regs)
4366  {
4367         struct mm_struct *mm = current->mm;
4368 @@ -338,6 +695,7 @@
4369  
4370         if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
4371                 regs->tpc &= 0xffffffff;
4372 +               regs->tnpc &= 0xffffffff;
4373                 address &= 0xffffffff;
4374         }
4375  
4376 @@ -346,6 +704,34 @@
4377         if (!vma)
4378                 goto bad_area;
4379  
4380 +       /* PaX: detect ITLB misses on non-exec pages */
4381 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
4382 +       if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address && 
4383 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
4384 +       {
4385 +               if (address != regs->tpc)
4386 +                       goto good_area;
4387 +
4388 +               up_read(&mm->mmap_sem);
4389 +               switch (pax_handle_fetch_fault(regs)) {
4390 +
4391 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4392 +               case 2:
4393 +               case 3:
4394 +                       goto fault_done;
4395 +#endif
4396 +
4397 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4398 +               case 4:
4399 +                       goto fault_done;
4400 +#endif
4401 +
4402 +               }
4403 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
4404 +               do_exit(SIGKILL);
4405 +       }
4406 +#endif
4407 +
4408         /* Pure DTLB misses do not tell us whether the fault causing
4409          * load/store/atomic was a write or not, it only says that there
4410          * was no match.  So in such a case we (carefully) read the
4411 diff -urN linux-2.4.24.org/arch/sparc64/solaris/misc.c linux-2.4.24/arch/sparc64/solaris/misc.c
4412 --- linux-2.4.24.org/arch/sparc64/solaris/misc.c        2004-02-04 23:09:26.540178364 +0100
4413 +++ linux-2.4.24/arch/sparc64/solaris/misc.c    2004-02-04 23:11:32.005091360 +0100
4414 @@ -54,6 +54,11 @@
4415         struct file *file = NULL;
4416         unsigned long retval, ret_type;
4417  
4418 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4419 +       if (flags & MAP_MIRROR)
4420 +               return -EINVAL;
4421 +#endif
4422 +
4423         /* Do we need it here? */
4424         set_personality(PER_SVR4);
4425         if (flags & MAP_NORESERVE) {
4426 diff -urN linux-2.4.24.org/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.24/arch/x86_64/ia32/ia32_ioctl.c
4427 --- linux-2.4.24.org/arch/x86_64/ia32/ia32_ioctl.c      2004-02-04 23:08:31.938531882 +0100
4428 +++ linux-2.4.24/arch/x86_64/ia32/ia32_ioctl.c  2004-02-04 23:11:32.013089697 +0100
4429 @@ -1940,7 +1940,11 @@
4430          * To have permissions to do most of the vt ioctls, we either have
4431          * to be the owner of the tty, or super-user.
4432          */
4433 +#ifdef CONFIG_GRKERNSEC
4434 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
4435 +#else
4436         if (current->tty == tty || suser())
4437 +#endif
4438                 return 1;
4439         return 0;                                                    
4440  }
4441 diff -urN linux-2.4.24.org/Documentation/Configure.help linux-2.4.24/Documentation/Configure.help
4442 --- linux-2.4.24.org/Documentation/Configure.help       2004-02-04 23:10:23.345366668 +0100
4443 +++ linux-2.4.24/Documentation/Configure.help   2004-02-04 23:11:32.070077848 +0100
4444 @@ -3002,6 +3002,20 @@
4445    If you want to compile it as a module, say M here and read
4446    Documentation/modules.txt.  If unsure, say `N'.
4447  
4448 +stealth networking support
4449 +CONFIG_IP_NF_MATCH_STEALTH
4450 +  Enabling this option will drop all syn packets coming to unserved tcp
4451 +  ports as well as all packets coming to unserved udp ports.  If you
4452 +  are using your system to route any type of packets (ie. via NAT)
4453 +  you should put this module at the end of your ruleset, since it will 
4454 +  drop packets that aren't going to ports that are listening on your 
4455 +  machine itself, it doesn't take into account that the packet might be 
4456 +  destined for someone on your internal network if you're using NAT for 
4457 +  instance.
4458 +
4459 +  If you want to compile it as a module, say M here and read
4460 +  Documentation/modules.txt.  If unsure, say `N'.
4461 +
4462  MAC address match support
4463  CONFIG_IP_NF_MATCH_MAC
4464    MAC matching allows you to match packets based on the source
4465 @@ -24277,6 +24291,897 @@
4466  
4467    "Area6" will work for most boards. For ADX, select "Area5".
4468  
4469 +Grsecurity
4470 +CONFIG_GRKERNSEC
4471 +  If you say Y here, you will be able to configure many features that
4472 +  will enhance the security of your system.  It is highly recommended
4473 +  that you say Y here and read through the help for each option so
4474 +  you fully understand the features and can evaluate their usefulness
4475 +  for your machine.
4476 +
4477 +Additional security levels
4478 +CONFIG_GRKERNSEC_LOW
4479 +
4480 +  Low additional security
4481 +  -----------------------------------------------------------------------
4482 +  If you choose this option, several of the grsecurity options will
4483 +  be enabled that will give you greater protection against a number
4484 +  of attacks, while assuring that none of your software will have any 
4485 +  conflicts with the additional security measures.  If you run a lot of 
4486 +  unusual software, or you are having problems with the higher security 
4487 +  levels, you should say Y here.  With this option, the following features
4488 +  are enabled:
4489 +  
4490 +  linking restrictions
4491 +  fifo restrictions
4492 +  random pids
4493 +  enforcing nproc on execve()
4494 +  restricted dmesg
4495 +  random ip ids
4496 +  enforced chdir("/") on chroot
4497 +
4498 +  Medium additional security
4499 +  -----------------------------------------------------------------------
4500 +  If you say Y here, several features in addition to those included in the 
4501 +  low additional security level will be enabled.  These features provide
4502 +  even more security to your system, though in rare cases they may
4503 +  be incompatible with very old or poorly written software.  If you 
4504 +  enable this option, make sure that your auth service (identd) is 
4505 +  running as gid 10 (usually group wheel). With this option the following 
4506 +  features (in addition to those provided in the low additional security 
4507 +  level) will be enabled:
4508 +
4509 +  random tcp source ports
4510 +  failed fork logging
4511 +  time change logging
4512 +  signal logging
4513 +  deny mounts in chroot
4514 +  deny double chrooting
4515 +  deny sysctl writes in chroot
4516 +  deny mknod in chroot
4517 +  deny access to abstract AF_UNIX sockets out of chroot
4518 +  deny pivot_root in chroot
4519 +  denied writes of /dev/kmem, /dev/mem, and /dev/port
4520 +  /proc restrictions with special gid set to 10 (usually wheel)
4521 +  address space layout randomization
4522 +  removal of addresses from /proc/<pid>/[maps|stat]
4523 +
4524 +  High additional security
4525 +  ----------------------------------------------------------------------
4526 +  If you say Y here, many of the features of grsecurity will be enabled,
4527 +  that will protect you against many kinds of attacks against
4528 +  your system.  The heightened security comes at a cost of an 
4529 +  increased chance of incompatibilities with rare software on your 
4530 +  machine.  Since this security level enables PaX, you should view 
4531 +  <http://pageexec.virtualave.net> and read about the PaX project.  While 
4532 +  you are there, download chpax and run it on binaries that cause 
4533 +  problems with PaX.  Also remember that since the /proc restrictions are 
4534 +  enabled, you must run your identd as group wheel (gid 10).  
4535 +  This security level enables the following features in addition to those
4536 +  listed in the low and medium security levels:
4537 +
4538 +  additional /proc restrictions
4539 +  chmod restrictions in chroot
4540 +  no signals, ptrace, or viewing processes outside of chroot
4541 +  capability restrictions in chroot
4542 +  deny fchdir out of chroot
4543 +  priority restrictions in chroot
4544 +  segmentation-based implementation of PaX
4545 +  mprotect restrictions
4546 +  kernel stack randomization
4547 +  mount/unmount/remount logging
4548 +  kernel symbol hiding
4549 +
4550 +Customized additional security
4551 +CONFIG_GRKERNSEC_CUSTOM
4552 +  If you say Y here, you will be able to configure every grsecurity 
4553 +  option, which allows you to enable many more features that aren't 
4554 +  covered in the basic security levels.  These additional features include 
4555 +  TPE, socket restrictions, and the sysctl system for grsecurity.  It is 
4556 +  advised that you read through the help for each option to determine its 
4557 +  usefulness in your situation.
4558 +
4559 +Enforce non-executable pages
4560 +CONFIG_GRKERNSEC_PAX_NOEXEC
4561 +  By design some architectures do not allow for protecting memory
4562 +  pages against execution or even if they do, Linux does not make
4563 +  use of this feature.  In practice this means that if a page is
4564 +  readable (such as the stack or heap) it is also executable.
4565 +
4566 +  There is a well known exploit technique that makes use of this
4567 +  fact and a common programming mistake where an attacker can
4568 +  introduce code of his choice somewhere in the attacked program's
4569 +  memory (typically the stack or the heap) and then execute it.
4570 +
4571 +  If the attacked program was running with different (typically
4572 +  higher) privileges than that of the attacker, then he can elevate
4573 +  his own privilege level (e.g. get a root shell, write to files for
4574 +  which he does not have write access to, etc).
4575 +
4576 +  Enabling this option will let you choose from various features
4577 +  that prevent the injection and execution of 'foreign' code in
4578 +  a program.
4579 +
4580 +  This will also break programs that rely on the old behaviour and
4581 +  expect that dynamically allocated memory via the malloc() family
4582 +  of functions is executable (which it is not).  Notable examples
4583 +  are the XFree86 4.x server, the java runtime and wine.
4584 +
4585 +  NOTE: you can use the 'chpax' utility to enable/disable this
4586 +  feature on a per file basis.  chpax is available at
4587 +  <http://pageexec.virtualave.net>
4588 +
4589 +Paging based non-executable pages
4590 +CONFIG_GRKERNSEC_PAX_PAGEEXEC
4591 +  This implementation is based on the paging feature of the CPU.
4592 +  On i386 it has a variable performance impact on applications
4593 +  depending on their memory usage pattern.  You should carefully
4594 +  test your applications before using this feature in production.
4595 +  On alpha, parisc, sparc and sparc64 there is no performance
4596 +  impact.  On ppc there is a slight performance impact.
4597 +
4598 +Segmentation based non-executable pages
4599 +CONFIG_GRKERNSEC_PAX_SEGMEXEC
4600 +  This implementation is based on the segmentation feature of the
4601 +  CPU and has little performance impact, however applications will
4602 +  be limited to a 1.5 GB address space instead of the normal 3 GB.
4603 +
4604 +Emulate trampolines
4605 +CONFIG_GRKERNSEC_PAX_EMUTRAMP
4606 +  There are some programs and libraries that for one reason or
4607 +  another attempt to execute special small code snippets from
4608 +  non-executable memory pages.  Most notable examples are the
4609 +  signal handler return code generated by the kernel itself and
4610 +  the GCC trampolines.
4611 +
4612 +  If you enabled CONFIG_GRKERNSEC_PAX_PAGEEXEC or 
4613 +  CONFIG_GRKERNSEC_PAX_SEGMEXEC then such programs will no longer
4614 +  work under your kernel.
4615 +
4616 +  As a remedy you can say Y here and use the 'chpax' utility to
4617 +  enable trampoline emulation for the affected programs yet still
4618 +  have the protection provided by the non-executable pages.
4619 +
4620 +  On parisc and ppc you MUST enable this option and EMUSIGRT as
4621 +  well, otherwise your system will not even boot.
4622 +
4623 +  Alternatively you can say N here and use the 'chpax' utility
4624 +  to disable CONFIG_GRKERNSEC_PAX_PAGEEXEC and 
4625 +  CONFIG_GRKERNSEC_PAX_SEGMEXEC for the affected files.
4626 +
4627 +  NOTE: enabling this feature *may* open up a loophole in the
4628 +  protection provided by non-executable pages that an attacker
4629 +  could abuse.  Therefore the best solution is to not have any
4630 +  files on your system that would require this option.  This can
4631 +  be achieved by not using libc5 (which relies on the kernel
4632 +  signal handler return code) and not using or rewriting programs
4633 +  that make use of the nested function implementation of GCC.
4634 +  Skilled users can just fix GCC itself so that it implements
4635 +  nested function calls in a way that does not interfere with PaX.
4636 +
4637 +Automatically emulate sigreturn trampolines
4638 +CONFIG_GRKERNSEC_PAX_EMUSIGRT
4639 +  Enabling this option will have the kernel automatically detect
4640 +  and emulate signal return trampolines executing on the stack
4641 +  that would otherwise lead to task termination.
4642 +
4643 +  This solution is intended as a temporary one for users with
4644 +  legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
4645 +  Modula-3 runtime, etc) or executables linked to such, basically
4646 +  everything that does not specify its own SA_RESTORER function in
4647 +  normal executable memory like glibc 2.1+ does.
4648 +
4649 +  On parisc and ppc you MUST enable this option, otherwise your
4650 +  system will not even boot.
4651 +
4652 +  NOTE: this feature cannot be disabled on a per executable basis
4653 +  and since it *does* open up a loophole in the protection provided
4654 +  by non-executable pages, the best solution is to not have any
4655 +  files on your system that would require this option.
4656 +
4657 +Restrict mprotect()
4658 +CONFIG_GRKERNSEC_PAX_MPROTECT
4659 +  Enabling this option will prevent programs from
4660 +   - changing the executable status of memory pages that were
4661 +     not originally created as executable,
4662 +   - making read-only executable pages writable again,
4663 +   - creating executable pages from anonymous memory.
4664 +
4665 +  You should say Y here to complete the protection provided by
4666 +  the enforcement of non-executable pages.
4667 +
4668 +  NOTE: you can use the 'chpax' utility to control this
4669 +  feature on a per file basis. chpax is available at
4670 +  <http://pageexec.virtualave.net>
4671 +
4672 +Disallow ELF text relocations
4673 +CONFIG_GRKERNSEC_PAX_NOELFRELOCS
4674 +  Non-executable pages and mprotect() restrictions are effective
4675 +  in preventing the introduction of new executable code into an
4676 +  attacked task's address space.  There remain only two venues
4677 +  for this kind of attack: if the attacker can execute already
4678 +  existing code in the attacked task then he can either have it
4679 +  create and mmap() a file containing his code or have it mmap()
4680 +  an already existing ELF library that does not have position
4681 +  independent code in it and use mprotect() on it to make it
4682 +  writable and copy his code there.  While protecting against
4683 +  the former approach is beyond PaX, the latter can be prevented
4684 +  by having only PIC ELF libraries on one's system (which do not
4685 +  need to relocate their code).  If you are sure this is your case,
4686 +  then enable this option otherwise be careful as you may not even
4687 +  be able to boot or log on your system (for example, some PAM
4688 +  modules are erroneously compiled as non-PIC by default).
4689 +
4690 +  NOTE: if you are using dynamic ELF executables (as suggested
4691 +  when using ASLR) then you must have made sure that you linked
4692 +  your files using the PIC version of crt1 (the et_dyn.zip package
4693 +  referenced there has already been updated to support this).
4694 +
4695 +Enforce non-executable kernel pages
4696 +CONFIG_GRKERNSEC_PAX_KERNEXEC
4697 +  This is the kernel land equivalent of PAGEEXEC and MPROTECT,
4698 +  that is, enabling this option will make it harder to inject
4699 +  and execute 'foreign' code in kernel memory itself.
4700 +
4701 +Address Space Layout Randomization
4702 +CONFIG_GRKERNSEC_PAX_ASLR
4703 +  Many if not most exploit techniques rely on the knowledge of
4704 +  certain addresses in the attacked program.  The following options
4705 +  will allow the kernel to apply a certain amount of randomization
4706 +  to specific parts of the program thereby forcing an attacker to
4707 +  guess them in most cases.  Any failed guess will most likely crash
4708 +  the attacked program which allows the kernel to detect such attempts
4709 +  and react on them.  PaX itself provides no reaction mechanisms,
4710 +  instead it is strongly encouraged that you make use of grsecurity's
4711 +  built-in crash detection features or develop one yourself.
4712 +
4713 +  By saying Y here you can choose to randomize the following areas:
4714 +   - top of the task's kernel stack
4715 +   - top of the task's userland stack
4716 +   - base address for mmap() requests that do not specify one
4717 +     (this includes all libraries)
4718 +   - base address of the main executable
4719 +
4720 +  It is strongly recommended to say Y here as address space layout
4721 +  randomization has negligible impact on performance yet it provides
4722 +  a very effective protection.
4723 +
4724 +  NOTE: you can use the 'chpax' utility to control most of these features
4725 +  on a per file basis.
4726 +
4727 +Randomize kernel stack base
4728 +CONFIG_GRKERNSEC_PAX_RANDKSTACK
4729 +  By saying Y here the kernel will randomize every task's kernel
4730 +  stack on every system call.  This will not only force an attacker
4731 +  to guess it but also prevent him from making use of possible
4732 +  leaked information about it.
4733 +
4734 +  Since the kernel stack is a rather scarce resource, randomization
4735 +  may cause unexpected stack overflows, therefore you should very
4736 +  carefully test your system.  Note that once enabled in the kernel
4737 +  configuration, this feature cannot be disabled on a per file basis.
4738 +
4739 +Randomize user stack base
4740 +CONFIG_GRKERNSEC_PAX_RANDUSTACK
4741 +  By saying Y here the kernel will randomize every task's userland
4742 +  stack.  The randomization is done in two steps where the second
4743 +  one may apply a big amount of shift to the top of the stack and
4744 +  cause problems for programs that want to use lots of memory (more
4745 +  than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
4746 +  For this reason the second step can be controlled by 'chpax' on
4747 +  a per file basis.
4748 +
4749 +Randomize ET_EXEC base
4750 +CONFIG_GRKERNSEC_PAX_RANDEXEC     
4751 +  By saying Y here the kernel will randomize the base address of normal
4752 +  ET_EXEC ELF executables as well.  This is accomplished by mapping the
4753 +  executable in memory in a special way which also allows for detecting
4754 +  attackers who attempt to execute its code for their purposes.  Since
4755 +  this special mapping causes performance degradation and the attack
4756 +  detection may create false alarms as well, you should carefully test
4757 +  your executables when this feature is enabled.
4758 +
4759 +  This solution is intended only as a temporary one until you relink
4760 +  your programs as a dynamic ELF file.
4761 +
4762 +  NOTE: you can use the 'chpax' utility to control this feature
4763 +  on a per file basis.
4764 +
4765 +Allow ELF ET_EXEC text relocations
4766 +CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
4767 +  On some architectures like the alpha there are incorrectly
4768 +  created applications that require text relocations and would
4769 +  not work without enabling this option.  If you are an alpha
4770 +  user, you should enable this option and disable it once you
4771 +  have made sure that none of your applications need it.
4772 +
4773 +Automatically emulate ELF PLT
4774 +CONFIG_GRKERNSEC_PAX_EMUPLT
4775 +  Enabling this option will have the kernel automatically detect
4776 +  and emulate the Procedure Linkage Table entries in ELF files.
4777 +  On some architectures such entries are in writable memory, and
4778 +  become non-executable leading to task termination.  Therefore
4779 +  it is mandatory that you enable this option on alpha, parisc, ppc,
4780 +  sparc and sparc64, otherwise your system would not even boot.
4781 +
4782 +  NOTE: this feature *does* open up a loophole in the protection
4783 +  provided by the non-executable pages, therefore the proper
4784 +  solution is to modify the toolchain to produce a PLT that does
4785 +  not need to be writable.
4786 +
4787 +Honor PT_GNU_STACK
4788 +CONFIG_GRKERNSEC_PAX_PT_GNU_STACK
4789 +  Enabling this option will have the kernel honor the PT_GNU_STACK
4790 +  ELF executable marking in the sense that it will automatically
4791 +  turn on EMUTRAMP for processes that need an executable stack
4792 +  due to the use of nested function trampolines.
4793 +
4794 +  This option should only be considered by users whose entire system
4795 +  has support for PT_GNU_STACK, otherwise it may unnecessarily enable
4796 +  EMUTRAMP for all userland applications.
4797 +
4798 +  NOTE: the same precautions apply as with EMUTRAMP however it is
4799 +  still the preferred solution to chpax because it places the burden
4800 +  of marking executables on the package/distribution makers and not
4801 +  end users.
4802 +
4803 +Honor PT_GNU_HEAP
4804 +CONFIG_GRKERNSEC_PAX_PT_GNU_HEAP
4805 +  Enabling this option will have the kernel honor the PT_GNU_HEAP
4806 +  ELF executable marking in the sense that it will automatically
4807 +  turn off MPROTECT for processes that need an executable heap
4808 +  due to runtime code generation.
4809 +
4810 +  This option should only be considered by users whose entire system
4811 +  has support for PT_GNU_HEAP.
4812 +
4813 +  Note: this is the preferred solution to chpax because it places
4814 +  the burden of marking executables on the package/distribution
4815 +  makers and not end users.
4816 +
4817 +Randomize mmap() base
4818 +CONFIG_GRKERNSEC_PAX_RANDMMAP
4819 +  By saying Y here the kernel will use a randomized base address for
4820 +  mmap() requests that do not specify one themselves.  As a result
4821 +  all dynamically loaded libraries will appear at random addresses
4822 +  and therefore be harder to exploit by a technique where an attacker
4823 +  attempts to execute library code for his purposes (e.g. spawn a
4824 +  shell from an exploited program that is running at an elevated
4825 +  privilege level).
4826 +
4827 +  Furthermore, if a program is relinked as a dynamic ELF file, its
4828 +  base address will be randomized as well, completing the full
4829 +  randomization of the address space layout.  Attacking such programs
4830 +  becomes a guess game.  You can find an example of doing this at
4831 +  <http://pageexec.virtualave.net/et_dyn.zip> and practical samples at
4832 +  <http://www.grsecurity.net/grsec-gcc-specs.tar.gz> .
4833 +
4834 +  NOTE: you can use the 'chpax' utility to control this feature
4835 +  on a per file basis.
4836 +
4837 +Deny writing to /dev/kmem, /dev/mem, and /dev/port
4838 +CONFIG_GRKERNSEC_KMEM
4839 +  If you say Y here, /dev/kmem and /dev/mem won't be allowed to
4840 +  be written to via mmap or otherwise to modify the running kernel.
4841 +  /dev/port will also not be allowed to be opened. If you have module
4842 +  support disabled, enabling this will close up four ways that are
4843 +  currently used  to insert malicious code into the running kernel.
4844 +  Even with all these features enabled, we still highly recommend that
4845 +  you use the ACL system, as it is still possible for an attacker to 
4846 +  modify the running kernel through privileged I/O granted by ioperm/iopl.
4847 +  If you are not using XFree86, you may be able to stop this additional
4848 +  case by enabling the 'Disable privileged I/O' option. Though nothing
4849 +  legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
4850 +  but only to video memory, which is the only writing we allow in this
4851 +  case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
4852 +  not be allowed to mprotect it with PROT_WRITE later.
4853 +  Enabling this feature could make certain apps like VMWare stop working,
4854 +  as they need to write to other locations in /dev/mem.
4855 +  It is highly recommended that you say Y here if you meet all the 
4856 +  conditions above.
4857 +
4858 +Disable privileged I/O
4859 +CONFIG_GRKERNSEC_IO
4860 +  If you say Y here, all ioperm and iopl calls will return an error.
4861 +  Ioperm and iopl can be used to modify the running kernel.
4862 +  Unfortunately, some programs need this access to operate properly,
4863 +  the most notable of which are XFree86 and hwclock.  hwclock can be
4864 +  remedied by having RTC support in the kernel, so CONFIG_RTC is
4865 +  enabled if this option is enabled, to ensure that hwclock operates
4866 +  correctly.  XFree86 still will not operate correctly with this option
4867 +  enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
4868 +  and you still want to protect your kernel against modification,
4869 +  use the ACL system.
4870 +
4871 +Hide kernel symbols
4872 +CONFIG_GRKERNSEC_HIDESYM
4873 +  If you say Y here, getting information on loaded modules, and 
4874 +  displaying all kernel symbols through a syscall will be restricted
4875 +  to users with CAP_SYS_MODULE.  This option is only effective 
4876 +  provided the following conditions are met:
4877 +  1) The kernel using grsecurity is not precompiled by some distribution
4878 +  2) You are using the ACL system and hiding other files such as your
4879 +     kernel image and System.map
4880 +  3) You have the additional /proc restrictions enabled, which removes
4881 +     /proc/kcore
4882 +  If the above conditions are met, this option will aid to provide a
4883 +  useful protection against local and remote kernel exploitation of
4884 +  overflows and arbitrary read/write vulnerabilities.
4885 +
4886 +/proc/<pid>/ipaddr support
4887 +CONFIG_GRKERNSEC_PROC_IPADDR
4888 +  If you say Y here, a new entry will be added to each /proc/<pid>
4889 +  directory that contains the IP address of the person using the task.
4890 +  The IP is carried across local TCP and AF_UNIX stream sockets.
4891 +  This information can be useful for IDS/IPSes to perform remote response
4892 +  to a local attack.  The entry is readable by only the owner of the 
4893 +  process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
4894 +  the RBAC system), and thus does not create privacy concerns.
4895 +
4896 +Proc Restrictions
4897 +CONFIG_GRKERNSEC_PROC
4898 +  If you say Y here, the permissions of the /proc filesystem
4899 +  will be altered to enhance system security and privacy.  Depending
4900 +  upon the options you choose, you can either restrict users to see
4901 +  only the processes they themselves run, or choose a group that can
4902 +  view all processes and files normally restricted to root if you choose
4903 +  the "restrict to user only" option.  NOTE: If you're running identd as 
4904 +  a non-root user, you will have to run it as the group you specify here.
4905 +
4906 +Restrict /proc to user only
4907 +CONFIG_GRKERNSEC_PROC_USER
4908 +  If you say Y here, non-root users will only be able to view their own 
4909 +  processes, and restricts them from viewing network-related information,  
4910 +  and viewing kernel symbol and module information.
4911 +
4912 +Restrict /proc to user and group
4913 +CONFIG_GRKERNSEC_PROC_USERGROUP
4914 +  If you say Y here, you will be able to select a group that will be
4915 +  able to view all processes, network-related information, and
4916 +  kernel and symbol information.  This option is useful if you want
4917 +  to run identd as a non-root user.
4918 +
4919 +Remove addresses from /proc/pid/[maps|stat]
4920 +CONFIG_GRKERNSEC_PROC_MEMMAP
4921 +  If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
4922 +  give no information about the addresses of its mappings if
4923 +  PaX features that rely on random addresses are enabled on the task.
4924 +  If you use PaX it is greatly recommended that you say Y here as it 
4925 +  closes up a hole that makes the full ASLR useless for suid 
4926 +  binaries.
4927 +
4928 +Additional proc restrictions
4929 +CONFIG_GRKERNSEC_PROC_ADD
4930 +  If you say Y here, additional restrictions will be placed on
4931 +  /proc that keep normal users from viewing cpu and device information.
4932 +
4933 +Dmesg(8) Restriction
4934 +CONFIG_GRKERNSEC_DMESG
4935 +  If you say Y here, non-root users will not be able to use dmesg(8)
4936 +  to view up to the last 4kb of messages in the kernel's log buffer.
4937 +  If the sysctl option is enabled, a sysctl option with name "dmesg" is 
4938 +  created.
4939 +
4940 +Linking restrictions
4941 +CONFIG_GRKERNSEC_LINK
4942 +  If you say Y here, /tmp race exploits will be prevented, since users
4943 +  will no longer be able to follow symlinks owned by other users in 
4944 +  world-writable +t directories (i.e. /tmp), unless the owner of the 
4945 +  symlink is the owner of the directory. users will also not be
4946 +  able to hardlink to files they do not own.  If the sysctl option is
4947 +  enabled, a sysctl option with name "linking_restrictions" is created.
4948 +
4949 +FIFO restrictions
4950 +CONFIG_GRKERNSEC_FIFO
4951 +  If you say Y here, users will not be able to write to FIFOs they don't
4952 +  own in world-writable +t directories (i.e. /tmp), unless the owner of
4953 +  the FIFO is the same owner of the directory it's held in.  If the sysctl
4954 +  option is enabled, a sysctl option with name "fifo_restrictions" is 
4955 +  created.
4956 +
4957 +Enforce RLIMIT_NPROC on execs
4958 +CONFIG_GRKERNSEC_EXECVE
4959 +  If you say Y here, users with a resource limit on processes will
4960 +  have the value checked during execve() calls.  The current system
4961 +  only checks the system limit during fork() calls.  If the sysctl option
4962 +  is enabled, a sysctl option with name "execve_limiting" is created.
4963 +
4964 +Single group for auditing
4965 +CONFIG_GRKERNSEC_AUDIT_GROUP
4966 +  If you say Y here, the exec, chdir, (un)mount, and ipc logging features
4967 +  will only operate on a group you specify.  This option is recommended
4968 +  if you only want to watch certain users instead of having a large
4969 +  amount of logs from the entire system.  If the sysctl option is enabled,
4970 +  a sysctl option with name "audit_group" is created.
4971 +
4972 +GID for auditing
4973 +CONFIG_GRKERNSEC_AUDIT_GID
4974 +  Here you can choose the GID that will be the target of kernel auditing.
4975 +  Remember to add the users you want to log to the GID specified here.
4976 +  If the sysctl option is enabled, whatever you choose here won't matter. 
4977 +  You'll have to specify the GID in your bootup script by echoing the GID 
4978 +  to the proper /proc entry.  View the help on the sysctl option for more 
4979 +  information.  If the sysctl option is enabled, a sysctl option with name 
4980 +  "audit_gid" is created.
4981 +
4982 +Chdir logging
4983 +CONFIG_GRKERNSEC_AUDIT_CHDIR
4984 +  If you say Y here, all chdir() calls will be logged.  If the sysctl 
4985 +  option is enabled, a sysctl option with name "audit_chdir" is created.
4986 +
4987 +(Un)Mount logging
4988 +CONFIG_GRKERNSEC_AUDIT_MOUNT
4989 +  If you say Y here, all mounts and unmounts will be logged.  If the 
4990 +  sysctl option is enabled, a sysctl option with name "audit_mount" is 
4991 +  created.
4992 +
4993 +IPC logging
4994 +CONFIG_GRKERNSEC_AUDIT_IPC
4995 +  If you say Y here, creation and removal of message queues, semaphores,
4996 +  and shared memory will be logged.  If the sysctl option is enabled, a
4997 +  sysctl option with name "audit_ipc" is created.
4998 +
4999 +Exec logging
5000 +CONFIG_GRKERNSEC_EXECLOG
5001 +  If you say Y here, all execve() calls will be logged (since the
5002 +  other exec*() calls are frontends to execve(), all execution
5003 +  will be logged).  Useful for shell-servers that like to keep track
5004 +  of their users.  If the sysctl option is enabled, a sysctl option with
5005 +  name "exec_logging" is created.
5006 +  WARNING: This option when enabled will produce a LOT of logs, especially
5007 +  on an active system.
5008 +
5009 +Resource logging
5010 +CONFIG_GRKERNSEC_RESLOG
5011 +  If you say Y here, all attempts to overstep resource limits will
5012 +  be logged with the resource name, the requested size, and the current
5013 +  limit.  It is highly recommended that you say Y here.
5014 +
5015 +Signal logging
5016 +CONFIG_GRKERNSEC_SIGNAL
5017 +  If you say Y here, certain important signals will be logged, such as
5018 +  SIGSEGV, which will as a result inform you of when a error in a program
5019 +  occurred, which in some cases could mean a possible exploit attempt.
5020 +  If the sysctl option is enabled, a sysctl option with name 
5021 +  "signal_logging" is created.
5022 +
5023 +Fork failure logging
5024 +CONFIG_GRKERNSEC_FORKFAIL
5025 +  If you say Y here, all failed fork() attempts will be logged.
5026 +  This could suggest a fork bomb, or someone attempting to overstep
5027 +  their process limit.  If the sysctl option is enabled, a sysctl option
5028 +  with name "forkfail_logging" is created.
5029 +
5030 +Time change logging
5031 +CONFIG_GRKERNSEC_TIME
5032 +  If you say Y here, any changes of the system clock will be logged.
5033 +  If the sysctl option is enabled, a sysctl option with name 
5034 +  "timechange_logging" is created.
5035 +
5036 +Chroot jail restrictions
5037 +CONFIG_GRKERNSEC_CHROOT
5038 +  If you say Y here, you will be able to choose several options that will
5039 +  make breaking out of a chrooted jail much more difficult.  If you
5040 +  encounter no software incompatibilities with the following options, it
5041 +  is recommended that you enable each one.
5042 +
5043 +Deny access to abstract AF_UNIX sockets out of chroot
5044 +CONFIG_GRKERNSEC_CHROOT_UNIX
5045 +  If you say Y here, processes inside a chroot will not be able to
5046 +  connect to abstract (meaning not belonging to a filesystem) Unix
5047 +  domain sockets that were bound outside of a chroot.  It is recommended
5048 +  that you say Y here.  If the sysctl option is enabled, a sysctl option
5049 +  with name "chroot_deny_unix" is created.
5050 +
5051 +Deny shmat() out of chroot
5052 +CONFIG_GRKERNSEC_CHROOT_SHMAT
5053 +  If you say Y here, processes inside a chroot will not be able to attach
5054 +  to shared memory segments that were created outside of the chroot jail.
5055 +  It is recommended that you say Y here.  If the sysctl option is enabled,
5056 +  a sysctl option with name "chroot_deny_shmat" is created.
5057 +
5058 +Protect outside processes
5059 +CONFIG_GRKERNSEC_CHROOT_FINDTASK
5060 +  If you say Y here, processes inside a chroot will not be able to
5061 +  kill, send signals with fcntl, ptrace, capget, setpgid, getpgid, 
5062 +  getsid, or view any process outside of the chroot.  If the sysctl 
5063 +  option is enabled, a sysctl option with name "chroot_findtask" is 
5064 +  created.
5065 +
5066 +Deny mounts in chroot
5067 +CONFIG_GRKERNSEC_CHROOT_MOUNT
5068 +  If you say Y here, processes inside a chroot will not be able to
5069 +  mount or remount filesystems.  If the sysctl option is enabled, a 
5070 +  sysctl option with name "chroot_deny_mount" is created.
5071 +
5072 +Deny pivot_root in chroot
5073 +CONFIG_GRKERNSEC_CHROOT_PIVOT
5074 +  If you say Y here, processes inside a chroot will not be able to use
5075 +  a function called pivot_root() that was introduced in Linux 2.3.41.  It 
5076 +  works similar to chroot in that it changes the root filesystem.  This 
5077 +  function could be misused in a chrooted process to attempt to break out 
5078 +  of the chroot, and therefore should not be allowed.  If the sysctl 
5079 +  option is enabled, a sysctl option with name "chroot_deny_pivot" is 
5080 +  created.
5081 +
5082 +Deny double-chroots
5083 +CONFIG_GRKERNSEC_CHROOT_DOUBLE
5084 +  If you say Y here, processes inside a chroot will not be able to chroot
5085 +  again.  This is a widely used method of breaking out of a chroot jail
5086 +  and should not be allowed.  If the sysctl option is enabled, a sysctl
5087 +  option with name "chroot_deny_chroot" is created.
5088 +
5089 +Deny fchdir outside of chroot
5090 +CONFIG_GRKERNSEC_CHROOT_FCHDIR
5091 +  If you say Y here, a well-known method of breaking chroots by fchdir'ing
5092 +  to a file descriptor of the chrooting process that points to a directory
5093 +  outside the filesystem will be stopped.  If the sysctl option
5094 +  is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
5095 +
5096 +Enforce chdir("/") on all chroots
5097 +CONFIG_GRKERNSEC_CHROOT_CHDIR
5098 +  If you say Y here, the current working directory of all newly-chrooted
5099 +  applications will be set to the the root directory of the chroot.
5100 +  The man page on chroot(2) states:
5101 +  Note that this call does not change  the  current  working
5102 +  directory,  so  that `.' can be outside the tree rooted at
5103 +  `/'.  In particular, the  super-user  can  escape  from  a
5104 +  `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.  
5105 +
5106 +  It is recommended that you say Y here, since it's not known to break
5107 +  any software.  If the sysctl option is enabled, a sysctl option with
5108 +  name "chroot_enforce_chdir" is created.
5109 +
5110 +Deny (f)chmod +s in chroot
5111 +CONFIG_GRKERNSEC_CHROOT_CHMOD
5112 +  If you say Y here, processes inside a chroot will not be able to chmod
5113 +  or fchmod files to make them have suid or sgid bits.  This protects 
5114 +  against another published method of breaking a chroot.  If the sysctl 
5115 +  option is enabled, a sysctl option with name "chroot_deny_chmod" is
5116 +  created.
5117 +
5118 +Deny mknod in chroot
5119 +CONFIG_GRKERNSEC_CHROOT_MKNOD
5120 +  If you say Y here, processes inside a chroot will not be allowed to
5121 +  mknod.  The problem with using mknod inside a chroot is that it
5122 +  would allow an attacker to create a device entry that is the same
5123 +  as one on the physical root of your system, which could range from
5124 +  anything from the console device to a device for your harddrive (which
5125 +  they could then use to wipe the drive or steal data).  It is recommended
5126 +  that you say Y here, unless you run into software incompatibilities.
5127 +  If the sysctl option is enabled, a sysctl option with name
5128 +  "chroot_deny_mknod" is created.
5129 +
5130 +Restrict priority changes in chroot
5131 +CONFIG_GRKERNSEC_CHROOT_NICE
5132 +  If you say Y here, processes inside a chroot will not be able to raise
5133 +  the priority of processes in the chroot, or alter the priority of 
5134 +  processes outside the chroot.  This provides more security than simply
5135 +  removing CAP_SYS_NICE from the process' capability set.  If the
5136 +  sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
5137 +  is created.
5138 +
5139 +Log all execs within chroot
5140 +CONFIG_GRKERNSEC_CHROOT_EXECLOG
5141 +  If you say Y here, all executions inside a chroot jail will be logged 
5142 +  to syslog.  This can cause a large amount of logs if certain
5143 +  applications (eg. djb's daemontools) are installed on the system, and
5144 +  is therefore left as an option.  If the sysctl option is enabled, a 
5145 +  sysctl option with name "chroot_execlog" is created.
5146 +
5147 +Deny sysctl writes in chroot
5148 +CONFIG_GRKERNSEC_CHROOT_SYSCTL
5149 +  If you say Y here, an attacker in a chroot will not be able to
5150 +  write to sysctl entries, either by sysctl(2) or through a /proc
5151 +  interface.  It is strongly recommended that you say Y here. If the
5152 +  sysctl option is enabled, a sysctl option with name 
5153 +  "chroot_deny_sysctl" is created.
5154 +
5155 +Chroot jail capability restrictions
5156 +CONFIG_GRKERNSEC_CHROOT_CAPS
5157 +  If you say Y here, the capabilities on all root processes within a
5158 +  chroot jail will be lowered to stop module insertion, raw i/o,
5159 +  system and net admin tasks, rebooting the system, modifying immutable 
5160 +  files, modifying IPC owned by another, and changing the system time.
5161 +  This is left an option because it can break some apps.  Disable this
5162 +  if your chrooted apps are having problems performing those kinds of
5163 +  tasks.  If the sysctl option is enabled, a sysctl option with
5164 +  name "chroot_caps" is created.
5165 +
5166 +Trusted path execution
5167 +CONFIG_GRKERNSEC_TPE
5168 +  If you say Y here, you will be able to choose a gid to add to the
5169 +  supplementary groups of users you want to mark as "untrusted."
5170 +  These users will not be able to execute any files that are not in
5171 +  root-owned directories writable only by root.  If the sysctl option
5172 +  is enabled, a sysctl option with name "tpe" is created.
5173 +
5174 +Group for trusted path execution
5175 +CONFIG_GRKERNSEC_TPE_GID
5176 +  Here you can choose the GID to enable trusted path protection for.
5177 +  Remember to add the users you want protection enabled for to the GID 
5178 +  specified here.  If the sysctl option is enabled, whatever you choose
5179 +  here won't matter. You'll have to specify the GID in your bootup 
5180 +  script by echoing the GID to the proper /proc entry.  View the help
5181 +  on the sysctl option for more information.  If the sysctl option is
5182 +  enabled, a sysctl option with name "tpe_gid" is created.
5183 +
5184 +Partially restrict non-root users
5185 +CONFIG_GRKERNSEC_TPE_ALL
5186 +  If you say Y here, All non-root users other than the ones in the 
5187 +  group specified in the main TPE option will only be allowed to
5188 +  execute files in directories they own that are not group or
5189 +  world-writable, or in directories owned by root and writable only by
5190 +  root.  If the sysctl option is enabled, a sysctl option with name 
5191 +  "tpe_restrict_all" is created.
5192 +
5193 +Randomized PIDs
5194 +CONFIG_GRKERNSEC_RANDPID
5195 +  If you say Y here, all PIDs created on the system will be
5196 +  pseudo-randomly generated.  This is extremely effective along
5197 +  with the /proc restrictions to disallow an attacker from guessing
5198 +  pids of daemons, etc.  PIDs are also used in some cases as part
5199 +  of a naming system for temporary files, so this option would keep
5200 +  those filenames from being predicted as well.  We also use code
5201 +  to make sure that PID numbers aren't reused too soon.  If the sysctl
5202 +  option is enabled, a sysctl option with name "rand_pids" is created.
5203 +
5204 +Larger entropy pools
5205 +CONFIG_GRKERNSEC_RANDNET
5206 +  If you say Y here, the entropy pools used for many features of Linux
5207 +  and grsecurity will be doubled in size.  Since several grsecurity 
5208 +  features use additional randomness, it is recommended that you say Y 
5209 +  here.  Saying Y here has a similar effect as modifying
5210 +  /proc/sys/kernel/random/poolsize.
5211 +
5212 +Truly random TCP ISN selection
5213 +CONFIG_GRKERNSEC_RANDISN
5214 +  If you say Y here, Linux's default selection of TCP Initial Sequence
5215 +  Numbers (ISNs) will be replaced with that of OpenBSD.  Linux uses
5216 +  an MD4 hash based on the connection plus a time value to create the
5217 +  ISN, while OpenBSD's selection is random.  If the sysctl option is 
5218 +  enabled, a sysctl option with name "rand_isns" is created.
5219 +
5220 +Randomized IP IDs
5221 +CONFIG_GRKERNSEC_RANDID
5222 +  If you say Y here, all the id field on all outgoing packets
5223 +  will be randomized.  This hinders os fingerprinters and
5224 +  keeps your machine from being used as a bounce for an untraceable
5225 +  portscan.  Ids are used for fragmented packets, fragments belonging
5226 +  to the same packet have the same id.  By default linux only
5227 +  increments the id value on each packet sent to an individual host.
5228 +  We use a port of the OpenBSD random ip id code to achieve the
5229 +  randomness, while keeping the possibility of id duplicates to
5230 +  near none.  If the sysctl option is enabled, a sysctl option with name
5231 +  "rand_ip_ids" is created.
5232 +
5233 +Randomized TCP source ports
5234 +CONFIG_GRKERNSEC_RANDSRC
5235 +  If you say Y here, situations where a source port is generated on the
5236 +  fly for the TCP protocol (ie. with connect() ) will be altered so that
5237 +  the source port is generated at random, instead of a simple incrementing
5238 +  algorithm.  If the sysctl option is enabled, a sysctl option with name
5239 +  "rand_tcp_src_ports" is created.
5240 +
5241 +Randomized RPC XIDs
5242 +CONFIG_GRKERNSEC_RANDRPC
5243 +  If you say Y here, the method of determining XIDs for RPC requests will
5244 +  be randomized, instead of using linux's default behavior of simply
5245 +  incrementing the XID.  If you want your RPC connections to be more
5246 +  secure, say Y here.  If the sysctl option is enabled, a sysctl option 
5247 +  with name "rand_rpc" is created.
5248 +
5249 +Socket restrictions
5250 +CONFIG_GRKERNSEC_SOCKET
5251 +  If you say Y here, you will be able to choose from several options.
5252 +  If you assign a GID on your system and add it to the supplementary
5253 +  groups of users you want to restrict socket access to, this patch
5254 +  will perform up to three things, based on the option(s) you choose.
5255 +
5256 +Deny all socket access
5257 +CONFIG_GRKERNSEC_SOCKET_ALL
5258 +  If you say Y here, you will be able to choose a GID of whose users will
5259 +  be unable to connect to other hosts from your machine or run server
5260 +  applications from your machine.  If the sysctl option is enabled, a
5261 +  sysctl option with name "socket_all" is created.
5262 +
5263 +Group for disabled socket access
5264 +CONFIG_GRKERNSEC_SOCKET_ALL_GID
5265 +  Here you can choose the GID to disable socket access for. Remember to 
5266 +  add the users you want socket access disabled for to the GID 
5267 +  specified here.  If the sysctl option is enabled, whatever you choose
5268 +  here won't matter. You'll have to specify the GID in your bootup 
5269 +  script by echoing the GID to the proper /proc entry.  View the help
5270 +  on the sysctl option for more information.  If the sysctl option is
5271 +  enabled, a sysctl option with name "socket_all_gid" is created.
5272 +
5273 +Deny all client socket access
5274 +CONFIG_GRKERNSEC_SOCKET_CLIENT
5275 +  If you say Y here, you will be able to choose a GID of whose users will
5276 +  be unable to connect to other hosts from your machine, but will be
5277 +  able to run servers.  If this option is enabled, all users in the group
5278 +  you specify will have to use passive mode when initiating ftp transfers
5279 +  from the shell on your machine.  If the sysctl option is enabled, a
5280 +  sysctl option with name "socket_client" is created.
5281 +
5282 +Group for disabled client socket access
5283 +CONFIG_GRKERNSEC_SOCKET_CLIENT_GID
5284 +  Here you can choose the GID to disable client socket access for. 
5285 +  Remember to add the users you want client socket access disabled for to 
5286 +  the GID specified here.  If the sysctl option is enabled, whatever you 
5287 +  choose here won't matter. You'll have to specify the GID in your bootup 
5288 +  script by echoing the GID to the proper /proc entry.  View the help
5289 +  on the sysctl option for more information.  If the sysctl option is
5290 +  enabled, a sysctl option with name "socket_client_gid" is created.
5291 +
5292 +Deny all server socket access
5293 +CONFIG_GRKERNSEC_SOCKET_SERVER
5294 +  If you say Y here, you will be able to choose a GID of whose users will
5295 +  be unable to run server applications from your machine.  If the sysctl 
5296 +  option is enabled, a sysctl option with name "socket_server" is created.
5297 +
5298 +Group for disabled server socket access
5299 +CONFIG_GRKERNSEC_SOCKET_SERVER_GID
5300 +  Here you can choose the GID to disable server socket access for. 
5301 +  Remember to add the users you want server socket access disabled for to 
5302 +  the GID specified here.  If the sysctl option is enabled, whatever you 
5303 +  choose here won't matter. You'll have to specify the GID in your bootup 
5304 +  script by echoing the GID to the proper /proc entry.  View the help
5305 +  on the sysctl option for more information.  If the sysctl option is
5306 +  enabled, a sysctl option with name "socket_server_gid" is created.
5307 +
5308 +Sysctl support
5309 +CONFIG_GRKERNSEC_SYSCTL
5310 +  If you say Y here, you will be able to change the options that
5311 +  grsecurity runs with at bootup, without having to recompile your
5312 +  kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
5313 +  to enable (1) or disable (0) various features.  All the sysctl entries
5314 +  are mutable until the "grsec_lock" entry is set to a non-zero value.
5315 +  All features are disabled by default. Please note that this option could 
5316 +  reduce the effectiveness of the added security of this patch if an ACL 
5317 +  system is not put in place.  Your init scripts should be read-only, and 
5318 +  root should not have access to adding modules or performing raw i/o 
5319 +  operations.  All options should be set at startup, and the grsec_lock 
5320 +  entry should be set to a non-zero value after all the options are set.  
5321 +  *THIS IS EXTREMELY IMPORTANT*
5322 +
5323 +Number of burst messages
5324 +CONFIG_GRKERNSEC_FLOODBURST
5325 +  This option allows you to choose the maximum number of messages allowed
5326 +  within the flood time interval you chose in a separate option.  The 
5327 +  default should be suitable for most people, however if you find that 
5328 +  many of your logs are being interpreted as flooding, you may want to 
5329 +  raise this value.
5330 +
5331 +Seconds in between log messages
5332 +CONFIG_GRKERNSEC_FLOODTIME
5333 +  This option allows you to enforce the number of seconds between
5334 +  grsecurity log messages.  The default should be suitable for most 
5335 +  people, however, if you choose to change it, choose a value small enough
5336 +  to allow informative logs to be produced, but large enough to
5337 +  prevent flooding.
5338 +
5339 +Hide kernel processes
5340 +CONFIG_GRKERNSEC_ACL_HIDEKERN
5341 +  If you say Y here, when the ACL system is enabled via gradm -E,
5342 +  an additional ACL will be passed to the kernel that hides all kernel
5343 +  processes.  These processes will only be viewable by the authenticated
5344 +  admin, or processes that have viewing access set.
5345 +
5346 +Maximum tries before password lockout
5347 +CONFIG_GRKERNSEC_ACL_MAXTRIES
5348 +  This option enforces the maximum number of times a user can attempt
5349 +  to authorize themselves with the grsecurity ACL system before being
5350 +  denied the ability to attempt authorization again for a specified time.  
5351 +  The lower the number, the harder it will be to brute-force a password.
5352 +
5353 +Time to wait after max password tries, in seconds
5354 +CONFIG_GRKERNSEC_ACL_TIMEOUT
5355 +  This option specifies the time the user must wait after attempting to 
5356 +  authorize to the ACL system with the maximum number of invalid 
5357 +  passwords.  The higher the number, the harder it will be to brute-force 
5358 +  a password.
5359 +
5360  Disable data cache
5361  CONFIG_DCACHE_DISABLE
5362    This option allows you to run the kernel with data cache disabled.
5363 diff -urN linux-2.4.24.org/drivers/char/keyboard.c linux-2.4.24/drivers/char/keyboard.c
5364 --- linux-2.4.24.org/drivers/char/keyboard.c    2004-02-04 23:06:42.951194036 +0100
5365 +++ linux-2.4.24/drivers/char/keyboard.c        2004-02-04 23:11:32.097072236 +0100
5366 @@ -545,6 +545,16 @@
5367         if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
5368             !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
5369                 return;
5370 +
5371 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
5372 +       {
5373 +               void *func = spec_fn_table[value];
5374 +               if (func == show_state || func == show_ptregs ||
5375 +                   func == show_mem)
5376 +                       return;
5377 +       }
5378 +#endif
5379 +
5380         spec_fn_table[value]();
5381  }
5382  
5383 diff -urN linux-2.4.24.org/drivers/char/mem.c linux-2.4.24/drivers/char/mem.c
5384 --- linux-2.4.24.org/drivers/char/mem.c 2004-02-04 23:06:42.949194452 +0100
5385 +++ linux-2.4.24/drivers/char/mem.c     2004-02-04 23:11:32.103070989 +0100
5386 @@ -22,6 +22,7 @@
5387  #include <linux/tty.h>
5388  #include <linux/capability.h>
5389  #include <linux/ptrace.h>
5390 +#include <linux/grsecurity.h>
5391  
5392  #include <asm/uaccess.h>
5393  #include <asm/io.h>
5394 @@ -42,6 +43,10 @@
5395  #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
5396  extern void tapechar_init(void);
5397  #endif
5398 +
5399 +#ifdef CONFIG_GRKERNSEC
5400 +extern struct file_operations grsec_fops;
5401 +#endif
5402       
5403  static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
5404                             const char * buf, size_t count, loff_t *ppos)
5405 @@ -115,6 +120,11 @@
5406         unsigned long p = *ppos;
5407         unsigned long end_mem;
5408  
5409 +#ifdef CONFIG_GRKERNSEC_KMEM
5410 +       gr_handle_mem_write();
5411 +       return -EPERM;
5412 +#endif
5413 +
5414         end_mem = __pa(high_memory);
5415         if (p >= end_mem)
5416                 return 0;
5417 @@ -187,6 +197,12 @@
5418  {
5419         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5420  
5421 +#ifdef CONFIG_GRKERNSEC_KMEM
5422 +       if (gr_handle_mem_mmap(offset, vma))
5423 +               return -EPERM;
5424 +#endif
5425 +
5426 +
5427         /*
5428          * Accessing memory above the top the kernel knows about or
5429          * through a file pointer that was marked O_SYNC will be
5430 @@ -286,6 +302,11 @@
5431         ssize_t virtr = 0;
5432         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
5433  
5434 +#ifdef CONFIG_GRKERNSEC_KMEM
5435 +       gr_handle_kmem_write();
5436 +       return -EPERM;
5437 +#endif
5438 +
5439         if (p < (unsigned long) high_memory) {
5440                 wrote = count;
5441                 if (count > (unsigned long) high_memory - p)
5442 @@ -402,7 +423,7 @@
5443                         count = size;
5444  
5445                 zap_page_range(mm, addr, count);
5446 -               zeromap_page_range(addr, count, PAGE_COPY);
5447 +               zeromap_page_range(addr, count, vma->vm_page_prot); 
5448  
5449                 size -= count;
5450                 buf += count;
5451 @@ -525,6 +546,15 @@
5452  
5453  static int open_port(struct inode * inode, struct file * filp)
5454  {
5455 +#ifdef CONFIG_GRKERNSEC_KMEM
5456 +       gr_handle_open_port();
5457 +       return -EPERM;
5458 +#endif
5459 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5460 +}
5461 +
5462 +static int open_mem(struct inode * inode, struct file * filp)
5463 +{
5464         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5465  }
5466  
5467 @@ -582,6 +612,11 @@
5468         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5469         unsigned long size = vma->vm_end - vma->vm_start;
5470  
5471 +#ifdef CONFIG_GRKERNSEC_KMEM
5472 +       if (gr_handle_mem_mmap(offset, vma))
5473 +               return -EPERM;
5474 +#endif
5475 +
5476         /*
5477          * If the user is not attempting to mmap a high memory address then
5478          * the standard mmap_mem mechanism will work.  High memory addresses
5479 @@ -617,7 +652,6 @@
5480  #define full_lseek      null_lseek
5481  #define write_zero     write_null
5482  #define read_full       read_zero
5483 -#define open_mem       open_port
5484  #define open_kmem      open_mem
5485  
5486  static struct file_operations mem_fops = {
5487 @@ -693,6 +727,11 @@
5488                 case 9:
5489                         filp->f_op = &urandom_fops;
5490                         break;
5491 +#ifdef CONFIG_GRKERNSEC
5492 +               case 10:
5493 +                       filp->f_op = &grsec_fops;
5494 +                       break;
5495 +#endif
5496                 default:
5497                         return -ENXIO;
5498         }
5499 @@ -719,7 +758,10 @@
5500         {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
5501         {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
5502         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
5503 -       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
5504 +       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
5505 +#ifdef CONFIG_GRKERNSEC
5506 +       {10,"grsec",   S_IRUSR | S_IWUGO,           &grsec_fops}
5507 +#endif
5508      };
5509      int i;
5510  
5511 diff -urN linux-2.4.24.org/drivers/char/random.c linux-2.4.24/drivers/char/random.c
5512 --- linux-2.4.24.org/drivers/char/random.c      2004-02-04 23:06:43.254131045 +0100
5513 +++ linux-2.4.24/drivers/char/random.c  2004-02-04 23:11:32.127066000 +0100
5514 @@ -262,9 +262,15 @@
5515  /*
5516   * Configuration information
5517   */
5518 +#ifdef CONFIG_GRKERNSEC_RANDNET
5519 +#define DEFAULT_POOL_SIZE 1024
5520 +#define SECONDARY_POOL_SIZE 256
5521 +#define BATCH_ENTROPY_SIZE 512
5522 +#else
5523  #define DEFAULT_POOL_SIZE 512
5524  #define SECONDARY_POOL_SIZE 128
5525  #define BATCH_ENTROPY_SIZE 256
5526 +#endif
5527  #define USE_SHA
5528  
5529  /*
5530 @@ -389,6 +395,7 @@
5531  /*
5532   * Static global variables
5533   */
5534 +
5535  static struct entropy_store *random_state; /* The default global store */
5536  static struct entropy_store *sec_random_state; /* secondary store */
5537  static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
5538 @@ -2210,6 +2217,29 @@
5539         return halfMD4Transform(hash, keyptr->secret);
5540  }
5541  
5542 +#ifdef CONFIG_GRKERNSEC
5543 +/* the following function is provided by PaX under the GPL */
5544 +unsigned long get_random_long(void)
5545 +{       
5546 +       static time_t rekey_time;
5547 +       static __u32 secret[12];
5548 +       time_t t;
5549 +
5550 +       /*
5551 +        * Pick a random secret every REKEY_INTERVAL seconds
5552 +        */
5553 +       t = CURRENT_TIME;
5554 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
5555 +               rekey_time = t;
5556 +               get_random_bytes(secret, sizeof(secret));
5557 +       }
5558 +
5559 +       secret[1] = halfMD4Transform(secret+8, secret);
5560 +       secret[0] = halfMD4Transform(secret+8, secret);
5561 +       return *(unsigned long *)secret;
5562 +}
5563 +#endif
5564 +
5565  #ifdef CONFIG_SYN_COOKIES
5566  /*
5567   * Secure SYN cookie computation. This is the algorithm worked out by
5568 diff -urN linux-2.4.24.org/drivers/char/tty_io.c linux-2.4.24/drivers/char/tty_io.c
5569 --- linux-2.4.24.org/drivers/char/tty_io.c      2004-02-04 23:06:42.694247464 +0100
5570 +++ linux-2.4.24/drivers/char/tty_io.c  2004-02-04 23:11:32.168057477 +0100
5571 @@ -99,7 +99,7 @@
5572  #include <linux/vt_kern.h>
5573  #include <linux/selection.h>
5574  #include <linux/devfs_fs_kernel.h>
5575 -
5576 +#include <linux/grsecurity.h>
5577  #include <linux/kmod.h>
5578  
5579  #ifdef CONFIG_VT
5580 @@ -1426,7 +1426,11 @@
5581                 retval = -ENODEV;
5582         filp->f_flags = saved_flags;
5583  
5584 +#ifdef CONFIG_GRKERNSEC
5585 +       if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG))
5586 +#else
5587         if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
5588 +#endif
5589                 retval = -EBUSY;
5590  
5591         if (retval) {
5592 @@ -1533,7 +1537,11 @@
5593  {
5594         char ch, mbz = 0;
5595  
5596 +#ifdef CONFIG_GRKERNSEC
5597 +       if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG))
5598 +#else
5599         if ((current->tty != tty) && !suser())
5600 +#endif
5601                 return -EPERM;
5602         if (get_user(ch, arg))
5603                 return -EFAULT;
5604 @@ -1571,7 +1579,11 @@
5605         if (inode->i_rdev == SYSCONS_DEV ||
5606             inode->i_rdev == CONSOLE_DEV) {
5607                 struct file *f;
5608 +#ifdef CONFIG_GRKERNSEC
5609 +               if (!capable(CAP_SYS_TTY_CONFIG))
5610 +#else
5611                 if (!suser())
5612 +#endif
5613                         return -EPERM;
5614                 spin_lock(&redirect_lock);
5615                 f = redirect;
5616 @@ -1623,7 +1635,11 @@
5617                  * This tty is already the controlling
5618                  * tty for another session group!
5619                  */
5620 +#ifdef CONFIG_GRKERNSEC
5621 +               if ((arg == 1) && capable(CAP_SYS_ADMIN)) {
5622 +#else
5623                 if ((arg == 1) && suser()) {
5624 +#endif
5625                         /*
5626                          * Steal it away
5627                          */
5628 diff -urN linux-2.4.24.org/drivers/char/vt.c linux-2.4.24/drivers/char/vt.c
5629 --- linux-2.4.24.org/drivers/char/vt.c  2004-02-04 23:06:45.362692603 +0100
5630 +++ linux-2.4.24/drivers/char/vt.c      2004-02-04 23:11:32.204049994 +0100
5631 @@ -32,6 +32,7 @@
5632  #include <linux/vt_kern.h>
5633  #include <linux/kbd_diacr.h>
5634  #include <linux/selection.h>
5635 +#include <linux/grsecurity.h>
5636  
5637  #ifdef CONFIG_FB_COMPAT_XPMAC
5638  #include <asm/vc_ioctl.h>
5639 @@ -443,7 +444,11 @@
5640          * to be the owner of the tty, or super-user.
5641          */
5642         perm = 0;
5643 +#ifdef CONFIG_GRKERNSEC
5644 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
5645 +#else
5646         if (current->tty == tty || suser())
5647 +#endif
5648                 perm = 1;
5649   
5650         kbd = kbd_table + console;
5651 @@ -1038,12 +1043,20 @@
5652                 return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
5653  
5654         case VT_LOCKSWITCH:
5655 +#ifdef CONFIG_GRKERNSEC
5656 +               if (!capable(CAP_SYS_TTY_CONFIG))
5657 +#else
5658                 if (!suser())
5659 +#endif
5660                    return -EPERM;
5661                 vt_dont_switch = 1;
5662                 return 0;
5663         case VT_UNLOCKSWITCH:
5664 +#ifdef CONFIG_GRKERNSEC
5665 +               if (!capable(CAP_SYS_TTY_CONFIG))
5666 +#else
5667                 if (!suser())
5668 +#endif
5669                    return -EPERM;
5670                 vt_dont_switch = 0;
5671                 return 0;
5672 diff -urN linux-2.4.24.org/drivers/pci/proc.c linux-2.4.24/drivers/pci/proc.c
5673 --- linux-2.4.24.org/drivers/pci/proc.c 2004-02-04 23:07:36.700017834 +0100
5674 +++ linux-2.4.24/drivers/pci/proc.c     2004-02-04 23:11:32.240042511 +0100
5675 @@ -562,7 +562,15 @@
5676                 pci_for_each_dev(dev) {
5677                         pci_proc_attach_device(dev);
5678                 }
5679 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
5680 +#ifdef CONFIG_GRKERNSEC_PROC_USER
5681 +               entry = create_proc_entry("pci", S_IRUSR, NULL);
5682 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
5683 +               entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
5684 +#endif
5685 +#else
5686                 entry = create_proc_entry("pci", 0, NULL);
5687 +#endif
5688                 if (entry)
5689                         entry->proc_fops = &proc_pci_operations;
5690         }
5691 diff -urN linux-2.4.24.org/fs/binfmt_aout.c linux-2.4.24/fs/binfmt_aout.c
5692 --- linux-2.4.24.org/fs/binfmt_aout.c   2004-02-04 23:04:03.768293611 +0100
5693 +++ linux-2.4.24/fs/binfmt_aout.c       2004-02-04 23:11:32.276035027 +0100
5694 @@ -5,6 +5,7 @@
5695   */
5696  
5697  #include <linux/module.h>
5698 +#include <linux/config.h>
5699  
5700  #include <linux/sched.h>
5701  #include <linux/kernel.h>
5702 @@ -113,10 +114,12 @@
5703  /* If the size of the dump file exceeds the rlimit, then see what would happen
5704     if we wrote the stack, but not the data area.  */
5705  #ifdef __sparc__
5706 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
5707         if ((dump.u_dsize+dump.u_ssize) >
5708             current->rlim[RLIMIT_CORE].rlim_cur)
5709                 dump.u_dsize = 0;
5710  #else
5711 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
5712         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
5713             current->rlim[RLIMIT_CORE].rlim_cur)
5714                 dump.u_dsize = 0;
5715 @@ -124,10 +127,12 @@
5716  
5717  /* Make sure we have enough room to write the stack and data areas. */
5718  #ifdef __sparc__
5719 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
5720         if ((dump.u_ssize) >
5721             current->rlim[RLIMIT_CORE].rlim_cur)
5722                 dump.u_ssize = 0;
5723  #else
5724 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
5725         if ((dump.u_ssize+1) * PAGE_SIZE >
5726             current->rlim[RLIMIT_CORE].rlim_cur)
5727                 dump.u_ssize = 0;
5728 @@ -276,6 +281,8 @@
5729         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
5730         if (rlim >= RLIM_INFINITY)
5731                 rlim = ~0;
5732 +
5733 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
5734         if (ex.a_data + ex.a_bss > rlim)
5735                 return -ENOMEM;
5736  
5737 @@ -307,6 +314,24 @@
5738         current->mm->mmap = NULL;
5739         compute_creds(bprm);
5740         current->flags &= ~PF_FORKNOEXEC;
5741 +
5742 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5743 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
5744 +               current->flags |= PF_PAX_PAGEEXEC;
5745 +
5746 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5747 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
5748 +                       current->flags |= PF_PAX_EMUTRAMP;
5749 +#endif
5750 +
5751 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5752 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))        
5753 +                       current->flags |= PF_PAX_MPROTECT;
5754 +#endif
5755 +
5756 +       }
5757 +#endif
5758 +
5759  #ifdef __sparc__
5760         if (N_MAGIC(ex) == NMAGIC) {
5761                 loff_t pos = fd_offset;
5762 @@ -393,7 +418,7 @@
5763  
5764                 down_write(&current->mm->mmap_sem);
5765                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
5766 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
5767 +                               PROT_READ | PROT_WRITE,
5768                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
5769                                 fd_offset + ex.a_text);
5770                 up_write(&current->mm->mmap_sem);
5771 diff -urN linux-2.4.24.org/fs/binfmt_elf.c linux-2.4.24/fs/binfmt_elf.c
5772 --- linux-2.4.24.org/fs/binfmt_elf.c    2004-02-04 23:03:59.398202305 +0100
5773 +++ linux-2.4.24/fs/binfmt_elf.c        2004-02-04 23:11:32.312027544 +0100
5774 @@ -11,6 +11,7 @@
5775  
5776  #include <linux/module.h>
5777  
5778 +#include <linux/config.h>
5779  #include <linux/fs.h>
5780  #include <linux/stat.h>
5781  #include <linux/sched.h>
5782 @@ -33,10 +34,13 @@
5783  #include <linux/smp_lock.h>
5784  #include <linux/compiler.h>
5785  #include <linux/highmem.h>
5786 +#include <linux/random.h>
5787 +#include <linux/grsecurity.h>
5788  
5789  #include <asm/uaccess.h>
5790  #include <asm/param.h>
5791  #include <asm/pgalloc.h>
5792 +#include <asm/system.h>
5793  
5794  #define DLINFO_ITEMS 13
5795  
5796 @@ -86,6 +90,12 @@
5797         if (end <= start)
5798                 return;
5799         do_brk(start, end - start);
5800 +
5801 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5802 +       if (current->flags & PF_PAX_RANDEXEC)
5803 +               do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
5804 +#endif
5805 +
5806  }
5807  
5808  
5809 @@ -446,6 +456,11 @@
5810         struct exec interp_ex;
5811         char passed_fileno[6];
5812         struct files_struct *files;
5813 +
5814 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5815 +       unsigned long load_addr_random = 0UL;
5816 +       unsigned long load_bias_random = 0UL;
5817 +#endif
5818         
5819         /* Get the exec-header */
5820         elf_ex = *((struct elfhdr *) bprm->buf);
5821 @@ -618,7 +633,92 @@
5822         current->mm->end_data = 0;
5823         current->mm->end_code = 0;
5824         current->mm->mmap = NULL;
5825 +
5826 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5827 +       current->mm->delta_mmap = 0UL;
5828 +       current->mm->delta_exec = 0UL;
5829 +       current->mm->delta_stack = 0UL;
5830 +#endif
5831 +
5832         current->flags &= ~PF_FORKNOEXEC;
5833 +
5834 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5835 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
5836 +               current->flags |= PF_PAX_PAGEEXEC;
5837 +#endif
5838 +
5839 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5840 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
5841 +               current->flags &= ~PF_PAX_PAGEEXEC;
5842 +               current->flags |= PF_PAX_SEGMEXEC;
5843 +       }
5844 +#endif
5845 +
5846 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5847 +       if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && (elf_ex.e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
5848 +               current->flags |= PF_PAX_EMUTRAMP;
5849 +#endif
5850 +
5851 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5852 +       if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex.e_ident[EI_PAX] & EF_PAX_MPROTECT))
5853 +               current->flags |= PF_PAX_MPROTECT;
5854 +#endif
5855 +
5856 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5857 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_RANDMMAP))
5858 +               current->flags |= PF_PAX_RANDMMAP;
5859 +#endif
5860 +
5861 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5862 +       if ((elf_ex.e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC) &&
5863 +           (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)))
5864 +               current->flags |= PF_PAX_RANDEXEC;
5865 +#endif
5866 +
5867 +#ifdef CONFIG_GRKERNSEC_PAX_PT_GNU_HEAP
5868 +       elf_ppnt = elf_phdata;
5869 +       for (i = 0; i < elf_ex.e_phnum; i++, elf_ppnt++)
5870 +               if (elf_ppnt->p_type == PT_GNU_HEAP) {
5871 +                       if (elf_ppnt->p_flags & PF_X)
5872 +                               current->flags & ~PF_PAX_MPROTECT;
5873 +                       break;
5874 +               }
5875 +#endif
5876 +
5877 +#ifdef CONFIG_GRKERNSEC_PAX_PT_GNU_STACK
5878 +       elf_ppnt = elf_phdata;
5879 +       for (i = 0; i < elf_ex.e_phnum; i++, elf_ppnt++)
5880 +               if (elf_ppnt->p_type == PT_GNU_STACK) {
5881 +                       if ((elf_ppnt->p_flags & PF_X) && (current->flags & PF_PAX_MPROTECT))
5882 +                               current->flags |= PF_PAX_EMUTRAMP;
5883 +                       break;
5884 +               }
5885 +#endif
5886 +
5887 +#ifdef CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS
5888 +       pax_set_flags(bprm);
5889 +#elif defined(CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS)
5890 +       if (pax_set_flags_func)
5891 +               (*pax_set_flags_func)(bprm);
5892 +#endif
5893 +
5894 +#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
5895 +       if (current->flags & PF_PAX_PAGEEXEC)
5896 +               current->mm->call_dl_resolve = 0UL;
5897 +#endif
5898 +
5899 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5900 +       if (current->flags & PF_PAX_RANDMMAP) {
5901 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
5902 +
5903 +               current->mm->delta_mmap = pax_delta_mask(get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
5904 +               current->mm->delta_exec = pax_delta_mask(get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
5905 +               current->mm->delta_stack = pax_delta_mask(get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
5906 +       }
5907 +#endif
5908 +
5909 +       gr_set_pax_flags(current);      
5910 +
5911         elf_entry = (unsigned long) elf_ex.e_entry;
5912  
5913         /* Do this so that we can load the interpreter, if need be.  We will
5914 @@ -627,7 +727,7 @@
5915         retval = setup_arg_pages(bprm);
5916         if (retval < 0) {
5917                 send_sig(SIGKILL, current, 0);
5918 -               return retval;
5919 +               goto out_free_dentry;
5920         }
5921         
5922         current->mm->start_stack = bprm->p;
5923 @@ -674,11 +774,84 @@
5924                            base, as well as whatever program they might try to exec.  This
5925                            is because the brk will follow the loader, and is not movable.  */
5926                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
5927 +
5928 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
5929 +                       /* PaX: randomize base address at the default exe base if requested */
5930 +                       if (current->flags & PF_PAX_RANDMMAP) {
5931 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
5932 +                               elf_flags |= MAP_FIXED;
5933 +                       }
5934 +#endif
5935 +
5936                 }
5937  
5938 -               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5939 -               if (BAD_ADDR(error))
5940 -                       continue;
5941 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5942 +               if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
5943 +                       error = -ENOMEM;
5944 +
5945 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5946 +                       if (current->flags & PF_PAX_PAGEEXEC)
5947 +                               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
5948 +#endif
5949 +
5950 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5951 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5952 +                               unsigned long addr, len;
5953 +
5954 +                               addr = ELF_PAGESTART(load_bias + vaddr);
5955 +                               len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
5956 +                               if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
5957 +                                       continue;
5958 +                               down_write(&current->mm->mmap_sem);
5959 +                               error = do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
5960 +                               up_write(&current->mm->mmap_sem);
5961 +                       }
5962 +#endif
5963 +
5964 +                       if (BAD_ADDR(error))
5965 +                               continue;
5966 +
5967 +                       /* PaX: mirror at a randomized base */
5968 +                       down_write(&current->mm->mmap_sem);
5969 +
5970 +                       if (!load_addr_set) {
5971 +                               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);
5972 +                               if (BAD_ADDR(load_addr_random)) {
5973 +                                       up_write(&current->mm->mmap_sem);
5974 +                                       continue;
5975 +                               }
5976 +                               load_bias_random = load_addr_random - vaddr;
5977 +                       }
5978 +
5979 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5980 +                       if (current->flags & PF_PAX_PAGEEXEC)
5981 +                               load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5982 +#endif
5983 +
5984 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5985 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5986 +                               if (elf_prot & PROT_EXEC) {
5987 +                                       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);
5988 +                                       if (!BAD_ADDR(load_addr_random)) {
5989 +                                               load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5990 +                                               if (!BAD_ADDR(load_addr_random))
5991 +                                                       load_addr_random -= SEGMEXEC_TASK_SIZE;
5992 +                                       }
5993 +                               } else
5994 +                                       load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5995 +                       }
5996 +#endif
5997 +
5998 +                       up_write(&current->mm->mmap_sem);
5999 +                       if (BAD_ADDR(load_addr_random))
6000 +                               continue;
6001 +               } else
6002 +#endif
6003 +               {
6004 +                       error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
6005 +                       if (BAD_ADDR(error))
6006 +                               continue;
6007 +               }
6008  
6009                 if (!load_addr_set) {
6010                         load_addr_set = 1;
6011 @@ -689,6 +862,11 @@
6012                                 load_addr += load_bias;
6013                                 reloc_func_desc = load_addr;
6014                         }
6015 +
6016 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
6017 +                       current->mm->delta_exec = load_addr_random - load_addr;
6018 +#endif
6019 +
6020                 }
6021                 k = elf_ppnt->p_vaddr;
6022                 if (k < start_code) start_code = k;
6023 @@ -715,6 +893,18 @@
6024         start_data += load_bias;
6025         end_data += load_bias;
6026  
6027 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
6028 +       elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT);
6029 +#undef pax_delta_mask
6030 +#endif
6031 +
6032 +       /* Calling set_brk effectively mmaps the pages that we need
6033 +        * for the bss and break sections
6034 +        */
6035 +       set_brk(elf_bss, elf_brk);
6036 +
6037 +       padzero(elf_bss);
6038 +
6039         if (elf_interpreter) {
6040                 if (interpreter_type == INTERPRETER_AOUT)
6041                         elf_entry = load_aout_interp(&interp_ex,
6042 @@ -763,13 +953,6 @@
6043         current->mm->end_data = end_data;
6044         current->mm->start_stack = bprm->p;
6045  
6046 -       /* Calling set_brk effectively mmaps the pages that we need
6047 -        * for the bss and break sections
6048 -        */
6049 -       set_brk(elf_bss, elf_brk);
6050 -
6051 -       padzero(elf_bss);
6052 -
6053  #if 0
6054         printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
6055         printk("(end_code) %lx\n" , (long) current->mm->end_code);
6056 @@ -806,6 +989,10 @@
6057         ELF_PLAT_INIT(regs, reloc_func_desc);
6058  #endif
6059  
6060 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
6061 +       pax_switch_segments(current);
6062 +#endif
6063 +
6064         start_thread(regs, elf_entry, bprm->p);
6065         if (current->ptrace & PT_PTRACED)
6066                 send_sig(SIGTRAP, current, 0);
6067 @@ -1033,8 +1220,11 @@
6068  #undef DUMP_SEEK
6069  
6070  #define DUMP_WRITE(addr, nr)   \
6071 +       do { \
6072 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
6073         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
6074 -               goto end_coredump;
6075 +               goto end_coredump; \
6076 +       } while (0);
6077  #define DUMP_SEEK(off) \
6078         if (!dump_seek(file, (off))) \
6079                 goto end_coredump;
6080 diff -urN linux-2.4.24.org/fs/buffer.c linux-2.4.24/fs/buffer.c
6081 --- linux-2.4.24.org/fs/buffer.c        2004-02-04 23:04:19.878943652 +0100
6082 +++ linux-2.4.24/fs/buffer.c    2004-02-04 23:11:32.341021516 +0100
6083 @@ -1906,6 +1906,9 @@
6084         int err;
6085  
6086         err = -EFBIG;
6087 +
6088 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
6089 +
6090          limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
6091         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
6092                 send_sig(SIGXFSZ, current, 0);
6093 diff -urN linux-2.4.24.org/fs/exec.c linux-2.4.24/fs/exec.c
6094 --- linux-2.4.24.org/fs/exec.c  2004-02-04 23:03:59.355211244 +0100
6095 +++ linux-2.4.24/fs/exec.c      2004-02-04 23:11:32.409007381 +0100
6096 @@ -43,6 +43,9 @@
6097  #include <asm/uaccess.h>
6098  #include <asm/pgalloc.h>
6099  #include <asm/mmu_context.h>
6100 +#include <linux/major.h>
6101 +#include <linux/random.h>
6102 +#include <linux/grsecurity.h>
6103  
6104  #ifdef CONFIG_KMOD
6105  #include <linux/kmod.h>
6106 @@ -56,6 +59,11 @@
6107  static struct linux_binfmt *formats;
6108  static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
6109  
6110 +#ifdef CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS
6111 +void (*pax_set_flags_func)(struct linux_binprm *bprm);
6112 +EXPORT_SYMBOL(pax_set_flags_func);
6113 +#endif
6114 +
6115  int register_binfmt(struct linux_binfmt * fmt)
6116  {
6117         struct linux_binfmt ** tmp = &formats;
6118 @@ -346,6 +354,11 @@
6119                 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
6120                 mpnt->vm_end = STACK_TOP;
6121                 mpnt->vm_flags = VM_STACK_FLAGS;
6122 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
6123 +               if (!(current->flags & PF_PAX_PAGEEXEC))
6124 +                       mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7];
6125 +               else
6126 +#endif
6127                 mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
6128                 mpnt->vm_ops = NULL;
6129                 mpnt->vm_pgoff = 0;
6130 @@ -615,6 +628,30 @@
6131         }
6132         current->comm[i] = '\0';
6133  
6134 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
6135 +       current->flags &= ~PF_PAX_PAGEEXEC;
6136 +#endif
6137 +
6138 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
6139 +       current->flags &= ~PF_PAX_EMUTRAMP;
6140 +#endif
6141 +
6142 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
6143 +       current->flags &= ~PF_PAX_MPROTECT;
6144 +#endif
6145 +
6146 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
6147 +       current->flags &= ~PF_PAX_RANDMMAP;
6148 +#endif
6149 +
6150 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
6151 +       current->flags &= ~PF_PAX_RANDEXEC;
6152 +#endif
6153 +
6154 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
6155 +       current->flags &= ~PF_PAX_SEGMEXEC;
6156 +#endif
6157 +
6158         flush_thread();
6159  
6160         de_thread(current);
6161 @@ -714,6 +751,9 @@
6162                         cap_set_full(bprm->cap_effective);
6163         }
6164  
6165 +       if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
6166 +               return -EACCES;
6167 +
6168         memset(bprm->buf,0,BINPRM_BUF_SIZE);
6169         return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
6170  }
6171 @@ -779,6 +819,8 @@
6172          current->suid = current->euid = current->fsuid = bprm->e_uid;
6173          current->sgid = current->egid = current->fsgid = bprm->e_gid;
6174  
6175 +       gr_handle_chroot_caps(current);
6176 +
6177         if(do_unlock)
6178                 unlock_kernel();
6179         current->keep_capabilities = 0;
6180 @@ -912,6 +954,11 @@
6181         struct file *file;
6182         int retval;
6183         int i;
6184 +#ifdef CONFIG_GRKERNSEC
6185 +       struct file *old_exec_file;
6186 +       struct acl_subject_label *old_acl;
6187 +       struct rlimit old_rlim[RLIM_NLIMITS];
6188 +#endif
6189  
6190         file = open_exec(filename);
6191  
6192 @@ -919,7 +966,26 @@
6193         if (IS_ERR(file))
6194                 return retval;
6195  
6196 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
6197 +
6198 +       if (gr_handle_nproc()) {
6199 +               allow_write_access(file);
6200 +               fput(file);
6201 +               return -EAGAIN;
6202 +       }
6203 +
6204 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
6205 +               allow_write_access(file);
6206 +               fput(file);
6207 +               return -EACCES;
6208 +       }
6209 +
6210         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
6211 +
6212 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
6213 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
6214 +#endif
6215 +
6216         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
6217  
6218         bprm.file = file;
6219 @@ -943,11 +1009,26 @@
6220         if (retval < 0) 
6221                 goto out; 
6222  
6223 +       if (!gr_tpe_allow(file)) {
6224 +               retval = -EACCES;
6225 +               goto out;
6226 +       }
6227 +
6228 +       if(gr_check_crash_exec(file)) {
6229 +               retval = -EACCES;
6230 +               goto out;
6231 +       }
6232 +
6233         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
6234         if (retval < 0) 
6235                 goto out; 
6236  
6237         bprm.exec = bprm.p;
6238 +
6239 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
6240 +
6241 +       gr_handle_exec_args(&bprm, argv);
6242 +
6243         retval = copy_strings(bprm.envc, envp, &bprm);
6244         if (retval < 0) 
6245                 goto out; 
6246 @@ -956,11 +1037,32 @@
6247         if (retval < 0) 
6248                 goto out; 
6249  
6250 +#ifdef CONFIG_GRKERNSEC
6251 +       old_acl = current->acl;
6252 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
6253 +       old_exec_file = current->exec_file;
6254 +       get_file(file);
6255 +       current->exec_file = file;
6256 +#endif
6257 +
6258 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
6259 +
6260         retval = search_binary_handler(&bprm,regs);
6261 -       if (retval >= 0)
6262 +       if (retval >= 0) {
6263 +#ifdef CONFIG_GRKERNSEC
6264 +               if (old_exec_file)
6265 +                       fput(old_exec_file);
6266 +#endif
6267                 /* execve success */
6268                 return retval;
6269 +       }
6270  
6271 +#ifdef CONFIG_GRKERNSEC
6272 +       current->acl = old_acl;
6273 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
6274 +       fput(current->exec_file);
6275 +       current->exec_file = old_exec_file;
6276 +#endif
6277  out:
6278         /* Something went wrong, return the inode and free the argument pages*/
6279         allow_write_access(bprm.file);
6280 @@ -1102,6 +1204,130 @@
6281         *out_ptr = 0;
6282  }
6283  
6284 +int pax_check_flags(unsigned long * flags)
6285 +{
6286 +       int retval = 0;
6287 +
6288 +#if !defined(__i386__) || !defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
6289 +       if (*flags & PF_PAX_SEGMEXEC)
6290 +       {
6291 +               *flags &= ~PF_PAX_SEGMEXEC;
6292 +               retval = -EINVAL;
6293 +       }
6294 +#endif
6295 +
6296 +       if ((*flags & PF_PAX_PAGEEXEC)
6297 +
6298 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEXEC
6299 +           &&  (*flags & PF_PAX_SEGMEXEC)
6300 +#endif
6301 +
6302 +          )
6303 +       {
6304 +               *flags &= ~PF_PAX_PAGEEXEC;
6305 +               retval = -EINVAL;
6306 +       }
6307 +
6308 +       if ((*flags & PF_PAX_MPROTECT)
6309 +
6310 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
6311 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
6312 +#endif
6313 +
6314 +          )
6315 +       {
6316 +               *flags &= ~PF_PAX_MPROTECT;
6317 +               retval = -EINVAL;
6318 +       }
6319 +
6320 +       if ((*flags & PF_PAX_EMUTRAMP)
6321 +
6322 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
6323 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
6324 +#endif
6325 +
6326 +          )
6327 +       {
6328 +               *flags &= ~PF_PAX_EMUTRAMP;
6329 +               retval = -EINVAL;
6330 +       }
6331 +
6332 +       if ((*flags & PF_PAX_RANDEXEC)
6333 +
6334 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
6335 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
6336 +#endif
6337 +
6338 +          )
6339 +       {
6340 +               *flags &= ~PF_PAX_RANDEXEC;
6341 +               retval = -EINVAL;
6342 +       }
6343 +
6344 +       return retval;
6345 +}
6346 +
6347 +EXPORT_SYMBOL(pax_check_flags);
6348 +
6349 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
6350 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
6351 +{
6352 +       struct task_struct *tsk = current;
6353 +       struct mm_struct *mm = current->mm;
6354 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
6355 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
6356 +       char* path_exec=NULL;
6357 +       char* path_fault=NULL;
6358 +       unsigned long start=0UL, end=0UL, offset=0UL;
6359 +
6360 +       if (buffer_exec && buffer_fault) {
6361 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
6362 +
6363 +               down_read(&mm->mmap_sem);
6364 +               vma = mm->mmap;
6365 +               while (vma && (!vma_exec || !vma_fault)) {
6366 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
6367 +                               vma_exec = vma;
6368 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
6369 +                               vma_fault = vma;
6370 +                       vma = vma->vm_next;
6371 +               }
6372 +               if (vma_exec) {
6373 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
6374 +                       if (IS_ERR(path_exec))
6375 +                               path_exec = "<path too long>";
6376 +               }
6377 +               if (vma_fault) {
6378 +                       start = vma_fault->vm_start;
6379 +                       end = vma_fault->vm_end;
6380 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
6381 +                       if (vma_fault->vm_file) {
6382 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
6383 +                               if (IS_ERR(path_fault))
6384 +                                       path_fault = "<path too long>";
6385 +                       } else
6386 +                               path_fault = "<anonymous mapping>";
6387 +               }
6388 +               up_read(&mm->mmap_sem);
6389 +       }
6390 +       if (tsk->curr_ip) {
6391 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: execution attempt in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->curr_ip), path_fault, start, end, offset);
6392 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: terminating task: %s(%s):%d, uid/euid: %u/%u, "
6393 +                               "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), path_exec, tsk->comm, tsk->pid,
6394 +                               tsk->uid, tsk->euid, pc, sp);
6395 +       } else {
6396 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
6397 +               printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
6398 +                               "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
6399 +                               tsk->uid, tsk->euid, pc, sp);
6400 +       }
6401 +       if (buffer_exec) free_page((unsigned long)buffer_exec);
6402 +       if (buffer_fault) free_page((unsigned long)buffer_fault);
6403 +       pax_report_insns(pc);
6404 +       do_coredump(SIGKILL, regs);
6405 +}
6406 +#endif
6407 +
6408  int do_coredump(long signr, struct pt_regs * regs)
6409  {
6410         struct linux_binfmt * binfmt;
6411 @@ -1122,6 +1348,7 @@
6412                 current->fsuid = 0;
6413         }
6414         current->mm->dumpable = 0;
6415 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
6416         if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
6417                 goto fail;
6418  
6419 @@ -1141,7 +1368,7 @@
6420                 goto close_fail;
6421         if (!file->f_op->write)
6422                 goto close_fail;
6423 -       if (do_truncate(file->f_dentry, 0) != 0)
6424 +       if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
6425                 goto close_fail;
6426  
6427         retval = binfmt->core_dump(signr, regs, file);
6428 diff -urN linux-2.4.24.org/fs/fcntl.c linux-2.4.24/fs/fcntl.c
6429 --- linux-2.4.24.org/fs/fcntl.c 2004-02-04 23:03:59.333215817 +0100
6430 +++ linux-2.4.24/fs/fcntl.c     2004-02-04 23:11:32.445999690 +0100
6431 @@ -12,6 +12,7 @@
6432  #include <linux/slab.h>
6433  #include <linux/iobuf.h>
6434  #include <linux/ptrace.h>
6435 +#include <linux/grsecurity.h>
6436  
6437  #include <asm/poll.h>
6438  #include <asm/siginfo.h>
6439 @@ -65,6 +66,8 @@
6440         int error;
6441         int start;
6442  
6443 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
6444 +
6445         write_lock(&files->file_lock);
6446         
6447         error = -EINVAL;
6448 @@ -87,6 +90,7 @@
6449         }
6450         
6451         error = -EMFILE;
6452 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6453         if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6454                 goto out;
6455  
6456 @@ -142,6 +146,8 @@
6457         struct file * file, *tofree;
6458         struct files_struct * files = current->files;
6459  
6460 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6461 +
6462         write_lock(&files->file_lock);
6463         if (!(file = fcheck(oldfd)))
6464                 goto out_unlock;
6465 @@ -450,6 +456,10 @@
6466                         match = -p->pgrp;
6467                 if (pid != match)
6468                         continue;
6469 +               if (gr_check_protected_task(p))
6470 +                       continue;
6471 +               if (gr_pid_is_chrooted(p))
6472 +                       continue;
6473                 send_sigio_to_task(p, fown, fd, band);
6474         }
6475  out:
6476 diff -urN linux-2.4.24.org/fs/locks.c linux-2.4.24/fs/locks.c
6477 --- linux-2.4.24.org/fs/locks.c 2004-02-04 23:04:20.499814552 +0100
6478 +++ linux-2.4.24/fs/locks.c     2004-02-04 23:11:32.481992206 +0100
6479 @@ -137,6 +137,8 @@
6480  /* Allocate an empty lock structure. */
6481  static struct file_lock *locks_alloc_lock(void)
6482  {
6483 +// XXX?
6484 +//     if(account) gr_learn_resource(current, RLIMIT_LOCKS, current->locks, 0);
6485         return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
6486  }
6487  
6488 diff -urN linux-2.4.24.org/fs/Makefile linux-2.4.24/fs/Makefile
6489 --- linux-2.4.24.org/fs/Makefile        2004-02-04 23:04:19.835952592 +0100
6490 +++ linux-2.4.24/fs/Makefile    2004-02-04 23:11:32.529982229 +0100
6491 @@ -7,7 +7,7 @@
6492  
6493  O_TARGET := fs.o
6494  
6495 -export-objs := filesystems.o open.o dcache.o buffer.o dquot.o
6496 +export-objs := filesystems.o open.o dcache.o buffer.o dquot.o exec.o
6497  mod-subdirs := nls
6498  
6499  obj-y :=       open.o read_write.o devices.o file_table.o buffer.o \
6500 diff -urN linux-2.4.24.org/fs/namei.c linux-2.4.24/fs/namei.c
6501 --- linux-2.4.24.org/fs/namei.c 2004-02-04 23:04:20.359843657 +0100
6502 +++ linux-2.4.24/fs/namei.c     2004-02-04 23:11:32.557976408 +0100
6503 @@ -22,6 +22,7 @@
6504  #include <linux/dnotify.h>
6505  #include <linux/smp_lock.h>
6506  #include <linux/personality.h>
6507 +#include <linux/grsecurity.h>
6508  
6509  #include <asm/namei.h>
6510  #include <asm/uaccess.h>
6511 @@ -343,6 +344,13 @@
6512                 current->state = TASK_RUNNING;
6513                 schedule();
6514         }
6515 +
6516 +       if (gr_handle_follow_link(dentry->d_parent->d_inode,
6517 +                                 dentry->d_inode, dentry, nd->mnt)) {
6518 +               path_release(nd);
6519 +               return -EACCES;
6520 +       }
6521 +
6522         current->link_count++;
6523         current->total_link_count++;
6524         UPDATE_ATIME(dentry->d_inode);
6525 @@ -643,6 +651,10 @@
6526                         }
6527                 }
6528  return_base:
6529 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
6530 +                       path_release(nd);
6531 +                       return -ENOENT;
6532 +               }
6533                 return 0;
6534  out_dput:
6535                 dput(dentry);
6536 @@ -1005,7 +1017,7 @@
6537         struct dentry *dentry;
6538         struct dentry *dir;
6539         int count = 0;
6540 -
6541 +       
6542         acc_mode = ACC_MODE(flag);
6543  
6544         /*
6545 @@ -1015,7 +1027,19 @@
6546                 error = path_lookup(pathname, lookup_flags(flag), nd);
6547                 if (error)
6548                         return error;
6549 +
6550 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
6551 +                       error = -EPERM;
6552 +                       goto exit;
6553 +               }
6554 +       
6555 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
6556 +                       error = -EACCES;
6557 +                       goto exit;
6558 +               }
6559 +
6560                 dentry = nd->dentry;
6561 +
6562                 goto ok;
6563         }
6564  
6565 @@ -1048,9 +1072,21 @@
6566  
6567         /* Negative dentry, just create the file */
6568         if (!dentry->d_inode) {
6569 -               if (!IS_POSIXACL(dir->d_inode))
6570 -                       mode &= ~current->fs->umask;
6571 +               if (!IS_POSIXACL(dir->d_inode))
6572 +                       mode &= ~current->fs->umask;
6573 +               if (gr_handle_chroot_chmod(dentry, nd->mnt, mode)) {
6574 +                       error = -EACCES;
6575 +                       up(&dir->d_inode->i_sem);
6576 +                       goto exit_dput;
6577 +               }
6578 +               if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
6579 +                       error = -EACCES;
6580 +                       up(&dir->d_inode->i_sem);
6581 +                       goto exit_dput;
6582 +               }                   
6583                 error = vfs_create(dir->d_inode, dentry, mode);
6584 +               if (!error)
6585 +                       gr_handle_create(dentry, nd->mnt);
6586                 up(&dir->d_inode->i_sem);
6587                 dput(nd->dentry);
6588                 nd->dentry = dentry;
6589 @@ -1059,12 +1095,34 @@
6590                 /* Don't check for write permission, don't truncate */
6591                 acc_mode = 0;
6592                 flag &= ~O_TRUNC;
6593 +
6594                 goto ok;
6595         }
6596  
6597         /*
6598          * It already exists.
6599          */
6600 +
6601 +       if (gr_handle_rawio(dentry->d_inode)) {
6602 +               error = -EPERM;
6603 +               up(&dir->d_inode->i_sem);
6604 +               goto exit_dput;
6605 +       }
6606 +
6607 +       if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
6608 +               error = -EACCES;
6609 +               up(&dir->d_inode->i_sem);
6610 +               goto exit_dput;
6611 +       }
6612 +
6613 +       inode = dentry->d_inode;
6614 +
6615 +       if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
6616 +               up(&dir->d_inode->i_sem);
6617 +               error = -EACCES;
6618 +               goto exit_dput;
6619 +       }
6620 +
6621         up(&dir->d_inode->i_sem);
6622  
6623         error = -EEXIST;
6624 @@ -1154,7 +1212,7 @@
6625                 if (!error) {
6626                         DQUOT_INIT(inode);
6627                         
6628 -                       error = do_truncate(dentry, 0);
6629 +                       error = do_truncate(dentry,0,nd->mnt);
6630                 }
6631                 put_write_access(inode);
6632                 if (error)
6633 @@ -1185,6 +1243,13 @@
6634          * stored in nd->last.name and we will have to putname() it when we
6635          * are done. Procfs-like symlinks just set LAST_BIND.
6636          */
6637 +
6638 +       if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
6639 +                                 dentry, nd->mnt)) {
6640 +               error = -EACCES;
6641 +               goto exit_dput;
6642 +       }
6643 +
6644         UPDATE_ATIME(dentry->d_inode);
6645         error = dentry->d_inode->i_op->follow_link(dentry, nd);
6646         dput(dentry);
6647 @@ -1284,6 +1349,19 @@
6648         if (!IS_POSIXACL(nd.dentry->d_inode))
6649                 mode &= ~current->fs->umask;
6650         if (!IS_ERR(dentry)) {
6651 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode) ||
6652 +                   gr_handle_chroot_chmod(dentry, nd.mnt, mode)) {
6653 +                       error = -EPERM;
6654 +                       dput(dentry);
6655 +                       goto out_dput;
6656 +               }
6657 +
6658 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
6659 +                       error = -EACCES;
6660 +                       dput(dentry);
6661 +                       goto out_dput;
6662 +               }
6663 +       
6664                 switch (mode & S_IFMT) {
6665                 case 0: case S_IFREG:
6666                         error = vfs_create(nd.dentry->d_inode,dentry,mode);
6667 @@ -1297,8 +1375,13 @@
6668                 default:
6669                         error = -EINVAL;
6670                 }
6671 +
6672 +               if(!error)
6673 +                       gr_handle_create(dentry, nd.mnt);
6674 +
6675                 dput(dentry);
6676         }
6677 +out_dput:
6678         up(&nd.dentry->d_inode->i_sem);
6679         path_release(&nd);
6680  out:
6681 @@ -1350,9 +1433,15 @@
6682                 dentry = lookup_create(&nd, 1);
6683                 error = PTR_ERR(dentry);
6684                 if (!IS_ERR(dentry)) {
6685 +                       error = 0;
6686                         if (!IS_POSIXACL(nd.dentry->d_inode))
6687 -                               mode &= ~current->fs->umask;
6688 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6689 +                               mode &= ~current->fs->umask;
6690 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
6691 +                               error = -EACCES;
6692 +                       if (!error)
6693 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6694 +                       if(!error)
6695 +                               gr_handle_create(dentry, nd.mnt);
6696                         dput(dentry);
6697                 }
6698                 up(&nd.dentry->d_inode->i_sem);
6699 @@ -1436,6 +1525,8 @@
6700         char * name;
6701         struct dentry *dentry;
6702         struct nameidata nd;
6703 +       ino_t saved_ino = 0;
6704 +       kdev_t saved_dev = 0;
6705  
6706         name = getname(pathname);
6707         if(IS_ERR(name))
6708 @@ -1460,7 +1551,22 @@
6709         dentry = lookup_hash(&nd.last, nd.dentry);
6710         error = PTR_ERR(dentry);
6711         if (!IS_ERR(dentry)) {
6712 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
6713 +               error = 0;
6714 +               if (dentry->d_inode) {
6715 +                       if (dentry->d_inode->i_nlink <= 1) {
6716 +                               saved_ino = dentry->d_inode->i_ino;
6717 +                               saved_dev = dentry->d_inode->i_dev;
6718 +                       }
6719 +
6720 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
6721 +                               error = -EACCES;
6722 +               }
6723 +
6724 +               if (!error)
6725 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
6726 +               if (!error && (saved_dev || saved_ino))
6727 +                       gr_handle_delete(saved_ino,saved_dev);
6728 +
6729                 dput(dentry);
6730         }
6731         up(&nd.dentry->d_inode->i_sem);
6732 @@ -1505,6 +1611,8 @@
6733         char * name;
6734         struct dentry *dentry;
6735         struct nameidata nd;
6736 +       ino_t saved_ino = 0;
6737 +       kdev_t saved_dev = 0;
6738  
6739         name = getname(pathname);
6740         if(IS_ERR(name))
6741 @@ -1523,7 +1631,21 @@
6742                 /* Why not before? Because we want correct error value */
6743                 if (nd.last.name[nd.last.len])
6744                         goto slashes;
6745 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
6746 +               error = 0;
6747 +               if (dentry->d_inode) {
6748 +                       if (dentry->d_inode->i_nlink <= 1) {
6749 +                               saved_ino = dentry->d_inode->i_ino;
6750 +                               saved_dev = dentry->d_inode->i_dev;
6751 +                       }
6752 +
6753 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
6754 +                               error = -EACCES;
6755 +               }
6756 +
6757 +               if (!error)
6758 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
6759 +               if (!error && (saved_ino || saved_dev))
6760 +                       gr_handle_delete(saved_ino,saved_dev);
6761         exit2:
6762                 dput(dentry);
6763         }
6764 @@ -1587,7 +1709,15 @@
6765                 dentry = lookup_create(&nd, 0);
6766                 error = PTR_ERR(dentry);
6767                 if (!IS_ERR(dentry)) {
6768 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6769 +                       error = 0;
6770 +
6771 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
6772 +                               error = -EACCES;
6773 +
6774 +                       if(!error)      
6775 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6776 +                       if (!error)
6777 +                               gr_handle_create(dentry, nd.mnt);
6778                         dput(dentry);
6779                 }
6780                 up(&nd.dentry->d_inode->i_sem);
6781 @@ -1671,7 +1801,27 @@
6782                 new_dentry = lookup_create(&nd, 0);
6783                 error = PTR_ERR(new_dentry);
6784                 if (!IS_ERR(new_dentry)) {
6785 -                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
6786 +                       error = 0;
6787 +
6788 +                       if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
6789 +                                              old_nd.dentry->d_inode,
6790 +                                              old_nd.dentry->d_inode->i_mode, to)) {
6791 +                               error = -EPERM;
6792 +                               goto out_error;
6793 +                       }
6794 +
6795 +                       if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
6796 +                                                old_nd.dentry, old_nd.mnt, to)) {
6797 +                               error = -EACCES;
6798 +                               goto out_error;
6799 +                       }
6800 +
6801 +                       error = vfs_link(old_nd.dentry, 
6802 +                                       nd.dentry->d_inode, new_dentry);
6803 +
6804 +                       if (!error)
6805 +                               gr_handle_create(new_dentry, nd.mnt);
6806 +out_error:
6807                         dput(new_dentry);
6808                 }
6809                 up(&nd.dentry->d_inode->i_sem);
6810 @@ -1907,10 +2057,15 @@
6811         if (IS_ERR(new_dentry))
6812                 goto exit4;
6813  
6814 -       lock_kernel();
6815 -       error = vfs_rename(old_dir->d_inode, old_dentry,
6816 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
6817 +                                    old_dentry, old_dir->d_inode, oldnd.mnt, newname);
6818 +
6819 +       if (error == 1) {
6820 +               lock_kernel();
6821 +               error = vfs_rename(old_dir->d_inode, old_dentry,
6822                                    new_dir->d_inode, new_dentry);
6823 -       unlock_kernel();
6824 +               unlock_kernel();
6825 +       }
6826  
6827         dput(new_dentry);
6828  exit4:
6829 diff -urN linux-2.4.24.org/fs/namespace.c linux-2.4.24/fs/namespace.c
6830 --- linux-2.4.24.org/fs/namespace.c     2004-02-04 23:03:59.301222470 +0100
6831 +++ linux-2.4.24/fs/namespace.c 2004-02-04 23:11:32.565974745 +0100
6832 @@ -15,6 +15,8 @@
6833  #include <linux/quotaops.h>
6834  #include <linux/acct.h>
6835  #include <linux/module.h>
6836 +#include <linux/sched.h>
6837 +#include <linux/grsecurity.h>
6838  
6839  #include <asm/uaccess.h>
6840  
6841 @@ -325,6 +327,8 @@
6842                         lock_kernel();
6843                         retval = do_remount_sb(sb, MS_RDONLY, 0);
6844                         unlock_kernel();
6845 +
6846 +                       gr_log_remount(mnt->mnt_devname, retval);
6847                 }
6848                 up_write(&sb->s_umount);
6849                 return retval;
6850 @@ -350,6 +354,9 @@
6851         }
6852         spin_unlock(&dcache_lock);
6853         up_write(&current->namespace->sem);
6854 +
6855 +       gr_log_unmount(mnt->mnt_devname, retval);
6856 +
6857         return retval;
6858  }
6859  
6860 @@ -729,6 +736,12 @@
6861         if (retval)
6862                 return retval;
6863  
6864 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
6865 +               retval = -EPERM;
6866 +               path_release(&nd);
6867 +               return retval;
6868 +       }
6869 +
6870         if (flags & MS_REMOUNT)
6871                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
6872                                     data_page);
6873 @@ -740,6 +753,9 @@
6874                 retval = do_add_mount(&nd, type_page, flags, mnt_flags,
6875                                       dev_name, data_page);
6876         path_release(&nd);
6877 +
6878 +       gr_log_mount(dev_name, dir_name, retval);
6879 +
6880         return retval;
6881  }
6882  
6883 @@ -909,6 +925,9 @@
6884         if (!capable(CAP_SYS_ADMIN))
6885                 return -EPERM;
6886  
6887 +       if (gr_handle_chroot_pivot())
6888 +               return -EPERM;
6889 +
6890         lock_kernel();
6891  
6892         error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
6893 diff -urN linux-2.4.24.org/fs/open.c linux-2.4.24/fs/open.c
6894 --- linux-2.4.24.org/fs/open.c  2004-02-04 23:03:59.562168210 +0100
6895 +++ linux-2.4.24/fs/open.c      2004-02-04 23:11:32.590969549 +0100
6896 @@ -15,6 +15,7 @@
6897  #include <linux/slab.h>
6898  #include <linux/tty.h>
6899  #include <linux/iobuf.h>
6900 +#include <linux/grsecurity.h>
6901  
6902  #include <asm/uaccess.h>
6903  
6904 @@ -95,7 +96,7 @@
6905         write_unlock(&files->file_lock);
6906  }
6907  
6908 -int do_truncate(struct dentry *dentry, loff_t length)
6909 +int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
6910  {
6911         struct inode *inode = dentry->d_inode;
6912         int error;
6913 @@ -105,6 +106,9 @@
6914         if (length < 0)
6915                 return -EINVAL;
6916  
6917 +       if (!gr_acl_handle_truncate(dentry, mnt))
6918 +               return -EACCES;
6919 +
6920         down_write(&inode->i_alloc_sem);
6921         down(&inode->i_sem);
6922         newattrs.ia_size = length;
6923 @@ -165,7 +169,7 @@
6924         error = locks_verify_truncate(inode, NULL, length);
6925         if (!error) {
6926                 DQUOT_INIT(inode);
6927 -               error = do_truncate(nd.dentry, length);
6928 +               error = do_truncate(nd.dentry, length, nd.mnt);
6929         }
6930         put_write_access(inode);
6931  
6932 @@ -217,7 +221,7 @@
6933  
6934         error = locks_verify_truncate(inode, file, length);
6935         if (!error)
6936 -               error = do_truncate(dentry, length);
6937 +               error = do_truncate(dentry, length, file->f_vfsmnt);
6938  out_putf:
6939         fput(file);
6940  out:
6941 @@ -292,6 +296,12 @@
6942                     (error = permission(inode,MAY_WRITE)) != 0)
6943                         goto dput_and_out;
6944         }
6945 +
6946 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6947 +               error = -EACCES;
6948 +               goto dput_and_out;
6949 +       }
6950 +
6951         error = notify_change(nd.dentry, &newattrs);
6952  dput_and_out:
6953         path_release(&nd);
6954 @@ -344,6 +354,12 @@
6955                     (error = permission(inode,MAY_WRITE)) != 0)
6956                         goto dput_and_out;
6957         }
6958 +
6959 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6960 +               error = -EACCES;
6961 +               goto dput_and_out;
6962 +       }
6963 +
6964         error = notify_change(nd.dentry, &newattrs);
6965  dput_and_out:
6966         path_release(&nd);
6967 @@ -386,6 +402,10 @@
6968                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
6969                    && !special_file(nd.dentry->d_inode->i_mode))
6970                         res = -EROFS;
6971 +               
6972 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
6973 +                       res =  -EACCES;
6974 +
6975                 path_release(&nd);
6976         }
6977  
6978 @@ -409,6 +429,8 @@
6979         if (error)
6980                 goto dput_and_out;
6981  
6982 +       gr_log_chdir(nd.dentry, nd.mnt);
6983 +
6984         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
6985  
6986  dput_and_out:
6987 @@ -439,6 +461,13 @@
6988                 goto out_putf;
6989  
6990         error = permission(inode, MAY_EXEC);
6991 +
6992 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
6993 +               error = -EPERM;
6994 +
6995 +       if (!error)
6996 +               gr_log_chdir(dentry, mnt);
6997 +
6998         if (!error)
6999                 set_fs_pwd(current->fs, mnt, dentry);
7000  out_putf:
7001 @@ -465,8 +494,16 @@
7002         if (!capable(CAP_SYS_CHROOT))
7003                 goto dput_and_out;
7004  
7005 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
7006 +               goto dput_and_out;
7007 +
7008         set_fs_root(current->fs, nd.mnt, nd.dentry);
7009         set_fs_altroot();
7010 +
7011 +       gr_handle_chroot_caps(current);
7012 +
7013 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
7014 +
7015         error = 0;
7016  dput_and_out:
7017         path_release(&nd);
7018 @@ -495,8 +532,20 @@
7019         err = -EPERM;
7020         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7021                 goto out_putf;
7022 +
7023 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
7024 +               err = -EACCES;
7025 +               goto out_putf;
7026 +       }
7027 +
7028         if (mode == (mode_t) -1)
7029                 mode = inode->i_mode;
7030 +
7031 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
7032 +               err = -EPERM;
7033 +               goto out_putf;
7034 +       }           
7035 +
7036         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
7037         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
7038         err = notify_change(dentry, &newattrs);
7039 @@ -527,8 +576,19 @@
7040         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7041                 goto dput_and_out;
7042  
7043 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
7044 +               error = -EACCES;
7045 +               goto dput_and_out;
7046 +       }
7047 +
7048         if (mode == (mode_t) -1)
7049                 mode = inode->i_mode;
7050 +
7051 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
7052 +               error = -EACCES;
7053 +               goto dput_and_out;
7054 +       }
7055 +
7056         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
7057         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
7058         error = notify_change(nd.dentry, &newattrs);
7059 @@ -539,7 +599,7 @@
7060         return error;
7061  }
7062  
7063 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
7064 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
7065  {
7066         struct inode * inode;
7067         int error;
7068 @@ -556,6 +616,12 @@
7069         error = -EPERM;
7070         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7071                 goto out;
7072 +
7073 +       if (!gr_acl_handle_chown(dentry, mnt)) {
7074 +               error = -EACCES;
7075 +               goto out;
7076 +       }
7077 +
7078         if (user == (uid_t) -1)
7079                 user = inode->i_uid;
7080         if (group == (gid_t) -1)
7081 @@ -606,7 +672,7 @@
7082  
7083         error = user_path_walk(filename, &nd);
7084         if (!error) {
7085 -               error = chown_common(nd.dentry, user, group);
7086 +               error = chown_common(nd.dentry, user, group, nd.mnt);
7087                 path_release(&nd);
7088         }
7089         return error;
7090 @@ -619,7 +685,7 @@
7091  
7092         error = user_path_walk_link(filename, &nd);
7093         if (!error) {
7094 -               error = chown_common(nd.dentry, user, group);
7095 +               error = chown_common(nd.dentry, user, group, nd.mnt);
7096                 path_release(&nd);
7097         }
7098         return error;
7099 @@ -633,7 +699,8 @@
7100  
7101         file = fget(fd);
7102         if (file) {
7103 -               error = chown_common(file->f_dentry, user, group);
7104 +               error = chown_common(file->f_dentry, user,
7105 +                               group, file->f_vfsmnt);
7106                 fput(file);
7107         }
7108         return error;
7109 @@ -753,6 +820,7 @@
7110          * N.B. For clone tasks sharing a files structure, this test
7111          * will limit the total number of files that can be opened.
7112          */
7113 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
7114         if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
7115                 goto out;
7116  
7117 diff -urN linux-2.4.24.org/fs/proc/array.c linux-2.4.24/fs/proc/array.c
7118 --- linux-2.4.24.org/fs/proc/array.c    2004-02-04 23:04:00.483976534 +0100
7119 +++ linux-2.4.24/fs/proc/array.c        2004-02-04 23:11:32.650957076 +0100
7120 @@ -298,6 +298,12 @@
7121         return buffer - orig;
7122  }
7123  
7124 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7125 +#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
7126 +                       task->flags & PF_PAX_SEGMEXEC || \
7127 +                       task->flags & PF_PAX_RANDEXEC)
7128 +#endif
7129 +
7130  int proc_pid_stat(struct task_struct *task, char * buffer)
7131  {
7132         unsigned long vsize, eip, esp, wchan;
7133 @@ -335,6 +341,19 @@
7134  
7135         wchan = get_wchan(task);
7136  
7137 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7138 +       if (PAX_RAND_FLAGS) {
7139 +               eip = 0;
7140 +               esp = 0;
7141 +               wchan = 0;
7142 +       }
7143 +#endif
7144 +#ifdef CONFIG_GRKERNSEC_HIDESYM
7145 +       wchan = 0;
7146 +       eip = 0;
7147 +       esp = 0;
7148 +#endif
7149 +
7150         collect_sigign_sigcatch(task, &sigign, &sigcatch);
7151  
7152         /* scale priority and nice values from timeslices to -20..20 */
7153 @@ -373,9 +392,15 @@
7154                 vsize,
7155                 mm ? mm->rss : 0, /* you might want to shift this left 3 */
7156                 task->rlim[RLIMIT_RSS].rlim_cur,
7157 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7158 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
7159 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
7160 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
7161 +#else
7162                 mm ? mm->start_code : 0,
7163                 mm ? mm->end_code : 0,
7164                 mm ? mm->start_stack : 0,
7165 +#endif
7166                 esp,
7167                 eip,
7168                 /* The signal information here is obsolete.
7169 @@ -513,6 +538,7 @@
7170  
7171  static int show_map(struct seq_file *m, void *v)
7172  {
7173 +       struct task_struct *task = m->private;
7174         struct vm_area_struct *map = v;
7175         struct file *file = map->vm_file;
7176         int flags = map->vm_flags;
7177 @@ -527,8 +553,13 @@
7178         }
7179  
7180         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
7181 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7182 +                       PAX_RAND_FLAGS ? 0UL : map->vm_start,
7183 +                       PAX_RAND_FLAGS ? 0UL : map->vm_end,
7184 +#else
7185                         map->vm_start,
7186                         map->vm_end,
7187 +#endif
7188                         flags & VM_READ ? 'r' : '-',
7189                         flags & VM_WRITE ? 'w' : '-',
7190                         flags & VM_EXEC ? 'x' : '-',
7191 @@ -601,6 +632,16 @@
7192         .show   = show_map
7193  };
7194  
7195 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR     
7196 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)    
7197 +{       
7198 +       int len;         
7199 +
7200 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));  
7201 +       return len;      
7202 +}       
7203 +#endif
7204 +
7205  #ifdef CONFIG_SMP
7206  int proc_pid_cpu(struct task_struct *task, char * buffer)
7207  {
7208 diff -urN linux-2.4.24.org/fs/proc/base.c linux-2.4.24/fs/proc/base.c
7209 --- linux-2.4.24.org/fs/proc/base.c     2004-02-04 23:04:00.462980900 +0100
7210 +++ linux-2.4.24/fs/proc/base.c 2004-02-04 23:11:32.687949385 +0100
7211 @@ -25,6 +25,7 @@
7212  #include <linux/string.h>
7213  #include <linux/seq_file.h>
7214  #include <linux/namespace.h>
7215 +#include <linux/grsecurity.h>
7216  
7217  /*
7218   * For hysterical raisins we keep the same inumbers as in the old procfs.
7219 @@ -40,6 +41,9 @@
7220  int proc_pid_status(struct task_struct*,char*);
7221  int proc_pid_statm(struct task_struct*,char*);
7222  int proc_pid_cpu(struct task_struct*,char*);
7223 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7224 +int proc_pid_ipaddr(struct task_struct*,char*);
7225 +#endif
7226  
7227  static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
7228  {
7229 @@ -263,9 +267,22 @@
7230  
7231  static int proc_permission(struct inode *inode, int mask)
7232  {
7233 +       int ret;
7234 +       struct task_struct *task;
7235 +
7236         if (vfs_permission(inode, mask) != 0)
7237                 return -EACCES;
7238 -       return proc_check_root(inode);
7239 +       ret = proc_check_root(inode);
7240 +
7241 +       if (ret)
7242 +               return ret;
7243 +
7244 +       task = inode->u.proc_i.task;
7245 +
7246 +       if (!task)
7247 +               return 0;
7248 +
7249 +       return gr_acl_handle_procpidmem(task);
7250  }
7251  
7252  extern struct seq_operations proc_pid_maps_op;
7253 @@ -598,6 +615,9 @@
7254         PROC_PID_STATM,
7255         PROC_PID_MAPS,
7256         PROC_PID_CPU,
7257 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7258 +       PROC_PID_IPADDR,
7259 +#endif
7260         PROC_PID_MOUNTS,
7261         PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
7262  };
7263 @@ -613,6 +633,9 @@
7264  #ifdef CONFIG_SMP
7265    E(PROC_PID_CPU,      "cpu",          S_IFREG|S_IRUGO),
7266  #endif
7267 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7268 +  E(PROC_PID_IPADDR,   "ipaddr",       S_IFREG|S_IRUSR),
7269 +#endif
7270    E(PROC_PID_MAPS,     "maps",         S_IFREG|S_IRUGO),
7271    E(PROC_PID_MEM,      "mem",          S_IFREG|S_IRUSR|S_IWUSR),
7272    E(PROC_PID_CWD,      "cwd",          S_IFLNK|S_IRWXUGO),
7273 @@ -769,10 +792,17 @@
7274         get_task_struct(task);
7275         inode->u.proc_i.task = task;
7276         inode->i_uid = 0;
7277 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7278 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7279 +#else
7280         inode->i_gid = 0;
7281 +#endif
7282 +
7283         if (ino == PROC_PID_INO || task_dumpable(task)) {
7284                 inode->i_uid = task->euid;
7285 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
7286                 inode->i_gid = task->egid;
7287 +#endif
7288         }
7289  
7290  out:
7291 @@ -980,6 +1010,12 @@
7292                         inode->u.proc_i.op.proc_read = proc_pid_cpu;
7293                         break;
7294  #endif
7295 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7296 +               case PROC_PID_IPADDR:
7297 +                       inode->i_fop = &proc_info_file_operations;
7298 +                       inode->u.proc_i.op.proc_read = proc_pid_ipaddr;
7299 +                       break;
7300 +#endif
7301                 case PROC_PID_MEM:
7302                         inode->i_op = &proc_mem_inode_operations;
7303                         inode->i_fop = &proc_mem_operations;
7304 @@ -1078,13 +1114,35 @@
7305         if (!task)
7306                 goto out;
7307  
7308 +       if(gr_check_hidden_task(task)) {
7309 +               free_task_struct(task);
7310 +               goto out;
7311 +       }
7312 +       
7313 +#ifdef CONFIG_GRKERNSEC_PROC
7314 +       if (current->uid && (task->uid != current->uid)
7315 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7316 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7317 +#endif
7318 +       ) {
7319 +               free_task_struct(task);
7320 +               goto out;
7321 +       }       
7322 +#endif
7323         inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
7324  
7325         free_task_struct(task);
7326  
7327         if (!inode)
7328                 goto out;
7329 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7330 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
7331 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7332 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
7333 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7334 +#else
7335         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
7336 +#endif
7337         inode->i_op = &proc_base_inode_operations;
7338         inode->i_fop = &proc_base_operations;
7339         inode->i_nlink = 3;
7340 @@ -1124,6 +1182,18 @@
7341                 int pid = p->pid;
7342                 if (!pid)
7343                         continue;
7344 +               if(gr_pid_is_chrooted(p))
7345 +                       continue;
7346 +               if(gr_check_hidden_task(p)) 
7347 +                       continue;
7348 +#ifdef CONFIG_GRKERNSEC_PROC
7349 +               if (current->uid && (p->uid != current->uid)
7350 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7351 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7352 +#endif
7353 +               )
7354 +                       continue;       
7355 +#endif
7356                 if (--index >= 0)
7357                         continue;
7358                 pids[nr_pids] = pid;
7359 diff -urN linux-2.4.24.org/fs/proc/generic.c linux-2.4.24/fs/proc/generic.c
7360 --- linux-2.4.24.org/fs/proc/generic.c  2004-02-04 23:04:00.459981524 +0100
7361 +++ linux-2.4.24/fs/proc/generic.c      2004-02-04 23:11:32.724941694 +0100
7362 @@ -504,6 +504,32 @@
7363         return ent;
7364  }
7365  
7366 +#ifdef CONFIG_GRKERNSEC_PROC
7367 +struct proc_dir_entry *proc_priv_mkdir(const char *name, struct proc_dir_entry *parent)
7368 +{
7369 +       struct proc_dir_entry *ent;
7370 +       mode_t mode = 0;
7371 +
7372 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7373 +       mode = S_IFDIR | S_IRUSR | S_IXUSR;
7374 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7375 +       mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP;
7376 +#endif
7377 +
7378 +       ent = proc_create(&parent, name, mode, 2);
7379 +       if (ent) {
7380 +               ent->proc_fops = &proc_dir_operations;
7381 +               ent->proc_iops = &proc_dir_inode_operations;
7382 +
7383 +               if (proc_register(parent, ent) < 0) {
7384 +                       kfree(ent);
7385 +                       ent = NULL;
7386 +               }
7387 +       }
7388 +       return ent;
7389 +}
7390 +#endif
7391 +
7392  struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
7393                                          struct proc_dir_entry *parent)
7394  {
7395 diff -urN linux-2.4.24.org/fs/proc/inode.c linux-2.4.24/fs/proc/inode.c
7396 --- linux-2.4.24.org/fs/proc/inode.c    2004-02-04 23:04:00.436986305 +0100
7397 +++ linux-2.4.24/fs/proc/inode.c        2004-02-04 23:11:32.750936290 +0100
7398 @@ -152,7 +152,11 @@
7399                 if (de->mode) {
7400                         inode->i_mode = de->mode;
7401                         inode->i_uid = de->uid;
7402 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7403 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7404 +#else
7405                         inode->i_gid = de->gid;
7406 +#endif                 
7407                 }
7408                 if (de->size)
7409                         inode->i_size = de->size;
7410 diff -urN linux-2.4.24.org/fs/proc/proc_misc.c linux-2.4.24/fs/proc/proc_misc.c
7411 --- linux-2.4.24.org/fs/proc/proc_misc.c        2004-02-04 23:04:00.386996700 +0100
7412 +++ linux-2.4.24/fs/proc/proc_misc.c    2004-02-04 23:11:32.777930677 +0100
7413 @@ -590,6 +590,7 @@
7414  void __init proc_misc_init(void)
7415  {
7416         struct proc_dir_entry *entry;
7417 +       int gr_mode = 0;
7418         static struct {
7419                 char *name;
7420                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
7421 @@ -604,17 +605,21 @@
7422  #ifdef CONFIG_STRAM_PROC
7423                 {"stram",       stram_read_proc},
7424  #endif
7425 -#ifdef CONFIG_MODULES
7426 +#if defined(CONFIG_MODULES) && !defined(CONFIG_GRKERNSEC_PROC)
7427                 {"modules",     modules_read_proc},
7428  #endif
7429                 {"stat",        kstat_read_proc},
7430 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7431                 {"devices",     devices_read_proc},
7432 -#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
7433 +#endif
7434 +#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
7435                 {"interrupts",  interrupts_read_proc},
7436  #endif
7437                 {"filesystems", filesystems_read_proc},
7438 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7439                 {"dma",         dma_read_proc},
7440                 {"cmdline",     cmdline_read_proc},
7441 +#endif
7442  #ifdef CONFIG_SGI_DS1286
7443                 {"rtc",         ds1286_read_proc},
7444  #endif
7445 @@ -626,29 +631,60 @@
7446         for (p = simple_ones; p->name; p++)
7447                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
7448  
7449 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7450 +       gr_mode = S_IRUSR;
7451 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7452 +       gr_mode = S_IRUSR | S_IRGRP;
7453 +#endif
7454 +#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES)
7455 +       create_proc_read_entry("modules", gr_mode, NULL, &modules_read_proc, NULL);
7456 +#endif
7457 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7458 +       create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
7459 +       create_proc_read_entry("dma", gr_mode, NULL, &dma_read_proc, NULL);
7460 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
7461 +#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
7462 +       create_proc_read_entry("interrupts", gr_mode, NULL, &interrupts_read_proc, NULL);
7463 +#endif
7464 +#endif
7465 +
7466         proc_symlink("mounts", NULL, "self/mounts");
7467  
7468         /* And now for trickier ones */
7469         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
7470         if (entry)
7471                 entry->proc_fops = &proc_kmsg_operations;
7472 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7473 +       create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
7474 +#else
7475         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
7476 -#if defined(CONFIG_X86)
7477 +#endif
7478 +#if defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
7479         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
7480 +#elif defined(CONFIG_X86)
7481 +       create_seq_entry("interrupts", gr_mode, &proc_interrupts_operations);
7482  #endif
7483 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7484 +       create_seq_entry("ioports", gr_mode, &proc_ioports_operations);
7485 +       create_seq_entry("iomem", gr_mode, &proc_iomem_operations);
7486 +       create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
7487 +#else
7488         create_seq_entry("ioports", 0, &proc_ioports_operations);
7489         create_seq_entry("iomem", 0, &proc_iomem_operations);
7490 -       create_seq_entry("partitions", 0, &proc_partitions_operations);
7491         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
7492 +#endif
7493 +       create_seq_entry("partitions", 0, &proc_partitions_operations);
7494  #ifdef CONFIG_MODULES
7495 -       create_seq_entry("ksyms", 0, &proc_ksyms_operations);
7496 +       create_seq_entry("ksyms", gr_mode, &proc_ksyms_operations);
7497  #endif
7498 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7499         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
7500         if (proc_root_kcore) {
7501                 proc_root_kcore->proc_fops = &proc_kcore_operations;
7502                 proc_root_kcore->size =
7503                                 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
7504         }
7505 +#endif
7506         if (prof_shift) {
7507                 entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
7508                 if (entry) {
7509 diff -urN linux-2.4.24.org/fs/proc/proc_tty.c linux-2.4.24/fs/proc/proc_tty.c
7510 --- linux-2.4.24.org/fs/proc/proc_tty.c 2004-02-04 23:04:00.551962398 +0100
7511 +++ linux-2.4.24/fs/proc/proc_tty.c     2004-02-04 23:11:32.817922362 +0100
7512 @@ -174,7 +174,11 @@
7513         if (!proc_mkdir("tty", 0))
7514                 return;
7515         proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
7516 +#ifdef CONFIG_GRKERNSEC_PROC
7517 +       proc_tty_driver = proc_priv_mkdir("tty/driver", 0);
7518 +#else
7519         proc_tty_driver = proc_mkdir("tty/driver", 0);
7520 +#endif
7521  
7522         create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
7523         create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
7524 diff -urN linux-2.4.24.org/fs/proc/root.c linux-2.4.24/fs/proc/root.c
7525 --- linux-2.4.24.org/fs/proc/root.c     2004-02-04 23:04:00.503972377 +0100
7526 +++ linux-2.4.24/fs/proc/root.c 2004-02-04 23:11:32.934898042 +0100
7527 @@ -37,13 +37,21 @@
7528                 return;
7529         }
7530         proc_misc_init();
7531 +#ifdef CONFIG_GRKERNSEC_PROC
7532 +       proc_net = proc_priv_mkdir("net", 0);
7533 +#else
7534         proc_net = proc_mkdir("net", 0);
7535 +#endif
7536  #ifdef CONFIG_SYSVIPC
7537         proc_mkdir("sysvipc", 0);
7538  #endif
7539  #ifdef CONFIG_SYSCTL
7540 +#ifdef CONFIG_GRKERNSEC_PROC
7541 +       proc_sys_root = proc_priv_mkdir("sys", 0);
7542 +#else
7543         proc_sys_root = proc_mkdir("sys", 0);
7544  #endif
7545 +#endif
7546  #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
7547         proc_mkdir("sys/fs", 0);
7548         proc_mkdir("sys/fs/binfmt_misc", 0);
7549 @@ -67,7 +75,12 @@
7550  #ifdef CONFIG_PPC_RTAS
7551         proc_rtas_init();
7552  #endif
7553 +
7554 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7555 +       proc_bus = proc_priv_mkdir("bus", 0);
7556 +#else
7557         proc_bus = proc_mkdir("bus", 0);
7558 +#endif
7559  }
7560  
7561  static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
7562 diff -urN linux-2.4.24.org/fs/readdir.c linux-2.4.24/fs/readdir.c
7563 --- linux-2.4.24.org/fs/readdir.c       2004-02-04 23:04:00.184038902 +0100
7564 +++ linux-2.4.24/fs/readdir.c   2004-02-04 23:11:33.368807827 +0100
7565 @@ -10,6 +10,7 @@
7566  #include <linux/stat.h>
7567  #include <linux/file.h>
7568  #include <linux/smp_lock.h>
7569 +#include <linux/grsecurity.h>
7570  
7571  #include <asm/uaccess.h>
7572  
7573 @@ -182,6 +183,7 @@
7574  struct readdir_callback {
7575         struct old_linux_dirent * dirent;
7576         int count;
7577 +       struct nameidata nd;
7578  };
7579  
7580  static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
7581 @@ -192,6 +194,10 @@
7582  
7583         if (buf->count)
7584                 return -EINVAL;
7585 +
7586 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7587 +               return 0;
7588 +           
7589         buf->count++;
7590         dirent = buf->dirent;
7591         put_user(ino, &dirent->d_ino);
7592 @@ -216,6 +222,9 @@
7593         buf.count = 0;
7594         buf.dirent = dirent;
7595  
7596 +       buf.nd.dentry = file->f_dentry;
7597 +       buf.nd.mnt = file->f_vfsmnt;
7598 +
7599         error = vfs_readdir(file, fillonedir, &buf);
7600         if (error >= 0)
7601                 error = buf.count;
7602 @@ -243,6 +252,7 @@
7603         struct linux_dirent * previous;
7604         int count;
7605         int error;
7606 +       struct nameidata nd;
7607  };
7608  
7609  static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
7610 @@ -255,6 +265,10 @@
7611         buf->error = -EINVAL;   /* only used if we fail.. */
7612         if (reclen > buf->count)
7613                 return -EINVAL;
7614 +
7615 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7616 +               return 0;
7617 +
7618         dirent = buf->previous;
7619         if (dirent)
7620                 put_user(offset, &dirent->d_off);
7621 @@ -287,6 +301,9 @@
7622         buf.count = count;
7623         buf.error = 0;
7624  
7625 +       buf.nd.dentry = file->f_dentry;
7626 +       buf.nd.mnt = file->f_vfsmnt;
7627 +
7628         error = vfs_readdir(file, filldir, &buf);
7629         if (error < 0)
7630                 goto out_putf;
7631 @@ -321,6 +338,7 @@
7632         struct linux_dirent64 * previous;
7633         int count;
7634         int error;
7635 +       struct nameidata nd;
7636  };
7637  
7638  static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
7639 @@ -333,6 +351,10 @@
7640         buf->error = -EINVAL;   /* only used if we fail.. */
7641         if (reclen > buf->count)
7642                 return -EINVAL;
7643 +
7644 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7645 +               return 0;
7646 +       
7647         dirent = buf->previous;
7648         if (dirent) {
7649                 d.d_off = offset;
7650 @@ -370,6 +392,9 @@
7651         buf.count = count;
7652         buf.error = 0;
7653  
7654 +       buf.nd.mnt = file->f_vfsmnt;
7655 +       buf.nd.dentry = file->f_dentry;
7656 +
7657         error = vfs_readdir(file, filldir64, &buf);
7658         if (error < 0)
7659                 goto out_putf;
7660 diff -urN linux-2.4.24.org/grsecurity/Config.in linux-2.4.24/grsecurity/Config.in
7661 --- linux-2.4.24.org/grsecurity/Config.in       1970-01-01 01:00:00.000000000 +0100
7662 +++ linux-2.4.24/grsecurity/Config.in   2004-02-04 23:11:33.377805956 +0100
7663 @@ -0,0 +1,372 @@
7664 +define_bool CONFIG_CRYPTO y
7665 +define_bool CONFIG_CRYPTO_SHA256 y
7666 +choice 'Security level' \
7667 +        "Low           CONFIG_GRKERNSEC_LOW \
7668 +         Medium                CONFIG_GRKERNSEC_MID \
7669 +         High          CONFIG_GRKERNSEC_HI \
7670 +         Customized    CONFIG_GRKERNSEC_CUSTOM" Customized
7671 +if [ "$CONFIG_GRKERNSEC_LOW" = "y" ]; then
7672 +define_bool CONFIG_GRKERNSEC_RANDSRC n
7673 +define_bool CONFIG_GRKERNSEC_RANDRPC n
7674 +define_bool CONFIG_GRKERNSEC_FORKFAIL n
7675 +define_bool CONFIG_GRKERNSEC_TIME n
7676 +define_bool CONFIG_GRKERNSEC_SIGNAL n
7677 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7678 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT n
7679 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7680 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE n
7681 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT n
7682 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD n
7683 +define_bool CONFIG_GRKERNSEC_PROC n
7684 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7685 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
7686 +define_bool CONFIG_GRKERNSEC_HIDESYM n
7687 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7688 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n
7689 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n
7690 +define_bool CONFIG_GRKERNSEC_KMEM n
7691 +define_bool CONFIG_GRKERNSEC_PROC_ADD n
7692 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7693 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7694 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7695 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK n
7696 +define_bool CONFIG_GRKERNSEC_PAX_ASLR n
7697 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP n
7698 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7699 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7700 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7701 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7702 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7703 +if [ "$CONFIG_X86" = "y" ]; then
7704 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7705 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7706 +define_bool CONFIG_GRKERNSEC_IO n
7707 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7708 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7709 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7710 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7711 +fi
7712 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7713 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7714 +define_bool CONFIG_GRKERNSEC_RESLOG n
7715 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7716 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7717 +
7718 +define_int  CONFIG_GRKERNSEC_FLOODTIME 10
7719 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7720 +define_bool CONFIG_GRKERNSEC_LINK y
7721 +define_bool CONFIG_GRKERNSEC_FIFO y
7722 +define_bool CONFIG_GRKERNSEC_RANDPID y
7723 +define_bool CONFIG_GRKERNSEC_EXECVE y
7724 +define_bool CONFIG_GRKERNSEC_RANDNET y
7725 +define_bool CONFIG_GRKERNSEC_RANDISN n
7726 +define_bool CONFIG_GRKERNSEC_DMESG y
7727 +define_bool CONFIG_GRKERNSEC_RANDID y
7728 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7729 +fi
7730 +if [ "$CONFIG_GRKERNSEC_MID" = "y" ]; then
7731 +define_bool CONFIG_GRKERNSEC_KMEM n
7732 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7733 +define_bool CONFIG_GRKERNSEC_HIDESYM n
7734 +define_bool CONFIG_GRKERNSEC_PROC_ADD n
7735 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7736 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7737 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7738 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7739 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7740 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7741 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7742 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7743 +if [ "$CONFIG_X86" = "y" ]; then
7744 +define_bool CONFIG_GRKERNSEC_IO n
7745 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7746 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7747 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7748 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7749 +fi
7750 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7751 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7752 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7753 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7754 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7755 +define_bool CONFIG_GRKERNSEC_RESLOG n
7756 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7757 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7758 +
7759 +define_int  CONFIG_GRKERNSEC_FLOODTIME 10
7760 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7761 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y
7762 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7763 +define_bool CONFIG_GRKERNSEC_LINK y
7764 +define_bool CONFIG_GRKERNSEC_FIFO y
7765 +define_bool CONFIG_GRKERNSEC_RANDPID y
7766 +define_bool CONFIG_GRKERNSEC_EXECVE y
7767 +define_bool CONFIG_GRKERNSEC_DMESG y
7768 +define_bool CONFIG_GRKERNSEC_RANDID y
7769 +define_bool CONFIG_GRKERNSEC_RANDNET y
7770 +define_bool CONFIG_GRKERNSEC_RANDISN y
7771 +define_bool CONFIG_GRKERNSEC_RANDSRC y
7772 +define_bool CONFIG_GRKERNSEC_RANDRPC y
7773 +define_bool CONFIG_GRKERNSEC_FORKFAIL y
7774 +define_bool CONFIG_GRKERNSEC_TIME y
7775 +define_bool CONFIG_GRKERNSEC_SIGNAL y
7776 +define_bool CONFIG_GRKERNSEC_CHROOT y
7777 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7778 +define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7779 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7780 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7781 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7782 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7783 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7784 +define_bool CONFIG_GRKERNSEC_PROC y
7785 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7786 +define_int  CONFIG_GRKERNSEC_PROC_GID 10
7787 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7788 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7789 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7790 +define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7791 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7792 +fi
7793 +if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then
7794 +define_int CONFIG_GRKERNSEC_FLOODTIME 10
7795 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7796 +define_bool CONFIG_GRKERNSEC_LINK y
7797 +define_bool CONFIG_GRKERNSEC_FIFO y
7798 +define_bool CONFIG_GRKERNSEC_RANDPID y
7799 +define_bool CONFIG_GRKERNSEC_EXECVE y
7800 +define_bool CONFIG_GRKERNSEC_DMESG y
7801 +define_bool CONFIG_GRKERNSEC_RANDID y
7802 +define_bool CONFIG_GRKERNSEC_RANDSRC y
7803 +define_bool CONFIG_GRKERNSEC_RANDRPC y
7804 +define_bool CONFIG_GRKERNSEC_FORKFAIL y
7805 +define_bool CONFIG_GRKERNSEC_TIME y
7806 +define_bool CONFIG_GRKERNSEC_SIGNAL y
7807 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT y
7808 +define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7809 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7810 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR y
7811 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7812 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7813 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7814 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7815 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS y
7816 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7817 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK y
7818 +define_bool CONFIG_GRKERNSEC_PROC y
7819 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7820 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y
7821 +define_bool CONFIG_GRKERNSEC_HIDESYM y
7822 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7823 +define_int  CONFIG_GRKERNSEC_PROC_GID 10
7824 +define_bool CONFIG_GRKERNSEC_KMEM y
7825 +define_bool CONFIG_GRKERNSEC_RESLOG y
7826 +define_bool CONFIG_GRKERNSEC_RANDNET y
7827 +define_bool CONFIG_GRKERNSEC_RANDISN y
7828 +
7829 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7830 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7831 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7832 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7833 +
7834 +define_bool CONFIG_GRKERNSEC_PROC_ADD y
7835 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD y
7836 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE y
7837 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7838 +define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7839 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7840 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC y
7841 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7842 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7843 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT y
7844 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7845 +if [ "$CONFIG_X86" = "y" ]; then
7846 +define_bool CONFIG_GRKERNSEC_IO n
7847 +if [ "$CONFIG_MODULES" = "n" ]; then
7848 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC y
7849 +fi
7850 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK y
7851 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC y
7852 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC y
7853 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7854 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7855 +fi
7856 +if [ "$CONFIG_PARISC" = "y" ]; then
7857 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP y
7858 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT y
7859 +fi
7860 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT y
7861 +fi
7862 +if [ "$CONFIG_GRKERNSEC_CUSTOM" = "y" ]; then
7863 +mainmenu_option next_comment
7864 +comment 'Address Space Protection'
7865 +bool 'Enforce non-executable pages' CONFIG_GRKERNSEC_PAX_NOEXEC
7866 +if [ "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7867 +  bool 'Paging based non-executable pages' CONFIG_GRKERNSEC_PAX_PAGEEXEC
7868 +  if [ "$CONFIG_X86" = "y" ]; then
7869 +    bool 'Segmentation based non-executable pages' CONFIG_GRKERNSEC_PAX_SEGMEXEC
7870 +  fi
7871 +  if [ "$CONFIG_X86" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7872 +    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7873 +      bool '   Emulate trampolines' CONFIG_GRKERNSEC_PAX_EMUTRAMP
7874 +      if [ "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then
7875 +        bool '    Automatically emulate sigreturn trampolines' CONFIG_GRKERNSEC_PAX_EMUSIGRT
7876 +      fi
7877 +    fi
7878 +  fi
7879 +  bool '   Restrict mprotect()' CONFIG_GRKERNSEC_PAX_MPROTECT
7880 +  if [ "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then
7881 +    if [ "$CONFIG_X86" = "y" ]; then
7882 +      bool '    Disallow ELF text relocations (DANGEROUS)' CONFIG_GRKERNSEC_PAX_NOELFRELOCS
7883 +    else
7884 +    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" ]; then
7885 +      bool '    Allow ELF ET_EXEC text relocations' CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
7886 +    fi
7887 +    if [ "$CONFIG_X86" = "y" -a "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" -a "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then
7888 +      bool '    Honor PT_GNU_STACK' CONFIG_GRKERNSEC_PAX_PT_GNU_STACK
7889 +    fi
7890 +    if [ "$CONFIG_X86" = "y" -a "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then
7891 +      bool '    Honor PT_GNU_HEAP' CONFIG_GRKERNSEC_PAX_PT_GNU_HEAP
7892 +    fi
7893 +    if [ "$CONFIG_PPC32" = "y" ]; then
7894 +      define_bool CONFIG_GRKERNSEC_PAX_SYSCALL y
7895 +    fi
7896 +    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7897 +      bool '    Automatically emulate ELF PLT' CONFIG_GRKERNSEC_PAX_EMUPLT
7898 +      if [ "$CONFIG_GRKERNSEC_PAX_EMUPLT" = "y" ]; then
7899 +        if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
7900 +         define_bool CONFIG_GRKERNSEC_PAX_DLRESOLVE y
7901 +        fi
7902 +      fi
7903 +    fi
7904 +    fi
7905 +  fi
7906 +fi
7907 +if [ "$CONFIG_X86" = "y" -a "$CONFIG_MODULES" = "n" ]; then
7908 +  bool 'Enforce non-executable kernel pages' CONFIG_GRKERNSEC_PAX_KERNEXEC
7909 +fi
7910 +bool 'Address Space Layout Randomization' CONFIG_GRKERNSEC_PAX_ASLR
7911 +if [ "$CONFIG_GRKERNSEC_PAX_ASLR" = "y" ]; then
7912 +  if [ "$CONFIG_X86_TSC" = "y" ]; then
7913 +    bool '  Randomize kernel stack base' CONFIG_GRKERNSEC_PAX_RANDKSTACK
7914 +  fi
7915 +  bool '  Randomize user stack base' CONFIG_GRKERNSEC_PAX_RANDUSTACK
7916 +  bool '  Randomize mmap() base' CONFIG_GRKERNSEC_PAX_RANDMMAP
7917 +  if [ "$CONFIG_GRKERNSEC_PAX_RANDMMAP" = "y" -a "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7918 +    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7919 +      bool '  Randomize ET_EXEC base' CONFIG_GRKERNSEC_PAX_RANDEXEC
7920 +    fi
7921 +  fi
7922 +fi
7923 +bool 'Deny writing to /dev/kmem, /dev/mem, and /dev/port' CONFIG_GRKERNSEC_KMEM
7924 +if [ "$CONFIG_X86" = "y" ]; then
7925 +  bool 'Disable privileged I/O' CONFIG_GRKERNSEC_IO
7926 +  if [ "$CONFIG_GRKERNSEC_IO" = "y" ]; then
7927 +    define_bool CONFIG_RTC y
7928 +  fi
7929 +fi
7930 +bool 'Remove addresses from /proc/pid/[maps|stat]' CONFIG_GRKERNSEC_PROC_MEMMAP
7931 +bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM
7932 +endmenu
7933 +mainmenu_option next_comment
7934 +comment 'Role Based Access Control Options'
7935 +bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN
7936 +int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7937 +int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7938 +endmenu
7939 +mainmenu_option next_comment
7940 +comment 'Filesystem Protections'
7941 +bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC
7942 +if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then
7943 + bool '   Restrict to user only' CONFIG_GRKERNSEC_PROC_USER
7944 + if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then
7945 +  bool '   Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP
7946 +  if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7947 +   int  '   GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001
7948 +  fi
7949 + fi
7950 + if [ "$CONFIG_GRKERNSEC_PROC_USER" != "n" -o "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7951 +  bool '   Additional restrictions' CONFIG_GRKERNSEC_PROC_ADD
7952 + fi
7953 +fi
7954 +bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK
7955 +bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO
7956 +bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT
7957 +if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then
7958 +bool '   Deny mounts' CONFIG_GRKERNSEC_CHROOT_MOUNT
7959 +bool '   Deny double-chroots' CONFIG_GRKERNSEC_CHROOT_DOUBLE
7960 +bool '   Deny pivot_root in chroot' CONFIG_GRKERNSEC_CHROOT_PIVOT
7961 +bool '   Enforce chdir("/") on all chroots' CONFIG_GRKERNSEC_CHROOT_CHDIR
7962 +bool '   Deny (f)chmod +s' CONFIG_GRKERNSEC_CHROOT_CHMOD
7963 +bool '   Deny fchdir out of chroot' CONFIG_GRKERNSEC_CHROOT_FCHDIR
7964 +bool '   Deny mknod' CONFIG_GRKERNSEC_CHROOT_MKNOD
7965 +bool '   Deny shmat() out of chroot' CONFIG_GRKERNSEC_CHROOT_SHMAT
7966 +bool '   Deny access to abstract AF_UNIX sockets out of chroot' CONFIG_GRKERNSEC_CHROOT_UNIX
7967 +bool '   Protect outside processes' CONFIG_GRKERNSEC_CHROOT_FINDTASK
7968 +bool '   Restrict priority changes' CONFIG_GRKERNSEC_CHROOT_NICE
7969 +bool '   Deny sysctl writes in chroot' CONFIG_GRKERNSEC_CHROOT_SYSCTL
7970 +bool '   Capability restrictions within chroot' CONFIG_GRKERNSEC_CHROOT_CAPS
7971 +fi
7972 +endmenu
7973 +mainmenu_option next_comment
7974 +comment 'Kernel Auditing'
7975 +bool 'Single group for auditing' CONFIG_GRKERNSEC_AUDIT_GROUP
7976 +if [ "$CONFIG_GRKERNSEC_AUDIT_GROUP" != "n" ]; then
7977 +int  '   GID for auditing' CONFIG_GRKERNSEC_AUDIT_GID 1007
7978 +fi
7979 +bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG
7980 +bool 'Resource logging' CONFIG_GRKERNSEC_RESLOG
7981 +bool 'Log execs within chroot' CONFIG_GRKERNSEC_CHROOT_EXECLOG
7982 +bool 'Chdir logging' CONFIG_GRKERNSEC_AUDIT_CHDIR
7983 +bool '(Un)Mount logging' CONFIG_GRKERNSEC_AUDIT_MOUNT
7984 +bool 'IPC logging' CONFIG_GRKERNSEC_AUDIT_IPC
7985 +bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL
7986 +bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL
7987 +bool 'Time change logging' CONFIG_GRKERNSEC_TIME
7988 +bool '/proc/<pid>/ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR
7989 +endmenu
7990 +mainmenu_option next_comment
7991 +comment 'Executable Protections'
7992 +bool 'Enforce RLIMIT_NPROC on execs' CONFIG_GRKERNSEC_EXECVE
7993 +bool 'Dmesg(8) restriction' CONFIG_GRKERNSEC_DMESG
7994 +bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID
7995 +bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE
7996 +if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then
7997 +bool '   Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
7998 +int  '   GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
7999 +fi
8000 +endmenu
8001 +mainmenu_option next_comment
8002 +comment 'Network Protections'
8003 +bool 'Larger entropy pools' CONFIG_GRKERNSEC_RANDNET
8004 +bool 'Truly random TCP ISN selection' CONFIG_GRKERNSEC_RANDISN
8005 +bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID
8006 +bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC
8007 +bool 'Randomized RPC XIDs' CONFIG_GRKERNSEC_RANDRPC
8008 +bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET
8009 +if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then
8010 +bool '  Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL
8011 +if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then
8012 +int  '   GID to deny all sockets for:' CONFIG_GRKERNSEC_SOCKET_ALL_GID 1004
8013 +fi
8014 +bool '  Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT
8015 +if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then
8016 +int  '   GID to deny client sockets for:' CONFIG_GRKERNSEC_SOCKET_CLIENT_GID 1003
8017 +fi
8018 +bool '  Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER
8019 +if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then
8020 +int  '   GID to deny server sockets for:' CONFIG_GRKERNSEC_SOCKET_SERVER_GID 1002
8021 +fi
8022 +fi
8023 +endmenu
8024 +if [ "$CONFIG_SYSCTL" != "n" ]; then
8025 +mainmenu_option next_comment
8026 +comment 'Sysctl support'
8027 +bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL
8028 +endmenu
8029 +fi
8030 +mainmenu_option next_comment
8031 +comment 'Logging options'
8032 +int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10
8033 +int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4
8034 +endmenu
8035 +fi
8036 diff -urN linux-2.4.24.org/grsecurity/gracl_alloc.c linux-2.4.24/grsecurity/gracl_alloc.c
8037 --- linux-2.4.24.org/grsecurity/gracl_alloc.c   1970-01-01 01:00:00.000000000 +0100
8038 +++ linux-2.4.24/grsecurity/gracl_alloc.c       2004-02-04 23:11:33.381805124 +0100
8039 @@ -0,0 +1,93 @@
8040 +/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
8041 +
8042 +#include <linux/kernel.h>
8043 +#include <linux/mm.h>
8044 +#include <linux/slab.h>
8045 +#include <linux/vmalloc.h>
8046 +#include <linux/gracl.h>
8047 +#include <linux/grsecurity.h>
8048 +
8049 +static unsigned long alloc_stack_next = 1;
8050 +static unsigned long alloc_stack_size = 1;
8051 +static void **alloc_stack;
8052 +
8053 +static __inline__ int
8054 +alloc_pop(void)
8055 +{
8056 +       if (alloc_stack_next == 1)
8057 +               return 0;
8058 +
8059 +       kfree(alloc_stack[alloc_stack_next - 2]);
8060 +
8061 +       alloc_stack_next--;
8062 +
8063 +       return 1;
8064 +}
8065 +
8066 +static __inline__ void
8067 +alloc_push(void *buf)
8068 +{
8069 +       if (alloc_stack_next >= alloc_stack_size)
8070 +               BUG();
8071 +
8072 +       alloc_stack[alloc_stack_next - 1] = buf;
8073 +
8074 +       alloc_stack_next++;
8075 +
8076 +       return;
8077 +}
8078 +
8079 +void *
8080 +acl_alloc(unsigned long len)
8081 +{
8082 +       void *ret;
8083 +
8084 +       if (len > PAGE_SIZE)
8085 +               BUG();
8086 +
8087 +       ret = kmalloc(len, GFP_KERNEL);
8088 +
8089 +       if (ret)
8090 +               alloc_push(ret);
8091 +
8092 +       return ret;
8093 +}
8094 +
8095 +void
8096 +acl_free_all(void)
8097 +{
8098 +       if (gr_acl_is_enabled() || !alloc_stack)
8099 +               return;
8100 +
8101 +       while (alloc_pop()) ;
8102 +
8103 +       if (alloc_stack) {
8104 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
8105 +                       kfree(alloc_stack);
8106 +               else
8107 +                       vfree(alloc_stack);
8108 +       }
8109 +
8110 +       alloc_stack = NULL;
8111 +       alloc_stack_size = 1;
8112 +       alloc_stack_next = 1;
8113 +
8114 +       return;
8115 +}
8116 +
8117 +int
8118 +acl_alloc_stack_init(unsigned long size)
8119 +{
8120 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
8121 +               alloc_stack =
8122 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
8123 +       else
8124 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
8125 +
8126 +       alloc_stack_size = size;
8127 +
8128 +       if (!alloc_stack)
8129 +               return 0;
8130 +       else
8131 +               return 1;
8132 +}
8133 diff -urN linux-2.4.24.org/grsecurity/gracl.c linux-2.4.24/grsecurity/gracl.c
8134 --- linux-2.4.24.org/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100
8135 +++ linux-2.4.24/grsecurity/gracl.c     2004-02-04 23:11:33.390803253 +0100
8136 @@ -0,0 +1,2766 @@
8137 +/* 
8138 + * grsecurity/gracl.c
8139 + * Copyright Brad Spengler 2001, 2002, 2003
8140 + *
8141 + */
8142 +
8143 +#include <linux/kernel.h>
8144 +#include <linux/sched.h>
8145 +#include <linux/mm.h>
8146 +#include <linux/file.h>
8147 +#include <linux/fs.h>
8148 +#include <linux/proc_fs.h>
8149 +#include <linux/smp_lock.h>
8150 +#include <linux/slab.h>
8151 +#include <linux/vmalloc.h>
8152 +#include <linux/types.h>
8153 +#include <linux/capability.h>
8154 +#include <linux/sysctl.h>
8155 +#include <linux/gracl.h>
8156 +#include <linux/gralloc.h>
8157 +#include <linux/grsecurity.h>
8158 +#include <linux/grinternal.h>
8159 +
8160 +#include <asm/uaccess.h>
8161 +#include <asm/errno.h>
8162 +#include <asm/mman.h>
8163 +
8164 +static struct acl_role_db acl_role_set;
8165 +static struct acl_role_label *role_list_head;
8166 +static struct name_db name_set;
8167 +static struct name_db inodev_set;
8168 +
8169 +static struct acl_role_label *default_role;
8170 +
8171 +static u16 acl_sp_role_value;
8172 +
8173 +static DECLARE_MUTEX(gr_dev_sem);
8174 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
8175 +
8176 +extern char *gr_shared_page[4][NR_CPUS];
8177 +struct gr_arg *gr_usermode;
8178 +
8179 +static unsigned long gr_status = GR_STATUS_INIT;
8180 +
8181 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
8182 +extern void gr_clear_learn_entries(void);
8183 +
8184 +#ifdef CONFIG_GRKERNSEC_RESLOG
8185 +extern __inline__ void gr_log_resource(const struct task_struct *task,
8186 +                                      const int res,
8187 +                                      const unsigned long wanted, const int gt);
8188 +#endif
8189 +
8190 +unsigned char *gr_system_salt;
8191 +unsigned char *gr_system_sum;
8192 +
8193 +static struct sprole_pw **acl_special_roles = NULL;
8194 +static __u16 num_sprole_pws = 0;
8195 +
8196 +static struct acl_role_label *kernel_role = NULL;
8197 +
8198 +/* The following are used to keep a place held in the hash table when we move
8199 +   entries around.  They can be replaced during insert. */
8200 +
8201 +static struct acl_subject_label *deleted_subject;
8202 +static struct acl_object_label *deleted_object;
8203 +static struct name_entry *deleted_inodev;
8204 +
8205 +/* for keeping track of the last and final allocated subjects, since
8206 +   nested subject parsing is tricky
8207 +*/
8208 +static struct acl_subject_label *s_last = NULL;
8209 +static struct acl_subject_label *s_final = NULL;
8210 +
8211 +static unsigned int gr_auth_attempts = 0;
8212 +static unsigned long gr_auth_expires = 0UL;
8213 +
8214 +extern int gr_init_uidset(void);
8215 +extern void gr_free_uidset(void);
8216 +extern void gr_remove_uid(uid_t uid);
8217 +extern int gr_find_uid(uid_t uid);
8218 +
8219 +__inline__ int
8220 +gr_acl_is_enabled(void)
8221 +{
8222 +       return (gr_status & GR_READY);
8223 +}
8224 +
8225 +__inline__ int
8226 +gr_acl_tpe_check(void)
8227 +{
8228 +       if (unlikely(!(gr_status & GR_READY)))
8229 +               return 0;
8230 +       if (current->role->roletype & GR_ROLE_TPE)
8231 +               return 1;
8232 +       else
8233 +               return 0;
8234 +}
8235 +
8236 +int
8237 +gr_handle_rawio(const struct inode *inode)
8238 +{
8239 +       if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
8240 +           ((gr_status & GR_READY)
8241 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
8242 +            || (grsec_enable_chroot_caps && proc_is_chrooted(current))
8243 +#endif
8244 +           ))
8245 +               return 1;
8246 +       return 0;
8247 +}
8248 +
8249 +
8250 +static __inline__ int
8251 +gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
8252 +{
8253 +       int i;
8254 +       unsigned long *l1;
8255 +       unsigned long *l2;
8256 +       unsigned char *c1;
8257 +       unsigned char *c2;
8258 +       int num_longs;
8259 +
8260 +       if (likely(lena != lenb))
8261 +               return 0;
8262 +
8263 +       l1 = (unsigned long *)a;
8264 +       l2 = (unsigned long *)b;
8265 +
8266 +       num_longs = lena / sizeof(unsigned long);
8267 +
8268 +       for (i = num_longs; i--; l1++, l2++) {
8269 +               if (unlikely(*l1 != *l2))
8270 +                       return 0;
8271 +       }
8272 +
8273 +       c1 = (unsigned char *) l1;
8274 +       c2 = (unsigned char *) l2;
8275 +
8276 +       i = lena - (num_longs * sizeof(unsigned long)); 
8277 +
8278 +       for (; i--; c1++, c2++) {
8279 +               if (unlikely(*c1 != *c2))
8280 +                       return 0;
8281 +       }
8282 +
8283 +       return 1;
8284 +}
8285 +               
8286 +static __inline__ char *
8287 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
8288 +           char *buf, int buflen)
8289 +{
8290 +       char *res;
8291 +       struct dentry *our_dentry;
8292 +       struct vfsmount *our_mount;
8293 +       struct vfsmount *rootmnt;
8294 +       struct dentry *root;
8295 +
8296 +       our_dentry = (struct dentry *) dentry;
8297 +       our_mount = (struct vfsmount *) vfsmnt;
8298 +
8299 +       read_lock(&child_reaper->fs->lock);
8300 +       rootmnt = mntget(child_reaper->fs->rootmnt);
8301 +       root = dget(child_reaper->fs->root);
8302 +       read_unlock(&child_reaper->fs->lock);
8303 +
8304 +       spin_lock(&dcache_lock);
8305 +       res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
8306 +       spin_unlock(&dcache_lock);
8307 +       if (unlikely(IS_ERR(res)))
8308 +               res = strcpy(buf, "<path too long>");
8309 +       dput(root);
8310 +       mntput(rootmnt);
8311 +       return res;
8312 +}
8313 +
8314 +char *
8315 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
8316 +{
8317 +       return d_real_path(dentry, mnt, gr_shared_page[0][smp_processor_id()],
8318 +                          PAGE_SIZE);
8319 +}
8320 +
8321 +char *
8322 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
8323 +{
8324 +       return d_real_path(dentry, mnt, gr_shared_page[1][smp_processor_id()],
8325 +                          PAGE_SIZE);
8326 +}
8327 +
8328 +char *
8329 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
8330 +{
8331 +       return d_real_path(dentry, mnt, gr_shared_page[2][smp_processor_id()],
8332 +                          PAGE_SIZE);
8333 +}
8334 +
8335 +char *
8336 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
8337 +{
8338 +       return d_real_path(dentry, mnt, gr_shared_page[3][smp_processor_id()],
8339 +                          PAGE_SIZE);
8340 +}
8341 +
8342 +__inline__ __u32
8343 +to_gr_audit(const __u32 reqmode)
8344 +{
8345 +       __u32 retmode = 0;
8346 +
8347 +       retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
8348 +       retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
8349 +       retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
8350 +       retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
8351 +       retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
8352 +       retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
8353 +       retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
8354 +       retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
8355 +       retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
8356 +
8357 +       return retmode;
8358 +}
8359 +
8360 +__inline__ struct acl_role_label *
8361 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
8362 +                     const gid_t gid)
8363 +{
8364 +       unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
8365 +       struct acl_role_label *match;
8366 +       struct role_allowed_ip *ipp;
8367 +       __u8 i = 0;
8368 +
8369 +       match = acl_role_set.r_hash[index];
8370 +
8371 +       while (match
8372 +              && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
8373 +               index = (index + (1 << i)) % acl_role_set.r_size;
8374 +               match = acl_role_set.r_hash[index];
8375 +               i = (i + 1) % 32;
8376 +       }
8377 +
8378 +       if (!match || match->uidgid != uid || !(match->roletype & GR_ROLE_USER)) {
8379 +             try_group:
8380 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
8381 +               match = acl_role_set.r_hash[index];
8382 +               i = 0;
8383 +
8384 +               while (match
8385 +                      && (match->uidgid != gid
8386 +                          || !(match->roletype & GR_ROLE_GROUP))) {
8387 +                       index = (index + (1 << i)) % acl_role_set.r_size;
8388 +                       match = acl_role_set.r_hash[index];
8389 +                       i = (i + 1) % 32;
8390 +               }
8391 +
8392 +               if (!match || match->uidgid != gid
8393 +                   || !(match->roletype & GR_ROLE_GROUP))
8394 +                       match = default_role;
8395 +               else if (likely(!match->allowed_ips)) {
8396 +                       return match;
8397 +               } else {
8398 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
8399 +                               if (likely
8400 +                                   ((task->curr_ip & ipp->netmask) ==
8401 +                                    (ipp->addr & ipp->netmask)))
8402 +                                       return match;
8403 +                       }
8404 +                       match = default_role;
8405 +               }
8406 +       } else if (likely(!match->allowed_ips)) {
8407 +               return match;
8408 +       } else {
8409 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
8410 +                       if (likely
8411 +                           ((task->curr_ip & ipp->netmask) ==
8412 +                            (ipp->addr & ipp->netmask)))
8413 +                               return match;
8414 +               }
8415 +               goto try_group;
8416 +       }
8417 +
8418 +       return match;
8419 +}
8420 +
8421 +__inline__ struct acl_subject_label *
8422 +lookup_acl_subj_label(const ino_t ino, const kdev_t dev,
8423 +                     const struct acl_role_label *role)
8424 +{
8425 +       unsigned long subj_size = role->subj_hash_size;
8426 +       struct acl_subject_label **s_hash = role->subj_hash;
8427 +       unsigned long index = fhash(ino, dev, subj_size);
8428 +       struct acl_subject_label *match;
8429 +       __u8 i = 0;
8430 +
8431 +       match = s_hash[index];
8432 +
8433 +       while (match && (match->inode != ino || match->device != dev ||
8434 +              (match->mode & GR_DELETED))) {
8435 +               index = (index + (1 << i)) % subj_size;
8436 +               match = s_hash[index];
8437 +               i = (i + 1) % 32;
8438 +       }
8439 +
8440 +       if (unlikely(match && (match != deleted_subject) &&
8441 +                    (match->inode == ino) && (match->device == dev) &&
8442 +                    !(match->mode & GR_DELETED)))
8443 +               return match;
8444 +       else
8445 +               return NULL;
8446 +}
8447 +
8448 +static __inline__ struct acl_object_label *
8449 +lookup_acl_obj_label(const ino_t ino, const kdev_t dev,
8450 +                    const struct acl_subject_label *subj)
8451 +{
8452 +       unsigned long obj_size = subj->obj_hash_size;
8453 +       struct acl_object_label **o_hash = subj->obj_hash;
8454 +       unsigned long index = fhash(ino, dev, obj_size);
8455 +       struct acl_object_label *match;
8456 +       __u8 i = 0;
8457 +
8458 +       match = o_hash[index];
8459 +
8460 +       while (match && (match->inode != ino || match->device != dev ||
8461 +              (match->mode & GR_DELETED))) {
8462 +               index = (index + (1 << i)) % obj_size;
8463 +               match = o_hash[index];
8464 +               i = (i + 1) % 32;
8465 +       }
8466 +
8467 +       if (unlikely(match && (match != deleted_object) &&
8468 +                    (match->inode == ino) && (match->device == dev) &&
8469 +                    !(match->mode & GR_DELETED)))
8470 +               return match;
8471 +       else
8472 +               return NULL;
8473 +}
8474 +
8475 +static __inline__ struct acl_object_label *
8476 +lookup_acl_obj_label_create(const ino_t ino, const kdev_t dev,
8477 +                    const struct acl_subject_label *subj)
8478 +{
8479 +       unsigned long obj_size = subj->obj_hash_size;
8480 +       struct acl_object_label **o_hash = subj->obj_hash;
8481 +       unsigned long index = fhash(ino, dev, obj_size);
8482 +       struct acl_object_label *match;
8483 +       __u8 i = 0;
8484 +
8485 +       match = o_hash[index];
8486 +
8487 +       while (match && (match->inode != ino || match->device != dev ||
8488 +              !(match->mode & GR_DELETED))) {
8489 +               index = (index + (1 << i)) % obj_size;
8490 +               match = o_hash[index];
8491 +               i = (i + 1) % 32;
8492 +       }
8493 +
8494 +       if (unlikely(match && (match != deleted_object) &&
8495 +                    (match->inode == ino) && (match->device == dev) &&
8496 +                    (match->mode & GR_DELETED)))
8497 +               return match;
8498 +
8499 +       i = 0;
8500 +       index = fhash(ino, dev, obj_size);
8501 +       match = o_hash[index];
8502 +
8503 +       while (match && (match->inode != ino || match->device != dev ||
8504 +              (match->mode & GR_DELETED))) {
8505 +               index = (index + (1 << i)) % obj_size;
8506 +               match = o_hash[index];
8507 +               i = (i + 1) % 32;
8508 +       }
8509 +
8510 +       if (unlikely(match && (match != deleted_object) &&
8511 +                    (match->inode == ino) && (match->device == dev) &&
8512 +                    !(match->mode & GR_DELETED)))
8513 +               return match;
8514 +       else
8515 +               return NULL;
8516 +}
8517 +
8518 +static __inline__ struct name_entry *
8519 +lookup_name_entry(const char *name)
8520 +{
8521 +       __u16 len = strlen(name);
8522 +       unsigned long index = nhash(name, len, name_set.n_size);
8523 +       struct name_entry *match;
8524 +       __u8 i = 0;
8525 +
8526 +       match = name_set.n_hash[index];
8527 +
8528 +       while (match && !gr_streq(match->name, name, match->len, len)) {
8529 +               index = (index + (1 << i)) % name_set.n_size;
8530 +               match = name_set.n_hash[index];
8531 +               i = (i + 1) % 32;
8532 +       }
8533 +
8534 +       if (unlikely(!match || !gr_streq(match->name, name, match->len, len)))
8535 +               return NULL;
8536 +       else
8537 +               return match;
8538 +}
8539 +
8540 +static __inline__ struct name_entry *
8541 +lookup_inodev_entry(const ino_t ino, const kdev_t dev)
8542 +{
8543 +       unsigned long index = fhash(ino, dev, inodev_set.n_size);
8544 +       struct name_entry *match;
8545 +       __u8 i = 0;
8546 +
8547 +       match = inodev_set.n_hash[index];
8548 +
8549 +       while (match && (match->inode != ino || match->device != dev)) {
8550 +               index = (index + (1 << i)) % inodev_set.n_size;
8551 +               match = inodev_set.n_hash[index];
8552 +               i = (i + 1) % 32;
8553 +       }
8554 +
8555 +       if (unlikely(match && (match != deleted_inodev) &&
8556 +                    (match->inode == ino) && (match->device == dev)))
8557 +               return match;
8558 +       else
8559 +               return NULL;
8560 +}
8561 +
8562 +static void
8563 +insert_inodev_entry(struct name_entry *nentry)
8564 +{
8565 +       unsigned long index = fhash(nentry->inode, nentry->device,
8566 +                                   inodev_set.n_size);
8567 +       struct name_entry **curr;
8568 +       __u8 i = 0;
8569 +
8570 +       curr = &inodev_set.n_hash[index];
8571 +
8572 +       while (*curr && *curr != deleted_inodev) {
8573 +               index = (index + (1 << i)) % inodev_set.n_size;
8574 +               curr = &inodev_set.n_hash[index];
8575 +               i = (i + 1) % 32;
8576 +       }
8577 +
8578 +       *curr = nentry;
8579 +
8580 +       return;
8581 +}
8582 +
8583 +static void
8584 +insert_acl_role_label(struct acl_role_label *role)
8585 +{
8586 +       unsigned long index =
8587 +           rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
8588 +       struct acl_role_label **curr;
8589 +       __u8 i = 0;
8590 +
8591 +       curr = &acl_role_set.r_hash[index];
8592 +
8593 +       while (*curr) {
8594 +               index = (index + (1 << i)) % acl_role_set.r_size;
8595 +               curr = &acl_role_set.r_hash[index];
8596 +               i = (i + 1) % 32;
8597 +       }
8598 +
8599 +       *curr = role;
8600 +
8601 +       return;
8602 +}
8603 +
8604 +static int
8605 +insert_name_entry(char *name, const ino_t inode, const kdev_t device)
8606 +{
8607 +       struct name_entry **curr;
8608 +       __u8 i = 0;
8609 +       __u16 len = strlen(name);
8610 +       unsigned long index = nhash(name, len, name_set.n_size);
8611 +
8612 +       curr = &name_set.n_hash[index];
8613 +
8614 +       while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
8615 +               index = (index + (1 << i)) % name_set.n_size;
8616 +               curr = &name_set.n_hash[index];
8617 +               i = (i + 1) % 32;
8618 +       }
8619 +
8620 +       if (!(*curr)) {
8621 +               struct name_entry *nentry =
8622 +                   acl_alloc(sizeof (struct name_entry));
8623 +               if (!nentry)
8624 +                       return 0;
8625 +               nentry->name = name;
8626 +               nentry->inode = inode;
8627 +               nentry->device = device;
8628 +               nentry->len = len;
8629 +               *curr = nentry;
8630 +               /* insert us into the table searchable by inode/dev */
8631 +               insert_inodev_entry(nentry);
8632 +       }
8633 +
8634 +       return 1;
8635 +}
8636 +
8637 +static void
8638 +insert_acl_obj_label(struct acl_object_label *obj,
8639 +                    struct acl_subject_label *subj)
8640 +{
8641 +       unsigned long index =
8642 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
8643 +       struct acl_object_label **curr;
8644 +       __u8 i = 0;
8645 +
8646 +       curr = &subj->obj_hash[index];
8647 +
8648 +       while (*curr && *curr != deleted_object) {
8649 +               index = (index + (1 << i)) % subj->obj_hash_size;
8650 +               curr = &subj->obj_hash[index];
8651 +               i = (i + 1) % 32;
8652 +       }
8653 +
8654 +       *curr = obj;
8655 +
8656 +       return;
8657 +}
8658 +
8659 +static void
8660 +insert_acl_subj_label(struct acl_subject_label *obj,
8661 +                     struct acl_role_label *role)
8662 +{
8663 +       unsigned long subj_size = role->subj_hash_size;
8664 +       struct acl_subject_label **s_hash = role->subj_hash;
8665 +       unsigned long index = fhash(obj->inode, obj->device, subj_size);
8666 +       struct acl_subject_label **curr;
8667 +       __u8 i = 0;
8668 +
8669 +       curr = &s_hash[index];
8670 +
8671 +       while (*curr && *curr != deleted_subject) {
8672 +               index = (index + (1 << i)) % subj_size;
8673 +               curr = &s_hash[index];
8674 +               i = (i + 1) % 32;
8675 +       }
8676 +
8677 +       *curr = obj;
8678 +
8679 +       return;
8680 +}
8681 +
8682 +static void **
8683 +create_table(__u32 * len)
8684 +{
8685 +       unsigned long table_sizes[] = {
8686 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
8687 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
8688 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
8689 +               268435399, 536870909, 1073741789, 2147483647
8690 +       };
8691 +       void *newtable = NULL;
8692 +       unsigned int pwr = 0;
8693 +
8694 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
8695 +              table_sizes[pwr] <= (2 * (*len)))
8696 +               pwr++;
8697 +
8698 +       if (table_sizes[pwr] <= (2 * (*len)))
8699 +               return newtable;
8700 +
8701 +       if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
8702 +               newtable =
8703 +                   kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
8704 +       else
8705 +               newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
8706 +
8707 +       *len = table_sizes[pwr];
8708 +
8709 +       return newtable;
8710 +}
8711 +
8712 +static int
8713 +init_variables(const unsigned long acl_obj_size,
8714 +              const unsigned long acl_subj_size,
8715 +              const unsigned long acl_ip_size,
8716 +              const unsigned long acl_role_size,
8717 +              const unsigned long allowed_ip_size,
8718 +              const unsigned long acl_trans_size,
8719 +              const __u16 num_sprole_pws)
8720 +{
8721 +       unsigned long stacksize;
8722 +
8723 +       acl_role_set.r_size = acl_role_size;
8724 +       name_set.n_size = (acl_obj_size + acl_subj_size);
8725 +       inodev_set.n_size = (acl_obj_size + acl_subj_size);
8726 +
8727 +       if (!gr_init_uidset())
8728 +               return 1;
8729 +
8730 +       /* set up the stack that holds allocation info */
8731 +
8732 +       stacksize = (3 * acl_obj_size) + (2 * acl_role_size) +
8733 +           (4 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
8734 +           allowed_ip_size + (2 * num_sprole_pws) + 5;
8735 +
8736 +       if (!acl_alloc_stack_init(stacksize))
8737 +               return 1;
8738 +
8739 +       /* create our empty, fake deleted acls */
8740 +       deleted_subject =
8741 +           (struct acl_subject_label *)
8742 +           acl_alloc(sizeof (struct acl_subject_label));
8743 +       deleted_object =
8744 +           (struct acl_object_label *)
8745 +           acl_alloc(sizeof (struct acl_object_label));
8746 +       deleted_inodev =
8747 +           (struct name_entry *) acl_alloc(sizeof (struct name_entry));
8748 +
8749 +       if (!deleted_subject || !deleted_object || !deleted_inodev)
8750 +               return 1;
8751 +
8752 +       memset(deleted_subject, 0, sizeof (struct acl_subject_label));
8753 +       memset(deleted_object, 0, sizeof (struct acl_object_label));
8754 +       memset(deleted_inodev, 0, sizeof (struct name_entry));
8755 +
8756 +       /* We only want 50% full tables for now */
8757 +
8758 +       acl_role_set.r_hash =
8759 +           (struct acl_role_label **) create_table(&acl_role_set.r_size);
8760 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
8761 +       inodev_set.n_hash =
8762 +           (struct name_entry **) create_table(&inodev_set.n_size);
8763 +
8764 +       if (!acl_role_set.r_hash || !name_set.n_hash || !inodev_set.n_hash)
8765 +               return 1;
8766 +       memset(acl_role_set.r_hash, 0,
8767 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
8768 +       memset(name_set.n_hash, 0,
8769 +              sizeof (struct name_entry *) * name_set.n_size);
8770 +       memset(inodev_set.n_hash, 0,
8771 +              sizeof (struct name_entry *) * inodev_set.n_size);
8772 +
8773 +       return 0;
8774 +}
8775 +
8776 +static void
8777 +free_variables(void)
8778 +{
8779 +       struct acl_subject_label *s;
8780 +       struct acl_role_label *r;
8781 +       struct task_struct *task;
8782 +
8783 +       gr_clear_learn_entries();
8784 +
8785 +       read_lock(&tasklist_lock);
8786 +       for_each_task(task) {
8787 +               task->acl_sp_role = 0;
8788 +               task->acl_role_id = 0;
8789 +               task->acl = NULL;
8790 +               task->role = NULL;
8791 +       }
8792 +       read_unlock(&tasklist_lock);
8793 +
8794 +       /* free all object hash tables */
8795 +
8796 +       if (role_list_head) {
8797 +               for (r = role_list_head; r; r = r->next) {
8798 +                       if (!r->subj_hash)
8799 +                               break;
8800 +                       for (s = r->proc_subject; s; s = s->next) {
8801 +                               if (!s->obj_hash)
8802 +                                       break;
8803 +                               if ((s->obj_hash_size *
8804 +                                    sizeof (struct acl_object_label *)) <=
8805 +                                   PAGE_SIZE)
8806 +                                       kfree(s->obj_hash);
8807 +                               else
8808 +                                       vfree(s->obj_hash);
8809 +                       }
8810 +                       if ((r->subj_hash_size *
8811 +                            sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
8812 +                               kfree(r->subj_hash);
8813 +                       else
8814 +                               vfree(r->subj_hash);
8815 +               }
8816 +       }
8817 +
8818 +       acl_free_all();
8819 +
8820 +       if (acl_role_set.r_hash) {
8821 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
8822 +                   PAGE_SIZE)
8823 +                       kfree(acl_role_set.r_hash);
8824 +               else
8825 +                       vfree(acl_role_set.r_hash);
8826 +       }
8827 +       if (name_set.n_hash) {
8828 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
8829 +                   PAGE_SIZE)
8830 +                       kfree(name_set.n_hash);
8831 +               else
8832 +                       vfree(name_set.n_hash);
8833 +       }
8834 +
8835 +       if (inodev_set.n_hash) {
8836 +               if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
8837 +                   PAGE_SIZE)
8838 +                       kfree(inodev_set.n_hash);
8839 +               else
8840 +                       vfree(inodev_set.n_hash);
8841 +       }
8842 +
8843 +       gr_free_uidset();
8844 +
8845 +       memset(&name_set, 0, sizeof (struct name_db));
8846 +       memset(&inodev_set, 0, sizeof (struct name_db));
8847 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
8848 +
8849 +       role_list_head = NULL;
8850 +       default_role = NULL;
8851 +
8852 +       return;
8853 +}
8854 +
8855 +static __u32
8856 +count_user_objs(struct acl_object_label *userp)
8857 +{
8858 +       struct acl_object_label o_tmp;
8859 +       __u32 num = 0;
8860 +
8861 +       while (userp) {
8862 +               if (copy_from_user(&o_tmp, userp,
8863 +                                  sizeof (struct acl_object_label)))
8864 +                       break;
8865 +
8866 +               userp = o_tmp.prev;
8867 +               num++;
8868 +       }
8869 +
8870 +       return num;
8871 +}
8872 +
8873 +static struct acl_subject_label *
8874 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
8875 +
8876 +static int
8877 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
8878 +              struct acl_role_label *role)
8879 +{
8880 +       struct acl_object_label *o_tmp;
8881 +       unsigned int len;
8882 +       char *tmp;
8883 +
8884 +       while (userp) {
8885 +               if ((o_tmp = (struct acl_object_label *)
8886 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
8887 +                       return -ENOMEM;
8888 +
8889 +               if (copy_from_user(o_tmp, userp,
8890 +                                  sizeof (struct acl_object_label)))
8891 +                       return -EFAULT;
8892 +
8893 +               userp = o_tmp->prev;
8894 +
8895 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
8896 +
8897 +               if (!len || len >= PATH_MAX)
8898 +                       return -EINVAL;
8899 +
8900 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
8901 +                       return -ENOMEM;
8902 +
8903 +               if (copy_from_user(tmp, o_tmp->filename, len))
8904 +                       return -EFAULT;
8905 +
8906 +               o_tmp->filename = tmp;
8907 +
8908 +               insert_acl_obj_label(o_tmp, subj);
8909 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
8910 +                                      o_tmp->device))
8911 +                       return -ENOMEM;
8912 +
8913 +               if (o_tmp->nested) {
8914 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
8915 +                       if (IS_ERR(o_tmp->nested))
8916 +                               return PTR_ERR(o_tmp->nested);
8917 +
8918 +                       s_final = o_tmp->nested;
8919 +               }
8920 +       }
8921 +
8922 +       return 0;
8923 +}
8924 +
8925 +static __u32
8926 +count_user_subjs(struct acl_subject_label *userp)
8927 +{
8928 +       struct acl_subject_label s_tmp;
8929 +       __u32 num = 0;
8930 +
8931 +       while (userp) {
8932 +               if (copy_from_user(&s_tmp, userp,
8933 +                                  sizeof (struct acl_subject_label)))
8934 +                       break;
8935 +
8936 +               userp = s_tmp.prev;
8937 +               /* do not count nested subjects against this count, since
8938 +                  they are not included in the hash table, but are
8939 +                  attached to objects.  We have already counted
8940 +                  the subjects in userspace for the allocation 
8941 +                  stack
8942 +               */
8943 +               if (!s_tmp.parent_subject)
8944 +                       num++;
8945 +       }
8946 +
8947 +       return num;
8948 +}
8949 +
8950 +static int
8951 +copy_user_allowedips(struct acl_role_label *rolep)
8952 +{
8953 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
8954 +
8955 +       ruserip = rolep->allowed_ips;
8956 +
8957 +       while (ruserip) {
8958 +               rlast = rtmp;
8959 +
8960 +               if ((rtmp = (struct role_allowed_ip *)
8961 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
8962 +                       return -ENOMEM;
8963 +
8964 +               if (copy_from_user(rtmp, ruserip,
8965 +                                  sizeof (struct role_allowed_ip)))
8966 +                       return -EFAULT;
8967 +
8968 +               ruserip = rtmp->prev;
8969 +
8970 +               if (!rlast) {
8971 +                       rtmp->prev = NULL;
8972 +                       rolep->allowed_ips = rtmp;
8973 +               } else {
8974 +                       rlast->next = rtmp;
8975 +                       rtmp->prev = rlast;
8976 +               }
8977 +
8978 +               if (!ruserip)
8979 +                       rtmp->next = NULL;
8980 +       }
8981 +
8982 +       return 0;
8983 +}
8984 +
8985 +static int
8986 +copy_user_transitions(struct acl_role_label *rolep)
8987 +{
8988 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
8989 +       unsigned int len;
8990 +       char *tmp;
8991 +
8992 +       rusertp = rolep->transitions;
8993 +
8994 +       while (rusertp) {
8995 +               rlast = rtmp;
8996 +
8997 +               if ((rtmp = (struct role_transition *)
8998 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
8999 +                       return -ENOMEM;
9000 +
9001 +               if (copy_from_user(rtmp, rusertp,
9002 +                                  sizeof (struct role_transition)))
9003 +                       return -EFAULT;
9004 +
9005 +               rusertp = rtmp->prev;
9006 +
9007 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
9008 +
9009 +               if (!len || len >= GR_SPROLE_LEN)
9010 +                       return -EINVAL;
9011 +
9012 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
9013 +                       return -ENOMEM;
9014 +
9015 +               if (copy_from_user(tmp, rtmp->rolename, len))
9016 +                       return -EFAULT;
9017 +
9018 +               rtmp->rolename = tmp;
9019 +
9020 +               if (!rlast) {
9021 +                       rtmp->prev = NULL;
9022 +                       rolep->transitions = rtmp;
9023 +               } else {
9024 +                       rlast->next = rtmp;
9025 +                       rtmp->prev = rlast;
9026 +               }
9027 +
9028 +               if (!rusertp)
9029 +                       rtmp->next = NULL;
9030 +       }
9031 +
9032 +       return 0;
9033 +}
9034 +
9035 +static struct acl_subject_label *
9036 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
9037 +{
9038 +       struct acl_subject_label *s_tmp = NULL;
9039 +       unsigned int len;
9040 +       char *tmp;
9041 +       __u32 num_objs;
9042 +       struct acl_ip_label **i_tmp, *i_utmp2;
9043 +       unsigned long i_num;
9044 +       int err;
9045 +
9046 +
9047 +       if ((s_tmp = (struct acl_subject_label *)
9048 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
9049 +               return ERR_PTR(-ENOMEM);
9050 +
9051 +       if (copy_from_user(s_tmp, userp,
9052 +                          sizeof (struct acl_subject_label)))
9053 +               return ERR_PTR(-EFAULT);
9054 +
9055 +       if (!s_last) {
9056 +               s_tmp->prev = NULL;
9057 +               role->proc_subject = s_tmp;
9058 +       } else {
9059 +               s_last->next = s_tmp;
9060 +               s_tmp->prev = s_last;
9061 +       }
9062 +
9063 +       s_last = s_tmp;
9064 +
9065 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
9066 +
9067 +       if (!len || len >= PATH_MAX)
9068 +               return ERR_PTR(-EINVAL);
9069 +
9070 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
9071 +               return ERR_PTR(-ENOMEM);
9072 +
9073 +       if (copy_from_user(tmp, s_tmp->filename, len))
9074 +               return ERR_PTR(-EFAULT);
9075 +
9076 +       s_tmp->filename = tmp;
9077 +
9078 +       if (!strcmp(s_tmp->filename, "/"))
9079 +               role->root_label = s_tmp;
9080 +
9081 +       /* set up object hash table */
9082 +       num_objs = count_user_objs(s_tmp->proc_object);
9083 +
9084 +       s_tmp->obj_hash_size = num_objs;
9085 +       s_tmp->obj_hash =
9086 +           (struct acl_object_label **)
9087 +           create_table(&(s_tmp->obj_hash_size));
9088 +
9089 +       if (!s_tmp->obj_hash)
9090 +               return ERR_PTR(-ENOMEM);
9091 +
9092 +       memset(s_tmp->obj_hash, 0,
9093 +              s_tmp->obj_hash_size *
9094 +              sizeof (struct acl_object_label *));
9095 +
9096 +       /* copy before adding in objects, since a nested
9097 +          acl could be found and be the final subject
9098 +          copied
9099 +       */
9100 +
9101 +       s_final = s_tmp;
9102 +
9103 +       /* add in objects */
9104 +       err = copy_user_objs(s_tmp->proc_object, s_tmp, role);
9105 +
9106 +       if (err)
9107 +               return ERR_PTR(err);
9108 +
9109 +       /* add in ip acls */
9110 +
9111 +       if (!s_tmp->ip_num) {
9112 +               s_tmp->ips = NULL;
9113 +               goto insert;
9114 +       }
9115 +
9116 +       i_tmp =
9117 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
9118 +                                              sizeof (struct
9119 +                                                      acl_ip_label *));
9120 +
9121 +       if (!i_tmp)
9122 +               return ERR_PTR(-ENOMEM);
9123 +
9124 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
9125 +               *(i_tmp + i_num) =
9126 +                   (struct acl_ip_label *)
9127 +                   acl_alloc(sizeof (struct acl_ip_label));
9128 +               if (!*(i_tmp + i_num))
9129 +                       return ERR_PTR(-ENOMEM);
9130 +
9131 +               if (copy_from_user
9132 +                   (&i_utmp2, s_tmp->ips + i_num,
9133 +                    sizeof (struct acl_ip_label *)))
9134 +                       return ERR_PTR(-EFAULT);
9135 +
9136 +               if (copy_from_user
9137 +                   (*(i_tmp + i_num), i_utmp2,
9138 +                    sizeof (struct acl_ip_label)))
9139 +                       return ERR_PTR(-EFAULT);
9140 +       }
9141 +
9142 +       s_tmp->ips = i_tmp;
9143 +
9144 +insert:
9145 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
9146 +                              s_tmp->device))
9147 +               return ERR_PTR(-ENOMEM);
9148 +
9149 +       return s_tmp;
9150 +}
9151 +
9152 +static int
9153 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
9154 +{
9155 +       struct acl_subject_label s_pre;
9156 +       struct acl_subject_label * ret;
9157 +       int err;
9158 +
9159 +       while (userp) {
9160 +               if (copy_from_user(&s_pre, userp,
9161 +                                  sizeof (struct acl_subject_label)))
9162 +                       return -EFAULT;
9163 +               
9164 +               /* do not add nested subjects here, add
9165 +                  while parsing objects
9166 +               */
9167 +
9168 +               if (s_pre.parent_subject) {
9169 +                       userp = s_pre.prev;
9170 +                       continue;
9171 +               }
9172 +
9173 +               ret = do_copy_user_subj(userp, role);
9174 +
9175 +               err = PTR_ERR(ret);
9176 +               if (IS_ERR(ret))
9177 +                       return err;
9178 +
9179 +               insert_acl_subj_label(ret, role);
9180 +
9181 +               userp = s_pre.prev;
9182 +       }
9183 +
9184 +       s_final->next = NULL;
9185 +
9186 +       return 0;
9187 +}
9188 +
9189 +static int
9190 +copy_user_acl(struct gr_arg *arg)
9191 +{
9192 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
9193 +       struct sprole_pw *sptmp;
9194 +       unsigned long r_num;
9195 +       unsigned int len;
9196 +       char *tmp;
9197 +       int err = 0;
9198 +       __u16 i;
9199 +       __u32 num_subjs;
9200 +
9201 +       /* we need a default and kernel role */
9202 +       if (arg->role_db.r_entries < 2)
9203 +               return -EINVAL;
9204 +
9205 +       /* copy special role authentication info from userspace */
9206 +
9207 +       num_sprole_pws = arg->num_sprole_pws;
9208 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
9209 +
9210 +       if (!acl_special_roles) {
9211 +               err = -ENOMEM;
9212 +               goto cleanup;
9213 +       }
9214 +
9215 +       for (i = 0; i < num_sprole_pws; i++) {
9216 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
9217 +               if (!sptmp) {
9218 +                       err = -ENOMEM;
9219 +                       goto cleanup;
9220 +               }
9221 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
9222 +                                  sizeof (struct sprole_pw))) {
9223 +                       err = -EFAULT;
9224 +                       goto cleanup;
9225 +               }
9226 +
9227 +               len =
9228 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
9229 +
9230 +               if (!len || len >= GR_SPROLE_LEN) {
9231 +                       err = -EINVAL;
9232 +                       goto cleanup;
9233 +               }
9234 +
9235 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
9236 +                       err = -ENOMEM;
9237 +                       goto cleanup;
9238 +               }
9239 +
9240 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
9241 +                       err = -EFAULT;
9242 +                       goto cleanup;
9243 +               }
9244 +
9245 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9246 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
9247 +#endif
9248 +               sptmp->rolename = tmp;
9249 +               acl_special_roles[i] = sptmp;
9250 +       }
9251 +
9252 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
9253 +
9254 +       for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
9255 +               r_last = r_tmp;
9256 +
9257 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
9258 +
9259 +               if (!r_tmp) {
9260 +                       err = -ENOMEM;
9261 +                       goto cleanup;
9262 +               }
9263 +
9264 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
9265 +                                  sizeof (struct acl_role_label *))) {
9266 +                       err = -EFAULT;
9267 +                       goto cleanup;
9268 +               }
9269 +
9270 +               if (copy_from_user(r_tmp, r_utmp2,
9271 +                                  sizeof (struct acl_role_label))) {
9272 +                       err = -EFAULT;
9273 +                       goto cleanup;
9274 +               }
9275 +
9276 +               if (!r_last) {
9277 +                       r_tmp->prev = NULL;
9278 +                       role_list_head = r_tmp;
9279 +               } else {
9280 +                       r_last->next = r_tmp;
9281 +                       r_tmp->prev = r_last;
9282 +               }
9283 +
9284 +               if (r_num == (arg->role_db.r_entries - 1))
9285 +                       r_tmp->next = NULL;
9286 +
9287 +               len = strnlen_user(r_tmp->rolename, PATH_MAX);
9288 +
9289 +               if (!len || len >= PATH_MAX) {
9290 +                       err = -EINVAL;
9291 +                       goto cleanup;
9292 +               }
9293 +
9294 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
9295 +                       err = -ENOMEM;
9296 +                       goto cleanup;
9297 +               }
9298 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
9299 +                       err = -EFAULT;
9300 +                       goto cleanup;
9301 +               }
9302 +               r_tmp->rolename = tmp;
9303 +
9304 +               if (!strcmp(r_tmp->rolename, "default")
9305 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
9306 +                       default_role = r_tmp;
9307 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
9308 +                       kernel_role = r_tmp;
9309 +               }
9310 +
9311 +               num_subjs = count_user_subjs(r_tmp->proc_subject);
9312 +
9313 +               r_tmp->subj_hash_size = num_subjs;
9314 +               r_tmp->subj_hash =
9315 +                   (struct acl_subject_label **)
9316 +                   create_table(&(r_tmp->subj_hash_size));
9317 +
9318 +               if (!r_tmp->subj_hash) {
9319 +                       err = -ENOMEM;
9320 +                       goto cleanup;
9321 +               }
9322 +
9323 +               err = copy_user_allowedips(r_tmp);
9324 +               if (err)
9325 +                       goto cleanup;
9326 +
9327 +               err = copy_user_transitions(r_tmp);
9328 +               if (err)
9329 +                       goto cleanup;
9330 +
9331 +               memset(r_tmp->subj_hash, 0,
9332 +                      r_tmp->subj_hash_size *
9333 +                      sizeof (struct acl_subject_label *));
9334 +
9335 +               s_last = NULL;
9336 +
9337 +               err = copy_user_subjs(r_tmp->proc_subject, r_tmp);
9338 +
9339 +               if (err)
9340 +                       goto cleanup;
9341 +
9342 +               insert_acl_role_label(r_tmp);
9343 +       }
9344 +
9345 +      cleanup:
9346 +       return err;
9347 +
9348 +}
9349 +
9350 +static int
9351 +gracl_init(struct gr_arg *args)
9352 +{
9353 +       int error = 0;
9354 +
9355 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
9356 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
9357 +
9358 +       if (init_variables(args->role_db.o_entries, args->role_db.s_entries,
9359 +                          args->role_db.i_entries, args->role_db.r_entries,
9360 +                          args->role_db.a_entries, args->role_db.t_entries,
9361 +                          args->num_sprole_pws)) {
9362 +               security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
9363 +               error = -ENOMEM;
9364 +               free_variables();
9365 +               goto out;
9366 +       }
9367 +
9368 +       error = copy_user_acl(args);
9369 +       if (error) {
9370 +               free_variables();
9371 +               goto out;
9372 +       }
9373 +
9374 +       if ((error = gr_set_acls(0))) {
9375 +               free_variables();
9376 +               goto out;
9377 +       }
9378 +
9379 +       gr_status |= GR_READY;
9380 +      out:
9381 +       return error;
9382 +}
9383 +
9384 +static struct acl_object_label *
9385 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
9386 +             const struct acl_subject_label *subj)
9387 +{
9388 +       struct dentry *dentry = (struct dentry *) l_dentry;
9389 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
9390 +       struct dentry *root;
9391 +       struct vfsmount *rootmnt;
9392 +       struct acl_object_label *retval;
9393 +
9394 +       read_lock(&child_reaper->fs->lock);
9395 +       rootmnt = mntget(child_reaper->fs->rootmnt);
9396 +       root = dget(child_reaper->fs->root);
9397 +       read_unlock(&child_reaper->fs->lock);
9398 +       spin_lock(&dcache_lock);
9399 +
9400 +       for (;;) {
9401 +               if (unlikely(dentry == root && mnt == rootmnt))
9402 +                       break;
9403 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
9404 +                       if (mnt->mnt_parent == mnt)
9405 +                               break;
9406 +
9407 +                       read_lock(&gr_inode_lock);
9408 +                       retval =
9409 +                           lookup_acl_obj_label(dentry->d_inode->i_ino,
9410 +                                                dentry->d_inode->i_dev, subj);
9411 +                       read_unlock(&gr_inode_lock);
9412 +                       if (unlikely(retval != NULL))
9413 +                               goto out;
9414 +
9415 +                       dentry = mnt->mnt_mountpoint;
9416 +                       mnt = mnt->mnt_parent;
9417 +                       continue;
9418 +               }
9419 +
9420 +               read_lock(&gr_inode_lock);
9421 +               retval =
9422 +                   lookup_acl_obj_label(dentry->d_inode->i_ino,
9423 +                                        dentry->d_inode->i_dev, subj);
9424 +               read_unlock(&gr_inode_lock);
9425 +               if (unlikely(retval != NULL))
9426 +                       goto out;
9427 +
9428 +               dentry = dentry->d_parent;
9429 +       }
9430 +
9431 +       read_lock(&gr_inode_lock);
9432 +       retval =
9433 +           lookup_acl_obj_label(dentry->d_inode->i_ino, dentry->d_inode->i_dev,
9434 +                                subj);
9435 +       read_unlock(&gr_inode_lock);
9436 +
9437 +       if (unlikely(retval == NULL)) {
9438 +               read_lock(&gr_inode_lock);
9439 +               retval =
9440 +                   lookup_acl_obj_label(root->d_inode->i_ino,
9441 +                                        root->d_inode->i_dev, subj);
9442 +               read_unlock(&gr_inode_lock);
9443 +       }
9444 +      out:
9445 +       spin_unlock(&dcache_lock);
9446 +       dput(root);
9447 +       mntput(rootmnt);
9448 +
9449 +       return retval;
9450 +}
9451 +
9452 +static struct acl_subject_label *
9453 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
9454 +              const struct acl_role_label *role)
9455 +{
9456 +       struct dentry *dentry = (struct dentry *) l_dentry;
9457 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
9458 +       struct dentry *root;
9459 +       struct vfsmount *rootmnt;
9460 +       struct acl_subject_label *retval;
9461 +
9462 +       read_lock(&child_reaper->fs->lock);
9463 +       rootmnt = mntget(child_reaper->fs->rootmnt);
9464 +       root = dget(child_reaper->fs->root);
9465 +       read_unlock(&child_reaper->fs->lock);
9466 +       spin_lock(&dcache_lock);
9467 +
9468 +       for (;;) {
9469 +               if (unlikely(dentry == root && mnt == rootmnt))
9470 +                       break;
9471 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
9472 +                       if (mnt->mnt_parent == mnt)
9473 +                               break;
9474 +
9475 +                       read_lock(&gr_inode_lock);
9476 +                       retval =
9477 +                           lookup_acl_subj_label(dentry->d_inode->i_ino,
9478 +                                                 dentry->d_inode->i_dev, role);
9479 +                       read_unlock(&gr_inode_lock);
9480 +                       if (unlikely(retval != NULL))
9481 +                               goto out;
9482 +
9483 +                       dentry = mnt->mnt_mountpoint;
9484 +                       mnt = mnt->mnt_parent;
9485 +                       continue;
9486 +               }
9487 +
9488 +               read_lock(&gr_inode_lock);
9489 +               retval =
9490 +                   lookup_acl_subj_label(dentry->d_inode->i_ino,
9491 +                                         dentry->d_inode->i_dev, role);
9492 +               read_unlock(&gr_inode_lock);
9493 +               if (unlikely(retval != NULL))
9494 +                       goto out;
9495 +
9496 +               dentry = dentry->d_parent;
9497 +       }
9498 +
9499 +       read_lock(&gr_inode_lock);
9500 +       retval =
9501 +           lookup_acl_subj_label(dentry->d_inode->i_ino,
9502 +                                 dentry->d_inode->i_dev, role);
9503 +       read_unlock(&gr_inode_lock);
9504 +
9505 +       if (unlikely(retval == NULL)) {
9506 +               read_lock(&gr_inode_lock);
9507 +               retval =
9508 +                   lookup_acl_subj_label(root->d_inode->i_ino,
9509 +                                         root->d_inode->i_dev, role);
9510 +               read_unlock(&gr_inode_lock);
9511 +       }
9512 +      out:
9513 +       spin_unlock(&dcache_lock);
9514 +       dput(root);
9515 +       mntput(rootmnt);
9516 +
9517 +       return retval;
9518 +}
9519 +
9520 +static __inline__ void
9521 +gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
9522 +            const struct task_struct *task, const char *pathname,
9523 +            const __u32 mode)
9524 +{
9525 +       security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
9526 +                      uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
9527 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
9528 +                      1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
9529 +
9530 +       return;
9531 +}
9532 +
9533 +__u32
9534 +gr_check_link(const struct dentry * new_dentry,
9535 +             const struct dentry * parent_dentry,
9536 +             const struct vfsmount * parent_mnt,
9537 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
9538 +{
9539 +       struct acl_object_label *obj;
9540 +       __u32 oldmode, newmode;
9541 +
9542 +       if (unlikely(!(gr_status & GR_READY)))
9543 +               return (GR_WRITE | GR_CREATE);
9544 +
9545 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
9546 +       oldmode = obj->mode;
9547 +
9548 +       if (current->acl->mode & GR_LEARN)
9549 +               oldmode |= (GR_WRITE | GR_CREATE);
9550 +       newmode =
9551 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
9552 +                           oldmode | GR_CREATE | GR_AUDIT_CREATE |
9553 +                           GR_AUDIT_WRITE | GR_SUPPRESS);
9554 +
9555 +       if ((newmode & oldmode) == oldmode)
9556 +               return newmode;
9557 +       else if (current->acl->mode & GR_LEARN) {
9558 +               gr_log_learn(current->role, current->uid, current->gid,
9559 +                       current, gr_to_filename(old_dentry, old_mnt), oldmode);
9560 +               return (GR_WRITE | GR_CREATE);
9561 +       } else if (newmode & GR_SUPPRESS)
9562 +               return GR_SUPPRESS;
9563 +       else
9564 +               return 0;
9565 +}
9566 +
9567 +__u32
9568 +gr_search_file(const struct dentry * dentry, const __u32 mode,
9569 +              const struct vfsmount * mnt)
9570 +{
9571 +       __u32 retval = mode;
9572 +       struct acl_subject_label *curracl;
9573 +       struct acl_object_label *currobj;
9574 +
9575 +       if (unlikely(!(gr_status & GR_READY)))
9576 +               return (mode & ~GR_AUDITS);
9577 +
9578 +       curracl = current->acl;
9579 +
9580 +       currobj = chk_obj_label(dentry, mnt, curracl);
9581 +       retval = currobj->mode & mode;
9582 +
9583 +       if (unlikely
9584 +           ((curracl->mode & GR_LEARN) && (mode != GR_PTRACERD)
9585 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
9586 +               __u32 new_mode = mode;
9587 +
9588 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9589 +
9590 +               retval = new_mode;
9591 +
9592 +               if (!(mode & GR_NOLEARN))
9593 +                       gr_log_learn(current->role, current->uid, current->gid,
9594 +                                    current, gr_to_filename(dentry, mnt), new_mode);
9595 +       }
9596 +
9597 +       return retval;
9598 +}
9599 +
9600 +__u32
9601 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
9602 +               const struct vfsmount * mnt, const __u32 mode)
9603 +{
9604 +       struct name_entry *match;
9605 +       struct acl_object_label *matchpo;
9606 +       struct acl_subject_label *curracl;
9607 +       __u32 retval;
9608 +
9609 +       if (unlikely(!(gr_status & GR_READY)))
9610 +               return (mode & ~GR_AUDITS);
9611 +
9612 +       match = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9613 +
9614 +       if (!match)
9615 +               goto check_parent;
9616 +
9617 +       curracl = current->acl;
9618 +
9619 +       read_lock(&gr_inode_lock);
9620 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
9621 +       read_unlock(&gr_inode_lock);
9622 +
9623 +       if (matchpo) {
9624 +               if ((matchpo->mode & mode) !=
9625 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
9626 +                   && curracl->mode & GR_LEARN) {
9627 +                       __u32 new_mode = mode;
9628 +
9629 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9630 +
9631 +                       gr_log_learn(current->role, current->uid, current->gid,
9632 +                                    current, gr_to_filename(new_dentry, mnt), new_mode);
9633 +
9634 +                       return new_mode;
9635 +               }
9636 +               return (matchpo->mode & mode);
9637 +       }
9638 +
9639 +      check_parent:
9640 +       curracl = current->acl;
9641 +
9642 +       matchpo = chk_obj_label(parent, mnt, curracl);
9643 +       retval = matchpo->mode & mode;
9644 +
9645 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
9646 +           && (curracl->mode & GR_LEARN)) {
9647 +               __u32 new_mode = mode;
9648 +
9649 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9650 +
9651 +               gr_log_learn(current->role, current->uid, current->gid, 
9652 +                            current, gr_to_filename(new_dentry, mnt), new_mode);
9653 +               return new_mode;
9654 +       }
9655 +
9656 +       return retval;
9657 +}
9658 +
9659 +int
9660 +gr_check_hidden_task(const struct task_struct *task)
9661 +{
9662 +       if (unlikely(!(gr_status & GR_READY)))
9663 +               return 0;
9664 +
9665 +       if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
9666 +               return 1;
9667 +
9668 +       return 0;
9669 +}
9670 +
9671 +int
9672 +gr_check_protected_task(const struct task_struct *task)
9673 +{
9674 +       if (unlikely(!(gr_status & GR_READY) || !task))
9675 +               return 0;
9676 +
9677 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
9678 +               return 1;
9679 +
9680 +       return 0;
9681 +}
9682 +
9683 +__inline__ void
9684 +gr_copy_label(struct task_struct *tsk)
9685 +{
9686 +       tsk->used_accept = 0;
9687 +       tsk->acl_sp_role = 0;
9688 +       tsk->acl_role_id = current->acl_role_id;
9689 +       tsk->acl = current->acl;
9690 +       tsk->role = current->role;
9691 +       tsk->curr_ip = current->curr_ip;
9692 +       if (current->exec_file)
9693 +               get_file(current->exec_file);
9694 +       tsk->exec_file = current->exec_file;
9695 +       tsk->is_writable = current->is_writable;
9696 +       if (unlikely(current->used_accept))
9697 +               current->curr_ip = 0;
9698 +
9699 +       return;
9700 +}
9701 +
9702 +static __inline__ void
9703 +gr_set_proc_res(void)
9704 +{
9705 +       struct acl_subject_label *proc;
9706 +       unsigned short i;
9707 +
9708 +       proc = current->acl;
9709 +
9710 +       if (proc->mode & GR_LEARN)
9711 +               return;
9712 +
9713 +       for (i = 0; i < RLIM_NLIMITS; i++) {
9714 +               if (!(proc->resmask & (1 << i)))
9715 +                       continue;
9716 +
9717 +               current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
9718 +               current->rlim[i].rlim_max = proc->res[i].rlim_max;
9719 +       }
9720 +
9721 +       return;
9722 +}
9723 +
9724 +void
9725 +gr_set_pax_flags(struct task_struct *task)
9726 +{
9727 +       struct acl_subject_label *proc;
9728 +
9729 +       if (unlikely(!(gr_status & GR_READY)))
9730 +               return;
9731 +
9732 +       proc = task->acl;
9733 +
9734 +       if (proc->mode & GR_PAXPAGE)
9735 +               task->flags &= ~PF_PAX_PAGEEXEC;
9736 +       if (proc->mode & GR_PAXSEGM)
9737 +               task->flags &= ~PF_PAX_SEGMEXEC;
9738 +       if (proc->mode & GR_PAXGCC)
9739 +               task->flags |= PF_PAX_EMUTRAMP;
9740 +       if (proc->mode & GR_PAXMPROTECT)
9741 +               task->flags &= ~PF_PAX_MPROTECT;
9742 +       if (proc->mode & GR_PAXRANDMMAP)
9743 +               task->flags &= ~PF_PAX_RANDMMAP;
9744 +       if (proc->mode & GR_PAXRANDEXEC)
9745 +               task->flags |= PF_PAX_RANDEXEC;
9746 +
9747 +       return;
9748 +}
9749 +
9750 +static __inline__ void
9751 +do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
9752 +{
9753 +       task->role = lookup_acl_role_label(task, uid, gid);
9754 +
9755 +       return;
9756 +}
9757 +
9758 +void
9759 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
9760 +{
9761 +       struct acl_object_label *obj;
9762 +       struct file *filp;
9763 +
9764 +       if (unlikely(!(gr_status & GR_READY)))
9765 +               return;
9766 +
9767 +       filp = task->exec_file;
9768 +
9769 +       /* kernel process, we'll give them the kernel role */
9770 +       if (unlikely(!filp)) {
9771 +               task->role = kernel_role;
9772 +               task->acl = kernel_role->root_label;
9773 +               return;
9774 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
9775 +               do_set_role_label(task, uid, gid);
9776 +
9777 +       task->acl =
9778 +           chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
9779 +
9780 +       task->is_writable = 0;
9781 +
9782 +       /* ignore additional mmap checks for processes that are writable 
9783 +          by the default ACL */
9784 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9785 +       if (unlikely(obj->mode & GR_WRITE))
9786 +               task->is_writable = 1;
9787 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9788 +       if (unlikely(obj->mode & GR_WRITE))
9789 +               task->is_writable = 1;
9790 +
9791 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9792 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9793 +#endif
9794 +
9795 +       gr_set_proc_res();
9796 +
9797 +       return;
9798 +}
9799 +
9800 +void
9801 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
9802 +{
9803 +       struct acl_subject_label *newacl;
9804 +       struct acl_object_label *obj;
9805 +       __u32 retmode;
9806 +
9807 +       if (unlikely(!(gr_status & GR_READY)))
9808 +               return;
9809 +
9810 +       newacl = chk_subj_label(dentry, mnt, current->role);
9811 +
9812 +       obj = chk_obj_label(dentry, mnt, current->acl);
9813 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
9814 +
9815 +       if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
9816 +               if (obj->nested)
9817 +                       current->acl = obj->nested;
9818 +               else
9819 +                       current->acl = newacl;
9820 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
9821 +               security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
9822 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
9823 +
9824 +       current->is_writable = 0;
9825 +
9826 +       /* ignore additional mmap checks for processes that are writable 
9827 +          by the default ACL */
9828 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
9829 +       if (unlikely(obj->mode & GR_WRITE))
9830 +               current->is_writable = 1;
9831 +       obj = chk_obj_label(dentry, mnt, current->role->root_label);
9832 +       if (unlikely(obj->mode & GR_WRITE))
9833 +               current->is_writable = 1;
9834 +
9835 +       gr_set_proc_res();
9836 +
9837 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9838 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
9839 +#endif
9840 +       return;
9841 +}
9842 +
9843 +static __inline__ void
9844 +do_handle_delete(const ino_t ino, const kdev_t dev)
9845 +{
9846 +       struct acl_object_label *matchpo;
9847 +       struct acl_subject_label *matchps;
9848 +       struct acl_subject_label *i;
9849 +       struct acl_role_label *role;
9850 +
9851 +       for (role = role_list_head; role; role = role->next) {
9852 +               for (i = role->proc_subject; i; i = i->next) {
9853 +                       if (unlikely(i->parent_subject &&
9854 +                                    (i->inode == ino) &&
9855 +                                    (i->device == dev)))
9856 +                               i->mode |= GR_DELETED;
9857 +                       if (unlikely((matchpo =
9858 +                            lookup_acl_obj_label(ino, dev, i)) != NULL))
9859 +                               matchpo->mode |= GR_DELETED;
9860 +               }
9861 +
9862 +               if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
9863 +                       matchps->mode |= GR_DELETED;
9864 +       }
9865 +
9866 +       return;
9867 +}
9868 +
9869 +void
9870 +gr_handle_delete(const ino_t ino, const kdev_t dev)
9871 +{
9872 +       if (unlikely(!(gr_status & GR_READY)))
9873 +               return;
9874 +
9875 +       write_lock(&gr_inode_lock);
9876 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
9877 +               do_handle_delete(ino, dev);
9878 +       write_unlock(&gr_inode_lock);
9879 +
9880 +       return;
9881 +}
9882 +
9883 +static __inline__ void
9884 +update_acl_obj_label(const ino_t oldinode, const kdev_t olddevice,
9885 +                    const ino_t newinode, const kdev_t newdevice,
9886 +                    struct acl_subject_label *subj)
9887 +{
9888 +       unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
9889 +       struct acl_object_label **match;
9890 +       struct acl_object_label *tmp;
9891 +       __u8 i = 0;
9892 +
9893 +       match = &subj->obj_hash[index];
9894 +
9895 +       while (*match && ((*match)->inode != oldinode ||
9896 +              (*match)->device != olddevice ||
9897 +              !((*match)->mode & GR_DELETED))) {
9898 +               index = (index + (1 << i)) % subj->obj_hash_size;
9899 +               match = &subj->obj_hash[index];
9900 +               i = (i + 1) % 32;
9901 +       }
9902 +
9903 +       if (*match && ((*match) != deleted_object)
9904 +           && ((*match)->inode == oldinode)
9905 +           && ((*match)->device == olddevice)
9906 +           && ((*match)->mode & GR_DELETED)) {
9907 +               tmp = *match;
9908 +               tmp->inode = newinode;
9909 +               tmp->device = newdevice;
9910 +               tmp->mode &= ~GR_DELETED;
9911 +
9912 +               *match = deleted_object;
9913 +
9914 +               insert_acl_obj_label(tmp, subj);
9915 +       }
9916 +
9917 +       return;
9918 +}
9919 +
9920 +static __inline__ void
9921 +update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice,
9922 +                     const ino_t newinode, const kdev_t newdevice,
9923 +                     struct acl_role_label *role)
9924 +{
9925 +       struct acl_subject_label **s_hash = role->subj_hash;
9926 +       unsigned long subj_size = role->subj_hash_size;
9927 +       unsigned long index = fhash(oldinode, olddevice, subj_size);
9928 +       struct acl_subject_label **match;
9929 +       struct acl_subject_label *tmp;
9930 +       __u8 i = 0;
9931 +
9932 +       match = &s_hash[index];
9933 +
9934 +       while (*match && ((*match)->inode != oldinode ||
9935 +              (*match)->device != olddevice ||
9936 +              !((*match)->mode & GR_DELETED))) {
9937 +               index = (index + (1 << i)) % subj_size;
9938 +               i = (i + 1) % 32;
9939 +               match = &s_hash[index];
9940 +       }
9941 +
9942 +       if (*match && (*match != deleted_subject)
9943 +           && ((*match)->inode == oldinode)
9944 +           && ((*match)->device == olddevice)
9945 +           && ((*match)->mode & GR_DELETED)) {
9946 +               tmp = *match;
9947 +
9948 +               tmp->inode = newinode;
9949 +               tmp->device = newdevice;
9950 +               tmp->mode &= ~GR_DELETED;
9951 +
9952 +               *match = deleted_subject;
9953 +
9954 +               insert_acl_subj_label(tmp, role);
9955 +       }
9956 +
9957 +       return;
9958 +}
9959 +
9960 +static __inline__ void
9961 +update_inodev_entry(const ino_t oldinode, const kdev_t olddevice,
9962 +                   const ino_t newinode, const kdev_t newdevice)
9963 +{
9964 +       unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
9965 +       struct name_entry **match;
9966 +       struct name_entry *tmp;
9967 +       __u8 i = 0;
9968 +
9969 +       match = &inodev_set.n_hash[index];
9970 +
9971 +       while (*match
9972 +              && ((*match)->inode != oldinode
9973 +                  || (*match)->device != olddevice)) {
9974 +               index = (index + (1 << i)) % inodev_set.n_size;
9975 +               i = (i + 1) % 32;
9976 +               match = &inodev_set.n_hash[index];
9977 +       }
9978 +
9979 +       if (*match && (*match != deleted_inodev)
9980 +           && ((*match)->inode == oldinode)
9981 +           && ((*match)->device == olddevice)) {
9982 +               tmp = *match;
9983 +
9984 +               tmp->inode = newinode;
9985 +               tmp->device = newdevice;
9986 +
9987 +               *match = deleted_inodev;
9988 +
9989 +               insert_inodev_entry(tmp);
9990 +       }
9991 +
9992 +       return;
9993 +}
9994 +
9995 +static __inline__ void
9996 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
9997 +                const struct vfsmount *mnt)
9998 +{
9999 +       struct acl_subject_label *i;
10000 +       struct acl_role_label *role;
10001 +
10002 +       for (role = role_list_head; role; role = role->next) {
10003 +               update_acl_subj_label(matchn->inode, matchn->device,
10004 +                                     dentry->d_inode->i_ino,
10005 +                                     dentry->d_inode->i_dev, role);
10006 +
10007 +               for (i = role->proc_subject; i; i = i->next) {
10008 +                       if (unlikely(i->parent_subject &&
10009 +                                    (i->inode == dentry->d_inode->i_ino) &&
10010 +                                    (i->device == dentry->d_inode->i_dev))) {
10011 +                               i->inode = dentry->d_inode->i_ino;
10012 +                               i->device = dentry->d_inode->i_dev;
10013 +                       }
10014 +                       update_acl_obj_label(matchn->inode, matchn->device,
10015 +                                            dentry->d_inode->i_ino,
10016 +                                            dentry->d_inode->i_dev, i);
10017 +               }
10018 +       }
10019 +
10020 +       update_inodev_entry(matchn->inode, matchn->device,
10021 +                           dentry->d_inode->i_ino, dentry->d_inode->i_dev);
10022 +
10023 +       return;
10024 +}
10025 +
10026 +void
10027 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
10028 +{
10029 +       struct name_entry *matchn;
10030 +
10031 +       if (unlikely(!(gr_status & GR_READY)))
10032 +               return;
10033 +
10034 +       matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
10035 +
10036 +       if (unlikely((unsigned long)matchn)) {
10037 +               write_lock(&gr_inode_lock);
10038 +               do_handle_create(matchn, dentry, mnt);
10039 +               write_unlock(&gr_inode_lock);
10040 +       }
10041 +
10042 +       return;
10043 +}
10044 +
10045 +int
10046 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
10047 +                struct dentry *old_dentry,
10048 +                struct dentry *new_dentry,
10049 +                struct vfsmount *mnt, const __u8 replace)
10050 +{
10051 +       struct name_entry *matchn;
10052 +       int error = 0;
10053 +
10054 +       matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
10055 +
10056 +       lock_kernel();
10057 +       error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
10058 +       unlock_kernel();
10059 +
10060 +       if (unlikely(error))
10061 +               return error;
10062 +
10063 +       /* we wouldn't have to check d_inode if it weren't for
10064 +          NFS silly-renaming
10065 +        */
10066 +
10067 +       write_lock(&gr_inode_lock);
10068 +       if (unlikely(replace && new_dentry->d_inode)) {
10069 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
10070 +                                       new_dentry->d_inode->i_dev) &&
10071 +                   (old_dentry->d_inode->i_nlink <= 1)))
10072 +                       do_handle_delete(new_dentry->d_inode->i_ino,
10073 +                                        new_dentry->d_inode->i_dev);
10074 +       }
10075 +
10076 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
10077 +                               old_dentry->d_inode->i_dev) &&
10078 +           (old_dentry->d_inode->i_nlink <= 1)))
10079 +               do_handle_delete(old_dentry->d_inode->i_ino,
10080 +                                old_dentry->d_inode->i_dev);
10081 +
10082 +       if (unlikely((unsigned long)matchn))
10083 +               do_handle_create(matchn, old_dentry, mnt);
10084 +       write_unlock(&gr_inode_lock);
10085 +
10086 +       return error;
10087 +}
10088 +
10089 +static int
10090 +lookup_special_role_auth(const char *rolename, unsigned char **salt,
10091 +                        unsigned char **sum)
10092 +{
10093 +       struct acl_role_label *r;
10094 +       struct role_transition *trans;
10095 +       __u16 i;
10096 +       int found = 0;
10097 +
10098 +       /* check transition table */
10099 +
10100 +       for (trans = current->role->transitions; trans; trans = trans->next) {
10101 +               if (!strcmp(rolename, trans->rolename)) {
10102 +                       found = 1;
10103 +                       break;
10104 +               }
10105 +       }
10106 +
10107 +       if (!found)
10108 +               return 0;
10109 +
10110 +       /* handle special roles that do not require authentication */
10111 +
10112 +       for (r = role_list_head; r; r = r->next) {
10113 +               if (!strcmp(rolename, r->rolename)
10114 +                   && (r->roletype & GR_ROLE_NOPW)) {
10115 +                       *salt = NULL;
10116 +                       *sum = NULL;
10117 +                       return 1;
10118 +               }
10119 +       }
10120 +
10121 +       for (i = 0; i < num_sprole_pws; i++) {
10122 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
10123 +                       *salt = acl_special_roles[i]->salt;
10124 +                       *sum = acl_special_roles[i]->sum;
10125 +                       return 1;
10126 +               }
10127 +       }
10128 +
10129 +       return 0;
10130 +}
10131 +
10132 +static void
10133 +assign_special_role(char *rolename)
10134 +{
10135 +       struct acl_object_label *obj;
10136 +       struct acl_role_label *r;
10137 +       struct acl_role_label *assigned = NULL;
10138 +       struct task_struct *tsk;
10139 +       struct file *filp;
10140 +
10141 +       for (r = role_list_head; r; r = r->next)
10142 +               if (!strcmp(rolename, r->rolename) &&
10143 +                   (r->roletype & GR_ROLE_SPECIAL))
10144 +                       assigned = r;
10145 +
10146 +       if (!assigned)
10147 +               return;
10148 +
10149 +       tsk = current->p_pptr;
10150 +       filp = tsk->exec_file;
10151 +
10152 +       if (tsk && filp) {
10153 +               tsk->is_writable = 0;
10154 +
10155 +               acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
10156 +               tsk->acl_sp_role = 1;
10157 +               tsk->acl_role_id = acl_sp_role_value;
10158 +               tsk->role = assigned;
10159 +               tsk->acl =
10160 +                   chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
10161 +
10162 +               /* ignore additional mmap checks for processes that are writable 
10163 +                  by the default ACL */
10164 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10165 +               if (unlikely(obj->mode & GR_WRITE))
10166 +                       tsk->is_writable = 1;
10167 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
10168 +               if (unlikely(obj->mode & GR_WRITE))
10169 +                       tsk->is_writable = 1;
10170 +
10171 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10172 +               printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
10173 +#endif
10174 +       }
10175 +
10176 +       return;
10177 +}
10178 +
10179 +ssize_t
10180 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
10181 +{
10182 +       struct gr_arg *arg;
10183 +       unsigned char *sprole_salt;
10184 +       unsigned char *sprole_sum;
10185 +       int error = sizeof (struct gr_arg);
10186 +       int error2 = 0;
10187 +
10188 +       down(&gr_dev_sem);
10189 +
10190 +       arg = (struct gr_arg *) buf;
10191 +
10192 +       if (count != sizeof (struct gr_arg)) {
10193 +               security_alert_good(GR_DEV_ACL_MSG, count,
10194 +                                   (int) sizeof (struct gr_arg));
10195 +               error = -EINVAL;
10196 +               goto out;
10197 +       }
10198 +
10199 +       if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10200 +           && time_before_eq(gr_auth_expires, jiffies)) {
10201 +               gr_auth_expires = 0;
10202 +               gr_auth_attempts = 0;
10203 +       }
10204 +
10205 +       if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
10206 +               error = -EFAULT;
10207 +               goto out;
10208 +       }
10209 +
10210 +       if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) {
10211 +               error = -EBUSY;
10212 +               goto out;
10213 +       }
10214 +
10215 +       /* if non-root trying to do anything other than use a special role,
10216 +          do not attempt authentication, do not count towards authentication
10217 +          locking
10218 +        */
10219 +
10220 +       if (gr_usermode->mode != SPROLE && current->uid) {
10221 +               error = -EPERM;
10222 +               goto out;
10223 +       }
10224 +
10225 +       /* ensure pw and special role name are null terminated */
10226 +
10227 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
10228 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
10229 +
10230 +       /* Okay. 
10231 +        * We have our enough of the argument structure..(we have yet
10232 +        * to copy_from_user the tables themselves) . Copy the tables
10233 +        * only if we need them, i.e. for loading operations. */
10234 +
10235 +       switch (gr_usermode->mode) {
10236 +       case STATUS:
10237 +                       if (gr_status & GR_READY)
10238 +                               error = 1;
10239 +                       else
10240 +                               error = 2;
10241 +                       goto out;
10242 +       case SHUTDOWN:
10243 +               if ((gr_status & GR_READY)
10244 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10245 +                       gr_status &= ~GR_READY;
10246 +                       security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
10247 +                       free_variables();
10248 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
10249 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
10250 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
10251 +               } else if (gr_status & GR_READY) {
10252 +                       security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
10253 +                       error = -EPERM;
10254 +               } else {
10255 +                       security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
10256 +                       error = -EAGAIN;
10257 +               }
10258 +               break;
10259 +       case ENABLE:
10260 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
10261 +                       security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
10262 +               else {
10263 +                       if (gr_status & GR_READY)
10264 +                               error = -EAGAIN;
10265 +                       else
10266 +                               error = error2;
10267 +                       security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
10268 +                                      DEFAULTSECARGS);
10269 +               }
10270 +               break;
10271 +       case RELOAD:
10272 +               if (!(gr_status & GR_READY)) {
10273 +                       security_alert_good(GR_RELOADI_ACL_MSG);
10274 +                       error = -EAGAIN;
10275 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10276 +                       lock_kernel();
10277 +                       gr_status &= ~GR_READY;
10278 +                       free_variables();
10279 +                       if (!(error2 = gracl_init(gr_usermode))) {
10280 +                               unlock_kernel();
10281 +                               security_alert_good(GR_RELOAD_ACL_MSG,
10282 +                                                   GR_VERSION);
10283 +                       } else {
10284 +                               unlock_kernel();
10285 +                               error = error2;
10286 +                               security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
10287 +                                              DEFAULTSECARGS);
10288 +                       }
10289 +               } else {
10290 +                       security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
10291 +                                      DEFAULTSECARGS);
10292 +                       error = -EPERM;
10293 +               }
10294 +               break;
10295 +       case SEGVMOD:
10296 +               if (unlikely(!(gr_status & GR_READY))) {
10297 +                       security_alert_good(GR_SEGVMODI_ACL_MSG,
10298 +                                           DEFAULTSECARGS);
10299 +                       error = -EAGAIN;
10300 +                       break;
10301 +               }
10302 +
10303 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10304 +                       security_alert_good(GR_SEGVMODS_ACL_MSG,
10305 +                                           DEFAULTSECARGS);
10306 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
10307 +                               struct acl_subject_label *segvacl;
10308 +                               segvacl =
10309 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
10310 +                                                         gr_usermode->segv_device,
10311 +                                                         current->role);
10312 +                               if (segvacl) {
10313 +                                       segvacl->crashes = 0;
10314 +                                       segvacl->expires = 0;
10315 +                               }
10316 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
10317 +                               gr_remove_uid(gr_usermode->segv_uid);
10318 +                       }
10319 +               } else {
10320 +                       security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
10321 +                       error = -EPERM;
10322 +               }
10323 +               break;
10324 +       case SPROLE:
10325 +               if (unlikely(!(gr_status & GR_READY))) {
10326 +                       security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
10327 +                       error = -EAGAIN;
10328 +                       break;
10329 +               }
10330 +
10331 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10332 +                   && time_before_eq(current->role->expires, jiffies)) {
10333 +                       current->role->expires = 0;
10334 +                       current->role->auth_attempts = 0;
10335 +               }
10336 +
10337 +               if (time_after(current->role->expires, jiffies)) {
10338 +                       error = -EBUSY;
10339 +                       goto out;
10340 +               }
10341 +
10342 +               if (lookup_special_role_auth
10343 +                   (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
10344 +                   && ((!sprole_salt && !sprole_sum)
10345 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
10346 +                       assign_special_role(gr_usermode->sp_role);
10347 +                       security_alert_good(GR_SPROLES_ACL_MSG,
10348 +                                           (current->p_pptr) ? current->
10349 +                                           p_pptr->role->rolename : "",
10350 +                                           acl_sp_role_value, DEFAULTSECARGS);
10351 +               } else {
10352 +                       security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
10353 +                                      DEFAULTSECARGS);
10354 +                       error = -EPERM;
10355 +                       current->role->auth_attempts++;
10356 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10357 +                               current->role->expires =
10358 +                                   jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
10359 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
10360 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
10361 +                                      gr_usermode->sp_role, DEFAULTSECARGS);
10362 +                       }
10363 +
10364 +                       goto out;
10365 +               }
10366 +               break;
10367 +       case UNSPROLE:
10368 +               if (unlikely(!(gr_status & GR_READY))) {
10369 +                       security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
10370 +                       error = -EAGAIN;
10371 +                       break;
10372 +               }
10373 +
10374 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10375 +                   && time_before_eq(current->role->expires, jiffies)) {
10376 +                       current->role->expires = 0;
10377 +                       current->role->auth_attempts = 0;
10378 +               }
10379 +
10380 +               if (time_after(current->role->expires, jiffies)) {
10381 +                       error = -EBUSY;
10382 +                       goto out;
10383 +               }
10384 +
10385 +               if ((current->role->roletype & GR_ROLE_SPECIAL) && 
10386 +                   lookup_special_role_auth
10387 +                   (current->role->rolename, &sprole_salt, &sprole_sum)
10388 +                   && ((!sprole_salt && !sprole_sum)
10389 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
10390 +                       security_alert_good(GR_UNSPROLES_ACL_MSG,
10391 +                                           (current->p_pptr) ? current->
10392 +                                           p_pptr->role->rolename : "",
10393 +                                           (current->p_pptr) ? current->
10394 +                                           p_pptr->acl_role_id : 0, DEFAULTSECARGS);
10395 +                       gr_set_acls(1);
10396 +                       if (current->p_pptr)
10397 +                               current->p_pptr->acl_sp_role = 0;
10398 +               } else {
10399 +                       security_alert(GR_UNSPROLEF_ACL_MSG, gr_usermode->sp_role,
10400 +                                      DEFAULTSECARGS);
10401 +                       error = -EPERM;
10402 +                       current->role->auth_attempts++;
10403 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10404 +                               current->role->expires =
10405 +                                   jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
10406 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
10407 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
10408 +                                      current->role->rolename, DEFAULTSECARGS);
10409 +                       }
10410 +
10411 +                       goto out;
10412 +               }
10413 +               break;
10414 +       default:
10415 +               security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
10416 +                              DEFAULTSECARGS);
10417 +               error = -EINVAL;
10418 +               break;
10419 +       }
10420 +
10421 +       if (error != -EPERM)
10422 +               goto out;
10423 +
10424 +       gr_auth_attempts++;
10425 +
10426 +       if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10427 +               security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
10428 +               gr_auth_expires = jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
10429 +       }
10430 +
10431 +      out:
10432 +       up(&gr_dev_sem);
10433 +       return error;
10434 +}
10435 +
10436 +int
10437 +gr_set_acls(const int type)
10438 +{
10439 +       struct acl_object_label *obj;
10440 +       struct task_struct *task;
10441 +       struct file *filp;
10442 +       unsigned short i;
10443 +
10444 +       read_lock(&tasklist_lock);
10445 +       for_each_task(task) {
10446 +               /* check to see if we're called from the exit handler,
10447 +                  if so, only replace ACLs that have inherited the admin
10448 +                  ACL */
10449 +
10450 +               if (type && (task->role != current->role ||
10451 +                            task->acl_role_id != current->acl_role_id))
10452 +                       continue;
10453 +
10454 +               task->acl_role_id = 0;
10455 +
10456 +               if ((filp = task->exec_file)) {
10457 +                       do_set_role_label(task, task->uid, task->gid);
10458 +
10459 +                       task->acl =
10460 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
10461 +                                          task->role);
10462 +                       if (task->acl) {
10463 +                               struct acl_subject_label *curr;
10464 +                               curr = task->acl;
10465 +
10466 +                               task->is_writable = 0;
10467 +                               /* ignore additional mmap checks for processes that are writable 
10468 +                                  by the default ACL */
10469 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10470 +                               if (unlikely(obj->mode & GR_WRITE))
10471 +                                       task->is_writable = 1;
10472 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
10473 +                               if (unlikely(obj->mode & GR_WRITE))
10474 +                                       task->is_writable = 1;
10475 +
10476 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10477 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
10478 +#endif
10479 +                               if (!(curr->mode & GR_LEARN))
10480 +                                       for (i = 0; i < RLIM_NLIMITS; i++) {
10481 +                                               if (!(curr->resmask & (1 << i)))
10482 +                                                       continue;
10483 +
10484 +                                               task->rlim[i].rlim_cur =
10485 +                                                   curr->res[i].rlim_cur;
10486 +                                               task->rlim[i].rlim_max =
10487 +                                                   curr->res[i].rlim_max;
10488 +                                       }
10489 +                       } else {
10490 +                               read_unlock(&tasklist_lock);
10491 +                               security_alert_good(GR_DEFACL_MSG, task->comm,
10492 +                                                   task->pid);
10493 +                               return 1;
10494 +                       }
10495 +               } else {
10496 +                       // it's a kernel process
10497 +                       task->role = kernel_role;
10498 +                       task->acl = kernel_role->root_label;
10499 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
10500 +                       task->acl->mode &= ~GR_FIND;
10501 +#endif
10502 +               }
10503 +       }
10504 +       read_unlock(&tasklist_lock);
10505 +       return 0;
10506 +}
10507 +
10508 +void
10509 +gr_learn_resource(const struct task_struct *task,
10510 +                 const int res, const unsigned long wanted, const int gt)
10511 +{
10512 +       struct acl_subject_label *acl;
10513 +
10514 +       if (unlikely((gr_status & GR_READY) &&
10515 +                    task->acl && (task->acl->mode & GR_LEARN)))
10516 +               goto skip_reslog;
10517 +
10518 +#ifdef CONFIG_GRKERNSEC_RESLOG
10519 +       gr_log_resource(task, res, wanted, gt);
10520 +#endif
10521 +      skip_reslog:
10522 +
10523 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
10524 +               return;
10525 +
10526 +       acl = task->acl;
10527 +
10528 +       if (likely(!acl || !(acl->mode & GR_LEARN) ||
10529 +                  !(acl->resmask & (1 << (unsigned short) res))))
10530 +               return;
10531 +
10532 +       if (wanted >= acl->res[res].rlim_cur) {
10533 +               unsigned long res_add;
10534 +
10535 +               res_add = wanted;
10536 +               switch (res) {
10537 +               case RLIMIT_CPU:
10538 +                       res_add += GR_RLIM_CPU_BUMP;
10539 +                       break;
10540 +               case RLIMIT_FSIZE:
10541 +                       res_add += GR_RLIM_FSIZE_BUMP;
10542 +                       break;
10543 +               case RLIMIT_DATA:
10544 +                       res_add += GR_RLIM_DATA_BUMP;
10545 +                       break;
10546 +               case RLIMIT_STACK:
10547 +                       res_add += GR_RLIM_STACK_BUMP;
10548 +                       break;
10549 +               case RLIMIT_CORE:
10550 +                       res_add += GR_RLIM_CORE_BUMP;
10551 +                       break;
10552 +               case RLIMIT_RSS:
10553 +                       res_add += GR_RLIM_RSS_BUMP;
10554 +                       break;
10555 +               case RLIMIT_NPROC:
10556 +                       res_add += GR_RLIM_NPROC_BUMP;
10557 +                       break;
10558 +               case RLIMIT_NOFILE:
10559 +                       res_add += GR_RLIM_NOFILE_BUMP;
10560 +                       break;
10561 +               case RLIMIT_MEMLOCK:
10562 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
10563 +                       break;
10564 +               case RLIMIT_AS:
10565 +                       res_add += GR_RLIM_AS_BUMP;
10566 +                       break;
10567 +               case RLIMIT_LOCKS:
10568 +                       res_add += GR_RLIM_LOCKS_BUMP;
10569 +                       break;
10570 +               }
10571 +
10572 +               acl->res[res].rlim_cur = res_add;
10573 +
10574 +               if (wanted > acl->res[res].rlim_max)
10575 +                       acl->res[res].rlim_max = res_add;
10576 +
10577 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10578 +                              current->role->roletype, acl->filename,
10579 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
10580 +                              "", (unsigned long) res);
10581 +       }
10582 +
10583 +       return;
10584 +}
10585 +
10586 +#ifdef CONFIG_SYSCTL
10587 +extern struct proc_dir_entry *proc_sys_root;
10588 +
10589 +__u32
10590 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
10591 +                const void *newval)
10592 +{
10593 +       struct proc_dir_entry *tmp;
10594 +       struct nameidata nd;
10595 +       const char *proc_sys = "/proc/sys";
10596 +       char *path = gr_shared_page[0][smp_processor_id()];
10597 +       struct acl_object_label *obj;
10598 +       unsigned short len = 0, pos = 0, depth = 0, i;
10599 +       __u32 err = 0;
10600 +       __u32 mode = 0;
10601 +
10602 +       if (unlikely(!(gr_status & GR_READY)))
10603 +               return 1;
10604 +
10605 +       if (oldval)
10606 +               mode |= GR_READ;
10607 +       if (newval)
10608 +               mode |= GR_WRITE;
10609 +
10610 +       /* convert the requested sysctl entry into a pathname */
10611 +
10612 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
10613 +               len += strlen(tmp->name);
10614 +               len++;
10615 +               depth++;
10616 +       }
10617 +
10618 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
10619 +               return 0;       // deny
10620 +
10621 +       memset(path, 0, PAGE_SIZE);
10622 +
10623 +       memcpy(path, proc_sys, strlen(proc_sys));
10624 +
10625 +       pos += strlen(proc_sys);
10626 +
10627 +       for (; depth > 0; depth--) {
10628 +               path[pos] = '/';
10629 +               pos++;
10630 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
10631 +                    tmp = tmp->parent) {
10632 +                       if (depth == i) {
10633 +                               memcpy(path + pos, tmp->name,
10634 +                                      strlen(tmp->name));
10635 +                               pos += strlen(tmp->name);
10636 +                       }
10637 +                       i++;
10638 +               }
10639 +       }
10640 +
10641 +       if (path_init(path, LOOKUP_FOLLOW, &nd))
10642 +               err = path_walk(path, &nd);
10643 +
10644 +       if (err)
10645 +               goto out;
10646 +
10647 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
10648 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
10649 +
10650 +       if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
10651 +               __u32 new_mode = mode;
10652 +
10653 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10654 +
10655 +               err = new_mode;
10656 +               gr_log_learn(current->role, current->uid, current->gid,
10657 +                            current, path, new_mode);
10658 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
10659 +               security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
10660 +                              (mode & GR_READ) ? " reading" : "",
10661 +                              (mode & GR_WRITE) ? " writing" : "",
10662 +                              DEFAULTSECARGS);
10663 +               err = 0;
10664 +       } else if ((err & mode) != mode) {
10665 +               err = 0;
10666 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
10667 +               security_audit(GR_SYSCTL_ACL_MSG, "successful",
10668 +                              path, (mode & GR_READ) ? " reading" : "",
10669 +                              (mode & GR_WRITE) ? " writing" : "",
10670 +                              DEFAULTSECARGS);
10671 +       }
10672 +
10673 +       path_release(&nd);
10674 +
10675 +      out:
10676 +       return err;
10677 +}
10678 +#endif
10679 +
10680 +int
10681 +gr_handle_ptrace(struct task_struct *task, const long request)
10682 +{
10683 +       struct file *filp;
10684 +       __u32 retmode;
10685 +
10686 +       if (unlikely(!(gr_status & GR_READY)))
10687 +               return 0;
10688 +
10689 +       filp = task->exec_file;
10690 +
10691 +       if (unlikely(!filp))
10692 +               return 0;
10693 +
10694 +       retmode = gr_search_file(filp->f_dentry, GR_PTRACERD, filp->f_vfsmnt);
10695 +
10696 +       if (retmode & GR_PTRACERD) {
10697 +               switch (request) {
10698 +               case PTRACE_POKETEXT:
10699 +               case PTRACE_POKEDATA:
10700 +               case PTRACE_POKEUSR:
10701 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
10702 +               case PTRACE_SETREGS:
10703 +               case PTRACE_SETFPREGS:
10704 +#endif
10705 +#ifdef CONFIG_X86
10706 +               case PTRACE_SETFPXREGS:
10707 +#endif
10708 +#ifdef CONFIG_ALTIVEC
10709 +               case PTRACE_SETVRREGS:
10710 +#endif
10711 +                       return 1;
10712 +               default:
10713 +                       return 0;
10714 +               }
10715 +       } else if (!(current->acl->mode & GR_OVERRIDE) &&
10716 +                  !(current->role->roletype & GR_ROLE_GOD)
10717 +                  && (current->acl != task->acl
10718 +                      || (current->acl != current->role->root_label
10719 +                          && current->pid != task->pid))) {
10720 +               security_alert(GR_PTRACE_ACL_MSG,
10721 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10722 +                              task->comm, task->pid, DEFAULTSECARGS);
10723 +               return 1;
10724 +       }
10725 +
10726 +       return 0;
10727 +}
10728 +
10729 +int
10730 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
10731 +{
10732 +       __u32 retmode;
10733 +       struct acl_subject_label *subj;
10734 +
10735 +       if (unlikely(!(gr_status & GR_READY)))
10736 +               return 0;
10737 +
10738 +       if (unlikely
10739 +           ((current->ptrace & PT_PTRACED)
10740 +            && !(current->acl->mode & GR_OVERRIDE)))
10741 +               retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
10742 +       else
10743 +               return 0;
10744 +
10745 +       subj = chk_subj_label(dentry, mnt, current->role);
10746 +
10747 +       if (!(retmode & GR_PTRACERD) &&
10748 +           !(current->role->roletype & GR_ROLE_GOD) &&
10749 +           (current->acl != subj)) {
10750 +               security_alert(GR_PTRACE_EXEC_ACL_MSG,
10751 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
10752 +               return 1;
10753 +       }
10754 +
10755 +       return 0;
10756 +}
10757 +
10758 +int
10759 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
10760 +{
10761 +       struct acl_object_label *obj, *obj2;
10762 +
10763 +       if (unlikely(!(gr_status & GR_READY) ||
10764 +                    (current->acl->mode & GR_OVERRIDE) || !filp ||
10765 +                    !(prot & PROT_EXEC)))
10766 +               return 0;
10767 +
10768 +       if (unlikely(current->is_writable))
10769 +               return 0;
10770 +
10771 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10772 +       obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
10773 +                            current->role->root_label);
10774 +       if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
10775 +               security_alert(GR_WRITLIB_ACL_MSG,
10776 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10777 +                              DEFAULTSECARGS);
10778 +               return 1;
10779 +       }
10780 +
10781 +       return 0;
10782 +}
10783 +
10784 +int
10785 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
10786 +{
10787 +       __u32 mode;
10788 +
10789 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10790 +               return 1;
10791 +
10792 +       mode =
10793 +           gr_search_file(file->f_dentry,
10794 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10795 +                          file->f_vfsmnt);
10796 +
10797 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10798 +               security_alert(GR_MMAP_ACL_MSG, "denied",
10799 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10800 +                              DEFAULTSECARGS);
10801 +               return 0;
10802 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10803 +               return 0;
10804 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10805 +               security_audit(GR_MMAP_ACL_MSG, "successful",
10806 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10807 +                              DEFAULTSECARGS);
10808 +               return 1;
10809 +       }
10810 +
10811 +       return 1;
10812 +}
10813 +
10814 +int
10815 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
10816 +{
10817 +       __u32 mode;
10818 +
10819 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10820 +               return 1;
10821 +
10822 +       mode =
10823 +           gr_search_file(file->f_dentry,
10824 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10825 +                          file->f_vfsmnt);
10826 +
10827 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10828 +               security_alert(GR_MPROTECT_ACL_MSG, "denied",
10829 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10830 +                              DEFAULTSECARGS);
10831 +               return 0;
10832 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10833 +               return 0;
10834 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10835 +               security_audit(GR_MPROTECT_ACL_MSG, "successful",
10836 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10837 +                              DEFAULTSECARGS);
10838 +               return 1;
10839 +       }
10840 +
10841 +       return 1;
10842 +}
10843 +
10844 +void
10845 +gr_acl_handle_psacct(struct task_struct *task, const long code)
10846 +{
10847 +       unsigned long runtime;
10848 +       unsigned long cputime;
10849 +       unsigned int wday, cday;
10850 +       __u8 whr, chr;
10851 +       __u8 wmin, cmin;
10852 +       __u8 wsec, csec;
10853 +       char cur_tty[64] = { 0 };
10854 +       char parent_tty[64] = { 0 };
10855 +
10856 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
10857 +                    !(task->acl->mode & GR_PROCACCT)))
10858 +               return;
10859 +
10860 +       runtime = (jiffies - task->start_time) / HZ;
10861 +       wday = runtime / (3600 * 24);
10862 +       runtime -= wday * (3600 * 24);
10863 +       whr = runtime / 3600;
10864 +       runtime -= whr * 3600;
10865 +       wmin = runtime / 60;
10866 +       runtime -= wmin * 60;
10867 +       wsec = runtime;
10868 +
10869 +       cputime = (task->times.tms_utime + task->times.tms_stime) / HZ;
10870 +       cday = cputime / (3600 * 24);
10871 +       cputime -= cday * (3600 * 24);
10872 +       chr = cputime / 3600;
10873 +       cputime -= chr * 3600;
10874 +       cmin = cputime / 60;
10875 +       cputime -= cmin * 60;
10876 +       csec = cputime;
10877 +
10878 +       security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
10879 +                      task->pid, NIPQUAD(task->curr_ip), tty_name(task->tty,
10880 +                                                                  cur_tty),
10881 +                      task->uid, task->euid, task->gid, task->egid, wday, whr,
10882 +                      wmin, wsec, cday, chr, cmin, csec,
10883 +                      (task->
10884 +                       flags & PF_SIGNALED) ? "killed by signal" : "exited",
10885 +                      code, gr_parent_task_fullpath(task), 
10886 +                      task->p_pptr->comm, task->p_pptr->pid,
10887 +                      NIPQUAD(task->p_pptr->curr_ip),
10888 +                      tty_name(task->p_pptr->tty, parent_tty),
10889 +                      task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid,
10890 +                      task->p_pptr->egid);
10891 +
10892 +       return;
10893 +}
10894 +
10895 +void gr_set_kernel_label(struct task_struct *task)
10896 +{
10897 +       if (gr_status & GR_READY) {
10898 +               task->role = kernel_role;
10899 +               task->acl = kernel_role->root_label;
10900 +       }
10901 +       return;
10902 +}
10903 diff -urN linux-2.4.24.org/grsecurity/gracl_cap.c linux-2.4.24/grsecurity/gracl_cap.c
10904 --- linux-2.4.24.org/grsecurity/gracl_cap.c     1970-01-01 01:00:00.000000000 +0100
10905 +++ linux-2.4.24/grsecurity/gracl_cap.c 2004-02-04 23:11:33.392802838 +0100
10906 @@ -0,0 +1,71 @@
10907 +/* capability handling routines, (c) Brad Spengler 2002,2003 */
10908 +
10909 +#include <linux/kernel.h>
10910 +#include <linux/sched.h>
10911 +#include <linux/capability.h>
10912 +#include <linux/gracl.h>
10913 +#include <linux/grsecurity.h>
10914 +#include <linux/grinternal.h>
10915 +
10916 +static const char *captab_log[29] = {
10917 +       "CAP_CHOWN",
10918 +       "CAP_DAC_OVERRIDE",
10919 +       "CAP_DAC_READ_SEARCH",
10920 +       "CAP_FOWNER",
10921 +       "CAP_FSETID",
10922 +       "CAP_KILL",
10923 +       "CAP_SETGID",
10924 +       "CAP_SETUID",
10925 +       "CAP_SETPCAP",
10926 +       "CAP_LINUX_IMMUTABLE",
10927 +       "CAP_NET_BIND_SERVICE",
10928 +       "CAP_NET_BROADCAST",
10929 +       "CAP_NET_ADMIN",
10930 +       "CAP_NET_RAW",
10931 +       "CAP_IPC_LOCK",
10932 +       "CAP_IPC_OWNER",
10933 +       "CAP_SYS_MODULE",
10934 +       "CAP_SYS_RAWIO",
10935 +       "CAP_SYS_CHROOT",
10936 +       "CAP_SYS_PTRACE",
10937 +       "CAP_SYS_PACCT",
10938 +       "CAP_SYS_ADMIN",
10939 +       "CAP_SYS_BOOT",
10940 +       "CAP_SYS_NICE",
10941 +       "CAP_SYS_RESOURCE",
10942 +       "CAP_SYS_TIME",
10943 +       "CAP_SYS_TTY_CONFIG",
10944 +       "CAP_MKNOD",
10945 +       "CAP_LEASE"
10946 +};
10947 +
10948 +int
10949 +gr_is_capable(const int cap)
10950 +{
10951 +       struct acl_subject_label *curracl;
10952 +
10953 +       if (!gr_acl_is_enabled())
10954 +               return 1;
10955 +
10956 +       curracl = current->acl;
10957 +
10958 +       if (!cap_raised(curracl->cap_lower, cap))
10959 +               return 1;
10960 +
10961 +       if ((curracl->mode & GR_LEARN)
10962 +           && cap_raised(current->cap_effective, cap)) {
10963 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10964 +                              current->role->roletype, current->uid,
10965 +                              current->gid, current->exec_file ?
10966 +                              gr_to_filename(current->exec_file->f_dentry,
10967 +                              current->exec_file->f_vfsmnt) : curracl->filename,
10968 +                              curracl->filename, 0UL,
10969 +                              0UL, "", (unsigned long) cap, NIPQUAD(current->curr_ip));
10970 +               return 1;
10971 +       }
10972 +
10973 +       if ((cap >= 0) && (cap < 29) && cap_raised(current->cap_effective, cap))
10974 +               security_alert(GR_CAP_ACL_MSG, captab_log[cap], DEFAULTSECARGS);
10975 +
10976 +       return 0;
10977 +}
10978 diff -urN linux-2.4.24.org/grsecurity/gracl_fs.c linux-2.4.24/grsecurity/gracl_fs.c
10979 --- linux-2.4.24.org/grsecurity/gracl_fs.c      1970-01-01 01:00:00.000000000 +0100
10980 +++ linux-2.4.24/grsecurity/gracl_fs.c  2004-02-04 23:11:33.397801798 +0100
10981 @@ -0,0 +1,469 @@
10982 +#include <linux/kernel.h>
10983 +#include <linux/sched.h>
10984 +#include <linux/types.h>
10985 +#include <linux/fs.h>
10986 +#include <linux/file.h>
10987 +#include <linux/grsecurity.h>
10988 +#include <linux/grinternal.h>
10989 +#include <linux/gracl.h>
10990 +
10991 +__u32
10992 +gr_acl_handle_hidden_file(const struct dentry * dentry,
10993 +                         const struct vfsmount * mnt)
10994 +{
10995 +       __u32 mode;
10996 +
10997 +       if (unlikely(!dentry->d_inode))
10998 +               return GR_FIND;
10999 +
11000 +       mode =
11001 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
11002 +
11003 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
11004 +               security_audit(GR_HIDDEN_ACL_MSG, "successful",
11005 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
11006 +               return mode;
11007 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
11008 +               security_alert(GR_HIDDEN_ACL_MSG, "denied",
11009 +                              gr_to_filename(dentry, mnt),
11010 +                              DEFAULTSECARGS);
11011 +               return 0;
11012 +       } else if (unlikely(!(mode & GR_FIND)))
11013 +               return 0;
11014 +
11015 +       return GR_FIND;
11016 +}
11017 +
11018 +__u32
11019 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
11020 +                  const int fmode)
11021 +{
11022 +       __u32 reqmode = GR_FIND;
11023 +       __u32 mode;
11024 +
11025 +       if (unlikely(!dentry->d_inode))
11026 +               return reqmode;
11027 +
11028 +       if (unlikely(fmode & O_APPEND))
11029 +               reqmode |= GR_APPEND;
11030 +       else if (unlikely(fmode & FMODE_WRITE))
11031 +               reqmode |= GR_WRITE;
11032 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
11033 +               reqmode |= GR_READ;
11034 +
11035 +       mode =
11036 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
11037 +                          mnt);
11038 +
11039 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11040 +               security_audit(GR_OPEN_ACL_MSG, "successful",
11041 +                              gr_to_filename(dentry, mnt),
11042 +                              reqmode & GR_READ ? " reading" : "",
11043 +                              reqmode & GR_WRITE ? " writing" :
11044 +                              reqmode & GR_APPEND ? " appending" : "",
11045 +                              DEFAULTSECARGS);
11046 +               return reqmode;
11047 +       } else
11048 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11049 +       {
11050 +               security_alert(GR_OPEN_ACL_MSG, "denied",
11051 +                              gr_to_filename(dentry, mnt),
11052 +                              reqmode & GR_READ ? " reading" : "",
11053 +                              reqmode & GR_WRITE ? " writing" : reqmode &
11054 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
11055 +               return 0;
11056 +       } else if (unlikely((mode & reqmode) != reqmode))
11057 +               return 0;
11058 +
11059 +       return reqmode;
11060 +}
11061 +
11062 +__u32
11063 +gr_acl_handle_creat(const struct dentry * dentry,
11064 +                   const struct dentry * p_dentry,
11065 +                   const struct vfsmount * p_mnt, const int fmode,
11066 +                   const int imode)
11067 +{
11068 +       __u32 reqmode = GR_WRITE | GR_CREATE;
11069 +       __u32 mode;
11070 +
11071 +       if (unlikely(fmode & O_APPEND))
11072 +               reqmode |= GR_APPEND;
11073 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
11074 +               reqmode |= GR_READ;
11075 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
11076 +               reqmode |= GR_SETID;
11077 +
11078 +       mode =
11079 +           gr_check_create(dentry, p_dentry, p_mnt,
11080 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
11081 +
11082 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11083 +               security_audit(GR_CREATE_ACL_MSG, "successful",
11084 +                              gr_to_filename(dentry, p_mnt),
11085 +                              reqmode & GR_READ ? " reading" : "",
11086 +                              reqmode & GR_WRITE ? " writing" :
11087 +                              reqmode & GR_APPEND ? " appending" : "",
11088 +                              DEFAULTSECARGS);
11089 +               return reqmode;
11090 +       } else
11091 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11092 +       {
11093 +               security_alert(GR_CREATE_ACL_MSG, "denied",
11094 +                              gr_to_filename(dentry, p_mnt),
11095 +                              reqmode & GR_READ ? " reading" : "",
11096 +                              reqmode & GR_WRITE ? " writing" : reqmode &
11097 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
11098 +               return 0;
11099 +       } else if (unlikely((mode & reqmode) != reqmode))
11100 +               return 0;
11101 +
11102 +       return reqmode;
11103 +}
11104 +
11105 +__u32
11106 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
11107 +                    const int fmode)
11108 +{
11109 +       __u32 mode, reqmode = GR_FIND;
11110 +
11111 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
11112 +               reqmode |= GR_EXEC;
11113 +       if (fmode & S_IWOTH)
11114 +               reqmode |= GR_WRITE;
11115 +       if (fmode & S_IROTH)
11116 +               reqmode |= GR_READ;
11117 +
11118 +       mode =
11119 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
11120 +                          mnt);
11121 +
11122 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11123 +               security_audit(GR_ACCESS_ACL_MSG, "successful",
11124 +                              gr_to_filename(dentry, mnt),
11125 +                              reqmode & GR_READ ? " reading" : "",
11126 +                              reqmode & GR_WRITE ? " writing" : "",
11127 +                              reqmode & GR_EXEC ? " executing" : "",
11128 +                              DEFAULTSECARGS);
11129 +               return reqmode;
11130 +       } else
11131 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11132 +       {
11133 +               security_alert(GR_ACCESS_ACL_MSG, "denied",
11134 +                              gr_to_filename(dentry, mnt),
11135 +                              reqmode & GR_READ ? " reading" : "",
11136 +                              reqmode & GR_WRITE ? " writing" : "",
11137 +                              reqmode & GR_EXEC ? " executing" : "",
11138 +                              DEFAULTSECARGS);
11139 +               return 0;
11140 +       } else if (unlikely((mode & reqmode) != reqmode))
11141 +               return 0;
11142 +
11143 +       return reqmode;
11144 +}
11145 +
11146 +#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
11147 +{ \
11148 +       __u32 mode; \
11149 +       \
11150 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
11151 +       \
11152 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
11153 +               security_audit(fmt, "successful", \
11154 +                               gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
11155 +               return mode; \
11156 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
11157 +               security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
11158 +                               DEFAULTSECARGS); \
11159 +               return 0; \
11160 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
11161 +               return 0; \
11162 +       \
11163 +       return (reqmode); \
11164 +}
11165 +
11166 +__u32
11167 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
11168 +{
11169 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
11170 +}
11171 +
11172 +__u32
11173 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
11174 +{
11175 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
11176 +}
11177 +
11178 +__u32
11179 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
11180 +{
11181 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
11182 +}
11183 +
11184 +__u32
11185 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
11186 +{
11187 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
11188 +}
11189 +
11190 +__u32
11191 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
11192 +                    mode_t mode)
11193 +{
11194 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
11195 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
11196 +                                  GR_FCHMOD_ACL_MSG);
11197 +       } else {
11198 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
11199 +       }
11200 +}
11201 +
11202 +__u32
11203 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
11204 +                   mode_t mode)
11205 +{
11206 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
11207 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
11208 +                                  GR_CHMOD_ACL_MSG);
11209 +       } else {
11210 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
11211 +       }
11212 +}
11213 +
11214 +__u32
11215 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
11216 +{
11217 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
11218 +}
11219 +
11220 +__u32
11221 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
11222 +{
11223 +       generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
11224 +}
11225 +
11226 +__u32
11227 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
11228 +{
11229 +       generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
11230 +                          GR_UNIXCONNECT_ACL_MSG);
11231 +}
11232 +
11233 +__u32
11234 +gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
11235 +                     const ino_t ino)
11236 +{
11237 +       if (likely((unsigned long)(dentry->d_inode))) {
11238 +               struct dentry d = *dentry;
11239 +               struct inode inode = *(dentry->d_inode);
11240 +
11241 +               inode.i_ino = ino;
11242 +               d.d_inode = &inode;
11243 +
11244 +               if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
11245 +                       return 0;
11246 +       }
11247 +
11248 +       return 1;
11249 +}
11250 +
11251 +__u32
11252 +gr_acl_handle_link(const struct dentry * new_dentry,
11253 +                  const struct dentry * parent_dentry,
11254 +                  const struct vfsmount * parent_mnt,
11255 +                  const struct dentry * old_dentry,
11256 +                  const struct vfsmount * old_mnt, const char *to)
11257 +{
11258 +       __u32 needmode = GR_WRITE | GR_CREATE;
11259 +       __u32 mode;
11260 +
11261 +       mode =
11262 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
11263 +                         old_mnt);
11264 +
11265 +       if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
11266 +               security_audit(GR_LINK_ACL_MSG, "successful",
11267 +                              gr_to_filename(old_dentry, old_mnt), to,
11268 +                              DEFAULTSECARGS);
11269 +               return mode;
11270 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
11271 +               security_alert(GR_LINK_ACL_MSG, "denied",
11272 +                              gr_to_filename(old_dentry, old_mnt), to,
11273 +                              DEFAULTSECARGS);
11274 +               return 0;
11275 +       } else if (unlikely((mode & needmode) != needmode))
11276 +               return 0;
11277 +
11278 +       return (GR_WRITE | GR_CREATE);
11279 +}
11280 +
11281 +__u32
11282 +gr_acl_handle_symlink(const struct dentry * new_dentry,
11283 +                     const struct dentry * parent_dentry,
11284 +                     const struct vfsmount * parent_mnt, const char *from)
11285 +{
11286 +       __u32 needmode = GR_WRITE | GR_CREATE;
11287 +       __u32 mode;
11288 +
11289 +       mode =
11290 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
11291 +                           GR_CREATE | GR_AUDIT_CREATE |
11292 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
11293 +
11294 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
11295 +               security_audit(GR_SYMLINK_ACL_MSG, "successful",
11296 +                              from, gr_to_filename(new_dentry, parent_mnt),
11297 +                              DEFAULTSECARGS);
11298 +               return mode;
11299 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
11300 +               security_alert(GR_SYMLINK_ACL_MSG, "denied",
11301 +                              from, gr_to_filename(new_dentry, parent_mnt),
11302 +                              DEFAULTSECARGS);
11303 +               return 0;
11304 +       } else if (unlikely((mode & needmode) != needmode))
11305 +               return 0;
11306 +
11307 +       return (GR_WRITE | GR_CREATE);
11308 +}
11309 +
11310 +#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
11311 +{ \
11312 +       __u32 mode; \
11313 +       \
11314 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
11315 +       \
11316 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
11317 +               security_audit(fmt, "successful", \
11318 +                               gr_to_filename(new_dentry, parent_mnt), \
11319 +                               DEFAULTSECARGS); \
11320 +               return mode; \
11321 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
11322 +               security_alert(fmt, "denied", \
11323 +                               gr_to_filename(new_dentry, parent_mnt), \
11324 +                               DEFAULTSECARGS); \
11325 +               return 0; \
11326 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
11327 +               return 0; \
11328 +       \
11329 +       return (reqmode); \
11330 +}
11331 +
11332 +__u32
11333 +gr_acl_handle_mknod(const struct dentry * new_dentry,
11334 +                   const struct dentry * parent_dentry,
11335 +                   const struct vfsmount * parent_mnt,
11336 +                   const int mode)
11337 +{
11338 +       __u32 reqmode = GR_WRITE | GR_CREATE;
11339 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
11340 +               reqmode |= GR_SETID;
11341 +
11342 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
11343 +                                 reqmode, GR_MKNOD_ACL_MSG);
11344 +}
11345 +
11346 +__u32
11347 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
11348 +                   const struct dentry *parent_dentry,
11349 +                   const struct vfsmount *parent_mnt)
11350 +{
11351 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
11352 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
11353 +}
11354 +
11355 +#define RENAME_CHECK_SUCCESS(old, new) \
11356 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
11357 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
11358 +
11359 +int
11360 +gr_acl_handle_rename(struct dentry *new_dentry,
11361 +                    struct dentry *parent_dentry,
11362 +                    const struct vfsmount *parent_mnt,
11363 +                    struct dentry *old_dentry,
11364 +                    struct inode *old_parent_inode,
11365 +                    struct vfsmount *old_mnt, const char *newname)
11366 +{
11367 +       __u8 gr_replace = 1;
11368 +       __u32 comp1, comp2;
11369 +       int error = 0;
11370 +
11371 +       if (unlikely(!gr_acl_is_enabled()))
11372 +               return 1;
11373 +
11374 +       if (!new_dentry->d_inode) {
11375 +               gr_replace = 0;
11376 +
11377 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
11378 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
11379 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
11380 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
11381 +                                      GR_DELETE | GR_AUDIT_DELETE |
11382 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
11383 +                                      GR_SUPPRESS, old_mnt);
11384 +       } else {
11385 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
11386 +                                      GR_CREATE | GR_DELETE |
11387 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
11388 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
11389 +                                      GR_SUPPRESS, parent_mnt);
11390 +               comp2 =
11391 +                   gr_search_file(old_dentry,
11392 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
11393 +                                  GR_DELETE | GR_AUDIT_DELETE |
11394 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
11395 +       }
11396 +
11397 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
11398 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
11399 +               security_audit(GR_RENAME_ACL_MSG, "successful",
11400 +                              gr_to_filename(old_dentry, old_mnt),
11401 +                              newname, DEFAULTSECARGS);
11402 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
11403 +                && !(comp2 & GR_SUPPRESS)) {
11404 +               security_alert(GR_RENAME_ACL_MSG, "denied",
11405 +                              gr_to_filename(old_dentry, old_mnt), newname,
11406 +                              DEFAULTSECARGS);
11407 +               error = -EACCES;
11408 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
11409 +               error = -EACCES;
11410 +
11411 +       if (error)
11412 +               return error;
11413 +
11414 +       error = gr_handle_rename(old_parent_inode, parent_dentry->d_inode,
11415 +                                old_dentry, new_dentry, old_mnt, gr_replace);
11416 +
11417 +       return error;
11418 +}
11419 +
11420 +void
11421 +gr_acl_handle_exit(void)
11422 +{
11423 +       u16 id;
11424 +       char *rolename;
11425 +
11426 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
11427 +               id = current->acl_role_id;
11428 +               rolename = current->role->rolename;
11429 +               gr_set_acls(1);
11430 +               security_alert_good(GR_SPROLEL_ACL_MSG,
11431 +                                   rolename, id, DEFAULTSECARGS);
11432 +       }
11433 +
11434 +       if (current->exec_file) {
11435 +               fput(current->exec_file);
11436 +               current->exec_file = NULL;
11437 +       }
11438 +}
11439 +
11440 +int
11441 +gr_acl_handle_procpidmem(const struct task_struct *task)
11442 +{
11443 +       if (unlikely(!gr_acl_is_enabled()))
11444 +               return 0;
11445 +
11446 +       if (task->acl->mode & GR_PROTPROCFD)
11447 +               return -EACCES;
11448 +
11449 +       return 0;
11450 +}
11451 diff -urN linux-2.4.24.org/grsecurity/gracl_ip.c linux-2.4.24/grsecurity/gracl_ip.c
11452 --- linux-2.4.24.org/grsecurity/gracl_ip.c      1970-01-01 01:00:00.000000000 +0100
11453 +++ linux-2.4.24/grsecurity/gracl_ip.c  2004-02-04 23:11:33.400801175 +0100
11454 @@ -0,0 +1,235 @@
11455 +/* 
11456 + * grsecurity/gracl_ip.c
11457 + * Copyright Brad Spengler 2002, 2003
11458 + *
11459 + */
11460 +
11461 +#include <linux/kernel.h>
11462 +#include <asm/uaccess.h>
11463 +#include <asm/errno.h>
11464 +#include <net/sock.h>
11465 +#include <linux/file.h>
11466 +#include <linux/fs.h>
11467 +#include <linux/net.h>
11468 +#include <linux/in.h>
11469 +#include <linux/skbuff.h>
11470 +#include <linux/ip.h>
11471 +#include <linux/udp.h>
11472 +#include <linux/smp_lock.h>
11473 +#include <linux/types.h>
11474 +#include <linux/sched.h>
11475 +#include <linux/gracl.h>
11476 +#include <linux/grsecurity.h>
11477 +#include <linux/grinternal.h>
11478 +
11479 +#define GR_BIND        0x01
11480 +#define GR_CONNECT     0x02
11481 +
11482 +static const char * gr_protocols[256] = {
11483 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
11484 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
11485 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
11486 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
11487 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
11488 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
11489 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
11490 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
11491 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
11492 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
11493 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
11494 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
11495 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
11496 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
11497 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
11498 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
11499 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
11500 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
11501 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
11502 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
11503 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
11504 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
11505 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
11506 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
11507 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
11508 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
11509 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
11510 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
11511 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
11512 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
11513 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
11514 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
11515 +       };
11516 +
11517 +static const char * gr_socktypes[11] = {
11518 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
11519 +       "unknown:7", "unknown:8", "unknown:9", "packet"
11520 +       };
11521 +
11522 +__inline__ const char *
11523 +gr_proto_to_name(unsigned char proto)
11524 +{
11525 +       return gr_protocols[proto];
11526 +}
11527 +
11528 +__inline__ const char *
11529 +gr_socktype_to_name(unsigned char type)
11530 +{
11531 +       return gr_socktypes[type];
11532 +}
11533 +
11534 +int
11535 +gr_search_socket(const int domain, const int type, const int protocol)
11536 +{
11537 +       struct acl_subject_label *curr;
11538 +
11539 +       if (unlikely(!gr_acl_is_enabled()))
11540 +               goto exit;
11541 +
11542 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
11543 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
11544 +               goto exit;      // let the kernel handle it
11545 +
11546 +       curr = current->acl;
11547 +
11548 +       if (!curr->ips)
11549 +               goto exit;
11550 +
11551 +       if ((curr->ip_type & (1 << type)) &&
11552 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
11553 +               goto exit;
11554 +
11555 +       if (curr->mode & GR_LEARN) {
11556 +               /* we don't place acls on raw sockets , and sometimes
11557 +                  dgram/ip sockets are opened for ioctl and not
11558 +                  bind/connect, so we'll fake a bind learn log */
11559 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
11560 +                       __u32 fakeip = 0;
11561 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11562 +                                      current->role->roletype, current->uid,
11563 +                                      current->gid, current->exec_file ?
11564 +                                      gr_to_filename(current->exec_file->f_dentry,
11565 +                                      current->exec_file->f_vfsmnt) :
11566 +                                      curr->filename, curr->filename,
11567 +                                      NIPQUAD(fakeip), 0, type,
11568 +                                      protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
11569 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
11570 +                       __u32 fakeip = 0;
11571 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11572 +                                      current->role->roletype, current->uid,
11573 +                                      current->gid, current->exec_file ?
11574 +                                      gr_to_filename(current->exec_file->f_dentry,
11575 +                                      current->exec_file->f_vfsmnt) :
11576 +                                      curr->filename, curr->filename,
11577 +                                      NIPQUAD(fakeip), 0, type,
11578 +                                      protocol, GR_BIND, NIPQUAD(current->curr_ip));
11579 +               }
11580 +               /* we'll log when they use connect or bind */
11581 +               goto exit;
11582 +       }
11583 +
11584 +       security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
11585 +                      gr_proto_to_name(protocol), DEFAULTSECARGS);
11586 +
11587 +       return 0;
11588 +      exit:
11589 +       return 1;
11590 +}
11591 +
11592 +static __inline__ int
11593 +gr_search_connectbind(const int mode, const struct sock *sk,
11594 +                     const struct sockaddr_in *addr, const int type)
11595 +{
11596 +       struct acl_subject_label *curr;
11597 +       struct acl_ip_label *ip;
11598 +       unsigned long i;
11599 +       __u32 ip_addr = 0;
11600 +       __u16 ip_port = 0;
11601 +
11602 +       if (unlikely(!gr_acl_is_enabled() || sk->family != PF_INET))
11603 +               return 1;
11604 +
11605 +       curr = current->acl;
11606 +
11607 +       if (!curr->ips)
11608 +               return 1;
11609 +
11610 +       ip_addr = addr->sin_addr.s_addr;
11611 +       ip_port = ntohs(addr->sin_port);
11612 +
11613 +       for (i = 0; i < curr->ip_num; i++) {
11614 +               ip = *(curr->ips + i);
11615 +               if ((ip->mode & mode) &&
11616 +                   (ip_port >= ip->low) &&
11617 +                   (ip_port <= ip->high) &&
11618 +                   ((ntohl(ip_addr) & ip->netmask) ==
11619 +                    (ntohl(ip->addr) & ip->netmask))
11620 +                   && (ip->
11621 +                       proto[sk->protocol / 32] & (1 << (sk->protocol % 32)))
11622 +                   && (ip->type & (1 << type)))
11623 +                       return 1;
11624 +       }
11625 +
11626 +       if (curr->mode & GR_LEARN) {
11627 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11628 +                              current->role->roletype, current->uid,
11629 +                              current->gid, current->exec_file ?
11630 +                              gr_to_filename(current->exec_file->f_dentry,
11631 +                              current->exec_file->f_vfsmnt) :
11632 +                              curr->filename, curr->filename,
11633 +                              NIPQUAD(ip_addr), ip_port, type,
11634 +                              sk->protocol, mode, NIPQUAD(current->curr_ip));
11635 +               return 1;
11636 +       }
11637 +
11638 +       if (mode == GR_BIND)
11639 +               security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11640 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11641 +                              DEFAULTSECARGS);
11642 +       else if (mode == GR_CONNECT)
11643 +               security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11644 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11645 +                              DEFAULTSECARGS);
11646 +
11647 +       return 0;
11648 +}
11649 +
11650 +int
11651 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
11652 +{
11653 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
11654 +}
11655 +
11656 +int
11657 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
11658 +{
11659 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
11660 +}
11661 +
11662 +int
11663 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
11664 +{
11665 +       if (addr)
11666 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
11667 +       else {
11668 +               struct sockaddr_in sin;
11669 +
11670 +               sin.sin_addr.s_addr = sk->daddr;
11671 +               sin.sin_port = sk->dport;
11672 +
11673 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11674 +       }
11675 +}
11676 +
11677 +int
11678 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
11679 +{
11680 +       struct sockaddr_in sin;
11681 +
11682 +       if (unlikely(skb->len < sizeof (struct udphdr)))
11683 +               return 1;       // skip this packet
11684 +
11685 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
11686 +       sin.sin_port = skb->h.uh->source;
11687 +
11688 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11689 +}
11690 diff -urN linux-2.4.24.org/grsecurity/gracl_learn.c linux-2.4.24/grsecurity/gracl_learn.c
11691 --- linux-2.4.24.org/grsecurity/gracl_learn.c   1970-01-01 01:00:00.000000000 +0100
11692 +++ linux-2.4.24/grsecurity/gracl_learn.c       2004-02-04 23:11:33.402800759 +0100
11693 @@ -0,0 +1,228 @@
11694 +#include <linux/kernel.h>
11695 +#include <linux/mm.h>
11696 +#include <linux/sched.h>
11697 +#include <linux/poll.h>
11698 +#include <linux/smp_lock.h>
11699 +#include <linux/string.h>
11700 +#include <linux/file.h>
11701 +#include <linux/types.h>
11702 +#include <linux/vmalloc.h>
11703 +#include <linux/grinternal.h>
11704 +
11705 +extern ssize_t write_grsec_handler(struct file * file, const char * buf,
11706 +                                  size_t count, loff_t *ppos);
11707 +extern int gr_acl_is_enabled(void);
11708 +
11709 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
11710 +static DECLARE_WAIT_QUEUE_HEAD(input_wait);
11711 +static atomic_t learn_buffer_count = ATOMIC_INIT(0);
11712 +static int gr_learn_attached;
11713 +
11714 +#define LEARN_BUFFER_SLOTS 256
11715 +#define LEARN_BUFFER_SIZE 16384
11716 +
11717 +static spinlock_t learn_buffer_lock[LEARN_BUFFER_SLOTS] = { [0 ... (LEARN_BUFFER_SLOTS - 1)] = SPIN_LOCK_UNLOCKED };
11718 +static char *learn_buffer[LEARN_BUFFER_SLOTS];
11719 +static int learn_buffer_len[LEARN_BUFFER_SLOTS];
11720 +
11721 +static ssize_t
11722 +read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
11723 +{
11724 +       DECLARE_WAITQUEUE(wait, current);
11725 +       ssize_t retval = 0;
11726 +       char *tmp;
11727 +       unsigned int len;
11728 +       int i;
11729 +
11730 +       add_wait_queue(&learn_wait, &wait);
11731 +       set_current_state(TASK_INTERRUPTIBLE);
11732 +       do {
11733 +               if (atomic_read(&learn_buffer_count) > 1)
11734 +                       break;
11735 +
11736 +               if (file->f_flags & O_NONBLOCK) {
11737 +                       retval = -EAGAIN;
11738 +                       goto out;
11739 +               }
11740 +               if (signal_pending(current)) {
11741 +                       retval = -ERESTARTSYS;
11742 +                       goto out;
11743 +               }
11744 +
11745 +               schedule();
11746 +       } while (1);
11747 +
11748 +
11749 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11750 +               spin_lock(&learn_buffer_lock[i]);
11751 +               len = learn_buffer_len[i];
11752 +               tmp = learn_buffer[i];
11753 +               if (!len || !tmp) {
11754 +                       spin_unlock(&learn_buffer_lock[i]);
11755 +                       continue;
11756 +               }
11757 +               learn_buffer[i] = NULL;
11758 +               learn_buffer_len[i] = 0;
11759 +               spin_unlock(&learn_buffer_lock[i]);
11760 +
11761 +               if (count < ((i * LEARN_BUFFER_SIZE) + len)) {
11762 +                       retval = -EINVAL;
11763 +                       vfree(tmp);
11764 +                       goto out;
11765 +               }
11766 +               if (copy_to_user(buf + (i * LEARN_BUFFER_SIZE), tmp, len)) {
11767 +                       retval = -EFAULT;
11768 +                       vfree(tmp);
11769 +                       goto out;
11770 +               }
11771 +
11772 +               retval += len;
11773 +               vfree(tmp);
11774 +               atomic_dec(&learn_buffer_count);
11775 +               atomic_dec(&learn_buffer_count);
11776 +       }
11777 +
11778 +       wake_up(&input_wait);
11779 +out:
11780 +       set_current_state(TASK_RUNNING);
11781 +       remove_wait_queue(&learn_wait, &wait);
11782 +       return retval;
11783 +}
11784 +
11785 +static unsigned int
11786 +poll_learn(struct file * file, poll_table * wait)
11787 +{
11788 +       poll_wait(file, &learn_wait, wait);
11789 +
11790 +       if (atomic_read(&learn_buffer_count) > 1)
11791 +               return (POLLIN | POLLRDNORM);
11792 +
11793 +       return 0;
11794 +}
11795 +
11796 +void
11797 +gr_clear_learn_entries(void)
11798 +{
11799 +       int i;
11800 +
11801 +       atomic_set(&learn_buffer_count, 0);
11802 +       wake_up(&input_wait);
11803 +       
11804 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11805 +               if (learn_buffer_len[i]) {
11806 +                       vfree(learn_buffer[i]);
11807 +                       learn_buffer[i] = NULL;
11808 +                       learn_buffer_len[i] = 0;
11809 +               }
11810 +       }
11811 +
11812 +       return;
11813 +}
11814 +
11815 +void
11816 +gr_add_learn_entry(const char *fmt, ...)
11817 +{
11818 +       DECLARE_WAITQUEUE(wait, current);
11819 +       va_list args;
11820 +       char *tmpbuf;
11821 +       char *buf;
11822 +       int i;
11823 +       unsigned int len;
11824 +
11825 +       if (!gr_learn_attached)
11826 +               return;
11827 +
11828 +       tmpbuf = vmalloc(LEARN_BUFFER_SIZE);
11829 +
11830 +       if (tmpbuf == NULL)
11831 +               return;
11832 +
11833 +       va_start(args, fmt);
11834 +       len = vsnprintf(tmpbuf, LEARN_BUFFER_SIZE, fmt, args);
11835 +       va_end(args);
11836 +
11837 +       if (len < 0)
11838 +               len = LEARN_BUFFER_SIZE - 1;
11839 +
11840 +       buf = vmalloc(len + 1);
11841 +
11842 +       if (buf == NULL) {
11843 +               vfree(tmpbuf);
11844 +               return;
11845 +       }
11846 +
11847 +       memcpy(buf, tmpbuf, len);
11848 +       buf[len] = '\0';
11849 +       vfree(tmpbuf);
11850 +
11851 +       add_wait_queue(&input_wait, &wait);
11852 +
11853 +       atomic_inc(&learn_buffer_count);
11854 +       if (atomic_read(&learn_buffer_count) > ((2 * (LEARN_BUFFER_SLOTS - 1)) + 1)) {
11855 +               /* don't sleep under the BKL */
11856 +//             if (unlikely(current->lock_depth >= 0)) {
11857 +               remove_wait_queue(&input_wait, &wait);
11858 +               atomic_dec(&learn_buffer_count);
11859 +               vfree(buf);
11860 +               return;
11861 +//             }
11862 +//             sleep_on(&input_wait);
11863 +       }
11864 +
11865 +       if (!gr_acl_is_enabled()) {
11866 +               remove_wait_queue(&input_wait, &wait);
11867 +               atomic_dec(&learn_buffer_count);
11868 +               vfree(buf);
11869 +               return;
11870 +       }
11871 +
11872 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11873 +               spin_lock(&learn_buffer_lock[i]);
11874 +
11875 +               if (learn_buffer_len[i]) {
11876 +                       spin_unlock(&learn_buffer_lock[i]);
11877 +                       continue;
11878 +               }
11879 +
11880 +               learn_buffer[i] = buf;
11881 +
11882 +               learn_buffer_len[i] = len + 1;
11883 +
11884 +               atomic_inc(&learn_buffer_count);
11885 +               spin_unlock(&learn_buffer_lock[i]);
11886 +               break;
11887 +       }
11888 +
11889 +       remove_wait_queue(&input_wait, &wait);
11890 +       wake_up_interruptible(&learn_wait);
11891 +
11892 +       return;
11893 +}
11894 +
11895 +static int
11896 +open_learn(struct inode *inode, struct file *file)
11897 +{
11898 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
11899 +               return -EBUSY;
11900 +       else if (file->f_mode & FMODE_READ)
11901 +               gr_learn_attached = 1;
11902 +
11903 +       return 0;
11904 +}
11905 +
11906 +static int
11907 +close_learn(struct inode *inode, struct file *file)
11908 +{
11909 +       if (file->f_mode & FMODE_READ)
11910 +               gr_learn_attached = 0;
11911 +
11912 +       return 0;
11913 +}
11914 +               
11915 +struct file_operations grsec_fops = {
11916 +       read:           read_learn,
11917 +       write:          write_grsec_handler,
11918 +       open:           open_learn,
11919 +       release:        close_learn,
11920 +       poll:           poll_learn,
11921 +};
11922 diff -urN linux-2.4.24.org/grsecurity/gracl_res.c linux-2.4.24/grsecurity/gracl_res.c
11923 --- linux-2.4.24.org/grsecurity/gracl_res.c     1970-01-01 01:00:00.000000000 +0100
11924 +++ linux-2.4.24/grsecurity/gracl_res.c 2004-02-04 23:11:33.406799928 +0100
11925 @@ -0,0 +1,46 @@
11926 +/* resource handling routines (c) Brad Spengler 2002, 2003 */
11927 +
11928 +#include <linux/kernel.h>
11929 +#include <linux/sched.h>
11930 +#include <linux/gracl.h>
11931 +#include <linux/grinternal.h>
11932 +
11933 +static const char *restab_log[11] = {
11934 +       "RLIMIT_CPU",
11935 +       "RLIMIT_FSIZE",
11936 +       "RLIMIT_DATA",
11937 +       "RLIMIT_STACK",
11938 +       "RLIMIT_CORE",
11939 +       "RLIMIT_RSS",
11940 +       "RLIMIT_NPROC",
11941 +       "RLIMIT_NOFILE",
11942 +       "RLIMIT_MEMLOCK",
11943 +       "RLIMIT_AS",
11944 +       "RLIMIT_LOCKS"
11945 +};
11946 +
11947 +__inline__ void
11948 +gr_log_resource(const struct task_struct *task,
11949 +               const int res, const unsigned long wanted, const int gt)
11950 +{
11951 +       if (unlikely(res == RLIMIT_NPROC && 
11952 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
11953 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
11954 +               return;
11955 +
11956 +       if (unlikely(((gt && wanted > task->rlim[res].rlim_cur) ||
11957 +                     (!gt && wanted >= task->rlim[res].rlim_cur)) &&
11958 +                    task->rlim[res].rlim_cur != RLIM_INFINITY))
11959 +               security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
11960 +                              task->rlim[res].rlim_cur,
11961 +                              gr_task_fullpath(task), task->comm,
11962 +                              task->pid, task->uid, task->euid,
11963 +                              task->gid, task->egid,
11964 +                              gr_parent_task_fullpath(task),
11965 +                              task->p_pptr->comm,
11966 +                              task->p_pptr->pid, task->p_pptr->uid, 
11967 +                              task->p_pptr->euid, task->p_pptr->gid,
11968 +                              task->p_pptr->egid);
11969 +
11970 +       return;
11971 +}
11972 diff -urN linux-2.4.24.org/grsecurity/gracl_segv.c linux-2.4.24/grsecurity/gracl_segv.c
11973 --- linux-2.4.24.org/grsecurity/gracl_segv.c    1970-01-01 01:00:00.000000000 +0100
11974 +++ linux-2.4.24/grsecurity/gracl_segv.c        2004-02-04 23:11:33.408799512 +0100
11975 @@ -0,0 +1,327 @@
11976 +/* 
11977 + * grsecurity/gracl_segv.c
11978 + * Copyright Brad Spengler 2002, 2003
11979 + *
11980 + */
11981 +
11982 +#include <linux/kernel.h>
11983 +#include <linux/mm.h>
11984 +#include <asm/uaccess.h>
11985 +#include <asm/errno.h>
11986 +#include <asm/mman.h>
11987 +#include <net/sock.h>
11988 +#include <linux/file.h>
11989 +#include <linux/fs.h>
11990 +#include <linux/net.h>
11991 +#include <linux/in.h>
11992 +#include <linux/smp_lock.h>
11993 +#include <linux/slab.h>
11994 +#include <linux/types.h>
11995 +#include <linux/sched.h>
11996 +#include <linux/timer.h>
11997 +#include <linux/gracl.h>
11998 +#include <linux/grsecurity.h>
11999 +#include <linux/grinternal.h>
12000 +
12001 +static struct crash_uid *uid_set;
12002 +static unsigned short uid_used;
12003 +static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
12004 +extern rwlock_t gr_inode_lock;
12005 +extern __inline__ struct acl_subject_label *lookup_acl_subj_label(const ino_t
12006 +                                                                 inode,
12007 +                                                                 const kdev_t
12008 +                                                                 dev,
12009 +                                                                 struct
12010 +                                                                 acl_role_label
12011 +                                                                 *role);
12012 +
12013 +int
12014 +gr_init_uidset(void)
12015 +{
12016 +       uid_set =
12017 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
12018 +       uid_used = 0;
12019 +
12020 +       return uid_set ? 1 : 0;
12021 +}
12022 +
12023 +void
12024 +gr_free_uidset(void)
12025 +{
12026 +       if (uid_set)
12027 +               kfree(uid_set);
12028 +
12029 +       return;
12030 +}
12031 +
12032 +int
12033 +gr_find_uid(const uid_t uid)
12034 +{
12035 +       struct crash_uid *tmp = uid_set;
12036 +       uid_t buid;
12037 +       int low = 0, high = uid_used - 1, mid;
12038 +
12039 +       while (high >= low) {
12040 +               mid = (low + high) >> 1;
12041 +               buid = tmp[mid].uid;
12042 +               if (buid == uid)
12043 +                       return mid;
12044 +               if (buid > uid)
12045 +                       high = mid - 1;
12046 +               if (buid < uid)
12047 +                       low = mid + 1;
12048 +       }
12049 +
12050 +       return -1;
12051 +}
12052 +
12053 +static __inline__ void
12054 +gr_insertsort(void)
12055 +{
12056 +       unsigned short i, j;
12057 +       struct crash_uid index;
12058 +
12059 +       for (i = 1; i < uid_used; i++) {
12060 +               index = uid_set[i];
12061 +               j = i;
12062 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
12063 +                       uid_set[j] = uid_set[j - 1];
12064 +                       j--;
12065 +               }
12066 +               uid_set[j] = index;
12067 +       }
12068 +
12069 +       return;
12070 +}
12071 +
12072 +static __inline__ void
12073 +gr_insert_uid(const uid_t uid, const unsigned long expires)
12074 +{
12075 +       int loc;
12076 +
12077 +       if (uid_used == GR_UIDTABLE_MAX)
12078 +               return;
12079 +
12080 +       loc = gr_find_uid(uid);
12081 +
12082 +       if (loc >= 0) {
12083 +               uid_set[loc].expires = expires;
12084 +               return;
12085 +       }
12086 +
12087 +       uid_set[uid_used].uid = uid;
12088 +       uid_set[uid_used].expires = expires;
12089 +       uid_used++;
12090 +
12091 +       gr_insertsort();
12092 +
12093 +       return;
12094 +}
12095 +
12096 +void
12097 +gr_remove_uid(const unsigned short loc)
12098 +{
12099 +       unsigned short i;
12100 +
12101 +       for (i = loc + 1; i < uid_used; i++)
12102 +               uid_set[i - i] = uid_set[i];
12103 +
12104 +       uid_used--;
12105 +
12106 +       return;
12107 +}
12108 +
12109 +int
12110 +gr_check_crash_uid(const uid_t uid)
12111 +{
12112 +       int loc;
12113 +
12114 +       if (unlikely(!gr_acl_is_enabled()))
12115 +               return 0;
12116 +
12117 +       read_lock(&gr_uid_lock);
12118 +       loc = gr_find_uid(uid);
12119 +       read_unlock(&gr_uid_lock);
12120 +
12121 +       if (loc < 0)
12122 +               return 0;
12123 +
12124 +       write_lock(&gr_uid_lock);
12125 +       if (time_before_eq(uid_set[loc].expires, jiffies))
12126 +               gr_remove_uid(loc);
12127 +       else {
12128 +               write_unlock(&gr_uid_lock);
12129 +               return 1;
12130 +       }
12131 +
12132 +       write_unlock(&gr_uid_lock);
12133 +       return 0;
12134 +}
12135 +
12136 +static __inline__ int
12137 +proc_is_setxid(const struct task_struct *task)
12138 +{
12139 +       if (task->uid != task->euid || task->uid != task->suid ||
12140 +           task->uid != task->fsuid)
12141 +               return 1;
12142 +       if (task->gid != task->egid || task->gid != task->sgid ||
12143 +           task->gid != task->fsgid)
12144 +               return 1;
12145 +
12146 +       return 0;
12147 +}
12148 +static __inline__ int
12149 +gr_fake_force_sig(int sig, struct task_struct *t)
12150 +{
12151 +       unsigned long int flags;
12152 +
12153 +       spin_lock_irqsave(&t->sigmask_lock, flags);
12154 +       if (t->sig == NULL) {
12155 +               spin_unlock_irqrestore(&t->sigmask_lock, flags);
12156 +               return -ESRCH;
12157 +       }
12158 +
12159 +       if (t->sig->action[sig - 1].sa.sa_handler == SIG_IGN)
12160 +               t->sig->action[sig - 1].sa.sa_handler = SIG_DFL;
12161 +       sigdelset(&t->blocked, sig);
12162 +       recalc_sigpending(t);
12163 +       spin_unlock_irqrestore(&t->sigmask_lock, flags);
12164 +
12165 +       return send_sig_info(sig, (void *) 1L, t);
12166 +}
12167 +
12168 +void
12169 +gr_handle_crash(struct task_struct *task, const int sig)
12170 +{
12171 +       struct acl_subject_label *curr;
12172 +       struct acl_subject_label *curr2;
12173 +       struct task_struct *tsk;
12174 +
12175 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
12176 +               return;
12177 +
12178 +       if (unlikely(!gr_acl_is_enabled()))
12179 +               return;
12180 +
12181 +       curr = task->acl;
12182 +
12183 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
12184 +               return;
12185 +
12186 +       if (time_before_eq(curr->expires, jiffies)) {
12187 +               curr->expires = 0;
12188 +               curr->crashes = 0;
12189 +       }
12190 +
12191 +       curr->crashes++;
12192 +
12193 +       if (!curr->expires)
12194 +               curr->expires = jiffies + curr->res[GR_CRASH_RES].rlim_max;
12195 +
12196 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
12197 +           time_after(curr->expires, jiffies)) {
12198 +               if (task->uid && proc_is_setxid(task)) {
12199 +                       security_alert(GR_SEGVSTART_ACL_MSG,
12200 +                                      gr_task_fullpath(task), task->comm,
12201 +                                      task->pid, task->uid, task->euid,
12202 +                                      task->gid, task->egid,
12203 +                                      gr_parent_task_fullpath(task),
12204 +                                      task->p_pptr->comm, task->p_pptr->pid,
12205 +                                      task->p_pptr->uid, task->p_pptr->euid,
12206 +                                      task->p_pptr->gid, task->p_pptr->egid,
12207 +                                      task->uid,
12208 +                                      curr->res[GR_CRASH_RES].rlim_max / HZ);
12209 +                       write_lock(&gr_uid_lock);
12210 +                       gr_insert_uid(task->uid, curr->expires);
12211 +                       write_unlock(&gr_uid_lock);
12212 +                       curr->expires = 0;
12213 +                       curr->crashes = 0;
12214 +                       read_lock(&tasklist_lock);
12215 +                       for_each_task(tsk) {
12216 +                               if (tsk != task && tsk->uid == task->uid)
12217 +                                       gr_fake_force_sig(SIGKILL, tsk);
12218 +                       }
12219 +                       read_unlock(&tasklist_lock);
12220 +               } else {
12221 +                       security_alert(GR_SEGVNOSUID_ACL_MSG,
12222 +                                      gr_task_fullpath(task), task->comm,
12223 +                                      task->pid, task->uid, task->euid,
12224 +                                      task->gid, task->egid,
12225 +                                      gr_parent_task_fullpath(task),
12226 +                                      task->p_pptr->comm, task->p_pptr->pid,
12227 +                                      task->p_pptr->uid, task->p_pptr->euid,
12228 +                                      task->p_pptr->gid, task->p_pptr->egid,
12229 +                                      kdevname(curr->device), curr->inode,
12230 +                                      curr->res[GR_CRASH_RES].rlim_max / HZ);
12231 +                       read_lock(&tasklist_lock);
12232 +                       for_each_task(tsk) {
12233 +                               if (likely(tsk != task)) {
12234 +                                       curr2 = tsk->acl;
12235 +
12236 +                                       if (curr2->device == curr->device &&
12237 +                                           curr2->inode == curr->inode)
12238 +                                               gr_fake_force_sig(SIGKILL, tsk);
12239 +                               }
12240 +                       }
12241 +                       read_unlock(&tasklist_lock);
12242 +               }
12243 +       }
12244 +
12245 +       return;
12246 +}
12247 +
12248 +int
12249 +gr_check_crash_exec(const struct file *filp)
12250 +{
12251 +       struct acl_subject_label *curr;
12252 +
12253 +       if (unlikely(!gr_acl_is_enabled()))
12254 +               return 0;
12255 +
12256 +       read_lock(&gr_inode_lock);
12257 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
12258 +                                    filp->f_dentry->d_inode->i_dev,
12259 +                                    current->role);
12260 +       read_unlock(&gr_inode_lock);
12261 +
12262 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
12263 +           (!curr->crashes && !curr->expires))
12264 +               return 0;
12265 +
12266 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
12267 +           time_after(curr->expires, jiffies))
12268 +               return 1;
12269 +       else if (time_before_eq(curr->expires, jiffies)) {
12270 +               curr->crashes = 0;
12271 +               curr->expires = 0;
12272 +       }
12273 +
12274 +       return 0;
12275 +}
12276 +
12277 +void
12278 +gr_handle_alertkill(void)
12279 +{
12280 +       struct acl_subject_label *curracl;
12281 +       __u32 curr_ip;
12282 +       struct task_struct *task;
12283 +
12284 +       if (unlikely(!gr_acl_is_enabled()))
12285 +               return;
12286 +
12287 +       curracl = current->acl;
12288 +       curr_ip = current->curr_ip;
12289 +
12290 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
12291 +           (curr_ip != 0xffffffff)) {
12292 +               read_lock(&tasklist_lock);
12293 +               for_each_task(task) {
12294 +                       if (task->curr_ip == curr_ip)
12295 +                               gr_fake_force_sig(SIGKILL, task);
12296 +               }
12297 +               read_unlock(&tasklist_lock);
12298 +       } else if (curracl->mode & GR_KILLPROC)
12299 +               gr_fake_force_sig(SIGKILL, current);
12300 +
12301 +       return;
12302 +}
12303 diff -urN linux-2.4.24.org/grsecurity/gracl_shm.c linux-2.4.24/grsecurity/gracl_shm.c
12304 --- linux-2.4.24.org/grsecurity/gracl_shm.c     1970-01-01 01:00:00.000000000 +0100
12305 +++ linux-2.4.24/grsecurity/gracl_shm.c 2004-02-04 23:11:33.411798888 +0100
12306 @@ -0,0 +1,36 @@
12307 +/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
12308 +
12309 +#include <linux/kernel.h>
12310 +#include <linux/mm.h>
12311 +#include <linux/sched.h>
12312 +#include <linux/file.h>
12313 +#include <linux/ipc.h>
12314 +#include <linux/gracl.h>
12315 +#include <linux/grsecurity.h>
12316 +#include <linux/grinternal.h>
12317 +
12318 +int
12319 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12320 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
12321 +{
12322 +       struct task_struct *task;
12323 +
12324 +       if (!gr_acl_is_enabled())
12325 +               return 1;
12326 +
12327 +       task = find_task_by_pid(shm_cprid);
12328 +
12329 +       if (unlikely(!task))
12330 +               task = find_task_by_pid(shm_lapid);
12331 +
12332 +       if (unlikely(task && ((task->start_time < shm_createtime) ||
12333 +                             (task->pid == shm_lapid)) &&
12334 +                    (task->acl->mode & GR_PROTSHM) &&
12335 +                    (task->acl != current->acl))) {
12336 +               security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
12337 +                              DEFAULTSECARGS);
12338 +               return 0;
12339 +       }
12340 +
12341 +       return 1;
12342 +}
12343 diff -urN linux-2.4.24.org/grsecurity/grsec_chdir.c linux-2.4.24/grsecurity/grsec_chdir.c
12344 --- linux-2.4.24.org/grsecurity/grsec_chdir.c   1970-01-01 01:00:00.000000000 +0100
12345 +++ linux-2.4.24/grsecurity/grsec_chdir.c       2004-02-04 23:11:33.415798057 +0100
12346 @@ -0,0 +1,20 @@
12347 +#include <linux/kernel.h>
12348 +#include <linux/sched.h>
12349 +#include <linux/fs.h>
12350 +#include <linux/file.h>
12351 +#include <linux/grsecurity.h>
12352 +#include <linux/grinternal.h>
12353 +
12354 +void
12355 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
12356 +{
12357 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
12358 +       if ((grsec_enable_chdir && grsec_enable_group &&
12359 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
12360 +                                             !grsec_enable_group)) {
12361 +               security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
12362 +                              DEFAULTSECARGS);
12363 +       }
12364 +#endif
12365 +       return;
12366 +}
12367 diff -urN linux-2.4.24.org/grsecurity/grsec_chroot.c linux-2.4.24/grsecurity/grsec_chroot.c
12368 --- linux-2.4.24.org/grsecurity/grsec_chroot.c  1970-01-01 01:00:00.000000000 +0100
12369 +++ linux-2.4.24/grsecurity/grsec_chroot.c      2004-02-04 23:11:33.417797641 +0100
12370 @@ -0,0 +1,333 @@
12371 +#include <linux/kernel.h>
12372 +#include <linux/sched.h>
12373 +#include <linux/file.h>
12374 +#include <linux/fs.h>
12375 +#include <linux/types.h>
12376 +#include <linux/grinternal.h>
12377 +
12378 +int
12379 +gr_handle_chroot_unix(const pid_t pid)
12380 +{
12381 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12382 +       struct task_struct *p, **htable;
12383 +
12384 +       if (unlikely(!grsec_enable_chroot_unix))
12385 +               return 1;
12386 +
12387 +       if (likely(!proc_is_chrooted(current)))
12388 +               return 1;
12389 +
12390 +       read_lock(&tasklist_lock);
12391 +
12392 +       htable = &pidhash[pid_hashfn(pid)];
12393 +
12394 +       for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ;
12395 +
12396 +       if (unlikely(p && !have_same_root(current, p))) {
12397 +               read_unlock(&tasklist_lock);
12398 +               security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
12399 +               return 0;
12400 +       }
12401 +       read_unlock(&tasklist_lock);
12402 +#endif
12403 +       return 1;
12404 +}
12405 +
12406 +int
12407 +gr_handle_chroot_nice(void)
12408 +{
12409 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12410 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
12411 +               security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
12412 +               return -EPERM;
12413 +       }
12414 +#endif
12415 +       return 0;
12416 +}
12417 +
12418 +int
12419 +gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval)
12420 +{
12421 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12422 +       if (grsec_enable_chroot_nice && (!have_same_root(p, current)
12423 +                                        || (have_same_root(p, current)
12424 +                                            && (niceval < task_nice(p))
12425 +                                            && proc_is_chrooted(current)))) {
12426 +               security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
12427 +                              DEFAULTSECARGS);
12428 +               return -ESRCH;
12429 +       }
12430 +#endif
12431 +       return 0;
12432 +}
12433 +
12434 +int
12435 +gr_handle_chroot_capset(const struct task_struct *target)
12436 +{
12437 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12438 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
12439 +           !have_same_root(current, target)) {
12440 +               security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
12441 +                              DEFAULTSECARGS);
12442 +               return 1;
12443 +       }
12444 +#endif
12445 +       return 0;
12446 +}
12447 +
12448 +int
12449 +gr_handle_chroot_rawio(const struct inode *inode)
12450 +{
12451 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12452 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
12453 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
12454 +               return 1;
12455 +#endif
12456 +       return 0;
12457 +}
12458 +
12459 +int
12460 +gr_pid_is_chrooted(const struct task_struct *p)
12461 +{
12462 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
12463 +       if (!grsec_enable_chroot_findtask || (current->pid <= 1))
12464 +               return 0;
12465 +
12466 +       if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
12467 +           child_reaper && child_reaper->fs && child_reaper->fs->root &&
12468 +           child_reaper->fs->root->d_inode && current && current->fs &&
12469 +           current->fs->root && current->fs->root->d_inode) {
12470 +               if (proc_is_chrooted(current) && !have_same_root(current, p))
12471 +                       return 1;
12472 +       }
12473 +#endif
12474 +       return 0;
12475 +}
12476 +
12477 +int
12478 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
12479 +{
12480 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
12481 +       if (!grsec_enable_chroot_fchdir)
12482 +               return 1;
12483 +
12484 +       if (!proc_is_chrooted(current))
12485 +               return 1;
12486 +       else {
12487 +               struct dentry *dentry = u_dentry;
12488 +               struct vfsmount *mnt = u_mnt;
12489 +               struct dentry *realroot;
12490 +               struct vfsmount *realrootmnt;
12491 +               struct dentry *currentroot;
12492 +               struct vfsmount *currentmnt;
12493 +
12494 +               read_lock(&child_reaper->fs->lock);
12495 +               realrootmnt = mntget(child_reaper->fs->rootmnt);
12496 +               realroot = dget(child_reaper->fs->root);
12497 +               read_unlock(&child_reaper->fs->lock);
12498 +
12499 +               read_lock(&current->fs->lock);
12500 +               currentmnt = mntget(current->fs->rootmnt);
12501 +               currentroot = dget(current->fs->root);
12502 +               read_unlock(&current->fs->lock);
12503 +
12504 +               spin_lock(&dcache_lock);
12505 +               for (;;) {
12506 +                       if (unlikely
12507 +                           ((dentry == realroot && mnt == realrootmnt)
12508 +                            || (dentry == currentroot && mnt == currentmnt)))
12509 +                               break;
12510 +                       if (unlikely
12511 +                           (dentry == mnt->mnt_root || IS_ROOT(dentry))) {
12512 +                               if (mnt->mnt_parent == mnt)
12513 +                                       break;
12514 +                               dentry = mnt->mnt_mountpoint;
12515 +                               mnt = mnt->mnt_parent;
12516 +                               continue;
12517 +                       }
12518 +                       dentry = dentry->d_parent;
12519 +               }
12520 +               spin_unlock(&dcache_lock);
12521 +
12522 +               dput(currentroot);
12523 +               mntput(currentmnt);
12524 +
12525 +               if (dentry == realroot && mnt == realrootmnt) {
12526 +                       /* ok, they're definitely trying to fchdir outside of the
12527 +                          chroot. */
12528 +                       dput(realroot);
12529 +                       mntput(realrootmnt);
12530 +                       security_alert(GR_CHROOT_FCHDIR_MSG,
12531 +                                      gr_to_filename(u_dentry, u_mnt),
12532 +                                      DEFAULTSECARGS);
12533 +                       return 0;
12534 +               } else {
12535 +                       dput(realroot);
12536 +                       mntput(realrootmnt);
12537 +                       return 1;
12538 +               }
12539 +       }
12540 +#endif
12541 +       return 1;
12542 +}
12543 +
12544 +int
12545 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12546 +               const time_t shm_createtime)
12547 +{
12548 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12549 +       struct task_struct *p, **htable;
12550 +
12551 +       if (unlikely(!grsec_enable_chroot_shmat))
12552 +               return 1;
12553 +
12554 +       if (likely(!proc_is_chrooted(current)))
12555 +               return 1;
12556 +
12557 +       read_lock(&tasklist_lock);
12558 +
12559 +       htable = &pidhash[pid_hashfn(shm_cprid)];
12560 +
12561 +       for (p = *htable; p && p->pid != shm_cprid; p = p->pidhash_next) ;
12562 +
12563 +       if (unlikely(p && !have_same_root(current, p) &&
12564 +                    (p->start_time < shm_createtime))) {
12565 +               read_unlock(&tasklist_lock);
12566 +               security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12567 +               return 0;
12568 +       }
12569 +
12570 +       if (unlikely(!p)) {
12571 +               htable = &pidhash[pid_hashfn(shm_lapid)];
12572 +               for (p = *htable; p && p->pid != shm_lapid;
12573 +                    p = p->pidhash_next) ;
12574 +
12575 +               if (unlikely(p && !have_same_root(current, p))) {
12576 +                       read_unlock(&tasklist_lock);
12577 +                       security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12578 +                       return 0;
12579 +               }
12580 +       }
12581 +
12582 +       read_unlock(&tasklist_lock);
12583 +#endif
12584 +       return 1;
12585 +}
12586 +
12587 +void
12588 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12589 +{
12590 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12591 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
12592 +               security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
12593 +                              DEFAULTSECARGS);
12594 +#endif
12595 +       return;
12596 +}
12597 +
12598 +int
12599 +gr_handle_chroot_mknod(const struct dentry *dentry,
12600 +                      const struct vfsmount *mnt, const int mode)
12601 +{
12602 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12603 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) &&
12604 +           proc_is_chrooted(current)) {
12605 +               security_alert(GR_MKNOD_CHROOT_MSG,
12606 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12607 +               return -EPERM;
12608 +       }
12609 +#endif
12610 +       return 0;
12611 +}
12612 +
12613 +int
12614 +gr_handle_chroot_mount(const struct dentry *dentry,
12615 +                      const struct vfsmount *mnt, const char *dev_name)
12616 +{
12617 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12618 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
12619 +               security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
12620 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12621 +               return -EPERM;
12622 +       }
12623 +#endif
12624 +       return 0;
12625 +}
12626 +
12627 +int
12628 +gr_handle_chroot_pivot(void)
12629 +{
12630 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12631 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
12632 +               security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
12633 +               return -EPERM;
12634 +       }
12635 +#endif
12636 +       return 0;
12637 +}
12638 +
12639 +int
12640 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
12641 +{
12642 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12643 +       if (grsec_enable_chroot_double && proc_is_chrooted(current)) {
12644 +               security_alert(GR_CHROOT_CHROOT_MSG,
12645 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12646 +               return -EPERM;
12647 +       }
12648 +#endif
12649 +       return 0;
12650 +}
12651 +
12652 +void
12653 +gr_handle_chroot_caps(struct task_struct *task)
12654 +{
12655 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12656 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
12657 +               task->cap_permitted =
12658 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
12659 +               task->cap_inheritable =
12660 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
12661 +               task->cap_effective =
12662 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
12663 +       }
12664 +#endif
12665 +       return;
12666 +}
12667 +
12668 +int
12669 +gr_handle_chroot_sysctl(const int op)
12670 +{
12671 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12672 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
12673 +           && (op & 002))
12674 +               return -EACCES;
12675 +#endif
12676 +       return 0;
12677 +}
12678 +
12679 +void
12680 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
12681 +{
12682 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12683 +       if (grsec_enable_chroot_chdir)
12684 +               set_fs_pwd(current->fs, mnt, dentry);
12685 +#endif
12686 +       return;
12687 +}
12688 +
12689 +int
12690 +gr_handle_chroot_chmod(const struct dentry *dentry,
12691 +                      const struct vfsmount *mnt, const int mode)
12692 +{
12693 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12694 +       if (grsec_enable_chroot_chmod &&
12695 +           ((mode & S_ISUID) || (mode & S_ISGID)) &&
12696 +           proc_is_chrooted(current)) {
12697 +               security_alert(GR_CHMOD_CHROOT_MSG,
12698 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12699 +               return -EPERM;
12700 +       }
12701 +#endif
12702 +       return 0;
12703 +}
12704 diff -urN linux-2.4.24.org/grsecurity/grsec_disabled.c linux-2.4.24/grsecurity/grsec_disabled.c
12705 --- linux-2.4.24.org/grsecurity/grsec_disabled.c        1970-01-01 01:00:00.000000000 +0100
12706 +++ linux-2.4.24/grsecurity/grsec_disabled.c    2004-02-04 23:11:33.420797017 +0100
12707 @@ -0,0 +1,380 @@
12708 +/* 
12709 + * when grsecurity is disabled, compile all external functions into nothing
12710 + */
12711 +
12712 +#include <linux/kernel.h>
12713 +#include <linux/config.h>
12714 +#include <linux/sched.h>
12715 +#include <linux/file.h>
12716 +#include <linux/fs.h>
12717 +#include <linux/kdev_t.h>
12718 +#include <linux/net.h>
12719 +#include <linux/in.h>
12720 +#include <linux/ip.h>
12721 +#include <linux/skbuff.h>
12722 +#include <linux/sysctl.h>
12723 +
12724 +#ifdef CONFIG_SYSCTL
12725 +__u32
12726 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
12727 +{
12728 +       return mode;
12729 +}
12730 +#endif
12731 +
12732 +int
12733 +gr_acl_is_enabled(void)
12734 +{
12735 +       return 0;
12736 +}
12737 +
12738 +int
12739 +gr_handle_rawio(const struct inode *inode)
12740 +{
12741 +       return 0;
12742 +}
12743 +
12744 +void
12745 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12746 +{
12747 +       return;
12748 +}
12749 +
12750 +int
12751 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12752 +{
12753 +       return 0;
12754 +}
12755 +
12756 +int
12757 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
12758 +{
12759 +       return 0;
12760 +}
12761 +
12762 +int
12763 +gr_handle_ptrace(struct task_struct *task, const long request)
12764 +{
12765 +       return 0;
12766 +}
12767 +
12768 +void
12769 +gr_learn_resource(const struct task_struct *task,
12770 +                 const int res, const unsigned long wanted, const int gt)
12771 +{
12772 +       return;
12773 +}
12774 +
12775 +int
12776 +gr_set_acls(const int type)
12777 +{
12778 +       return 0;
12779 +}
12780 +
12781 +int
12782 +gr_check_hidden_task(const struct task_struct *tsk)
12783 +{
12784 +       return 0;
12785 +}
12786 +
12787 +int
12788 +gr_check_protected_task(const struct task_struct *task)
12789 +{
12790 +       return 0;
12791 +}
12792 +
12793 +__inline__ void
12794 +gr_copy_label(struct task_struct *tsk)
12795 +{
12796 +       return;
12797 +}
12798 +
12799 +void
12800 +gr_set_pax_flags(struct task_struct *task)
12801 +{
12802 +       return;
12803 +}
12804 +
12805 +void
12806 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
12807 +{
12808 +       return;
12809 +}
12810 +
12811 +void
12812 +gr_handle_delete(const ino_t ino, const kdev_t dev)
12813 +{
12814 +       return;
12815 +}
12816 +
12817 +void
12818 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
12819 +{
12820 +       return;
12821 +}
12822 +
12823 +void
12824 +gr_handle_crash(struct task_struct *task, const int sig)
12825 +{
12826 +       return;
12827 +}
12828 +
12829 +int
12830 +gr_check_crash_exec(const struct file *filp)
12831 +{
12832 +       return 0;
12833 +}
12834 +
12835 +int
12836 +gr_check_crash_uid(const uid_t uid)
12837 +{
12838 +       return 0;
12839 +}
12840 +
12841 +int
12842 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
12843 +                struct dentry *old_dentry,
12844 +                struct dentry *new_dentry,
12845 +                struct vfsmount *mnt, const __u8 replace)
12846 +{
12847 +       return 0;
12848 +}
12849 +
12850 +int
12851 +gr_search_socket(const int family, const int type, const int protocol)
12852 +{
12853 +       return 1;
12854 +}
12855 +
12856 +int
12857 +gr_search_connectbind(const int mode, const struct socket *sock,
12858 +                     const struct sockaddr_in *addr)
12859 +{
12860 +       return 1;
12861 +}
12862 +
12863 +int
12864 +gr_is_capable(const int cap)
12865 +{
12866 +       return 1;
12867 +}
12868 +
12869 +void
12870 +gr_handle_alertkill(void)
12871 +{
12872 +       return;
12873 +}
12874 +
12875 +__u32
12876 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
12877 +{
12878 +       return 1;
12879 +}
12880 +
12881 +__u32
12882 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12883 +                         const struct vfsmount * mnt)
12884 +{
12885 +       return 1;
12886 +}
12887 +
12888 +__u32
12889 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12890 +                  const int fmode)
12891 +{
12892 +       return 1;
12893 +}
12894 +
12895 +__u32
12896 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12897 +{
12898 +       return 1;
12899 +}
12900 +
12901 +__u32
12902 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
12903 +{
12904 +       return 1;
12905 +}
12906 +
12907 +int
12908 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
12909 +                  unsigned int *vm_flags)
12910 +{
12911 +       return 1;
12912 +}
12913 +
12914 +__u32
12915 +gr_acl_handle_truncate(const struct dentry * dentry,
12916 +                      const struct vfsmount * mnt)
12917 +{
12918 +       return 1;
12919 +}
12920 +
12921 +__u32
12922 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
12923 +{
12924 +       return 1;
12925 +}
12926 +
12927 +__u32
12928 +gr_acl_handle_access(const struct dentry * dentry,
12929 +                    const struct vfsmount * mnt, const int fmode)
12930 +{
12931 +       return 1;
12932 +}
12933 +
12934 +__u32
12935 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
12936 +                    mode_t mode)
12937 +{
12938 +       return 1;
12939 +}
12940 +
12941 +__u32
12942 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
12943 +                   mode_t mode)
12944 +{
12945 +       return 1;
12946 +}
12947 +
12948 +__u32
12949 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
12950 +{
12951 +       return 1;
12952 +}
12953 +
12954 +void
12955 +grsecurity_init(void)
12956 +{
12957 +       return;
12958 +}
12959 +
12960 +__u32
12961 +gr_acl_handle_mknod(const struct dentry * new_dentry,
12962 +                   const struct dentry * parent_dentry,
12963 +                   const struct vfsmount * parent_mnt,
12964 +                   const int mode)
12965 +{
12966 +       return 1;
12967 +}
12968 +
12969 +__u32
12970 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
12971 +                   const struct dentry * parent_dentry,
12972 +                   const struct vfsmount * parent_mnt)
12973 +{
12974 +       return 1;
12975 +}
12976 +
12977 +__u32
12978 +gr_acl_handle_symlink(const struct dentry * new_dentry,
12979 +                     const struct dentry * parent_dentry,
12980 +                     const struct vfsmount * parent_mnt, const char *from)
12981 +{
12982 +       return 1;
12983 +}
12984 +
12985 +__u32
12986 +gr_acl_handle_link(const struct dentry * new_dentry,
12987 +                  const struct dentry * parent_dentry,
12988 +                  const struct vfsmount * parent_mnt,
12989 +                  const struct dentry * old_dentry,
12990 +                  const struct vfsmount * old_mnt, const char *to)
12991 +{
12992 +       return 1;
12993 +}
12994 +
12995 +int
12996 +gr_acl_handle_rename(const struct dentry *new_dentry,
12997 +                    const struct dentry *parent_dentry,
12998 +                    const struct vfsmount *parent_mnt,
12999 +                    const struct dentry *old_dentry,
13000 +                    const struct inode *old_parent_inode,
13001 +                    const struct vfsmount *old_mnt, const char *newname)
13002 +{
13003 +       return 1;
13004 +}
13005 +
13006 +__u32
13007 +gr_acl_handle_filldir(const struct dentry * dentry,
13008 +                     const struct vfsmount * mnt, const ino_t ino)
13009 +{
13010 +       return 1;
13011 +}
13012 +
13013 +int
13014 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
13015 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
13016 +{
13017 +       return 1;
13018 +}
13019 +
13020 +int
13021 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
13022 +{
13023 +       return 1;
13024 +}
13025 +
13026 +int
13027 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
13028 +{
13029 +       return 1;
13030 +}
13031 +
13032 +__u32
13033 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
13034 +{
13035 +       return 1;
13036 +}
13037 +
13038 +__u32
13039 +gr_acl_handle_creat(const struct dentry * dentry,
13040 +                   const struct dentry * p_dentry,
13041 +                   const struct vfsmount * p_mnt, const int fmode,
13042 +                   const int imode)
13043 +{
13044 +       return 1;
13045 +}
13046 +
13047 +void
13048 +gr_acl_handle_exit(void)
13049 +{
13050 +       return;
13051 +}
13052 +
13053 +int
13054 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
13055 +{
13056 +       return 1;
13057 +}
13058 +
13059 +void
13060 +gr_set_role_label(const uid_t uid, const gid_t gid)
13061 +{
13062 +       return;
13063 +}
13064 +
13065 +int
13066 +gr_acl_handle_procpidmem(const struct task_struct *task)
13067 +{
13068 +       return 0;
13069 +}
13070 +
13071 +int
13072 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
13073 +{
13074 +       return 1;
13075 +}
13076 +
13077 +int
13078 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
13079 +{
13080 +       return 1;
13081 +}
13082 +
13083 +void
13084 +gr_set_kernel_label(struct task_struct *task)
13085 +{
13086 +       return;
13087 +}
13088 diff -urN linux-2.4.24.org/grsecurity/grsec_exec.c linux-2.4.24/grsecurity/grsec_exec.c
13089 --- linux-2.4.24.org/grsecurity/grsec_exec.c    1970-01-01 01:00:00.000000000 +0100
13090 +++ linux-2.4.24/grsecurity/grsec_exec.c        2004-02-04 23:11:33.422796602 +0100
13091 @@ -0,0 +1,70 @@
13092 +#include <linux/kernel.h>
13093 +#include <linux/sched.h>
13094 +#include <linux/file.h>
13095 +#include <linux/fs.h>
13096 +#include <linux/types.h>
13097 +#include <linux/grdefs.h>
13098 +#include <linux/grinternal.h>
13099 +#include <linux/capability.h>
13100 +
13101 +#include <asm/uaccess.h>
13102 +
13103 +int
13104 +gr_handle_nproc(void)
13105 +{
13106 +#ifdef CONFIG_GRKERNSEC_EXECVE
13107 +       if (grsec_enable_execve && current->user &&
13108 +           (atomic_read(&current->user->processes) >
13109 +            current->rlim[RLIMIT_NPROC].rlim_cur) &&
13110 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
13111 +               security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
13112 +               return -EAGAIN;
13113 +       }
13114 +#endif
13115 +       return 0;
13116 +}
13117 +
13118 +void
13119 +gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
13120 +{
13121 +#ifdef CONFIG_GRKERNSEC_EXECLOG
13122 +       char grarg[64] = { 0 };
13123 +       __u8 execlen = 0;
13124 +       unsigned int i;
13125 +
13126 +       if (!((grsec_enable_execlog && grsec_enable_group &&
13127 +              in_group_p(grsec_audit_gid))
13128 +             || (grsec_enable_execlog && !grsec_enable_group)))
13129 +               return;
13130 +
13131 +       if (unlikely(!argv))
13132 +               goto log;
13133 +
13134 +       for (i = 0; i < bprm->argc && execlen < 62; i++) {
13135 +               char *p;
13136 +               __u8 len;
13137 +
13138 +               if (get_user(p, argv + i))
13139 +                       goto log;
13140 +               if (!p)
13141 +                       goto log;
13142 +               len = strnlen_user(p, 62 - execlen);
13143 +               if (len > 62 - execlen)
13144 +                       len = 62 - execlen;
13145 +               else if (len > 0)
13146 +                       len--;
13147 +               if (copy_from_user(grarg + execlen, p, len))
13148 +                       goto log;
13149 +               execlen += len;
13150 +               *(grarg + execlen) = ' ';
13151 +               *(grarg + execlen + 1) = '\0';
13152 +               execlen++;
13153 +       }
13154 +
13155 +      log:
13156 +       security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
13157 +                                                        bprm->file->f_vfsmnt),
13158 +                      grarg, DEFAULTSECARGS);
13159 +#endif
13160 +       return;
13161 +}
13162 diff -urN linux-2.4.24.org/grsecurity/grsec_fifo.c linux-2.4.24/grsecurity/grsec_fifo.c
13163 --- linux-2.4.24.org/grsecurity/grsec_fifo.c    1970-01-01 01:00:00.000000000 +0100
13164 +++ linux-2.4.24/grsecurity/grsec_fifo.c        2004-02-04 23:11:33.425795978 +0100
13165 @@ -0,0 +1,24 @@
13166 +#include <linux/kernel.h>
13167 +#include <linux/sched.h>
13168 +#include <linux/fs.h>
13169 +#include <linux/file.h>
13170 +#include <linux/grinternal.h>
13171 +
13172 +int
13173 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
13174 +              const struct dentry *dir, const int flag, const int acc_mode)
13175 +{
13176 +#ifdef CONFIG_GRKERNSEC_FIFO
13177 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
13178 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
13179 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
13180 +           (current->fsuid != dentry->d_inode->i_uid)) {
13181 +               if (!permission(dentry->d_inode, acc_mode))
13182 +                       security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
13183 +                                      dentry->d_inode->i_uid,
13184 +                                      dentry->d_inode->i_gid, DEFAULTSECARGS);
13185 +               return -EACCES;
13186 +       }
13187 +#endif
13188 +       return 0;
13189 +}
13190 diff -urN linux-2.4.24.org/grsecurity/grsec_fork.c linux-2.4.24/grsecurity/grsec_fork.c
13191 --- linux-2.4.24.org/grsecurity/grsec_fork.c    1970-01-01 01:00:00.000000000 +0100
13192 +++ linux-2.4.24/grsecurity/grsec_fork.c        2004-02-04 23:11:33.427795562 +0100
13193 @@ -0,0 +1,14 @@
13194 +#include <linux/kernel.h>
13195 +#include <linux/sched.h>
13196 +#include <linux/grsecurity.h>
13197 +#include <linux/grinternal.h>
13198 +
13199 +void
13200 +gr_log_forkfail(const int retval)
13201 +{
13202 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
13203 +       if (grsec_enable_forkfail)
13204 +               security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
13205 +#endif
13206 +       return;
13207 +}
13208 diff -urN linux-2.4.24.org/grsecurity/grsec_init.c linux-2.4.24/grsecurity/grsec_init.c
13209 --- linux-2.4.24.org/grsecurity/grsec_init.c    1970-01-01 01:00:00.000000000 +0100
13210 +++ linux-2.4.24/grsecurity/grsec_init.c        2004-02-04 23:11:33.430794939 +0100
13211 @@ -0,0 +1,222 @@
13212 +#include <linux/kernel.h>
13213 +#include <linux/sched.h>
13214 +#include <linux/mm.h>
13215 +#include <linux/smp_lock.h>
13216 +#include <linux/gracl.h>
13217 +#include <linux/slab.h>
13218 +#include <linux/vmalloc.h>
13219 +
13220 +int grsec_enable_link;
13221 +int grsec_enable_dmesg;
13222 +int grsec_enable_fifo;
13223 +int grsec_enable_execve;
13224 +int grsec_enable_execlog;
13225 +int grsec_enable_signal;
13226 +int grsec_enable_forkfail;
13227 +int grsec_enable_time;
13228 +int grsec_enable_group;
13229 +int grsec_audit_gid;
13230 +int grsec_enable_chdir;
13231 +int grsec_enable_audit_ipc;
13232 +int grsec_enable_mount;
13233 +int grsec_enable_chroot_findtask;
13234 +int grsec_enable_chroot_mount;
13235 +int grsec_enable_chroot_shmat;
13236 +int grsec_enable_chroot_fchdir;
13237 +int grsec_enable_chroot_double;
13238 +int grsec_enable_chroot_pivot;
13239 +int grsec_enable_chroot_chdir;
13240 +int grsec_enable_chroot_chmod;
13241 +int grsec_enable_chroot_mknod;
13242 +int grsec_enable_chroot_nice;
13243 +int grsec_enable_chroot_execlog;
13244 +int grsec_enable_chroot_caps;
13245 +int grsec_enable_chroot_sysctl;
13246 +int grsec_enable_chroot_unix;
13247 +int grsec_enable_tpe;
13248 +int grsec_tpe_gid;
13249 +int grsec_enable_tpe_all;
13250 +int grsec_enable_randpid;
13251 +int grsec_enable_randid;
13252 +int grsec_enable_randisn;
13253 +int grsec_enable_randsrc;
13254 +int grsec_enable_randrpc;
13255 +int grsec_enable_socket_all;
13256 +int grsec_socket_all_gid;
13257 +int grsec_enable_socket_client;
13258 +int grsec_socket_client_gid;
13259 +int grsec_enable_socket_server;
13260 +int grsec_socket_server_gid;
13261 +int grsec_lock;
13262 +
13263 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
13264 +unsigned long grsec_alert_wtime = 0;
13265 +unsigned long grsec_alert_fyet = 0;
13266 +
13267 +spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
13268 +unsigned long grsec_alertgood_wtime = 0;
13269 +unsigned long grsec_alertgood_fyet = 0;
13270 +
13271 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
13272 +
13273 +char *gr_shared_page[4][NR_CPUS];
13274 +extern struct gr_arg *gr_usermode;
13275 +extern unsigned char *gr_system_salt;
13276 +extern unsigned char *gr_system_sum;
13277 +extern struct task_struct **gr_conn_table;
13278 +extern const unsigned int gr_conn_table_size;
13279 +
13280 +void
13281 +grsecurity_init(void)
13282 +{
13283 +       int i, j;
13284 +       /* create the per-cpu shared pages */
13285 +
13286 +       for (j = 0; j < 4; j++) {
13287 +               for (i = 0; i < NR_CPUS; i++) {
13288 +                       gr_shared_page[j][i] = (char *) get_zeroed_page(GFP_KERNEL);
13289 +                       if (!gr_shared_page[j][i]) {
13290 +                               panic("Unable to allocate grsecurity shared page");
13291 +                               return;
13292 +                       }
13293 +               }
13294 +       }
13295 +
13296 +       /* create hash tables for ip tagging */
13297 +
13298 +       gr_conn_table = (struct task_struct **) vmalloc(gr_conn_table_size * sizeof(struct task_struct *));
13299 +       if (gr_conn_table == NULL) {
13300 +               panic("Unable to allocate grsecurity IP tagging table");
13301 +               return;
13302 +       }
13303 +       memset(gr_conn_table, 0, gr_conn_table_size * sizeof(struct task_struct *));
13304 +
13305 +       /* allocate memory for authentication structure */
13306 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
13307 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
13308 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
13309 +
13310 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
13311 +               panic("Unable to allocate grsecurity authentication structure");
13312 +               return;
13313 +       }
13314 +
13315 +#ifndef CONFIG_GRKERNSEC_SYSCTL
13316 +       grsec_lock = 1;
13317 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
13318 +       grsec_enable_group = 1;
13319 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
13320 +#endif
13321 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
13322 +       grsec_enable_chdir = 1;
13323 +#endif
13324 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13325 +       grsec_enable_audit_ipc = 1;
13326 +#endif
13327 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13328 +       grsec_enable_mount = 1;
13329 +#endif
13330 +#ifdef CONFIG_GRKERNSEC_LINK
13331 +       grsec_enable_link = 1;
13332 +#endif
13333 +#ifdef CONFIG_GRKERNSEC_DMESG
13334 +       grsec_enable_dmesg = 1;
13335 +#endif
13336 +#ifdef CONFIG_GRKERNSEC_FIFO
13337 +       grsec_enable_fifo = 1;
13338 +#endif
13339 +#ifdef CONFIG_GRKERNSEC_EXECVE
13340 +       grsec_enable_execve = 1;
13341 +#endif
13342 +#ifdef CONFIG_GRKERNSEC_EXECLOG
13343 +       grsec_enable_execlog = 1;
13344 +#endif
13345 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13346 +       grsec_enable_signal = 1;
13347 +#endif
13348 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
13349 +       grsec_enable_forkfail = 1;
13350 +#endif
13351 +#ifdef CONFIG_GRKERNSEC_TIME
13352 +       grsec_enable_time = 1;
13353 +#endif
13354 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
13355 +       grsec_enable_chroot_findtask = 1;
13356 +#endif
13357 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
13358 +       grsec_enable_chroot_unix = 1;
13359 +#endif
13360 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
13361 +       grsec_enable_chroot_mount = 1;
13362 +#endif
13363 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
13364 +       grsec_enable_chroot_fchdir = 1;
13365 +#endif
13366 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
13367 +       grsec_enable_chroot_shmat = 1;
13368 +#endif
13369 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
13370 +       grsec_enable_chroot_double = 1;
13371 +#endif
13372 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
13373 +       grsec_enable_chroot_pivot = 1;
13374 +#endif
13375 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
13376 +       grsec_enable_chroot_chdir = 1;
13377 +#endif
13378 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
13379 +       grsec_enable_chroot_chmod = 1;
13380 +#endif
13381 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
13382 +       grsec_enable_chroot_mknod = 1;
13383 +#endif
13384 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
13385 +       grsec_enable_chroot_nice = 1;
13386 +#endif
13387 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
13388 +       grsec_enable_chroot_execlog = 1;
13389 +#endif
13390 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
13391 +       grsec_enable_chroot_caps = 1;
13392 +#endif
13393 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
13394 +       grsec_enable_chroot_sysctl = 1;
13395 +#endif
13396 +#ifdef CONFIG_GRKERNSEC_TPE
13397 +       grsec_enable_tpe = 1;
13398 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
13399 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
13400 +       grsec_enable_tpe_all = 1;
13401 +#endif
13402 +#endif
13403 +#ifdef CONFIG_GRKERNSEC_RANDPID
13404 +       grsec_enable_randpid = 1;
13405 +#endif
13406 +#ifdef CONFIG_GRKERNSEC_RANDID
13407 +       grsec_enable_randid = 1;
13408 +#endif
13409 +#ifdef CONFIG_GRKERNSEC_RANDISN
13410 +       grsec_enable_randisn = 1;
13411 +#endif
13412 +#ifdef CONFIG_GRKERNSEC_RANDSRC
13413 +       grsec_enable_randsrc = 1;
13414 +#endif
13415 +#ifdef CONFIG_GRKERNSEC_RANDRPC
13416 +       grsec_enable_randrpc = 1;
13417 +#endif
13418 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13419 +       grsec_enable_socket_all = 1;
13420 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
13421 +#endif
13422 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13423 +       grsec_enable_socket_client = 1;
13424 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
13425 +#endif
13426 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13427 +       grsec_enable_socket_server = 1;
13428 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
13429 +#endif
13430 +#endif
13431 +
13432 +       return;
13433 +}
13434 diff -urN linux-2.4.24.org/grsecurity/grsec_ipc.c linux-2.4.24/grsecurity/grsec_ipc.c
13435 --- linux-2.4.24.org/grsecurity/grsec_ipc.c     1970-01-01 01:00:00.000000000 +0100
13436 +++ linux-2.4.24/grsecurity/grsec_ipc.c 2004-02-04 23:11:33.491782259 +0100
13437 @@ -0,0 +1,81 @@
13438 +#include <linux/kernel.h>
13439 +#include <linux/sched.h>
13440 +#include <linux/types.h>
13441 +#include <linux/ipc.h>
13442 +#include <linux/grsecurity.h>
13443 +#include <linux/grinternal.h>
13444 +
13445 +void
13446 +gr_log_msgget(const int ret, const int msgflg)
13447 +{
13448 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13449 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13450 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13451 +                                         !grsec_enable_group)) && (ret >= 0)
13452 +           && (msgflg & IPC_CREAT))
13453 +               security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
13454 +#endif
13455 +       return;
13456 +}
13457 +
13458 +void
13459 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
13460 +{
13461 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13462 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13463 +            grsec_enable_audit_ipc) ||
13464 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13465 +               security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13466 +#endif
13467 +       return;
13468 +}
13469 +
13470 +void
13471 +gr_log_semget(const int err, const int semflg)
13472 +{
13473 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13474 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13475 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13476 +                                         !grsec_enable_group)) && (err >= 0)
13477 +           && (semflg & IPC_CREAT))
13478 +               security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
13479 +#endif
13480 +       return;
13481 +}
13482 +
13483 +void
13484 +gr_log_semrm(const uid_t uid, const uid_t cuid)
13485 +{
13486 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13487 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13488 +            grsec_enable_audit_ipc) ||
13489 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13490 +               security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13491 +#endif
13492 +       return;
13493 +}
13494 +
13495 +void
13496 +gr_log_shmget(const int err, const int shmflg, const size_t size)
13497 +{
13498 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13499 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13500 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13501 +                                         !grsec_enable_group)) && (err >= 0)
13502 +           && (shmflg & IPC_CREAT))
13503 +               security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
13504 +#endif
13505 +       return;
13506 +}
13507 +
13508 +void
13509 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
13510 +{
13511 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13512 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13513 +            grsec_enable_audit_ipc) ||
13514 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13515 +               security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13516 +#endif
13517 +       return;
13518 +}
13519 diff -urN linux-2.4.24.org/grsecurity/grsec_link.c linux-2.4.24/grsecurity/grsec_link.c
13520 --- linux-2.4.24.org/grsecurity/grsec_link.c    1970-01-01 01:00:00.000000000 +0100
13521 +++ linux-2.4.24/grsecurity/grsec_link.c        2004-02-04 23:11:33.495781427 +0100
13522 @@ -0,0 +1,41 @@
13523 +#include <linux/kernel.h>
13524 +#include <linux/sched.h>
13525 +#include <linux/fs.h>
13526 +#include <linux/file.h>
13527 +#include <linux/grinternal.h>
13528 +
13529 +int
13530 +gr_handle_follow_link(const struct inode *parent,
13531 +                     const struct inode *inode,
13532 +                     const struct dentry *dentry, const struct vfsmount *mnt)
13533 +{
13534 +#ifdef CONFIG_GRKERNSEC_LINK
13535 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
13536 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
13537 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
13538 +               security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
13539 +                              inode->i_uid, inode->i_gid, DEFAULTSECARGS);
13540 +               return -EACCES;
13541 +       }
13542 +#endif
13543 +       return 0;
13544 +}
13545 +
13546 +int
13547 +gr_handle_hardlink(const struct dentry *dentry,
13548 +                  const struct vfsmount *mnt,
13549 +                  struct inode *inode, const int mode, const char *to)
13550 +{
13551 +#ifdef CONFIG_GRKERNSEC_LINK
13552 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
13553 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
13554 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
13555 +            (permission(inode, MAY_READ | MAY_WRITE))) &&
13556 +           !capable(CAP_FOWNER) && current->uid) {
13557 +               security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
13558 +                              inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
13559 +               return -EPERM;
13560 +       }
13561 +#endif
13562 +       return 0;
13563 +}
13564 diff -urN linux-2.4.24.org/grsecurity/grsec_mem.c linux-2.4.24/grsecurity/grsec_mem.c
13565 --- linux-2.4.24.org/grsecurity/grsec_mem.c     1970-01-01 01:00:00.000000000 +0100
13566 +++ linux-2.4.24/grsecurity/grsec_mem.c 2004-02-04 23:11:33.497781011 +0100
13567 @@ -0,0 +1,54 @@
13568 +#include <linux/kernel.h>
13569 +#include <linux/sched.h>
13570 +#include <linux/mm.h>
13571 +#include <linux/grinternal.h>
13572 +
13573 +void
13574 +gr_handle_ioperm(void)
13575 +{
13576 +       security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
13577 +       return;
13578 +}
13579 +
13580 +void
13581 +gr_handle_iopl(void)
13582 +{
13583 +       security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
13584 +       return;
13585 +}
13586 +
13587 +void
13588 +gr_handle_mem_write(void)
13589 +{
13590 +       security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
13591 +       return;
13592 +}
13593 +
13594 +void
13595 +gr_handle_kmem_write(void)
13596 +{
13597 +       security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
13598 +       return;
13599 +}
13600 +
13601 +void
13602 +gr_handle_open_port(void)
13603 +{
13604 +       security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
13605 +       return;
13606 +}
13607 +
13608 +int
13609 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
13610 +{
13611 +       if (offset < __pa(high_memory) &&
13612 +           (pgprot_val(vma->vm_page_prot) & PROT_WRITE) &&
13613 +           !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
13614 +           !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
13615 +               security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
13616 +               return -EPERM;
13617 +       } else if (offset < __pa(high_memory))
13618 +               vma->vm_flags &= ~VM_MAYWRITE;
13619 +
13620 +       return 0;
13621 +}
13622 diff -urN linux-2.4.24.org/grsecurity/grsec_mount.c linux-2.4.24/grsecurity/grsec_mount.c
13623 --- linux-2.4.24.org/grsecurity/grsec_mount.c   1970-01-01 01:00:00.000000000 +0100
13624 +++ linux-2.4.24/grsecurity/grsec_mount.c       2004-02-04 23:11:33.499780596 +0100
13625 @@ -0,0 +1,34 @@
13626 +#include <linux/kernel.h>
13627 +#include <linux/sched.h>
13628 +#include <linux/grsecurity.h>
13629 +#include <linux/grinternal.h>
13630 +
13631 +void
13632 +gr_log_remount(const char *devname, const int retval)
13633 +{
13634 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13635 +       if (grsec_enable_mount && (retval >= 0))
13636 +               security_audit(GR_REMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13637 +#endif
13638 +       return;
13639 +}
13640 +
13641 +void
13642 +gr_log_unmount(const char *devname, const int retval)
13643 +{
13644 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13645 +       if (grsec_enable_mount && (retval >= 0))
13646 +               security_audit(GR_UNMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13647 +#endif
13648 +       return;
13649 +}
13650 +
13651 +void
13652 +gr_log_mount(const char *from, const char *to, const int retval)
13653 +{
13654 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13655 +       if (grsec_enable_mount && (retval >= 0))
13656 +               security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
13657 +#endif
13658 +       return;
13659 +}
13660 diff -urN linux-2.4.24.org/grsecurity/grsec_rand.c linux-2.4.24/grsecurity/grsec_rand.c
13661 --- linux-2.4.24.org/grsecurity/grsec_rand.c    1970-01-01 01:00:00.000000000 +0100
13662 +++ linux-2.4.24/grsecurity/grsec_rand.c        2004-02-04 23:11:33.501780180 +0100
13663 @@ -0,0 +1,36 @@
13664 +#include <linux/kernel.h>
13665 +#include <linux/sched.h>
13666 +#include <linux/smp_lock.h>
13667 +#include <linux/grsecurity.h>
13668 +#include <linux/grinternal.h>
13669 +
13670 +extern int last_pid;
13671 +
13672 +int
13673 +gr_random_pid(spinlock_t * pid_lock)
13674 +{
13675 +#ifdef CONFIG_GRKERNSEC_RANDPID
13676 +       struct task_struct *p;
13677 +       int pid;
13678 +
13679 +       if (grsec_enable_randpid && current->fs->root) {
13680 +               read_lock(&tasklist_lock);
13681 +               spin_lock(pid_lock);
13682 +
13683 +             repeater:
13684 +
13685 +               pid = 1 + (get_random_long() % PID_MAX);
13686 +
13687 +               for_each_task(p) {
13688 +                       if (p->pid == pid || p->pgrp == pid ||
13689 +                           p->tgid == pid || p->session == pid)
13690 +                               goto repeater;
13691 +               }
13692 +               last_pid = pid;
13693 +               spin_unlock(pid_lock);
13694 +               read_unlock(&tasklist_lock);
13695 +               return pid;
13696 +       }
13697 +#endif
13698 +       return 0;
13699 +}
13700 diff -urN linux-2.4.24.org/grsecurity/grsec_sig.c linux-2.4.24/grsecurity/grsec_sig.c
13701 --- linux-2.4.24.org/grsecurity/grsec_sig.c     1970-01-01 01:00:00.000000000 +0100
13702 +++ linux-2.4.24/grsecurity/grsec_sig.c 2004-02-04 23:11:33.504779556 +0100
13703 @@ -0,0 +1,47 @@
13704 +#include <linux/kernel.h>
13705 +#include <linux/sched.h>
13706 +#include <linux/grinternal.h>
13707 +
13708 +void
13709 +gr_log_signal(const int sig, const struct task_struct *t)
13710 +{
13711 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13712 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
13713 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
13714 +               if (t->pid == current->pid) {
13715 +                       security_alert_good(GR_UNISIGLOG_MSG, sig,
13716 +                                           DEFAULTSECARGS);
13717 +               } else {
13718 +                       security_alert_good(GR_DUALSIGLOG_MSG, sig,
13719 +                                           gr_task_fullpath0(t), t->comm,
13720 +                                           t->pid, t->uid, t->euid, t->gid,
13721 +                                           t->egid, gr_parent_task_fullpath0(t),
13722 +                                           t->p_pptr->comm,
13723 +                                           t->p_pptr->pid, t->p_pptr->uid,
13724 +                                           t->p_pptr->euid, t->p_pptr->gid,
13725 +                                           t->p_pptr->egid, DEFAULTSECARGS);
13726 +               }
13727 +       }
13728 +#endif
13729 +       return;
13730 +}
13731 +
13732 +int
13733 +gr_handle_signal(const struct task_struct *p, const int sig)
13734 +{
13735 +#ifdef CONFIG_GRKERNSEC
13736 +       if (current->pid > 1 && gr_check_protected_task(p)) {
13737 +               security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p),
13738 +                              p->comm, p->pid, p->uid,
13739 +                              p->euid, p->gid, p->egid,
13740 +                              gr_parent_task_fullpath0(p), p->p_pptr->comm,
13741 +                              p->p_pptr->pid, p->p_pptr->uid,
13742 +                              p->p_pptr->euid, p->p_pptr->gid,
13743 +                              p->p_pptr->egid, DEFAULTSECARGS);
13744 +               return -EPERM;
13745 +       } else if (gr_pid_is_chrooted(p)) {
13746 +               return -EPERM;
13747 +       }
13748 +#endif
13749 +       return 0;
13750 +}
13751 diff -urN linux-2.4.24.org/grsecurity/grsec_sock.c linux-2.4.24/grsecurity/grsec_sock.c
13752 --- linux-2.4.24.org/grsecurity/grsec_sock.c    1970-01-01 01:00:00.000000000 +0100
13753 +++ linux-2.4.24/grsecurity/grsec_sock.c        2004-02-04 23:11:33.508778725 +0100
13754 @@ -0,0 +1,205 @@
13755 +#include <linux/kernel.h>
13756 +#include <linux/sched.h>
13757 +#include <linux/file.h>
13758 +#include <linux/net.h>
13759 +#include <net/sock.h>
13760 +#include <linux/grsecurity.h>
13761 +#include <linux/grinternal.h>
13762 +#include <linux/gracl.h>
13763 +
13764 +#ifdef CONFIG_GRKERNSEC
13765 +struct task_struct **gr_conn_table;
13766 +const unsigned int gr_conn_table_size = 65521;
13767 +struct task_struct *deleted_conn = (struct task_struct *)~0;
13768 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
13769 +
13770 +extern __inline__ const char * gr_socktype_to_name(unsigned char type);
13771 +extern __inline__ const char * gr_proto_to_name(unsigned char proto);
13772 +
13773 +static __inline__ int 
13774 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
13775 +{
13776 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
13777 +}
13778 +
13779 +static __inline__ int
13780 +conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr, 
13781 +          __u16 sport, __u16 dport)
13782 +{
13783 +       if (unlikely(task != deleted_conn && task->gr_saddr == saddr && 
13784 +                    task->gr_daddr == daddr && task->gr_sport == sport &&
13785 +                    task->gr_dport == dport))
13786 +               return 1;
13787 +       else
13788 +               return 0;
13789 +}
13790 +
13791 +void gr_add_to_task_ip_table(struct task_struct *task)
13792 +{
13793 +       unsigned int index;
13794 +
13795 +       if (unlikely(gr_conn_table == NULL))
13796 +               return;
13797 +
13798 +       index = conn_hash(task->gr_saddr, task->gr_daddr,
13799 +                         task->gr_sport, task->gr_dport, 
13800 +                         gr_conn_table_size);
13801 +
13802 +       spin_lock(&gr_conn_table_lock);
13803 +
13804 +       while (gr_conn_table[index] && gr_conn_table[index] != deleted_conn) {
13805 +               index = (index + 1) % gr_conn_table_size;
13806 +       }
13807 +
13808 +       gr_conn_table[index] = task;
13809 +
13810 +       spin_unlock(&gr_conn_table_lock);
13811 +
13812 +       return;
13813 +}
13814 +
13815 +void gr_del_task_from_ip_table_nolock(struct task_struct *task)
13816 +{
13817 +       unsigned int index;
13818 +
13819 +       if (unlikely(gr_conn_table == NULL))
13820 +               return;
13821 +
13822 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
13823 +                         task->gr_sport, task->gr_dport, 
13824 +                         gr_conn_table_size);
13825 +
13826 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
13827 +               task->gr_saddr, task->gr_daddr, task->gr_sport, 
13828 +               task->gr_dport)) {
13829 +               index = (index + 1) % gr_conn_table_size;
13830 +       }
13831 +
13832 +       if (gr_conn_table[index] && conn_match(gr_conn_table[index],
13833 +               task->gr_saddr, task->gr_daddr, task->gr_sport, 
13834 +               task->gr_dport)) {
13835 +               if (gr_conn_table[(index + 1) % gr_conn_table_size])
13836 +                       gr_conn_table[index] = deleted_conn;
13837 +               else
13838 +                       gr_conn_table[index] = NULL;
13839 +       }
13840 +
13841 +       return;
13842 +}
13843 +
13844 +struct task_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
13845 +                                            __u16 sport, __u16 dport)
13846 +{
13847 +       unsigned int index;
13848 +
13849 +       if (unlikely(gr_conn_table == NULL))
13850 +               return NULL;
13851 +
13852 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
13853 +
13854 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
13855 +               saddr, daddr, sport, dport)) {
13856 +               index = (index + 1) % gr_conn_table_size;
13857 +       }
13858 +
13859 +       if (unlikely(gr_conn_table[index] && conn_match(gr_conn_table[index],
13860 +                    saddr, daddr, sport, dport)))
13861 +               return gr_conn_table[index];
13862 +       else
13863 +               return NULL;
13864 +}
13865 +
13866 +#endif
13867 +
13868 +void gr_del_task_from_ip_table(struct task_struct *task)
13869 +{
13870 +#ifdef CONFIG_GRKERNSEC
13871 +       spin_lock(&gr_conn_table_lock);
13872 +       gr_del_task_from_ip_table_nolock(task);
13873 +       spin_unlock(&gr_conn_table_lock);
13874 +#endif
13875 +       return;
13876 +}
13877 +
13878 +void
13879 +gr_attach_curr_ip(const struct sock *sk)
13880 +{
13881 +#ifdef CONFIG_GRKERNSEC
13882 +       struct task_struct *p;
13883 +
13884 +       if (unlikely(sk->protocol != IPPROTO_TCP))
13885 +               return;
13886 +
13887 +       spin_lock(&gr_conn_table_lock);
13888 +       p = gr_lookup_task_ip_table(sk->daddr, sk->rcv_saddr,
13889 +                                   sk->dport, sk->sport);
13890 +       if (unlikely(p != NULL)) {
13891 +               current->curr_ip = p->curr_ip;
13892 +               current->used_accept = 1;
13893 +               gr_del_task_from_ip_table_nolock(p);
13894 +               spin_unlock(&gr_conn_table_lock);
13895 +               return;
13896 +       }
13897 +       spin_unlock(&gr_conn_table_lock);
13898 +
13899 +       current->curr_ip = sk->daddr;
13900 +       current->used_accept = 1;
13901 +#endif
13902 +       return;
13903 +}
13904 +
13905 +int
13906 +gr_handle_sock_all(const int family, const int type, const int protocol)
13907 +{
13908 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13909 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
13910 +           (family != AF_UNIX) && (family != AF_LOCAL) && (type < SOCK_MAX)) {
13911 +               security_alert(GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol),
13912 +                              DEFAULTSECARGS);
13913 +               return -EACCES;
13914 +       }
13915 +#endif
13916 +       return 0;
13917 +}
13918 +
13919 +int
13920 +gr_handle_sock_server(const struct sockaddr *sck)
13921 +{
13922 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13923 +       if (grsec_enable_socket_server &&
13924 +           in_group_p(grsec_socket_server_gid) &&
13925 +           sck && (sck->sa_family != AF_UNIX) &&
13926 +           (sck->sa_family != AF_LOCAL)) {
13927 +               security_alert(GR_BIND_MSG, DEFAULTSECARGS);
13928 +               return -EACCES;
13929 +       }
13930 +#endif
13931 +       return 0;
13932 +}
13933 +
13934 +int
13935 +gr_handle_sock_client(const struct sockaddr *sck)
13936 +{
13937 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13938 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
13939 +           sck && (sck->sa_family != AF_UNIX) &&
13940 +           (sck->sa_family != AF_LOCAL)) {
13941 +               security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
13942 +               return -EACCES;
13943 +       }
13944 +#endif
13945 +       return 0;
13946 +}
13947 +
13948 +__u32
13949 +gr_cap_rtnetlink(void)
13950 +{
13951 +#ifdef CONFIG_GRKERNSEC
13952 +       if (!gr_acl_is_enabled())
13953 +               return current->cap_effective;
13954 +       else
13955 +               return (current->cap_effective & ~(current->acl->cap_lower));
13956 +#else
13957 +       return current->cap_effective;
13958 +#endif
13959 +}
13960 diff -urN linux-2.4.24.org/grsecurity/grsec_sysctl.c linux-2.4.24/grsecurity/grsec_sysctl.c
13961 --- linux-2.4.24.org/grsecurity/grsec_sysctl.c  1970-01-01 01:00:00.000000000 +0100
13962 +++ linux-2.4.24/grsecurity/grsec_sysctl.c      2004-02-04 23:11:33.509778517 +0100
13963 @@ -0,0 +1,16 @@
13964 +#include <linux/kernel.h>
13965 +#include <linux/sched.h>
13966 +#include <linux/sysctl.h>
13967 +#include <linux/grinternal.h>
13968 +
13969 +int
13970 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
13971 +{
13972 +#ifdef CONFIG_GRKERNSEC_SYSCTL
13973 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
13974 +               security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
13975 +               return -EACCES;
13976 +       }
13977 +#endif
13978 +       return 0;
13979 +}
13980 diff -urN linux-2.4.24.org/grsecurity/grsec_time.c linux-2.4.24/grsecurity/grsec_time.c
13981 --- linux-2.4.24.org/grsecurity/grsec_time.c    1970-01-01 01:00:00.000000000 +0100
13982 +++ linux-2.4.24/grsecurity/grsec_time.c        2004-02-04 23:11:33.511778101 +0100
13983 @@ -0,0 +1,13 @@
13984 +#include <linux/kernel.h>
13985 +#include <linux/sched.h>
13986 +#include <linux/grinternal.h>
13987 +
13988 +void
13989 +gr_log_timechange(void)
13990 +{
13991 +#ifdef CONFIG_GRKERNSEC_TIME
13992 +       if (grsec_enable_time)
13993 +               security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
13994 +#endif
13995 +       return;
13996 +}
13997 diff -urN linux-2.4.24.org/grsecurity/grsec_tpe.c linux-2.4.24/grsecurity/grsec_tpe.c
13998 --- linux-2.4.24.org/grsecurity/grsec_tpe.c     1970-01-01 01:00:00.000000000 +0100
13999 +++ linux-2.4.24/grsecurity/grsec_tpe.c 2004-02-04 23:11:33.527774775 +0100
14000 @@ -0,0 +1,35 @@
14001 +#include <linux/kernel.h>
14002 +#include <linux/sched.h>
14003 +#include <linux/file.h>
14004 +#include <linux/fs.h>
14005 +#include <linux/grinternal.h>
14006 +
14007 +extern int gr_acl_tpe_check(void);
14008 +
14009 +int
14010 +gr_tpe_allow(const struct file *file)
14011 +{
14012 +#ifdef CONFIG_GRKERNSEC
14013 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
14014 +
14015 +       if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
14016 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
14017 +                                               (inode->i_mode & S_IWOTH))))) {
14018 +               security_alert(GR_EXEC_TPE_MSG,
14019 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
14020 +                              DEFAULTSECARGS);
14021 +               return 0;
14022 +       }
14023 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
14024 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
14025 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
14026 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
14027 +               security_alert(GR_EXEC_TPE_MSG,
14028 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
14029 +                              DEFAULTSECARGS);
14030 +               return 0;
14031 +       }
14032 +#endif
14033 +#endif
14034 +       return 1;
14035 +}
14036 diff -urN linux-2.4.24.org/grsecurity/grsum.c linux-2.4.24/grsecurity/grsum.c
14037 --- linux-2.4.24.org/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100
14038 +++ linux-2.4.24/grsecurity/grsum.c     2004-02-04 23:11:33.529774360 +0100
14039 @@ -0,0 +1,59 @@
14040 +#include <linux/kernel.h>
14041 +#include <linux/sched.h>
14042 +#include <linux/mm.h>
14043 +#include <asm/scatterlist.h>
14044 +#include <linux/crypto.h>
14045 +#include <linux/gracl.h>
14046 +
14047 +
14048 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
14049 +#error "crypto and sha256 must be built into the kernel"
14050 +#endif
14051 +
14052 +int
14053 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
14054 +{
14055 +       char *p;
14056 +       struct crypto_tfm *tfm;
14057 +       unsigned char temp_sum[GR_SHA_LEN];
14058 +       struct scatterlist sg[2];
14059 +       volatile int retval = 0;
14060 +       volatile int dummy = 0;
14061 +       unsigned int i;
14062 +
14063 +       tfm = crypto_alloc_tfm("sha256", 0);
14064 +       if (tfm == NULL) {
14065 +               /* should never happen, since sha256 should be built in */
14066 +               return 1;
14067 +       }
14068 +
14069 +       crypto_digest_init(tfm);
14070 +
14071 +       p = salt;
14072 +       sg[0].page = virt_to_page(p);
14073 +       sg[0].offset = ((long) p & ~PAGE_MASK);
14074 +       sg[0].length = GR_SALT_LEN;
14075 +       
14076 +       crypto_digest_update(tfm, sg, 1);
14077 +
14078 +       p = entry->pw;
14079 +       sg[0].page = virt_to_page(p);
14080 +       sg[0].offset = ((long) p & ~PAGE_MASK);
14081 +       sg[0].length = strlen(entry->pw);
14082 +
14083 +       crypto_digest_update(tfm, sg, 1);
14084 +
14085 +       crypto_digest_final(tfm, temp_sum);
14086 +
14087 +       memset(entry->pw, 0, GR_PW_LEN);
14088 +
14089 +       for (i = 0; i < GR_SHA_LEN; i++)
14090 +               if (sum[i] != temp_sum[i])
14091 +                       retval = 1;
14092 +               else
14093 +                       dummy = 1;      // waste a cycle
14094 +
14095 +       crypto_free_tfm(tfm);
14096 +
14097 +       return retval;
14098 +}
14099 diff -urN linux-2.4.24.org/grsecurity/Makefile linux-2.4.24/grsecurity/Makefile
14100 --- linux-2.4.24.org/grsecurity/Makefile        1970-01-01 01:00:00.000000000 +0100
14101 +++ linux-2.4.24/grsecurity/Makefile    2004-02-04 23:11:33.531773944 +0100
14102 @@ -0,0 +1,24 @@
14103 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
14104 +# during 2001, 2002, and 2003 it has been completely redesigned by
14105 +# Brad Spengler
14106 +#
14107 +# All code in this directory and various hooks inserted throughout the kernel
14108 +# are copyright Brad Spengler, and released under the GPL, unless otherwise
14109 +# noted (as in obsd_rand.c)
14110 +
14111 +O_TARGET := grsec.o
14112 +
14113 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
14114 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
14115 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o
14116 +
14117 +ifeq ($(CONFIG_GRKERNSEC),y)
14118 +obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
14119 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
14120 +       gracl_learn.o
14121 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
14122 +else
14123 +obj-y += grsec_disabled.o
14124 +endif
14125 +
14126 +include $(TOPDIR)/Rules.make
14127 diff -urN linux-2.4.24.org/grsecurity/obsd_rand.c linux-2.4.24/grsecurity/obsd_rand.c
14128 --- linux-2.4.24.org/grsecurity/obsd_rand.c     1970-01-01 01:00:00.000000000 +0100
14129 +++ linux-2.4.24/grsecurity/obsd_rand.c 2004-02-04 23:11:33.535773112 +0100
14130 @@ -0,0 +1,185 @@
14131 +
14132 +/*
14133 + * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
14134 + * 
14135 + * Version 1.89, last modified 19-Sep-99
14136 + *    
14137 + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
14138 + * All rights reserved.
14139 + *
14140 + * Copyright 1998 Niels Provos <provos@citi.umich.edu>
14141 + * All rights reserved.
14142 + * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
14143 + * such a mathematical system to generate more random (yet non-repeating)
14144 + * ids to solve the resolver/named problem.  But Niels designed the
14145 + * actual system based on the constraints.
14146 + *
14147 + * Redistribution and use in source and binary forms, with or without
14148 + * modification, are permitted provided that the following conditions
14149 + * are met:
14150 + * 1. Redistributions of source code must retain the above copyright
14151 + *    notice, this list of conditions and the following disclaimer,
14152 + * 2. Redistributions in binary form must reproduce the above copyright
14153 + *    notice, this list of conditions and the following disclaimer in the
14154 + *    documentation and/or other materials provided with the distribution.
14155 + *
14156 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14157 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14158 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14159 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14160 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14161 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
14162 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
14163 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14164 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
14165 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14166 + */
14167 +
14168 +#include <linux/kernel.h>
14169 +#include <linux/sched.h>
14170 +#include <linux/timer.h>
14171 +#include <linux/smp_lock.h>
14172 +#include <linux/random.h>
14173 +#include <linux/grsecurity.h>
14174 +
14175 +#define RU_OUT 180
14176 +#define RU_MAX 30000
14177 +#define RU_GEN 2
14178 +#define RU_N 32749
14179 +#define RU_AGEN 7
14180 +#define RU_M 31104
14181 +#define PFAC_N 3
14182 +const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
14183 +
14184 +static __u16 ru_x;
14185 +static __u16 ru_seed, ru_seed2;
14186 +static __u16 ru_a, ru_b;
14187 +static __u16 ru_g;
14188 +static __u16 ru_counter = 0;
14189 +static __u16 ru_msb = 0;
14190 +static unsigned long ru_reseed = 0;
14191 +static __u32 tmp;
14192 +
14193 +#define TCP_RNDISS_ROUNDS      15
14194 +#define TCP_RNDISS_OUT         7200
14195 +#define TCP_RNDISS_MAX         30000
14196 +
14197 +static __u8 tcp_rndiss_sbox[128];
14198 +static __u16 tcp_rndiss_msb;
14199 +static __u16 tcp_rndiss_cnt;
14200 +static unsigned long tcp_rndiss_reseed;
14201 +
14202 +static __u16 pmod(__u16, __u16, __u16);
14203 +static void ip_initid(void);
14204 +__u16 ip_randomid(void);
14205 +
14206 +static __u16
14207 +pmod(__u16 gen, __u16 exp, __u16 mod)
14208 +{
14209 +       __u16 s, t, u;
14210 +
14211 +       s = 1;
14212 +       t = gen;
14213 +       u = exp;
14214 +
14215 +       while (u) {
14216 +               if (u & 1)
14217 +                       s = (s * t) % mod;
14218 +               u >>= 1;
14219 +               t = (t * t) % mod;
14220 +       }
14221 +       return (s);
14222 +}
14223 +
14224 +static void
14225 +ip_initid(void)
14226 +{
14227 +       __u16 j, i;
14228 +       int noprime = 1;
14229 +
14230 +       ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
14231 +
14232 +       ru_seed = (tmp >> 16) & 0x7FFF;
14233 +       ru_seed2 = get_random_long() & 0x7FFF;
14234 +
14235 +       ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
14236 +       ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
14237 +       while (ru_b % 3 == 0)
14238 +               ru_b += 2;
14239 +
14240 +       j = (tmp = get_random_long()) % RU_N;
14241 +       tmp = tmp >> 16;
14242 +
14243 +       while (noprime) {
14244 +               for (i = 0; i < PFAC_N; i++)
14245 +                       if (j % pfacts[i] == 0)
14246 +                               break;
14247 +
14248 +               if (i >= PFAC_N)
14249 +                       noprime = 0;
14250 +               else
14251 +                       j = (j + 1) % RU_N;
14252 +       }
14253 +
14254 +       ru_g = pmod(RU_GEN, j, RU_N);
14255 +       ru_counter = 0;
14256 +
14257 +       ru_reseed = xtime.tv_sec + RU_OUT;
14258 +       ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
14259 +}
14260 +
14261 +__u16
14262 +ip_randomid(void)
14263 +{
14264 +       int i, n;
14265 +
14266 +       if (ru_counter >= RU_MAX || time_after(xtime.tv_sec, ru_reseed))
14267 +               ip_initid();
14268 +
14269 +       if (!tmp)
14270 +               tmp = get_random_long();
14271 +
14272 +       n = tmp & 0x3;
14273 +       tmp = tmp >> 2;
14274 +       if (ru_counter + n >= RU_MAX)
14275 +               ip_initid();
14276 +       for (i = 0; i <= n; i++)
14277 +               ru_x = (ru_a * ru_x + ru_b) % RU_M;
14278 +       ru_counter += i;
14279 +
14280 +       return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
14281 +}
14282 +
14283 +__u16
14284 +tcp_rndiss_encrypt(__u16 val)
14285 +{
14286 +       __u16 sum = 0, i;
14287 +
14288 +       for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
14289 +               sum += 0x79b9;
14290 +               val ^= ((__u16) tcp_rndiss_sbox[(val ^ sum) & 0x7f]) << 7;
14291 +               val = ((val & 0xff) << 7) | (val >> 8);
14292 +       }
14293 +
14294 +       return val;
14295 +}
14296 +
14297 +static void
14298 +tcp_rndiss_init(void)
14299 +{
14300 +       get_random_bytes(tcp_rndiss_sbox, sizeof (tcp_rndiss_sbox));
14301 +       tcp_rndiss_reseed = xtime.tv_sec + TCP_RNDISS_OUT;
14302 +       tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
14303 +       tcp_rndiss_cnt = 0;
14304 +}
14305 +
14306 +__u32
14307 +ip_randomisn(void)
14308 +{
14309 +       if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
14310 +           time_after(xtime.tv_sec, tcp_rndiss_reseed))
14311 +               tcp_rndiss_init();
14312 +
14313 +       return (((tcp_rndiss_encrypt(tcp_rndiss_cnt++) |
14314 +                 tcp_rndiss_msb) << 16) | (get_random_long() & 0x7fff));
14315 +}
14316 diff -urN linux-2.4.24.org/include/asm-alpha/a.out.h linux-2.4.24/include/asm-alpha/a.out.h
14317 --- linux-2.4.24.org/include/asm-alpha/a.out.h  2004-02-04 23:05:12.407021261 +0100
14318 +++ linux-2.4.24/include/asm-alpha/a.out.h      2004-02-04 23:11:33.560767916 +0100
14319 @@ -98,7 +98,7 @@
14320         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
14321                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
14322  
14323 -#define STACK_TOP \
14324 +#define __STACK_TOP \
14325    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
14326  
14327  #endif
14328 diff -urN linux-2.4.24.org/include/asm-alpha/elf.h linux-2.4.24/include/asm-alpha/elf.h
14329 --- linux-2.4.24.org/include/asm-alpha/elf.h    2004-02-04 23:05:11.748158261 +0100
14330 +++ linux-2.4.24/include/asm-alpha/elf.h        2004-02-04 23:11:33.596760432 +0100
14331 @@ -41,6 +41,18 @@
14332  
14333  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
14334  
14335 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14336 +#define PAX_ELF_ET_DYN_BASE(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
14337 +
14338 +#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
14339 +#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
14340 +#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
14341 +#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
14342 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14343 +#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
14344 +#endif
14345 +
14346 +
14347  /* $0 is set by ld.so to a pointer to a function which might be 
14348     registered using atexit.  This provides a mean for the dynamic
14349     linker to call DT_FINI functions for shared libraries that have
14350 diff -urN linux-2.4.24.org/include/asm-alpha/mman.h linux-2.4.24/include/asm-alpha/mman.h
14351 --- linux-2.4.24.org/include/asm-alpha/mman.h   2004-02-04 23:05:12.684963467 +0100
14352 +++ linux-2.4.24/include/asm-alpha/mman.h       2004-02-04 23:11:33.640751286 +0100
14353 @@ -24,6 +24,10 @@
14354  #define MAP_LOCKED     0x8000          /* lock the mapping */
14355  #define MAP_NORESERVE  0x10000         /* don't check for reservations */
14356  
14357 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14358 +#define MAP_MIRROR     0x20000
14359 +#endif
14360 +
14361  #define MS_ASYNC       1               /* sync memory asynchronously */
14362  #define MS_SYNC                2               /* synchronous memory sync */
14363  #define MS_INVALIDATE  4               /* invalidate the caches */
14364 diff -urN linux-2.4.24.org/include/asm-alpha/pgtable.h linux-2.4.24/include/asm-alpha/pgtable.h
14365 --- linux-2.4.24.org/include/asm-alpha/pgtable.h        2004-02-04 23:05:12.337035813 +0100
14366 +++ linux-2.4.24/include/asm-alpha/pgtable.h    2004-02-04 23:11:33.681742764 +0100
14367 @@ -96,6 +96,17 @@
14368  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
14369  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
14370  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
14371 +
14372 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14373 +#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
14374 +#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
14375 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
14376 +#else
14377 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14378 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14379 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14380 +#endif
14381 +
14382  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
14383  
14384  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
14385 diff -urN linux-2.4.24.org/include/asm-i386/a.out.h linux-2.4.24/include/asm-i386/a.out.h
14386 --- linux-2.4.24.org/include/asm-i386/a.out.h   2004-02-04 23:05:03.457882094 +0100
14387 +++ linux-2.4.24/include/asm-i386/a.out.h       2004-02-04 23:11:33.717735280 +0100
14388 @@ -19,7 +19,11 @@
14389  
14390  #ifdef __KERNEL__
14391  
14392 -#define STACK_TOP      TASK_SIZE
14393 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14394 +#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
14395 +#else
14396 +#define __STACK_TOP    TASK_SIZE
14397 +#endif
14398  
14399  #endif
14400  
14401 diff -urN linux-2.4.24.org/include/asm-i386/desc.h linux-2.4.24/include/asm-i386/desc.h
14402 --- linux-2.4.24.org/include/asm-i386/desc.h    2004-02-04 23:05:03.540864839 +0100
14403 +++ linux-2.4.24/include/asm-i386/desc.h        2004-02-04 23:20:39.338293845 +0100
14404 @@ -46,7 +46,8 @@
14405  };
14406  
14407  extern struct desc_struct gdt_table[];
14408 -extern struct desc_struct *idt, *gdt;
14409 +extern struct desc_struct gdt_table2[];
14410 +extern struct desc_struct *idt, *gdt, *gdt2;
14411  
14412  struct Xgt_desc_struct {
14413         unsigned short size;
14414 @@ -55,6 +56,7 @@
14415  
14416  #define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
14417  #define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
14418 +#define gdt_descr2 (*(struct Xgt_desc_struct *)((char *)&gdt2 - 2))
14419  
14420  #define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3))
14421  
14422 @@ -64,10 +66,11 @@
14423   * This is the ldt that every process will get unless we need
14424   * something other than this.
14425   */
14426 -extern struct desc_struct default_ldt[];
14427 +extern const struct desc_struct default_ldt[];
14428  extern void set_intr_gate(unsigned int irq, void * addr);
14429 -extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
14430 -extern void set_tss_desc(unsigned int n, void *addr);
14431 +extern void set_ldt_desc(unsigned int n, const void *addr, unsigned int size);
14432 +extern void __set_ldt_desc(unsigned int n, const void *addr, unsigned int size);
14433 +extern void set_tss_desc(unsigned int n, const void *addr);
14434  
14435  static inline void clear_LDT(void)
14436  {
14437 @@ -82,7 +85,7 @@
14438  static inline void load_LDT (mm_context_t *pc)
14439  {
14440         int cpu = smp_processor_id();
14441 -       void *segments = pc->ldt;
14442 +       const void *segments = pc->ldt;
14443         int count = pc->size;
14444  
14445         if (!count) {
14446 @@ -94,6 +97,21 @@
14447         __load_LDT(cpu);
14448  }
14449  
14450 +static inline void _load_LDT (mm_context_t *pc)
14451 +{
14452 +       int cpu = smp_processor_id();
14453 +       const void *segments = pc->ldt;
14454 +       int count = LDT_ENTRIES;
14455 +
14456 +       if (!segments) {
14457 +               segments = &default_ldt[0];
14458 +               count = 5;
14459 +       }
14460 +               
14461 +       __set_ldt_desc(cpu, segments, count);
14462 +       __load_LDT(cpu);
14463 +}
14464 +
14465  #endif /* !__ASSEMBLY__ */
14466  
14467  #endif
14468 diff -urN linux-2.4.24.org/include/asm-i386/elf.h linux-2.4.24/include/asm-i386/elf.h
14469 --- linux-2.4.24.org/include/asm-i386/elf.h     2004-02-04 23:05:02.447092272 +0100
14470 +++ linux-2.4.24/include/asm-i386/elf.h 2004-02-04 23:11:33.825712830 +0100
14471 @@ -55,7 +55,22 @@
14472     the loader.  We need to make sure that it is out of the way of the program
14473     that it will "exec", and that there is sufficient room for the brk.  */
14474  
14475 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14476 +#define ELF_ET_DYN_BASE                ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2)
14477 +#else
14478  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
14479 +#endif
14480 +
14481 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14482 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
14483 +
14484 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14485 +#define PAX_DELTA_MMAP_LEN(tsk)                16
14486 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14487 +#define PAX_DELTA_EXEC_LEN(tsk)                16
14488 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT  
14489 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
14490 +#endif
14491  
14492  /* Wow, the "main" arch needs arch dependent functions too.. :) */
14493  
14494 diff -urN linux-2.4.24.org/include/asm-i386/hw_irq.h linux-2.4.24/include/asm-i386/hw_irq.h
14495 --- linux-2.4.24.org/include/asm-i386/hw_irq.h  2004-02-04 23:05:02.650050070 +0100
14496 +++ linux-2.4.24/include/asm-i386/hw_irq.h      2004-02-04 23:11:33.851707426 +0100
14497 @@ -128,6 +128,7 @@
14498  asmlinkage void x(void); \
14499  asmlinkage void call_##x(void); \
14500  __asm__( \
14501 +"\n .text" \
14502  "\n"__ALIGN_STR"\n" \
14503  SYMBOL_NAME_STR(x) ":\n\t" \
14504         "pushl $"#v"-256\n\t" \
14505 @@ -141,6 +142,7 @@
14506  asmlinkage void x(struct pt_regs * regs); \
14507  asmlinkage void call_##x(void); \
14508  __asm__( \
14509 +"\n .text" \
14510  "\n"__ALIGN_STR"\n" \
14511  SYMBOL_NAME_STR(x) ":\n\t" \
14512         "pushl $"#v"-256\n\t" \
14513 @@ -155,6 +157,7 @@
14514  #define BUILD_COMMON_IRQ() \
14515  asmlinkage void call_do_IRQ(void); \
14516  __asm__( \
14517 +       "\n .text" \
14518         "\n" __ALIGN_STR"\n" \
14519         "common_interrupt:\n\t" \
14520         SAVE_ALL \
14521 @@ -175,6 +178,7 @@
14522  #define BUILD_IRQ(nr) \
14523  asmlinkage void IRQ_NAME(nr); \
14524  __asm__( \
14525 +"\n .text" \
14526  "\n"__ALIGN_STR"\n" \
14527  SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
14528         "pushl $"#nr"-256\n\t" \
14529 diff -urN linux-2.4.24.org/include/asm-i386/mman.h linux-2.4.24/include/asm-i386/mman.h
14530 --- linux-2.4.24.org/include/asm-i386/mman.h    2004-02-04 23:05:03.509871284 +0100
14531 +++ linux-2.4.24/include/asm-i386/mman.h        2004-02-04 23:11:33.883700774 +0100
14532 @@ -18,6 +18,10 @@
14533  #define MAP_LOCKED     0x2000          /* pages are locked */
14534  #define MAP_NORESERVE  0x4000          /* don't check for reservations */
14535  
14536 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
14537 +#define MAP_MIRROR     0x8000
14538 +#endif
14539 +
14540  #define MS_ASYNC       1               /* sync memory asynchronously */
14541  #define MS_INVALIDATE  2               /* invalidate the caches */
14542  #define MS_SYNC                4               /* synchronous memory sync */
14543 diff -urN linux-2.4.24.org/include/asm-i386/page.h linux-2.4.24/include/asm-i386/page.h
14544 --- linux-2.4.24.org/include/asm-i386/page.h    2004-02-04 23:05:03.322910160 +0100
14545 +++ linux-2.4.24/include/asm-i386/page.h        2004-02-04 23:11:33.888699735 +0100
14546 @@ -78,7 +78,7 @@
14547   * and CONFIG_HIGHMEM64G options in the kernel configuration.
14548   */
14549  
14550 -#define __PAGE_OFFSET          (0xC0000000)
14551 +#include <asm/page_offset.h>
14552  
14553  /*
14554   * This much address space is reserved for vmalloc() and iomap()
14555 diff -urN linux-2.4.24.org/include/asm-i386/page_offset.h linux-2.4.24/include/asm-i386/page_offset.h
14556 --- linux-2.4.24.org/include/asm-i386/page_offset.h     1970-01-01 01:00:00.000000000 +0100
14557 +++ linux-2.4.24/include/asm-i386/page_offset.h 2004-02-04 23:11:33.892698903 +0100
14558 @@ -0,0 +1,2 @@
14559 +#define __KERNEL_TEXT_OFFSET   (0xC0400000)
14560 +#define __PAGE_OFFSET          (0xC0000000)
14561 diff -urN linux-2.4.24.org/include/asm-i386/pgtable.h linux-2.4.24/include/asm-i386/pgtable.h
14562 --- linux-2.4.24.org/include/asm-i386/pgtable.h 2004-02-04 23:05:03.210933443 +0100
14563 +++ linux-2.4.24/include/asm-i386/pgtable.h     2004-02-04 23:11:33.919693291 +0100
14564 @@ -205,6 +205,16 @@
14565  #define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
14566  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
14567  
14568 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14569 +#define PAGE_SHARED_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
14570 +#define PAGE_COPY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
14571 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) 
14572 +#else
14573 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14574 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14575 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14576 +#endif
14577 +
14578  #define __PAGE_KERNEL \
14579         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
14580  #define __PAGE_KERNEL_NOCACHE \
14581 @@ -237,18 +247,18 @@
14582   * This is the closest we can get..
14583   */
14584  #define __P000 PAGE_NONE
14585 -#define __P001 PAGE_READONLY
14586 -#define __P010 PAGE_COPY
14587 -#define __P011 PAGE_COPY
14588 +#define __P001  PAGE_READONLY_NOEXEC
14589 +#define __P010  PAGE_COPY_NOEXEC
14590 +#define __P011  PAGE_COPY_NOEXEC
14591  #define __P100 PAGE_READONLY
14592  #define __P101 PAGE_READONLY
14593  #define __P110 PAGE_COPY
14594  #define __P111 PAGE_COPY
14595  
14596  #define __S000 PAGE_NONE
14597 -#define __S001 PAGE_READONLY
14598 -#define __S010 PAGE_SHARED
14599 -#define __S011 PAGE_SHARED
14600 +#define __S001  PAGE_READONLY_NOEXEC
14601 +#define __S010  PAGE_SHARED_NOEXEC
14602 +#define __S011  PAGE_SHARED_NOEXEC
14603  #define __S100 PAGE_READONLY
14604  #define __S101 PAGE_READONLY
14605  #define __S110 PAGE_SHARED
14606 @@ -324,7 +334,7 @@
14607  ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
14608  
14609  /* to find an entry in a page-table-directory. */
14610 -#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14611 +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14612  
14613  #define __pgd_offset(address) pgd_index(address)
14614  
14615 diff -urN linux-2.4.24.org/include/asm-i386/processor.h linux-2.4.24/include/asm-i386/processor.h
14616 --- linux-2.4.24.org/include/asm-i386/processor.h       2004-02-04 23:05:02.557069404 +0100
14617 +++ linux-2.4.24/include/asm-i386/processor.h   2004-02-04 23:11:33.960684768 +0100
14618 @@ -261,10 +261,19 @@
14619   */
14620  #define TASK_SIZE      (PAGE_OFFSET)
14621  
14622 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14623 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
14624 +#endif
14625 +
14626  /* This decides where the kernel will search for a free chunk of vm
14627   * space during mmap's.
14628   */
14629 +
14630 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14631 +#define TASK_UNMAPPED_BASE     ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3)
14632 +#else
14633  #define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
14634 +#endif
14635  
14636  /*
14637   * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
14638 diff -urN linux-2.4.24.org/include/asm-i386/system.h linux-2.4.24/include/asm-i386/system.h
14639 --- linux-2.4.24.org/include/asm-i386/system.h  2004-02-04 23:05:05.777399787 +0100
14640 +++ linux-2.4.24/include/asm-i386/system.h      2004-02-04 23:11:34.125650470 +0100
14641 @@ -11,6 +11,7 @@
14642  
14643  struct task_struct;    /* one of the stranger aspects of C forward declarations.. */
14644  extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
14645 +void pax_switch_segments(struct task_struct *);
14646  
14647  #define switch_to(prev,next,last) do {                                 \
14648         asm volatile("pushl %%esi\n\t"                                  \
14649 diff -urN linux-2.4.24.org/include/asm-parisc/a.out.h linux-2.4.24/include/asm-parisc/a.out.h
14650 --- linux-2.4.24.org/include/asm-parisc/a.out.h 2004-02-04 23:05:51.860817467 +0100
14651 +++ linux-2.4.24/include/asm-parisc/a.out.h     2004-02-04 23:11:34.647541962 +0100
14652 @@ -22,7 +22,7 @@
14653  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
14654   * prumpf */
14655  
14656 -#define STACK_TOP      TASK_SIZE
14657 +#define __STACK_TOP    TASK_SIZE
14658  
14659  #endif
14660  
14661 diff -urN linux-2.4.24.org/include/asm-parisc/elf.h linux-2.4.24/include/asm-parisc/elf.h
14662 --- linux-2.4.24.org/include/asm-parisc/elf.h   2004-02-04 23:05:51.103974841 +0100
14663 +++ linux-2.4.24/include/asm-parisc/elf.h       2004-02-04 23:11:34.674536350 +0100
14664 @@ -135,6 +135,17 @@
14665  
14666  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
14667  
14668 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14669 +#define PAX_ELF_ET_DYN_BASE(tsk)        0x10000UL
14670 +
14671 +#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
14672 +#define PAX_DELTA_MMAP_LEN(tsk)         16
14673 +#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
14674 +#define PAX_DELTA_EXEC_LEN(tsk)         16
14675 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14676 +#define PAX_DELTA_STACK_LEN(tsk)        16
14677 +#endif
14678 +
14679  /* This yields a mask that user programs can use to figure out what
14680     instruction set this CPU supports.  This could be done in user space,
14681     but it's not easy, and we've already done it here.  */
14682 diff -urN linux-2.4.24.org/include/asm-parisc/mman.h linux-2.4.24/include/asm-parisc/mman.h
14683 --- linux-2.4.24.org/include/asm-parisc/mman.h  2004-02-04 23:05:51.947799381 +0100
14684 +++ linux-2.4.24/include/asm-parisc/mman.h      2004-02-04 23:11:34.698531361 +0100
14685 @@ -18,6 +18,10 @@
14686  #define MAP_NORESERVE  0x4000          /* don't check for reservations */
14687  #define MAP_GROWSDOWN  0x8000          /* stack-like segment */
14688  
14689 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14690 +#define MAP_MIRROR     0x0400
14691 +#endif
14692 +
14693  #define MS_SYNC                1               /* synchronous memory sync */
14694  #define MS_ASYNC       2               /* sync memory asynchronously */
14695  #define MS_INVALIDATE  4               /* invalidate the caches */
14696 diff -urN linux-2.4.24.org/include/asm-parisc/pgtable.h linux-2.4.24/include/asm-parisc/pgtable.h
14697 --- linux-2.4.24.org/include/asm-parisc/pgtable.h       2004-02-04 23:05:51.137967772 +0100
14698 +++ linux-2.4.24/include/asm-parisc/pgtable.h   2004-02-04 23:11:34.728525125 +0100
14699 @@ -167,6 +167,17 @@
14700  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
14701  #define PAGE_COPY       PAGE_EXECREAD
14702  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
14703 +
14704 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14705 +#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
14706 +#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14707 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14708 +#else
14709 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14710 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14711 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14712 +#endif
14713 +
14714  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
14715  #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
14716  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
14717 diff -urN linux-2.4.24.org/include/asm-ppc/a.out.h linux-2.4.24/include/asm-ppc/a.out.h
14718 --- linux-2.4.24.org/include/asm-ppc/a.out.h    2004-02-04 23:05:22.174990165 +0100
14719 +++ linux-2.4.24/include/asm-ppc/a.out.h        2004-02-04 23:11:34.754519720 +0100
14720 @@ -2,7 +2,7 @@
14721  #define __PPC_A_OUT_H__
14722  
14723  /* grabbed from the intel stuff  */
14724 -#define STACK_TOP TASK_SIZE
14725 +#define __STACK_TOP TASK_SIZE
14726  
14727  
14728  struct exec
14729 diff -urN linux-2.4.24.org/include/asm-ppc/elf.h linux-2.4.24/include/asm-ppc/elf.h
14730 --- linux-2.4.24.org/include/asm-ppc/elf.h      2004-02-04 23:05:22.842851294 +0100
14731 +++ linux-2.4.24/include/asm-ppc/elf.h  2004-02-04 23:11:34.787512861 +0100
14732 @@ -46,6 +46,17 @@
14733  
14734  #define ELF_ET_DYN_BASE         (0x08000000)
14735  
14736 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14737 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
14738 +
14739 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14740 +#define PAX_DELTA_MMAP_LEN(tsk)                15
14741 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14742 +#define PAX_DELTA_EXEC_LEN(tsk)                15
14743 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
14744 +#define PAX_DELTA_STACK_LEN(tsk)       15
14745 +#endif
14746 +
14747  #define USE_ELF_CORE_DUMP
14748  #define ELF_EXEC_PAGESIZE      4096
14749  
14750 diff -urN linux-2.4.24.org/include/asm-ppc/mman.h linux-2.4.24/include/asm-ppc/mman.h
14751 --- linux-2.4.24.org/include/asm-ppc/mman.h     2004-02-04 23:05:22.697881438 +0100
14752 +++ linux-2.4.24/include/asm-ppc/mman.h 2004-02-04 23:11:34.798510574 +0100
14753 @@ -19,6 +19,10 @@
14754  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14755  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14756  
14757 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14758 +#define MAP_MIRROR     0x0200
14759 +#endif
14760 +
14761  #define MS_ASYNC       1               /* sync memory asynchronously */
14762  #define MS_INVALIDATE  2               /* invalidate the caches */
14763  #define MS_SYNC                4               /* synchronous memory sync */
14764 diff -urN linux-2.4.24.org/include/asm-ppc/pgtable.h linux-2.4.24/include/asm-ppc/pgtable.h
14765 --- linux-2.4.24.org/include/asm-ppc/pgtable.h  2004-02-04 23:05:21.658097645 +0100
14766 +++ linux-2.4.24/include/asm-ppc/pgtable.h      2004-02-04 23:11:34.822505585 +0100
14767 @@ -400,6 +400,16 @@
14768  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
14769  #define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
14770  
14771 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14772 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
14773 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14774 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14775 +#else
14776 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
14777 +# define PAGE_COPY_NOEXEC      PAGE_COPY
14778 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
14779 +#endif
14780 +
14781  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
14782  #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_SHARED)
14783  #define PAGE_KERNEL_CI __pgprot(_PAGE_IO)
14784 @@ -411,21 +421,21 @@
14785   * This is the closest we can get..
14786   */
14787  #define __P000 PAGE_NONE
14788 -#define __P001 PAGE_READONLY_X
14789 -#define __P010 PAGE_COPY
14790 -#define __P011 PAGE_COPY_X
14791 -#define __P100 PAGE_READONLY
14792 +#define __P001 PAGE_READONLY_NOEXEC
14793 +#define __P010 PAGE_COPY_NOEXEC
14794 +#define __P011 PAGE_COPY_NOEXEC
14795 +#define __P100 PAGE_READONLY_X
14796  #define __P101 PAGE_READONLY_X
14797 -#define __P110 PAGE_COPY
14798 +#define __P110 PAGE_COPY_X
14799  #define __P111 PAGE_COPY_X
14800  
14801  #define __S000 PAGE_NONE
14802 -#define __S001 PAGE_READONLY_X
14803 -#define __S010 PAGE_SHARED
14804 -#define __S011 PAGE_SHARED_X
14805 -#define __S100 PAGE_READONLY
14806 +#define __S001 PAGE_READONLY_NOEXEC
14807 +#define __S010 PAGE_SHARED_NOEXEC
14808 +#define __S011 PAGE_SHARED_NOEXEC
14809 +#define __S100 PAGE_READONLY_X
14810  #define __S101 PAGE_READONLY_X
14811 -#define __S110 PAGE_SHARED
14812 +#define __S110 PAGE_SHARED_X
14813  #define __S111 PAGE_SHARED_X
14814  
14815  #ifndef __ASSEMBLY__
14816 diff -urN linux-2.4.24.org/include/asm-sparc/a.out.h linux-2.4.24/include/asm-sparc/a.out.h
14817 --- linux-2.4.24.org/include/asm-sparc/a.out.h  2004-02-04 23:05:17.864886383 +0100
14818 +++ linux-2.4.24/include/asm-sparc/a.out.h      2004-02-04 23:11:34.886492282 +0100
14819 @@ -91,7 +91,7 @@
14820  
14821  #include <asm/page.h>
14822  
14823 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
14824 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
14825  
14826  #endif /* __KERNEL__ */
14827  
14828 diff -urN linux-2.4.24.org/include/asm-sparc/elf.h linux-2.4.24/include/asm-sparc/elf.h
14829 --- linux-2.4.24.org/include/asm-sparc/elf.h    2004-02-04 23:05:17.976863100 +0100
14830 +++ linux-2.4.24/include/asm-sparc/elf.h        2004-02-04 23:11:34.921485006 +0100
14831 @@ -83,6 +83,18 @@
14832  
14833  #define ELF_ET_DYN_BASE         (0x08000000)
14834  
14835 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14836 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
14837 +
14838 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14839 +#define PAX_DELTA_MMAP_LEN(tsk)                16
14840 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14841 +#define PAX_DELTA_EXEC_LEN(tsk)                16
14842 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
14843 +#define PAX_DELTA_STACK_LEN(tsk)       16
14844 +#endif
14845 +
14846 +
14847  /* This yields a mask that user programs can use to figure out what
14848     instruction set this cpu supports.  This can NOT be done in userspace
14849     on Sparc.  */
14850 diff -urN linux-2.4.24.org/include/asm-sparc/mman.h linux-2.4.24/include/asm-sparc/mman.h
14851 --- linux-2.4.24.org/include/asm-sparc/mman.h   2004-02-04 23:05:17.597941890 +0100
14852 +++ linux-2.4.24/include/asm-sparc/mman.h       2004-02-04 23:11:34.958477315 +0100
14853 @@ -24,6 +24,10 @@
14854  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14855  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14856  
14857 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14858 +#define MAP_MIRROR     0x0400
14859 +#endif
14860 +
14861  #define MS_ASYNC       1               /* sync memory asynchronously */
14862  #define MS_INVALIDATE  2               /* invalidate the caches */
14863  #define MS_SYNC                4               /* synchronous memory sync */
14864 diff -urN linux-2.4.24.org/include/asm-sparc/pgtable.h linux-2.4.24/include/asm-sparc/pgtable.h
14865 --- linux-2.4.24.org/include/asm-sparc/pgtable.h        2004-02-04 23:05:17.789901975 +0100
14866 +++ linux-2.4.24/include/asm-sparc/pgtable.h    2004-02-04 23:11:34.975473781 +0100
14867 @@ -97,6 +97,13 @@
14868  BTFIXUPDEF_INT(page_shared)
14869  BTFIXUPDEF_INT(page_copy)
14870  BTFIXUPDEF_INT(page_readonly)
14871 +
14872 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14873 +BTFIXUPDEF_INT(page_shared_noexec)
14874 +BTFIXUPDEF_INT(page_copy_noexec)
14875 +BTFIXUPDEF_INT(page_readonly_noexec)
14876 +#endif
14877 +
14878  BTFIXUPDEF_INT(page_kernel)
14879  
14880  #define PMD_SHIFT              BTFIXUP_SIMM13(pmd_shift)
14881 @@ -118,6 +125,16 @@
14882  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
14883  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
14884  
14885 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14886 +#define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
14887 +#define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
14888 +#define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
14889 +#else
14890 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14891 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14892 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14893 +#endif
14894 +
14895  extern unsigned long page_kernel;
14896  
14897  #ifdef MODULE
14898 diff -urN linux-2.4.24.org/include/asm-sparc/pgtsrmmu.h linux-2.4.24/include/asm-sparc/pgtsrmmu.h
14899 --- linux-2.4.24.org/include/asm-sparc/pgtsrmmu.h       2004-02-04 23:05:17.395983884 +0100
14900 +++ linux-2.4.24/include/asm-sparc/pgtsrmmu.h   2004-02-04 23:11:35.011466298 +0100
14901 @@ -76,6 +76,15 @@
14902                                     SRMMU_EXEC | SRMMU_REF)
14903  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14904                                     SRMMU_EXEC | SRMMU_REF)
14905 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14906 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14907 +                                          SRMMU_WRITE | SRMMU_REF)
14908 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14909 +                                          SRMMU_REF)
14910 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14911 +                                          SRMMU_REF)
14912 +#endif
14913 +
14914  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
14915                                     SRMMU_DIRTY | SRMMU_REF)
14916  
14917 diff -urN linux-2.4.24.org/include/asm-sparc/uaccess.h linux-2.4.24/include/asm-sparc/uaccess.h
14918 --- linux-2.4.24.org/include/asm-sparc/uaccess.h        2004-02-04 23:05:17.554950830 +0100
14919 +++ linux-2.4.24/include/asm-sparc/uaccess.h    2004-02-04 23:11:35.048458607 +0100
14920 @@ -39,7 +39,7 @@
14921   * No one can read/write anything from userland in the kernel space by setting
14922   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
14923   */
14924 -#define __user_ok(addr,size) ((addr) < STACK_TOP)
14925 +#define __user_ok(addr,size) ((addr) < __STACK_TOP)
14926  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
14927  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
14928  #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
14929 diff -urN linux-2.4.24.org/include/asm-sparc64/a.out.h linux-2.4.24/include/asm-sparc64/a.out.h
14930 --- linux-2.4.24.org/include/asm-sparc64/a.out.h        2004-02-04 23:05:25.314337387 +0100
14931 +++ linux-2.4.24/include/asm-sparc64/a.out.h    2004-02-04 23:11:35.078452371 +0100
14932 @@ -95,7 +95,7 @@
14933  
14934  #ifdef __KERNEL__
14935  
14936 -#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14937 +#define __STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14938  
14939  #endif
14940  
14941 diff -urN linux-2.4.24.org/include/asm-sparc64/elf.h linux-2.4.24/include/asm-sparc64/elf.h
14942 --- linux-2.4.24.org/include/asm-sparc64/elf.h  2004-02-04 23:05:24.131583322 +0100
14943 +++ linux-2.4.24/include/asm-sparc64/elf.h      2004-02-04 23:11:35.100447798 +0100
14944 @@ -82,6 +82,17 @@
14945  #define ELF_ET_DYN_BASE         0x0000010000000000UL
14946  #endif
14947  
14948 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14949 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 0x10000UL : 0x100000UL)
14950 +
14951 +#define PAX_DELTA_MMAP_LSB(tsk)         (PAGE_SHIFT + 1)
14952 +#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14953 +#define PAX_DELTA_EXEC_LSB(tsk)         (PAGE_SHIFT + 1)
14954 +#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14955 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14956 +#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 15 : 29 )
14957 +#endif
14958 +
14959  
14960  /* This yields a mask that user programs can use to figure out what
14961     instruction set this cpu supports.  */
14962 diff -urN linux-2.4.24.org/include/asm-sparc64/mman.h linux-2.4.24/include/asm-sparc64/mman.h
14963 --- linux-2.4.24.org/include/asm-sparc64/mman.h 2004-02-04 23:05:24.097590390 +0100
14964 +++ linux-2.4.24/include/asm-sparc64/mman.h     2004-02-04 23:11:35.125442601 +0100
14965 @@ -24,6 +24,10 @@
14966  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14967  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14968  
14969 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14970 +#define MAP_MIRROR     0x0400
14971 +#endif
14972 +
14973  #define MS_ASYNC       1               /* sync memory asynchronously */
14974  #define MS_INVALIDATE  2               /* invalidate the caches */
14975  #define MS_SYNC                4               /* synchronous memory sync */
14976 diff -urN linux-2.4.24.org/include/asm-sparc64/pgtable.h linux-2.4.24/include/asm-sparc64/pgtable.h
14977 --- linux-2.4.24.org/include/asm-sparc64/pgtable.h      2004-02-04 23:05:25.236353602 +0100
14978 +++ linux-2.4.24/include/asm-sparc64/pgtable.h  2004-02-04 23:11:35.156436157 +0100
14979 @@ -122,7 +122,8 @@
14980  #define _PAGE_G                0x0000000000000001      /* Global                             */
14981  
14982  /* Here are the SpitFire software bits we use in the TTE's. */
14983 -#define _PAGE_MODIFIED 0x0000000000000800      /* Modified Page (ie. dirty)          */
14984 +#define _PAGE_MODIFIED 0x0000000000001000      /* Modified Page (ie. dirty)          */
14985 +#define _PAGE_EXEC     0x0000000000000800      /* Executable SW bit                  */
14986  #define _PAGE_ACCESSED 0x0000000000000400      /* Accessed Page (ie. referenced)     */
14987  #define _PAGE_READ     0x0000000000000200      /* Readable SW Bit                    */
14988  #define _PAGE_WRITE    0x0000000000000100      /* Writable SW Bit                    */
14989 @@ -150,16 +151,30 @@
14990  
14991  /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
14992  #define PAGE_SHARED    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14993 -                                 __ACCESS_BITS | _PAGE_WRITE)
14994 +                                 __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
14995  
14996  #define PAGE_COPY      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14997 -                                 __ACCESS_BITS)
14998 +                                 __ACCESS_BITS | _PAGE_EXEC)
14999  
15000  #define PAGE_READONLY  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15001 -                                 __ACCESS_BITS)
15002 +                                 __ACCESS_BITS | _PAGE_EXEC)
15003  
15004  #define PAGE_KERNEL    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15005 -                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
15006 +                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \
15007 +                                 _PAGE_EXEC)
15008 +
15009 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
15010 +#define PAGE_SHARED_NOEXEC    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15011 +                                       __ACCESS_BITS | _PAGE_WRITE)
15012 +#define PAGE_COPY_NOEXEC      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15013 +                                       __ACCESS_BITS)
15014 +#define PAGE_READONLY_NOEXEC  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15015 +                                       __ACCESS_BITS)
15016 +#else
15017 +#define PAGE_SHARED_NOEXEC     PAGE_SHARED
15018 +#define PAGE_COPY_NOEXEC       PAGE_COPY
15019 +#define PAGE_READONLY_NOEXEC   PAGE_READONLY
15020 +#endif
15021  
15022  #define PAGE_INVALID   __pgprot (0)
15023  
15024 @@ -170,18 +185,18 @@
15025  #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
15026  
15027  #define __P000 PAGE_NONE
15028 -#define __P001 PAGE_READONLY
15029 -#define __P010 PAGE_COPY
15030 -#define __P011 PAGE_COPY
15031 +#define __P001 PAGE_READONLY_NOEXEC
15032 +#define __P010 PAGE_COPY_NOEXEC
15033 +#define __P011 PAGE_COPY_NOEXEC
15034  #define __P100 PAGE_READONLY
15035  #define __P101 PAGE_READONLY
15036  #define __P110 PAGE_COPY
15037  #define __P111 PAGE_COPY
15038  
15039  #define __S000 PAGE_NONE
15040 -#define __S001 PAGE_READONLY
15041 -#define __S010 PAGE_SHARED
15042 -#define __S011 PAGE_SHARED
15043 +#define __S001 PAGE_READONLY_NOEXEC
15044 +#define __S010 PAGE_SHARED_NOEXEC
15045 +#define __S011 PAGE_SHARED_NOEXEC
15046  #define __S100 PAGE_READONLY
15047  #define __S101 PAGE_READONLY
15048  #define __S110 PAGE_SHARED
15049 diff -urN linux-2.4.24.org/include/linux/a.out.h linux-2.4.24/include/linux/a.out.h
15050 --- linux-2.4.24.org/include/linux/a.out.h      2004-02-04 23:04:46.070497529 +0100
15051 +++ linux-2.4.24/include/linux/a.out.h  2004-02-04 23:11:35.199427219 +0100
15052 @@ -7,6 +7,16 @@
15053  
15054  #include <asm/a.out.h>
15055  
15056 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
15057 +#define __DELTA_STACK (current->mm->delta_stack)
15058 +#else
15059 +#define __DELTA_STACK 0UL
15060 +#endif
15061 +
15062 +#ifndef STACK_TOP
15063 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
15064 +#endif
15065 +
15066  #endif /* __STRUCT_EXEC_OVERRIDE__ */
15067  
15068  /* these go in the N_MACHTYPE field */
15069 @@ -37,6 +47,14 @@
15070    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
15071  };
15072  
15073 +/* Constants for the N_FLAGS field */
15074 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
15075 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
15076 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
15077 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */   
15078 +#define F_PAX_RANDEXEC 16      /* Randomize ET_EXEC base */
15079 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
15080 +
15081  #if !defined (N_MAGIC)
15082  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
15083  #endif
15084 diff -urN linux-2.4.24.org/include/linux/binfmts.h linux-2.4.24/include/linux/binfmts.h
15085 --- linux-2.4.24.org/include/linux/binfmts.h    2004-02-04 23:04:46.316446388 +0100
15086 +++ linux-2.4.24/include/linux/binfmts.h        2004-02-04 23:11:35.223422230 +0100
15087 @@ -61,6 +61,8 @@
15088  extern int do_coredump(long signr, struct pt_regs * regs);
15089  extern void set_binfmt(struct linux_binfmt *new);
15090  
15091 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
15092 +void pax_report_insns(void *pc);
15093  
15094  #if 0
15095  /* this went away now */
15096 diff -urN linux-2.4.24.org/include/linux/elf.h linux-2.4.24/include/linux/elf.h
15097 --- linux-2.4.24.org/include/linux/elf.h        2004-02-04 23:04:43.207092929 +0100
15098 +++ linux-2.4.24/include/linux/elf.h    2004-02-04 23:11:35.269412668 +0100
15099 @@ -34,6 +34,10 @@
15100  #define PT_MIPS_REGINFO                0x70000000
15101  #define PT_MIPS_OPTIONS                0x70000001
15102  
15103 +#define PT_LOOS                        0x60000000
15104 +#define PT_GNU_STACK           (PT_LOOS + 0x474e551)
15105 +#define PT_GNU_HEAP            (PT_LOOS + 0x474e552)
15106 +
15107  /* Flags in the e_flags field of the header */
15108  #define EF_MIPS_NOREORDER 0x00000001
15109  #define EF_MIPS_PIC       0x00000002
15110 @@ -122,6 +126,8 @@
15111  #define DT_DEBUG       21
15112  #define DT_TEXTREL     22
15113  #define DT_JMPREL      23
15114 +#define DT_FLAGS       30
15115 +#define DF_TEXTREL     0x00000004
15116  #define DT_LOPROC      0x70000000
15117  #define DT_HIPROC      0x7fffffff
15118  #define DT_MIPS_RLD_VERSION    0x70000001
15119 @@ -260,6 +266,13 @@
15120  #define R_MIPS_LOVENDOR                100
15121  #define R_MIPS_HIVENDOR                127
15122  
15123 +/* Constants for the e_flags field */
15124 +#define EF_PAX_PAGEEXEC               1       /* Paging based non-executable pages */
15125 +#define EF_PAX_EMUTRAMP               2       /* Emulate trampolines */
15126 +#define EF_PAX_MPROTECT               4       /* Restrict mprotect() */
15127 +#define EF_PAX_RANDMMAP               8       /* Randomize mmap() base */ 
15128 +#define EF_PAX_RANDEXEC                      16      /* Randomize ET_EXEC base */
15129 +#define EF_PAX_SEGMEXEC                      32      /* Segmentation based non-executable pages */
15130  
15131  /*
15132   * Sparc ELF relocation types
15133 @@ -555,6 +568,8 @@
15134  #define        EI_VERSION      6
15135  #define        EI_PAD          7
15136  
15137 +#define EI_PAX         14
15138 +
15139  #define        ELFMAG0         0x7f            /* EI_MAG */
15140  #define        ELFMAG1         'E'
15141  #define        ELFMAG2         'L'
15142 @@ -602,6 +617,7 @@
15143  #define elfhdr         elf32_hdr
15144  #define elf_phdr       elf32_phdr
15145  #define elf_note       elf32_note
15146 +#define elf_dyn                Elf32_Dyn
15147  
15148  #else
15149  
15150 @@ -609,6 +625,7 @@
15151  #define elfhdr         elf64_hdr
15152  #define elf_phdr       elf64_phdr
15153  #define elf_note       elf64_note
15154 +#define elf_dyn                Elf64_Dyn
15155  
15156  #endif
15157  
15158 diff -urN linux-2.4.24.org/include/linux/fs.h linux-2.4.24/include/linux/fs.h
15159 --- linux-2.4.24.org/include/linux/fs.h 2004-02-04 23:04:38.630044654 +0100
15160 +++ linux-2.4.24/include/linux/fs.h     2004-02-04 23:11:35.311403937 +0100
15161 @@ -1100,7 +1100,7 @@
15162  
15163  asmlinkage long sys_open(const char *, int, int);
15164  asmlinkage long sys_close(unsigned int);       /* yes, it's really unsigned */
15165 -extern int do_truncate(struct dentry *, loff_t start);
15166 +extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
15167  
15168  extern struct file *filp_open(const char *, int, int);
15169  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
15170 diff -urN linux-2.4.24.org/include/linux/gracl.h linux-2.4.24/include/linux/gracl.h
15171 --- linux-2.4.24.org/include/linux/gracl.h      1970-01-01 01:00:00.000000000 +0100
15172 +++ linux-2.4.24/include/linux/gracl.h  2004-02-04 23:11:35.316402898 +0100
15173 @@ -0,0 +1,212 @@
15174 +#ifndef GR_ACL_H
15175 +#define GR_ACL_H
15176 +#endif
15177 +#include <linux/grdefs.h>
15178 +#include <linux/resource.h>
15179 +
15180 +#include <asm/resource.h>
15181 +
15182 +/* * * * * * * * * * * * * * * * * * * * *
15183 + * grsecurity ACL System
15184 + * Main header file
15185 + * Purpose: define most gracl data structures 
15186 + * * * * * * * * * * * * * * * * * * * * */
15187 +
15188 +/* Major status information */
15189 +
15190 +#define GR_VERSION  "grsecurity 2.0-rc4"
15191 +
15192 +enum {
15193 +
15194 +       SHUTDOWN = 0,
15195 +       ENABLE = 1,
15196 +       SPROLE = 2,
15197 +       RELOAD = 3,
15198 +       SEGVMOD = 4,
15199 +       STATUS = 5,
15200 +       UNSPROLE = 6
15201 +};
15202 +
15203 +/* Password setup definitions
15204 + * kernel/grhash.c */
15205 +enum {
15206 +       GR_PW_LEN = 128,
15207 +       GR_SALT_LEN = 16,
15208 +       GR_SHA_LEN = 32,
15209 +};
15210 +
15211 +enum {
15212 +       GR_SPROLE_LEN = 64,
15213 +};
15214 +
15215 +/* Begin Data Structures */
15216 +
15217 +struct sprole_pw {
15218 +       unsigned char *rolename;
15219 +       unsigned char salt[GR_SALT_LEN];
15220 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
15221 +};
15222 +
15223 +struct name_entry {
15224 +       ino_t inode;
15225 +       kdev_t device;
15226 +       char *name;
15227 +       __u16 len;
15228 +};
15229 +
15230 +struct acl_role_db {
15231 +       struct acl_role_label **r_hash;
15232 +       __u32 r_size;
15233 +};
15234 +
15235 +struct name_db {
15236 +       struct name_entry **n_hash;
15237 +       __u32 n_size;
15238 +};
15239 +
15240 +struct crash_uid {
15241 +       uid_t uid;
15242 +       unsigned long expires;
15243 +};
15244 +
15245 +/* Userspace Grsecurity ACL data structures */
15246 +struct acl_subject_label {
15247 +       char *filename;
15248 +       ino_t inode;
15249 +       kdev_t device;
15250 +       __u32 mode;
15251 +       __u32 cap_raise;
15252 +       __u32 cap_lower;
15253 +
15254 +       struct rlimit res[RLIM_NLIMITS + 1];
15255 +       __u16 resmask;
15256 +
15257 +       __u32 ip_proto[8];
15258 +       __u32 ip_type;
15259 +       struct acl_ip_label **ips;
15260 +       __u32 ip_num;
15261 +
15262 +       __u32 crashes;
15263 +       unsigned long expires;
15264 +
15265 +       struct acl_subject_label *parent_subject;
15266 +       struct acl_object_label *proc_object;
15267 +       struct acl_ip_label *ip_object;
15268 +       struct acl_subject_label *prev;
15269 +       struct acl_subject_label *next;
15270 +
15271 +       struct acl_object_label **obj_hash;
15272 +       __u32 obj_hash_size;
15273 +};
15274 +
15275 +struct role_allowed_ip {
15276 +       __u32 addr;
15277 +       __u32 netmask;
15278 +
15279 +       struct role_allowed_ip *prev;
15280 +       struct role_allowed_ip *next;
15281 +};
15282 +
15283 +struct role_transition {
15284 +       char *rolename;
15285 +
15286 +       struct role_transition *prev;
15287 +       struct role_transition *next;
15288 +};
15289 +
15290 +struct acl_role_label {
15291 +       char *rolename;
15292 +       uid_t uidgid;
15293 +       __u16 roletype;
15294 +
15295 +       __u16 auth_attempts;
15296 +       unsigned long expires;
15297 +
15298 +       struct acl_subject_label *root_label;
15299 +       struct acl_subject_label *proc_subject;
15300 +
15301 +       struct acl_role_label *prev;
15302 +       struct acl_role_label *next;
15303 +
15304 +       struct role_transition *transitions;
15305 +       struct role_allowed_ip *allowed_ips;
15306 +       struct acl_subject_label **subj_hash;
15307 +       __u32 subj_hash_size;
15308 +};
15309 +
15310 +struct user_acl_role_db {
15311 +       struct acl_role_label **r_table;
15312 +       __u32 r_entries;        /* number of entries in table */
15313 +       __u32 s_entries;        /* total number of subject acls */
15314 +       __u32 i_entries;        /* total number of ip acls */
15315 +       __u32 o_entries;        /* Total number of object acls */
15316 +       __u32 a_entries;        /* total number of allowed ips */
15317 +       __u32 t_entries;        /* total number of transitions */
15318 +};
15319 +
15320 +struct acl_object_label {
15321 +       char *filename;
15322 +       ino_t inode;
15323 +       kdev_t device;
15324 +       __u32 mode;
15325 +
15326 +       struct acl_subject_label *nested;
15327 +
15328 +       /* next two structures not used */
15329 +
15330 +       struct acl_object_label *prev;
15331 +       struct acl_object_label *next;
15332 +};
15333 +
15334 +struct acl_ip_label {
15335 +       __u32 addr;
15336 +       __u32 netmask;
15337 +       __u16 low, high;
15338 +       __u8 mode;
15339 +       __u32 type;
15340 +       __u32 proto[8];
15341 +
15342 +       /* next two structures not used */
15343 +
15344 +       struct acl_ip_label *prev;
15345 +       struct acl_ip_label *next;
15346 +};
15347 +
15348 +struct gr_arg {
15349 +       struct user_acl_role_db role_db;
15350 +       unsigned char pw[GR_PW_LEN];
15351 +       unsigned char salt[GR_SALT_LEN];
15352 +       unsigned char sum[GR_SHA_LEN];
15353 +       unsigned char sp_role[GR_SPROLE_LEN];
15354 +       struct sprole_pw *sprole_pws;
15355 +       __u16 num_sprole_pws;
15356 +       kdev_t segv_device;
15357 +       ino_t segv_inode;
15358 +       uid_t segv_uid;
15359 +       __u16 mode;
15360 +};
15361 +
15362 +/* End Data Structures Section */
15363 +
15364 +/* Hash functions generated by empirical testing by Brad Spengler
15365 +   Makes good use of the low bits of the inode.  Generally 0-1 times
15366 +   in loop for successful match.  0-3 for unsuccessful match.
15367 +   Shift/add algorithm with modulus of table size and an XOR*/
15368 +
15369 +static __inline__ unsigned long
15370 +rhash(const uid_t uid, const __u16 type, const unsigned long sz)
15371 +{
15372 +       return (((uid << type) + (uid ^ type)) % sz);
15373 +}
15374 +
15375 +static __inline__ unsigned long
15376 +fhash(const ino_t ino, const kdev_t dev, const unsigned long sz)
15377 +{
15378 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
15379 +}
15380 +
15381 +static __inline__ unsigned long
15382 +nhash(const char *name, const __u16 len, const unsigned long sz)
15383 +{
15384 +       return full_name_hash(name, len) % sz;
15385 +}
15386 diff -urN linux-2.4.24.org/include/linux/gralloc.h linux-2.4.24/include/linux/gralloc.h
15387 --- linux-2.4.24.org/include/linux/gralloc.h    1970-01-01 01:00:00.000000000 +0100
15388 +++ linux-2.4.24/include/linux/gralloc.h        2004-02-04 23:11:35.335398948 +0100
15389 @@ -0,0 +1,8 @@
15390 +#ifndef __GRALLOC_H
15391 +#define __GRALLOC_H
15392 +
15393 +void acl_free_all(void);
15394 +int acl_alloc_stack_init(unsigned long size);
15395 +void *acl_alloc(unsigned long len);
15396 +
15397 +#endif
15398 diff -urN linux-2.4.24.org/include/linux/grdefs.h linux-2.4.24/include/linux/grdefs.h
15399 --- linux-2.4.24.org/include/linux/grdefs.h     1970-01-01 01:00:00.000000000 +0100
15400 +++ linux-2.4.24/include/linux/grdefs.h 2004-02-04 23:11:35.339398117 +0100
15401 @@ -0,0 +1,103 @@
15402 +#ifndef GRDEFS_H
15403 +#define GRDEFS_H
15404 +
15405 +/* Begin grsecurity status declarations */
15406 +
15407 +enum {
15408 +       GR_READY = 0x01,
15409 +       GR_STATUS_INIT = 0x00   // disabled state
15410 +};
15411 +
15412 +/* Begin  ACL declarations */
15413 +
15414 +/* Role flags */
15415 +
15416 +enum {
15417 +       GR_ROLE_USER = 0x0001,
15418 +       GR_ROLE_GROUP = 0x0002,
15419 +       GR_ROLE_DEFAULT = 0x0004,
15420 +       GR_ROLE_SPECIAL = 0x0008,
15421 +       GR_ROLE_AUTH = 0x0010,
15422 +       GR_ROLE_NOPW = 0x0020,
15423 +       GR_ROLE_GOD = 0x0040,
15424 +       GR_ROLE_LEARN = 0x0080,
15425 +       GR_ROLE_TPE = 0x0100
15426 +};
15427 +
15428 +/* ACL Subject and Object mode flags */
15429 +enum {
15430 +       GR_DELETED = 0x00000080
15431 +};
15432 +
15433 +/* ACL Object-only mode flags */
15434 +enum {
15435 +       GR_READ         = 0x00000001,
15436 +       GR_APPEND       = 0x00000002,
15437 +       GR_WRITE        = 0x00000004,
15438 +       GR_EXEC         = 0x00000008,
15439 +       GR_FIND         = 0x00000010,
15440 +       GR_INHERIT      = 0x00000040,
15441 +       GR_PTRACERD     = 0x00000100,
15442 +       GR_SETID        = 0x00000200,
15443 +       GR_CREATE       = 0x00000400,
15444 +       GR_DELETE       = 0x00000800,
15445 +       GR_AUDIT_READ   = 0x00001000,
15446 +       GR_AUDIT_APPEND = 0x00002000,
15447 +       GR_AUDIT_WRITE  = 0x00004000,
15448 +       GR_AUDIT_EXEC   = 0x00008000,
15449 +       GR_AUDIT_FIND   = 0x00010000,
15450 +       GR_AUDIT_INHERIT= 0x00020000,
15451 +       GR_AUDIT_SETID  = 0x00040000,
15452 +       GR_AUDIT_CREATE = 0x00080000,
15453 +       GR_AUDIT_DELETE = 0x00100000,
15454 +       GR_SUPPRESS     = 0x00200000,
15455 +       GR_NOLEARN      = 0x00400000
15456 +};
15457 +
15458 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
15459 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
15460 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE)
15461 +
15462 +/* ACL subject-only mode flags */
15463 +enum {
15464 +       GR_KILL         = 0x00000001,
15465 +       GR_VIEW         = 0x00000002,
15466 +       GR_PROTECTED    = 0x00000100,
15467 +       GR_LEARN        = 0x00000200,
15468 +       GR_OVERRIDE     = 0x00000400,
15469 +       /* just a placeholder, this mode is only used in userspace */
15470 +       GR_DUMMY        = 0x00000800,
15471 +       GR_PAXPAGE      = 0x00001000,
15472 +       GR_PAXSEGM      = 0x00002000,
15473 +       GR_PAXGCC       = 0x00004000,
15474 +       GR_PAXRANDMMAP  = 0x00008000,
15475 +       GR_PAXRANDEXEC  = 0x00010000,
15476 +       GR_PAXMPROTECT  = 0x00020000,
15477 +       GR_PROTSHM      = 0x00040000,
15478 +       GR_KILLPROC     = 0x00080000,
15479 +       GR_KILLIPPROC   = 0x00100000,
15480 +       /* just a placeholder, this mode is only used in userspace */
15481 +       GR_NOTROJAN     = 0x00200000,
15482 +       GR_PROTPROCFD   = 0x00400000,
15483 +       GR_PROCACCT     = 0x00800000
15484 +};
15485 +
15486 +#define GR_CRASH_RES   11
15487 +#define GR_UIDTABLE_MAX 500
15488 +
15489 +/* begin resource learning section */
15490 +enum {
15491 +       GR_RLIM_CPU_BUMP = 60,
15492 +       GR_RLIM_FSIZE_BUMP = 50000,
15493 +       GR_RLIM_DATA_BUMP = 10000,
15494 +       GR_RLIM_STACK_BUMP = 1000,
15495 +       GR_RLIM_CORE_BUMP = 10000,
15496 +       GR_RLIM_RSS_BUMP = 500000,
15497 +       GR_RLIM_NPROC_BUMP = 1,
15498 +       GR_RLIM_NOFILE_BUMP = 5,
15499 +       GR_RLIM_MEMLOCK_BUMP = 50000,
15500 +       GR_RLIM_AS_BUMP = 500000,
15501 +       GR_RLIM_LOCKS_BUMP = 2
15502 +};
15503 +
15504 +#endif
15505 diff -urN linux-2.4.24.org/include/linux/grinternal.h linux-2.4.24/include/linux/grinternal.h
15506 --- linux-2.4.24.org/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100
15507 +++ linux-2.4.24/include/linux/grinternal.h     2004-02-04 23:11:35.341397701 +0100
15508 @@ -0,0 +1,200 @@
15509 +#ifndef __GRINTERNAL_H
15510 +#define __GRINTERNAL_H
15511 +
15512 +#ifdef CONFIG_GRKERNSEC
15513 +
15514 +#include <linux/grdefs.h>
15515 +#include <linux/grmsg.h>
15516 +
15517 +extern void gr_add_learn_entry(const char *fmt, ...);
15518 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
15519 +                           const struct vfsmount *mnt);
15520 +extern __u32 gr_check_create(const struct dentry *new_dentry,
15521 +                            const struct dentry *parent,
15522 +                            const struct vfsmount *mnt, const __u32 mode);
15523 +extern int gr_check_protected_task(const struct task_struct *task);
15524 +extern __inline__ __u32 to_gr_audit(const __u32 reqmode);
15525 +extern int gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
15526 +                           struct dentry *old_dentry,
15527 +                           struct dentry *new_dentry,
15528 +                           struct vfsmount *mnt, const __u8 replace);
15529 +extern int gr_set_acls(const int type);
15530 +
15531 +extern void gr_handle_alertkill(void);
15532 +extern char *gr_to_filename(const struct dentry *dentry,
15533 +                           const struct vfsmount *mnt);
15534 +extern char *gr_to_filename1(const struct dentry *dentry,
15535 +                           const struct vfsmount *mnt);
15536 +extern char *gr_to_filename2(const struct dentry *dentry,
15537 +                           const struct vfsmount *mnt);
15538 +extern char *gr_to_filename3(const struct dentry *dentry,
15539 +                           const struct vfsmount *mnt);
15540 +
15541 +extern int grsec_enable_link;
15542 +extern int grsec_enable_fifo;
15543 +extern int grsec_enable_execve;
15544 +extern int grsec_enable_forkbomb;
15545 +extern int grsec_forkbomb_gid;
15546 +extern int grsec_forkbomb_sec;
15547 +extern int grsec_forkbomb_max;
15548 +extern int grsec_enable_execlog;
15549 +extern int grsec_enable_signal;
15550 +extern int grsec_enable_forkfail;
15551 +extern int grsec_enable_time;
15552 +extern int grsec_enable_chroot_shmat;
15553 +extern int grsec_enable_chroot_findtask;
15554 +extern int grsec_enable_chroot_mount;
15555 +extern int grsec_enable_chroot_double;
15556 +extern int grsec_enable_chroot_pivot;
15557 +extern int grsec_enable_chroot_chdir;
15558 +extern int grsec_enable_chroot_chmod;
15559 +extern int grsec_enable_chroot_mknod;
15560 +extern int grsec_enable_chroot_fchdir;
15561 +extern int grsec_enable_chroot_nice;
15562 +extern int grsec_enable_chroot_execlog;
15563 +extern int grsec_enable_chroot_caps;
15564 +extern int grsec_enable_chroot_sysctl;
15565 +extern int grsec_enable_chroot_unix;
15566 +extern int grsec_enable_tpe;
15567 +extern int grsec_tpe_gid;
15568 +extern int grsec_enable_tpe_all;
15569 +extern int grsec_enable_randpid;
15570 +extern int grsec_enable_socket_all;
15571 +extern int grsec_socket_all_gid;
15572 +extern int grsec_enable_socket_client;
15573 +extern int grsec_socket_client_gid;
15574 +extern int grsec_enable_socket_server;
15575 +extern int grsec_socket_server_gid;
15576 +extern int grsec_audit_gid;
15577 +extern int grsec_enable_group;
15578 +extern int grsec_enable_audit_ipc;
15579 +extern int grsec_enable_mount;
15580 +extern int grsec_enable_chdir;
15581 +extern int grsec_lock;
15582 +
15583 +extern struct task_struct *child_reaper;
15584 +
15585 +extern spinlock_t grsec_alert_lock;
15586 +extern unsigned long grsec_alert_wtime;
15587 +extern unsigned long grsec_alert_fyet;
15588 +
15589 +extern spinlock_t grsec_alertgood_lock;
15590 +extern unsigned long grsec_alertgood_wtime;
15591 +extern unsigned long grsec_alertgood_fyet;
15592 +
15593 +extern spinlock_t grsec_audit_lock;
15594 +
15595 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
15596 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
15597 +                       tsk->exec_file->f_vfsmnt) : "/")
15598 +
15599 +#define gr_parent_task_fullpath(tsk) (tsk->p_pptr->exec_file ? \
15600 +                       gr_to_filename3(tsk->p_pptr->exec_file->f_dentry, \
15601 +                       tsk->p_pptr->exec_file->f_vfsmnt) : "/")
15602 +
15603 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
15604 +                       gr_to_filename(tsk->exec_file->f_dentry, \
15605 +                       tsk->exec_file->f_vfsmnt) : "/")
15606 +
15607 +#define gr_parent_task_fullpath0(tsk) (tsk->p_pptr->exec_file ? \
15608 +                       gr_to_filename1(tsk->p_pptr->exec_file->f_dentry, \
15609 +                       tsk->p_pptr->exec_file->f_vfsmnt) : "/")
15610 +
15611 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && \
15612 +                         ((tsk_a->fs->root->d_inode->i_dev != \
15613 +                         child_reaper->fs->root->d_inode->i_dev) || \
15614 +                         (tsk_a->fs->root->d_inode->i_ino != \
15615 +                         child_reaper->fs->root->d_inode->i_ino)))
15616 +
15617 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_dev == \
15618 +                         tsk_b->fs->root->d_inode->i_dev) && \
15619 +                         (tsk_a->fs->root->d_inode->i_ino == \
15620 +                         tsk_b->fs->root->d_inode->i_ino))
15621 +
15622 +#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
15623 +                      current->pid, current->uid, \
15624 +                      current->euid, current->gid, current->egid, \
15625 +                      gr_parent_task_fullpath(current), \
15626 +                      current->p_pptr->comm, current->p_pptr->pid, \
15627 +                      current->p_pptr->uid, current->p_pptr->euid, \
15628 +                      current->p_pptr->gid, current->p_pptr->egid
15629 +
15630 +#define GR_CHROOT_CAPS ( \
15631 +       CAP_TO_MASK(CAP_FOWNER) | \
15632 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
15633 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
15634 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
15635 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
15636 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
15637 +       CAP_TO_MASK(CAP_IPC_OWNER))
15638 +
15639 +#define security_alert_good(normal_msg,args...) \
15640 +({ \
15641 +       spin_lock(&grsec_alertgood_lock); \
15642 +       \
15643 +       if (!grsec_alertgood_wtime || jiffies - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15644 +           grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet = 0; \
15645 +           if (current->curr_ip) \
15646 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15647 +           else \
15648 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15649 +       } else if((jiffies - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15650 +           grsec_alertgood_fyet++; \
15651 +           if (current->curr_ip) \
15652 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15653 +           else \
15654 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15655 +       } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15656 +           grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet++; \
15657 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15658 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15659 +       } \
15660 +       \
15661 +       spin_unlock(&grsec_alertgood_lock); \
15662 +})
15663 +
15664 +#define security_alert(normal_msg,args...) \
15665 +({ \
15666 +       spin_lock(&grsec_alert_lock); \
15667 +       \
15668 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15669 +           grsec_alert_wtime = jiffies; grsec_alert_fyet = 0; \
15670 +           if (current->curr_ip) \
15671 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15672 +           else \
15673 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15674 +       } else if((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15675 +           grsec_alert_fyet++; \
15676 +           if (current->curr_ip) \
15677 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15678 +           else \
15679 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15680 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15681 +           grsec_alert_wtime = jiffies; grsec_alert_fyet++; \
15682 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15683 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15684 +       } \
15685 +       \
15686 +       gr_handle_alertkill(); \
15687 +       spin_unlock(&grsec_alert_lock); \
15688 +})
15689 +
15690 +#define security_audit(normal_msg,args...) \
15691 +({ \
15692 +       spin_lock(&grsec_audit_lock); \
15693 +       if (current->curr_ip) \
15694 +               printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
15695 +                      NIPQUAD(current->curr_ip) , ## args); \
15696 +       else \
15697 +               printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
15698 +       spin_unlock(&grsec_audit_lock); \
15699 +})
15700 +
15701 +#define security_learn(normal_msg,args...) \
15702 +({ \
15703 +       gr_add_learn_entry(normal_msg "\n", ## args); \
15704 +})
15705 +
15706 +#endif
15707 +
15708 +#endif
15709 diff -urN linux-2.4.24.org/include/linux/grmsg.h linux-2.4.24/include/linux/grmsg.h
15710 --- linux-2.4.24.org/include/linux/grmsg.h      1970-01-01 01:00:00.000000000 +0100
15711 +++ linux-2.4.24/include/linux/grmsg.h  2004-02-04 23:11:35.345396870 +0100
15712 @@ -0,0 +1,105 @@
15713 +#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"
15714 +#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"
15715 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
15716 +#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
15717 +#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
15718 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
15719 +#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
15720 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
15721 +#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
15722 +#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
15723 +#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
15724 +#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
15725 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
15726 +#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"
15727 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
15728 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
15729 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
15730 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
15731 +#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
15732 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
15733 +#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
15734 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
15735 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
15736 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
15737 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
15738 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
15739 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
15740 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
15741 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
15742 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
15743 +#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
15744 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
15745 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
15746 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
15747 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution of [%.16s:%lu] for %lu seconds"
15748 +#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
15749 +#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
15750 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
15751 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
15752 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
15753 +#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
15754 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
15755 +#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
15756 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
15757 +#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
15758 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
15759 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
15760 +#define GR_INITF_ACL_MSG "init_variables() failed %s"
15761 +#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"
15762 +#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
15763 +#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
15764 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
15765 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
15766 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
15767 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
15768 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
15769 +#define GR_ENABLE_ACL_MSG "Loaded %s"
15770 +#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
15771 +#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
15772 +#define GR_RELOAD_ACL_MSG "Reloaded %s"
15773 +#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
15774 +#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
15775 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
15776 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
15777 +#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
15778 +#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
15779 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
15780 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
15781 +#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
15782 +#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
15783 +#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
15784 +#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
15785 +#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
15786 +#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
15787 +#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
15788 +#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
15789 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
15790 +#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
15791 +#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
15792 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
15793 +#define GR_TIME_MSG "time set by " DEFAULTSECMSG
15794 +#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
15795 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
15796 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
15797 +#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG
15798 +#define GR_SOCK2_MSG "attempted socket(%d,%.16s,%.16s) by " DEFAULTSECMSG
15799 +#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
15800 +#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
15801 +#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15802 +#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15803 +#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"
15804 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
15805 +#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
15806 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
15807 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
15808 +#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
15809 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
15810 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
15811 +#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
15812 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
15813 +#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
15814 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
15815 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
15816 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
15817 +#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
15818 diff -urN linux-2.4.24.org/include/linux/grsecurity.h linux-2.4.24/include/linux/grsecurity.h
15819 --- linux-2.4.24.org/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100
15820 +++ linux-2.4.24/include/linux/grsecurity.h     2004-02-04 23:11:35.350395830 +0100
15821 @@ -0,0 +1,177 @@
15822 +#ifndef GR_SECURITY_H
15823 +#define GR_SECURITY_H
15824 +
15825 +extern void gr_add_to_task_ip_table(struct task_struct *p);
15826 +extern void gr_del_task_from_ip_table(struct task_struct *p);
15827 +
15828 +extern int gr_pid_is_chrooted(const struct task_struct *p);
15829 +extern int gr_handle_chroot_nice(void);
15830 +extern int gr_handle_chroot_sysctl(const int op);
15831 +extern int gr_handle_chroot_capset(const struct task_struct *target);
15832 +extern int gr_handle_chroot_setpriority(const struct task_struct *p,
15833 +                                       const int niceval);
15834 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
15835 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
15836 +                                  const struct vfsmount *mnt);
15837 +extern void gr_handle_chroot_caps(struct task_struct *task);
15838 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
15839 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
15840 +                                 const struct vfsmount *mnt, const int mode);
15841 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
15842 +                                 const struct vfsmount *mnt, const int mode);
15843 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
15844 +                                 const struct vfsmount *mnt,
15845 +                                 const char *dev_name);
15846 +extern int gr_handle_chroot_pivot(void);
15847 +extern int gr_handle_chroot_unix(const pid_t pid);
15848 +
15849 +extern int gr_handle_rawio(const struct inode *inode);
15850 +extern int gr_handle_nproc(void);
15851 +
15852 +extern void gr_handle_ioperm(void);
15853 +extern void gr_handle_iopl(void);
15854 +
15855 +extern int gr_tpe_allow(const struct file *file);
15856 +
15857 +extern int gr_random_pid(spinlock_t * pid_lock);
15858 +
15859 +extern void gr_log_forkfail(const int retval);
15860 +extern void gr_log_timechange(void);
15861 +extern void gr_log_signal(const int sig, const struct task_struct *t);
15862 +extern void gr_log_chdir(const struct dentry *dentry,
15863 +                        const struct vfsmount *mnt);
15864 +extern void gr_log_chroot_exec(const struct dentry *dentry,
15865 +                              const struct vfsmount *mnt);
15866 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
15867 +extern void gr_log_remount(const char *devname, const int retval);
15868 +extern void gr_log_unmount(const char *devname, const int retval);
15869 +extern void gr_log_mount(const char *from, const char *to, const int retval);
15870 +extern void gr_log_msgget(const int ret, const int msgflg);
15871 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
15872 +extern void gr_log_semget(const int err, const int semflg);
15873 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
15874 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
15875 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
15876 +
15877 +extern int gr_handle_follow_link(const struct inode *parent,
15878 +                                const struct inode *inode,
15879 +                                const struct dentry *dentry,
15880 +                                const struct vfsmount *mnt);
15881 +extern int gr_handle_fifo(const struct dentry *dentry,
15882 +                         const struct vfsmount *mnt,
15883 +                         const struct dentry *dir, const int flag,
15884 +                         const int acc_mode);
15885 +extern int gr_handle_hardlink(const struct dentry *dentry,
15886 +                             const struct vfsmount *mnt,
15887 +                             struct inode *inode,
15888 +                             const int mode, const char *to);
15889 +
15890 +extern int gr_is_capable(const int cap);
15891 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
15892 +                             const unsigned long wanted, const int gt);
15893 +extern void gr_copy_label(struct task_struct *tsk);
15894 +extern void gr_handle_crash(struct task_struct *task, const int sig);
15895 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
15896 +extern int gr_check_crash_uid(const uid_t uid);
15897 +extern int gr_check_protected_task(const struct task_struct *task);
15898 +extern int gr_acl_handle_mmap(const struct file *file,
15899 +                             const unsigned long prot);
15900 +extern int gr_acl_handle_mprotect(const struct file *file,
15901 +                                 const unsigned long prot);
15902 +extern int gr_check_hidden_task(const struct task_struct *tsk);
15903 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
15904 +                                   const struct vfsmount *mnt);
15905 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
15906 +                                const struct vfsmount *mnt);
15907 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
15908 +                                 const struct vfsmount *mnt, const int fmode);
15909 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
15910 +                                 const struct vfsmount *mnt, mode_t mode);
15911 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
15912 +                                const struct vfsmount *mnt, mode_t mode);
15913 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
15914 +                                const struct vfsmount *mnt);
15915 +extern int gr_handle_ptrace_exec(const struct dentry *dentry,
15916 +                                const struct vfsmount *mnt);
15917 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
15918 +extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
15919 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
15920 +                                 const struct vfsmount *mnt);
15921 +extern int gr_check_crash_exec(const struct file *filp);
15922 +extern int gr_acl_is_enabled(void);
15923 +extern void gr_set_kernel_label(struct task_struct *task);
15924 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
15925 +                             const gid_t gid);
15926 +extern void gr_set_proc_label(const struct dentry *dentry,
15927 +                             const struct vfsmount *mnt);
15928 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
15929 +                                      const struct vfsmount *mnt);
15930 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
15931 +                               const struct vfsmount *mnt, const int fmode);
15932 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
15933 +                                const struct dentry *p_dentry,
15934 +                                const struct vfsmount *p_mnt, const int fmode,
15935 +                                const int imode);
15936 +extern void gr_handle_create(const struct dentry *dentry,
15937 +                            const struct vfsmount *mnt);
15938 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
15939 +                                const struct dentry *parent_dentry,
15940 +                                const struct vfsmount *parent_mnt,
15941 +                                const int mode);
15942 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
15943 +                                const struct dentry *parent_dentry,
15944 +                                const struct vfsmount *parent_mnt);
15945 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
15946 +                                const struct vfsmount *mnt);
15947 +extern void gr_handle_delete(const ino_t ino, const kdev_t dev);
15948 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
15949 +                                 const struct vfsmount *mnt);
15950 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
15951 +                                  const struct dentry *parent_dentry,
15952 +                                  const struct vfsmount *parent_mnt,
15953 +                                  const char *from);
15954 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
15955 +                               const struct dentry *parent_dentry,
15956 +                               const struct vfsmount *parent_mnt,
15957 +                               const struct dentry *old_dentry,
15958 +                               const struct vfsmount *old_mnt, const char *to);
15959 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
15960 +                               struct dentry *parent_dentry,
15961 +                               const struct vfsmount *parent_mnt,
15962 +                               struct dentry *old_dentry,
15963 +                               struct inode *old_parent_inode,
15964 +                               struct vfsmount *old_mnt, const char *newname);
15965 +extern __u32 gr_check_link(const struct dentry *new_dentry,
15966 +                          const struct dentry *parent_dentry,
15967 +                          const struct vfsmount *parent_mnt,
15968 +                          const struct dentry *old_dentry,
15969 +                          const struct vfsmount *old_mnt);
15970 +extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
15971 +                                  const struct vfsmount *mnt, const ino_t ino);
15972 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
15973 +                               const struct vfsmount *mnt);
15974 +extern void gr_set_pax_flags(struct task_struct *task);
15975 +extern void gr_acl_handle_exit(void);
15976 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
15977 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
15978 +extern __u32 gr_cap_rtnetlink(void);
15979 +
15980 +#ifdef CONFIG_GRKERNSEC
15981 +extern void gr_handle_mem_write(void);
15982 +extern void gr_handle_kmem_write(void);
15983 +extern void gr_handle_open_port(void);
15984 +extern int gr_handle_mem_mmap(const unsigned long offset,
15985 +                             struct vm_area_struct *vma);
15986 +
15987 +extern __u16 ip_randomid(void);
15988 +extern __u32 ip_randomisn(void);
15989 +extern unsigned long get_random_long(void);
15990 +
15991 +extern int grsec_enable_dmesg;
15992 +extern int grsec_enable_randid;
15993 +extern int grsec_enable_randisn;
15994 +extern int grsec_enable_randsrc;
15995 +extern int grsec_enable_randrpc;
15996 +#endif
15997 +
15998 +#endif
15999 diff -urN linux-2.4.24.org/include/linux/kernel.h linux-2.4.24/include/linux/kernel.h
16000 --- linux-2.4.24.org/include/linux/kernel.h     2004-02-04 23:04:42.638211219 +0100
16001 +++ linux-2.4.24/include/linux/kernel.h 2004-02-04 23:11:35.394386684 +0100
16002 @@ -71,14 +71,17 @@
16003  extern long long simple_strtoll(const char *,char **,unsigned int);
16004  extern int sprintf(char * buf, const char * fmt, ...)
16005         __attribute__ ((format (printf, 2, 3)));
16006 -extern int vsprintf(char *buf, const char *, va_list);
16007 +extern int vsprintf(char *buf, const char *, va_list)
16008 +       __attribute__ ((format (printf, 2, 0)));
16009  extern int snprintf(char * buf, size_t size, const char * fmt, ...)
16010         __attribute__ ((format (printf, 3, 4)));
16011 -extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
16012 +extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
16013 +       __attribute__ ((format (printf, 3, 0)));
16014  
16015  extern int sscanf(const char *, const char *, ...)
16016         __attribute__ ((format (scanf,2,3)));
16017 -extern int vsscanf(const char *, const char *, va_list);
16018 +extern int vsscanf(const char *, const char *, va_list)
16019 +       __attribute__ ((format (scanf, 2, 0)));
16020  
16021  extern void qsort(void *, size_t, size_t, int (*)(const void *,const void *));
16022  
16023 diff -urN linux-2.4.24.org/include/linux/mm.h linux-2.4.24/include/linux/mm.h
16024 --- linux-2.4.24.org/include/linux/mm.h 2004-02-04 23:04:38.412089975 +0100
16025 +++ linux-2.4.24/include/linux/mm.h     2004-02-04 23:11:35.432378785 +0100
16026 @@ -22,9 +22,13 @@
16027  extern struct list_head active_list;
16028  extern struct list_head inactive_list;
16029  
16030 +extern void gr_learn_resource(const struct task_struct * task, const int limit,
16031 +                             const unsigned long wanted, const int gt);
16032 +
16033  #include <asm/page.h>
16034  #include <asm/pgtable.h>
16035  #include <asm/atomic.h>
16036 +#include <asm/mman.h>
16037  
16038  /*
16039   * Linux kernel virtual memory manager primitives.
16040 @@ -104,6 +108,33 @@
16041  #define VM_DONTEXPAND  0x00040000      /* Cannot expand with mremap() */
16042  #define VM_RESERVED    0x00080000      /* Don't unmap it from swap_out */
16043  
16044 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16045 +#define VM_MIRROR      0x00100000      /* vma is mirroring another */
16046 +#endif
16047 +
16048 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
16049 +#define VM_MAYNOTWRITE 0x00200000      /* vma cannot be granted VM_WRITE any more */
16050 +#endif
16051 +
16052 +#ifdef ARCH_STACK_GROWSUP
16053 +#define __VM_STACK_FLAGS       0x00000233
16054 +#else
16055 +#define __VM_STACK_FLAGS       0x00000133
16056 +#endif
16057 +
16058 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
16059 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
16060 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | \
16061 +                       ((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16062 +                       ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
16063 +#else
16064 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_MAYEXEC | \
16065 +                       ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
16066 +#endif
16067 +#else
16068 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_EXEC | VM_MAYEXEC)
16069 +#endif
16070 +
16071  #ifndef VM_STACK_FLAGS
16072  #define VM_STACK_FLAGS 0x00000177
16073  #endif
16074 @@ -573,11 +604,38 @@
16075         unsigned long flag, unsigned long offset)
16076  {
16077         unsigned long ret = -EINVAL;
16078 +
16079 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
16080 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
16081 +                       (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
16082 +               goto out;
16083 +#endif
16084 +           
16085         if ((offset + PAGE_ALIGN(len)) < offset)
16086                 goto out;
16087         if (!(offset & ~PAGE_MASK))
16088                 ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
16089                                     offset >> PAGE_SHIFT);
16090 +
16091 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
16092 +#define BAD_ADDR(x)   ((unsigned long)(x) > TASK_SIZE)
16093 +       if ((current->flags & PF_PAX_SEGMEXEC) && !BAD_ADDR(ret) &&
16094 +               (prot & PROT_EXEC) && ((flag & MAP_TYPE) == MAP_PRIVATE)
16095 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
16096 +               && (!(current->flags & PF_PAX_MPROTECT) || (file && !(prot & PROT_WRITE)))
16097 +#endif
16098 +               )
16099 +       {
16100 +               unsigned long ret_m;
16101 +               ret_m = do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flag | MAP_MIRROR | MAP_FIXED, ret);
16102 +               if (BAD_ADDR(ret_m)) {
16103 +                       do_munmap(current->mm, ret, len);
16104 +                       ret = ret_m;
16105 +               }
16106 +       }
16107 +#undef BAD_ADDR
16108 +#endif
16109 +
16110  out:
16111         return ret;
16112  }
16113 @@ -596,6 +654,12 @@
16114  
16115  static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
16116  {
16117 +
16118 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16119 +       if ((vma->vm_flags | vm_flags) & VM_MIRROR)
16120 +               return 0;
16121 +#endif
16122 +
16123         if (!vma->vm_file && vma->vm_flags == vm_flags)
16124                 return 1;
16125         else
16126 @@ -649,7 +713,12 @@
16127  
16128         return gfp_mask;
16129  }
16130 -       
16131 +
16132 +/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
16133 +extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
16134 +extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
16135 +                                            struct vm_area_struct **pprev);
16136 +
16137  /* vma is the first one with  address < vma->vm_end,
16138   * and even  address < vma->vm_start. Have to extend vma. */
16139  static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
16140 @@ -664,11 +733,51 @@
16141         address &= PAGE_MASK;
16142         spin_lock(&vma->vm_mm->page_table_lock);
16143         grow = (vma->vm_start - address) >> PAGE_SHIFT;
16144 +
16145 +       gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address, 1);
16146 +       gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
16147 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
16148 +
16149 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16150 +       if (vma->vm_flags & VM_MIRROR) {
16151 +               struct vm_area_struct * vma_m;
16152 +               unsigned long address_m;
16153 +
16154 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16155 +               vma_m = find_vma(vma->vm_mm, address_m);
16156 +               if (!vma_m || vma_m->vm_start != address_m || !(vma_m->vm_flags & VM_MIRROR) ||
16157 +                   vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start) {
16158 +                       spin_unlock(&vma->vm_mm->page_table_lock);
16159 +                       printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
16160 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
16161 +                       return -ENOMEM;
16162 +               }
16163 +
16164 +               address_m = address + (unsigned long)vma->vm_private_data;
16165 +               if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
16166 +                   ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
16167 +                   ((vma_m->vm_flags & VM_LOCKED) && ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
16168 +                    current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
16169 +                       spin_unlock(&vma->vm_mm->page_table_lock);
16170 +                       return -ENOMEM;
16171 +               }
16172 +
16173 +               vma_m->vm_start = address_m;
16174 +               vma_m->vm_pgoff -= grow;
16175 +               vma_m->vm_mm->total_vm += grow;
16176 +               if (vma_m->vm_flags & VM_LOCKED)
16177 +                       vma_m->vm_mm->locked_vm += grow;
16178 +       } else
16179 +#endif
16180 +
16181         if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
16182 -           ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
16183 +           ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
16184 +           ((vma->vm_flags & VM_LOCKED) && ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
16185 +            current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
16186                 spin_unlock(&vma->vm_mm->page_table_lock);
16187                 return -ENOMEM;
16188         }
16189 +
16190         vma->vm_start = address;
16191         vma->vm_pgoff -= grow;
16192         vma->vm_mm->total_vm += grow;
16193 @@ -678,11 +787,6 @@
16194         return 0;
16195  }
16196  
16197 -/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
16198 -extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
16199 -extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
16200 -                                            struct vm_area_struct **pprev);
16201 -
16202  /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
16203     NULL if none.  Assume start_addr < end_addr. */
16204  static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
16205 diff -urN linux-2.4.24.org/include/linux/proc_fs.h linux-2.4.24/include/linux/proc_fs.h
16206 --- linux-2.4.24.org/include/linux/proc_fs.h    2004-02-04 23:04:38.193135503 +0100
16207 +++ linux-2.4.24/include/linux/proc_fs.h        2004-02-04 23:11:35.470370886 +0100
16208 @@ -143,6 +143,9 @@
16209  extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
16210                 struct proc_dir_entry *,kdev_t);
16211  extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
16212 +#ifdef CONFIG_GRKERNSEC_PROC
16213 +extern struct proc_dir_entry *proc_priv_mkdir(const char *, struct proc_dir_entry *);
16214 +#endif
16215  
16216  static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
16217         mode_t mode, struct proc_dir_entry *base, 
16218 diff -urN linux-2.4.24.org/include/linux/sched.h linux-2.4.24/include/linux/sched.h
16219 --- linux-2.4.24.org/include/linux/sched.h      2004-02-04 23:04:38.108153174 +0100
16220 +++ linux-2.4.24/include/linux/sched.h  2004-02-04 23:11:35.507363195 +0100
16221 @@ -28,6 +28,9 @@
16222  #include <linux/securebits.h>
16223  #include <linux/fs_struct.h>
16224  
16225 +extern int gr_is_capable(const int cap);
16226 +extern int gr_pid_is_chrooted(const struct task_struct *p);
16227 +
16228  struct exec_domain;
16229  
16230  /*
16231 @@ -250,6 +253,20 @@
16232         unsigned long cpu_vm_mask;
16233         unsigned long swap_address;
16234  
16235 +#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
16236 +       unsigned long call_dl_resolve;
16237 +#endif
16238 +
16239 +#if defined(CONFIG_PPC32) && defined(CONFIG_GRKERNSEC_PAX_EMUSIGRT)
16240 +       unsigned long call_syscall;
16241 +#endif
16242 +
16243 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
16244 +       unsigned long delta_mmap;               /* PaX: randomized offset */
16245 +       unsigned long delta_exec;               /* PaX: randomized offset */
16246 +       unsigned long delta_stack;              /* PaX: randomized offset */
16247 +#endif
16248
16249         unsigned dumpable:1;
16250  
16251         /* Architecture-specific MM context */
16252 @@ -422,7 +439,7 @@
16253         int (*notifier)(void *priv);
16254         void *notifier_data;
16255         sigset_t *notifier_mask;
16256 -       
16257 +
16258  /* Thread group tracking */
16259         u32 parent_exec_id;
16260         u32 self_exec_id;
16261 @@ -433,6 +450,22 @@
16262  
16263  /* journalling filesystem info */
16264         void *journal_info;
16265 +
16266 +#ifdef CONFIG_GRKERNSEC
16267 +/* added by grsecurity's ACL system */ 
16268 +       struct acl_subject_label *acl;
16269 +       struct acl_role_label *role;
16270 +       struct file *exec_file;
16271 +       u32 curr_ip;
16272 +       u32 gr_saddr;
16273 +       u32 gr_daddr;
16274 +       u16 gr_sport;
16275 +       u16 gr_dport;
16276 +       u16 acl_role_id;        
16277 +       u8 acl_sp_role:1;       
16278 +       u8 used_accept:1;       
16279 +       u8 is_writable:1;
16280 +#endif
16281  };
16282  
16283  /*
16284 @@ -454,6 +487,21 @@
16285  
16286  #define PF_USEDFPU     0x00100000      /* task used FPU this quantum (SMP) */
16287  
16288 +#define PF_PAX_PAGEEXEC       0x01000000      /* Paging based non-executable pages */
16289 +#define PF_PAX_EMUTRAMP       0x02000000      /* Emulate trampolines */
16290 +#define PF_PAX_MPROTECT       0x04000000      /* Restrict mprotect() */
16291 +#define PF_PAX_RANDMMAP       0x08000000      /* Randomize mmap() base */
16292 +#define PF_PAX_RANDEXEC              0x10000000      /* Randomize ET_EXEC base */
16293 +#define PF_PAX_SEGMEXEC              0x20000000      /* Segmentation based non-executable pages */
16294 +
16295 +extern int pax_check_flags(unsigned long *);
16296 +        
16297 +#ifdef CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS
16298 +extern void pax_set_flags(struct linux_binprm * bprm);
16299 +#elif defined(CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS)
16300 +extern void (*pax_set_flags_func)(struct linux_binprm * bprm);
16301 +#endif
16302 +
16303  /*
16304   * Ptrace flags
16305   */
16306 @@ -574,6 +622,8 @@
16307         *p->pidhash_pprev = p->pidhash_next;
16308  }
16309  
16310 +#include <asm/current.h>
16311 +
16312  static inline task_t *find_task_by_pid(int pid)
16313  {
16314         task_t *p, **htable = &pidhash[pid_hashfn(pid)];
16315 @@ -581,6 +631,8 @@
16316         for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
16317                 ;
16318  
16319 +       if(gr_pid_is_chrooted(p)) p = NULL;
16320 +
16321         return p;
16322  }
16323  
16324 @@ -589,8 +641,6 @@
16325  extern void free_uid(struct user_struct *);
16326  extern void switch_uid(struct user_struct *);
16327  
16328 -#include <asm/current.h>
16329 -
16330  extern unsigned long volatile jiffies;
16331  extern unsigned long itimer_ticks;
16332  extern unsigned long itimer_next;
16333 @@ -757,7 +807,7 @@
16334  static inline int capable(int cap)
16335  {
16336  #if 1 /* ok now */
16337 -       if (cap_raised(current->cap_effective, cap))
16338 +       if (cap_raised(current->cap_effective, cap) && gr_is_capable(cap))
16339  #else
16340         if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
16341  #endif
16342 diff -urN linux-2.4.24.org/include/linux/sysctl.h linux-2.4.24/include/linux/sysctl.h
16343 --- linux-2.4.24.org/include/linux/sysctl.h     2004-02-04 23:04:37.928190594 +0100
16344 +++ linux-2.4.24/include/linux/sysctl.h 2004-02-04 23:11:35.584347189 +0100
16345 @@ -128,6 +128,7 @@
16346         KERN_PPC_L3CR=57,       /* l3cr register on PPC */
16347         KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
16348         KERN_CORE_SETUID=59,    /* int: set to allow core dumps of setuid apps */
16349 +       KERN_GRSECURITY=68      /* grsecurity */
16350  };
16351  
16352  
16353 diff -urN linux-2.4.24.org/include/net/inetpeer.h linux-2.4.24/include/net/inetpeer.h
16354 --- linux-2.4.24.org/include/net/inetpeer.h     2004-02-04 23:05:21.185195977 +0100
16355 +++ linux-2.4.24/include/net/inetpeer.h 2004-02-04 23:11:35.849292104 +0100
16356 @@ -13,6 +13,7 @@
16357  #include <linux/init.h>
16358  #include <linux/sched.h>
16359  #include <linux/spinlock.h>
16360 +
16361  #include <asm/atomic.h>
16362  
16363  struct inet_peer
16364 @@ -34,6 +35,11 @@
16365  /* can be called with or without local BH being disabled */
16366  struct inet_peer       *inet_getpeer(__u32 daddr, int create);
16367  
16368 +#ifdef CONFIG_GRKERNSEC_RANDID
16369 +extern int grsec_enable_randid;
16370 +extern __u16 ip_randomid(void);
16371 +#endif
16372 +
16373  extern spinlock_t inet_peer_unused_lock;
16374  extern struct inet_peer *inet_peer_unused_head;
16375  extern struct inet_peer **inet_peer_unused_tailp;
16376 @@ -58,7 +64,14 @@
16377         __u16 id;
16378  
16379         spin_lock_bh(&inet_peer_idlock);
16380 -       id = p->ip_id_count++;
16381 +
16382 +#ifdef CONFIG_GRKERNSEC_RANDID
16383 +       if(grsec_enable_randid)
16384 +               id = htons(ip_randomid());
16385 +       else
16386 +#endif
16387 +               id = p->ip_id_count++;
16388 +
16389         spin_unlock_bh(&inet_peer_idlock);
16390         return id;
16391  }
16392 diff -urN linux-2.4.24.org/include/net/ip.h linux-2.4.24/include/net/ip.h
16393 --- linux-2.4.24.org/include/net/ip.h   2004-02-04 23:05:19.222604067 +0100
16394 +++ linux-2.4.24/include/net/ip.h       2004-02-04 23:11:35.881285452 +0100
16395 @@ -64,6 +64,11 @@
16396         void                    (*destructor)(struct sock *);
16397  };
16398  
16399 +#ifdef CONFIG_GRKERNSEC_RANDID
16400 +extern int grsec_enable_randid;
16401 +extern __u16 ip_randomid(void);
16402 +#endif
16403 +
16404  extern struct ip_ra_chain *ip_ra_chain;
16405  extern rwlock_t ip_ra_lock;
16406  
16407 @@ -197,7 +202,13 @@
16408                  * does not change, they drop every other packet in
16409                  * a TCP stream using header compression.
16410                  */
16411 -               iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
16412 +
16413 +#ifdef CONFIG_GRKERNSEC_RANDID
16414 +               if(grsec_enable_randid)
16415 +                       iph->id = htons(ip_randomid());
16416 +               else
16417 +#endif
16418 +                       iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
16419         } else
16420                 __ip_select_ident(iph, dst);
16421  }
16422 diff -urN linux-2.4.24.org/init/main.c linux-2.4.24/init/main.c
16423 --- linux-2.4.24.org/init/main.c        2004-02-04 23:04:20.873736801 +0100
16424 +++ linux-2.4.24/init/main.c    2004-02-04 23:11:35.935274227 +0100
16425 @@ -28,6 +28,7 @@
16426  #include <linux/bootmem.h>
16427  #include <linux/file.h>
16428  #include <linux/tty.h>
16429 +#include <linux/grsecurity.h>
16430  
16431  #include <asm/io.h>
16432  #include <asm/bugs.h>
16433 @@ -113,6 +114,8 @@
16434  extern void ipc_init(void);
16435  #endif
16436  
16437 +extern void grsecurity_init(void);
16438 +
16439  /*
16440   * Boot command-line arguments
16441   */
16442 @@ -568,6 +571,7 @@
16443         do_basic_setup();
16444  
16445         prepare_namespace();
16446 +       grsecurity_init();
16447  
16448         /*
16449          * Ok, we have completed the initial bootup, and
16450 diff -urN linux-2.4.24.org/ipc/msg.c linux-2.4.24/ipc/msg.c
16451 --- linux-2.4.24.org/ipc/msg.c  2004-02-04 23:06:17.123564481 +0100
16452 +++ linux-2.4.24/ipc/msg.c      2004-02-04 23:11:35.980264873 +0100
16453 @@ -22,6 +22,7 @@
16454  #include <linux/init.h>
16455  #include <linux/proc_fs.h>
16456  #include <linux/list.h>
16457 +#include <linux/grsecurity.h>
16458  #include <asm/uaccess.h>
16459  #include "util.h"
16460  
16461 @@ -326,6 +327,9 @@
16462                 msg_unlock(id);
16463         }
16464         up(&msg_ids.sem);
16465 +
16466 +       gr_log_msgget(ret, msgflg);
16467 +
16468         return ret;
16469  }
16470  
16471 @@ -560,6 +564,8 @@
16472                 break;
16473         }
16474         case IPC_RMID:
16475 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
16476 +
16477                 freeque (msqid); 
16478                 break;
16479         }
16480 diff -urN linux-2.4.24.org/ipc/sem.c linux-2.4.24/ipc/sem.c
16481 --- linux-2.4.24.org/ipc/sem.c  2004-02-04 23:06:17.121564897 +0100
16482 +++ linux-2.4.24/ipc/sem.c      2004-02-04 23:11:35.985263834 +0100
16483 @@ -63,6 +63,7 @@
16484  #include <linux/init.h>
16485  #include <linux/proc_fs.h>
16486  #include <linux/time.h>
16487 +#include <linux/grsecurity.h>
16488  #include <asm/uaccess.h>
16489  #include "util.h"
16490  
16491 @@ -182,6 +183,9 @@
16492         }
16493  
16494         up(&sem_ids.sem);
16495 +
16496 +       gr_log_semget(err, semflg);
16497 +
16498         return err;
16499  }
16500  
16501 @@ -724,6 +728,8 @@
16502  
16503         switch(cmd){
16504         case IPC_RMID:
16505 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
16506 +
16507                 freeary(semid);
16508                 err = 0;
16509                 break;
16510 diff -urN linux-2.4.24.org/ipc/shm.c linux-2.4.24/ipc/shm.c
16511 --- linux-2.4.24.org/ipc/shm.c  2004-02-04 23:06:17.133562402 +0100
16512 +++ linux-2.4.24/ipc/shm.c      2004-02-04 23:11:36.008259053 +0100
16513 @@ -23,6 +23,7 @@
16514  #include <linux/mman.h>
16515  #include <linux/proc_fs.h>
16516  #include <asm/uaccess.h>
16517 +#include <linux/grsecurity.h>
16518  
16519  #include "util.h"
16520  
16521 @@ -38,8 +39,21 @@
16522         time_t                  shm_ctim;
16523         pid_t                   shm_cprid;
16524         pid_t                   shm_lprid;
16525 +
16526 +#ifdef CONFIG_GRKERNSEC
16527 +       time_t                  shm_createtime;
16528 +       pid_t                   shm_lapid;
16529 +#endif
16530  };
16531  
16532 +#ifdef CONFIG_GRKERNSEC
16533 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16534 +                           const time_t shm_createtime, const uid_t cuid,
16535 +                           const int shmid);
16536 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16537 +                    const time_t shm_createtime);
16538 +#endif
16539 +
16540  #define shm_flags      shm_perm.mode
16541  
16542  static struct file_operations shm_file_operations;
16543 @@ -209,6 +223,9 @@
16544         shp->shm_lprid = 0;
16545         shp->shm_atim = shp->shm_dtim = 0;
16546         shp->shm_ctim = CURRENT_TIME;
16547 +#ifdef CONFIG_GRKERNSEC
16548 +       shp->shm_createtime = CURRENT_TIME;
16549 +#endif
16550         shp->shm_segsz = size;
16551         shp->shm_nattch = 0;
16552         shp->id = shm_buildid(id,shp->shm_perm.seq);
16553 @@ -254,6 +271,9 @@
16554                 shm_unlock(id);
16555         }
16556         up(&shm_ids.sem);
16557 +
16558 +       gr_log_shmget(err, shmflg, size);
16559 +
16560         return err;
16561  }
16562  
16563 @@ -509,6 +529,9 @@
16564                         err=-EPERM;
16565                         goto out_unlock_up;
16566                 }
16567 +
16568 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
16569 +
16570                 if (shp->shm_nattch){
16571                         shp->shm_flags |= SHM_DEST;
16572                         /* Do not find it any more */
16573 @@ -622,9 +645,28 @@
16574                 shm_unlock(shmid);
16575                 return -EACCES;
16576         }
16577 +
16578 +#ifdef CONFIG_GRKERNSEC
16579 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
16580 +                            shp->shm_perm.cuid, shmid)) {
16581 +               shm_unlock(shmid);
16582 +               return -EACCES;
16583 +       }
16584 +
16585 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
16586 +               shm_unlock(shmid);
16587 +               return -EACCES;
16588 +       }
16589 +#endif
16590 +
16591         file = shp->shm_file;
16592         size = file->f_dentry->d_inode->i_size;
16593         shp->shm_nattch++;
16594 +
16595 +#ifdef CONFIG_GRKERNSEC
16596 +       shp->shm_lapid = current->pid;
16597 +#endif
16598 +
16599         shm_unlock(shmid);
16600  
16601         down_write(&current->mm->mmap_sem);
16602 diff -urN linux-2.4.24.org/kernel/capability.c linux-2.4.24/kernel/capability.c
16603 --- linux-2.4.24.org/kernel/capability.c        2004-02-04 23:04:21.647575893 +0100
16604 +++ linux-2.4.24/kernel/capability.c    2004-02-04 23:11:36.046251154 +0100
16605 @@ -7,6 +7,7 @@
16606  
16607  #include <linux/mm.h>
16608  #include <asm/uaccess.h>
16609 +#include <linux/grsecurity.h>
16610  
16611  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
16612  
16613 @@ -170,6 +171,10 @@
16614               target = current;
16615       }
16616  
16617 +     if (gr_handle_chroot_capset(target)) {
16618 +            error = -ESRCH;
16619 +            goto out;
16620 +     }
16621  
16622       /* verify restrictions on target's new Inheritable set */
16623       if (!cap_issubset(inheritable,
16624 diff -urN linux-2.4.24.org/kernel/exit.c linux-2.4.24/kernel/exit.c
16625 --- linux-2.4.24.org/kernel/exit.c      2004-02-04 23:04:21.455615808 +0100
16626 +++ linux-2.4.24/kernel/exit.c  2004-02-04 23:11:36.096240760 +0100
16627 @@ -13,9 +13,11 @@
16628  #include <linux/personality.h>
16629  #include <linux/tty.h>
16630  #include <linux/namespace.h>
16631 +#include <linux/file.h>
16632  #ifdef CONFIG_BSD_PROCESS_ACCT
16633  #include <linux/acct.h>
16634  #endif
16635 +#include <linux/grsecurity.h>
16636  
16637  #include <asm/uaccess.h>
16638  #include <asm/pgtable.h>
16639 @@ -139,12 +141,21 @@
16640  {
16641         write_lock_irq(&tasklist_lock);
16642  
16643 +#ifdef CONFIG_GRKERNSEC
16644 +       if (current->exec_file) {
16645 +               fput(current->exec_file);
16646 +               current->exec_file = NULL;
16647 +       }
16648 +#endif
16649 +               
16650         /* Reparent to init */
16651         REMOVE_LINKS(current);
16652         current->p_pptr = child_reaper;
16653         current->p_opptr = child_reaper;
16654         SET_LINKS(current);
16655  
16656 +       gr_set_kernel_label(current);
16657 +
16658         /* Set the exit signal to SIGCHLD so we signal init on exit */
16659         current->exit_signal = SIGCHLD;
16660  
16661 @@ -173,7 +184,14 @@
16662  {
16663         struct fs_struct *fs;
16664  
16665 -
16666 +#ifdef CONFIG_GRKERNSEC
16667 +       if (current->exec_file) {
16668 +               fput(current->exec_file);
16669 +               current->exec_file = NULL;
16670 +       }
16671 +#endif
16672 +       gr_set_kernel_label(current);
16673 +       
16674         /*
16675          * If we were started as result of loading a module, close all of the
16676          * user space pages.  We don't need them, and if we didn't close them
16677 @@ -485,6 +503,11 @@
16678  #ifdef CONFIG_BSD_PROCESS_ACCT
16679         acct_process(code);
16680  #endif
16681 +
16682 +       gr_acl_handle_psacct(tsk, code);
16683 +       gr_acl_handle_exit();
16684 +       gr_del_task_from_ip_table(tsk);
16685 +
16686         __exit_mm(tsk);
16687  
16688         lock_kernel();
16689 diff -urN linux-2.4.24.org/kernel/fork.c linux-2.4.24/kernel/fork.c
16690 --- linux-2.4.24.org/kernel/fork.c      2004-02-04 23:04:20.955719753 +0100
16691 +++ linux-2.4.24/kernel/fork.c  2004-02-04 23:11:36.126234524 +0100
16692 @@ -22,6 +22,7 @@
16693  #include <linux/namespace.h>
16694  #include <linux/personality.h>
16695  #include <linux/compiler.h>
16696 +#include <linux/grsecurity.h>
16697  
16698  #include <asm/pgtable.h>
16699  #include <asm/pgalloc.h>
16700 @@ -94,6 +95,10 @@
16701         if (flags & CLONE_PID)
16702                 return current->pid;
16703  
16704 +       pid = gr_random_pid(&lastpid_lock);
16705 +       if (pid)
16706 +               return pid;
16707 +
16708         spin_lock(&lastpid_lock);
16709         beginpid = last_pid;
16710         if((++last_pid) & 0xffff8000) {
16711 @@ -672,6 +677,9 @@
16712          * friends to set the per-user process limit to something lower
16713          * than the amount of processes root is running. -- Rik
16714          */
16715 +
16716 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
16717 +
16718         if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
16719                       && p->user != &root_user
16720                       && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
16721 @@ -756,6 +764,7 @@
16722         retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
16723         if (retval)
16724                 goto bad_fork_cleanup_namespace;
16725 +       gr_copy_label(p);
16726         p->semundo = NULL;
16727         
16728         /* Our parent execution domain becomes current domain
16729 @@ -858,6 +867,9 @@
16730         free_uid(p->user);
16731  bad_fork_free:
16732         free_task_struct(p);
16733 +
16734 +       gr_log_forkfail(retval);
16735 +
16736         goto fork_out;
16737  }
16738  
16739 diff -urN linux-2.4.24.org/kernel/ksyms.c linux-2.4.24/kernel/ksyms.c
16740 --- linux-2.4.24.org/kernel/ksyms.c     2004-02-04 23:04:22.707355528 +0100
16741 +++ linux-2.4.24/kernel/ksyms.c 2004-02-04 23:11:36.162227041 +0100
16742 @@ -51,6 +51,7 @@
16743  #include <linux/dnotify.h>
16744  #include <linux/crc32.h>
16745  #include <linux/firmware.h>
16746 +#include <linux/grsecurity.h>
16747  #include <asm/checksum.h>
16748  
16749  #if defined(CONFIG_PROC_FS)
16750 @@ -635,3 +636,9 @@
16751  /* To match ksyms with System.map */
16752  extern const char _end[];
16753  EXPORT_SYMBOL(_end);
16754 +
16755 +/* grsecurity */
16756 +EXPORT_SYMBOL(gr_is_capable);
16757 +EXPORT_SYMBOL(gr_pid_is_chrooted);
16758 +EXPORT_SYMBOL(gr_learn_resource);
16759 +EXPORT_SYMBOL(gr_set_kernel_label);
16760 diff -urN linux-2.4.24.org/kernel/module.c linux-2.4.24/kernel/module.c
16761 --- linux-2.4.24.org/kernel/module.c    2004-02-04 23:04:21.090691688 +0100
16762 +++ linux-2.4.24/kernel/module.c        2004-02-04 23:11:36.194220389 +0100
16763 @@ -900,6 +900,11 @@
16764         struct module *mod;
16765         int err;
16766  
16767 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16768 +       if (!capable(CAP_SYS_MODULE))
16769 +               return -EPERM;
16770 +#endif
16771 +
16772         lock_kernel();
16773         if (name_user == NULL)
16774                 mod = &kernel_module;
16775 @@ -969,6 +974,11 @@
16776         int i;
16777         struct kernel_sym ksym;
16778  
16779 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16780 +       if (!capable(CAP_SYS_MODULE))
16781 +               return 0;
16782 +#endif
16783 +
16784         lock_kernel();
16785         for (mod = module_list, i = 0; mod; mod = mod->next) {
16786                 /* include the count for the module name! */
16787 diff -urN linux-2.4.24.org/kernel/printk.c linux-2.4.24/kernel/printk.c
16788 --- linux-2.4.24.org/kernel/printk.c    2004-02-04 23:04:22.874320810 +0100
16789 +++ linux-2.4.24/kernel/printk.c        2004-02-04 23:11:36.232212490 +0100
16790 @@ -27,6 +27,7 @@
16791  #include <linux/interrupt.h>                   /* For in_interrupt() */
16792  #include <linux/config.h>
16793  #include <linux/delay.h>
16794 +#include <linux/grsecurity.h>
16795  
16796  #include <asm/uaccess.h>
16797  
16798 @@ -299,6 +300,11 @@
16799  
16800  asmlinkage long sys_syslog(int type, char * buf, int len)
16801  {
16802 +#ifdef CONFIG_GRKERNSEC_DMESG
16803 +       if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
16804 +               return -EPERM;
16805 +       else
16806 +#endif
16807         if ((type != 3) && !capable(CAP_SYS_ADMIN))
16808                 return -EPERM;
16809         return do_syslog(type, buf, len);
16810 diff -urN linux-2.4.24.org/kernel/sched.c linux-2.4.24/kernel/sched.c
16811 --- linux-2.4.24.org/kernel/sched.c     2004-02-04 23:04:22.588380267 +0100
16812 +++ linux-2.4.24/kernel/sched.c 2004-02-04 23:11:36.273203967 +0100
16813 @@ -20,11 +20,13 @@
16814  #include <linux/nmi.h>
16815  #include <linux/interrupt.h>
16816  #include <linux/init.h>
16817 +#include <linux/file.h>
16818  #include <asm/uaccess.h>
16819  #include <linux/smp_lock.h>
16820  #include <asm/mmu_context.h>
16821  #include <linux/kernel_stat.h>
16822  #include <linux/completion.h>
16823 +#include <linux/grsecurity.h>
16824  
16825  /*
16826   * Convert user-nice values [ -20 ... 0 ... 19 ]
16827 @@ -1192,6 +1194,9 @@
16828                         return -EPERM;
16829                 if (increment < -40)
16830                         increment = -40;
16831 +
16832 +               if (gr_handle_chroot_nice())
16833 +                       return -EPERM;
16834         }
16835         if (increment > 40)
16836                 increment = 40;
16837 diff -urN linux-2.4.24.org/kernel/signal.c linux-2.4.24/kernel/signal.c
16838 --- linux-2.4.24.org/kernel/signal.c    2004-02-04 23:04:22.240452613 +0100
16839 +++ linux-2.4.24/kernel/signal.c        2004-02-04 23:11:36.318194613 +0100
16840 @@ -13,6 +13,8 @@
16841  #include <linux/smp_lock.h>
16842  #include <linux/init.h>
16843  #include <linux/sched.h>
16844 +#include <linux/fs.h>
16845 +#include <linux/grsecurity.h>
16846  
16847  #include <asm/uaccess.h>
16848  
16849 @@ -553,6 +555,8 @@
16850         if (!sig || !t->sig)
16851                 goto out_nolock;
16852  
16853 +       gr_log_signal(sig, t);
16854 +
16855         spin_lock_irqsave(&t->sigmask_lock, flags);
16856         handle_stop_signal(sig, t);
16857  
16858 @@ -602,6 +606,8 @@
16859         recalc_sigpending(t);
16860         spin_unlock_irqrestore(&t->sigmask_lock, flags);
16861  
16862 +       gr_handle_crash(t, sig);
16863 +
16864         return send_sig_info(sig, info, t);
16865  }
16866  
16867 @@ -621,9 +627,13 @@
16868                 read_lock(&tasklist_lock);
16869                 for_each_task(p) {
16870                         if (p->pgrp == pgrp && thread_group_leader(p)) {
16871 -                               int err = send_sig_info(sig, info, p);
16872 -                               if (retval)
16873 -                                       retval = err;
16874 +                               if (gr_handle_signal(p, sig))
16875 +                                       retval = -EPERM;
16876 +                               else {
16877 +                                       int err = send_sig_info(sig, info, p);
16878 +                                       if (retval)
16879 +                                               retval = err;
16880 +                               }
16881                         }
16882                 }
16883                 read_unlock(&tasklist_lock);
16884 @@ -674,7 +684,10 @@
16885                         if (tg)
16886                                 p = tg;
16887                  }
16888 -               error = send_sig_info(sig, info, p);
16889 +               if (gr_handle_signal(p, sig))
16890 +                       error = -EPERM;
16891 +               else
16892 +                       error = send_sig_info(sig, info, p);
16893         }
16894         read_unlock(&tasklist_lock);
16895         return error;
16896 @@ -699,10 +712,14 @@
16897                 read_lock(&tasklist_lock);
16898                 for_each_task(p) {
16899                         if (p->pid > 1 && p != current && thread_group_leader(p)) {
16900 -                               int err = send_sig_info(sig, info, p);
16901 -                               ++count;
16902 -                               if (err != -EPERM)
16903 -                                       retval = err;
16904 +                               if (gr_handle_signal(p, sig))
16905 +                                       retval = -EPERM;
16906 +                               else {
16907 +                                       int err = send_sig_info(sig, info, p);
16908 +                                       ++count;
16909 +                                       if (err != -EPERM)
16910 +                                               retval = err;
16911 +                               }
16912                         }
16913                 }
16914                 read_unlock(&tasklist_lock);
16915 diff -urN linux-2.4.24.org/kernel/sys.c linux-2.4.24/kernel/sys.c
16916 --- linux-2.4.24.org/kernel/sys.c       2004-02-04 23:04:20.898731603 +0100
16917 +++ linux-2.4.24/kernel/sys.c   2004-02-04 23:11:36.366184636 +0100
16918 @@ -4,6 +4,7 @@
16919   *  Copyright (C) 1991, 1992  Linus Torvalds
16920   */
16921  
16922 +#include <linux/config.h>
16923  #include <linux/module.h>
16924  #include <linux/mm.h>
16925  #include <linux/utsname.h>
16926 @@ -14,6 +15,7 @@
16927  #include <linux/prctl.h>
16928  #include <linux/init.h>
16929  #include <linux/highuid.h>
16930 +#include <linux/grsecurity.h>
16931  
16932  #include <asm/uaccess.h>
16933  #include <asm/io.h>
16934 @@ -239,6 +241,12 @@
16935                 }
16936                 if (error == -ESRCH)
16937                         error = 0;
16938 +
16939 +               if (gr_handle_chroot_setpriority(p, niceval)) {
16940 +                       read_unlock(&tasklist_lock);
16941 +                       return -ESRCH;
16942 +               }
16943 +
16944                 if (niceval < task_nice(p) && !capable(CAP_SYS_NICE))
16945                         error = -EACCES;
16946                 else
16947 @@ -425,6 +433,9 @@
16948         if (rgid != (gid_t) -1 ||
16949             (egid != (gid_t) -1 && egid != old_rgid))
16950                 current->sgid = new_egid;
16951 +
16952 +       gr_set_role_label(current, current->uid, new_rgid);
16953 +
16954         current->fsgid = new_egid;
16955         current->egid = new_egid;
16956         current->gid = new_rgid;
16957 @@ -447,6 +458,9 @@
16958                         current->mm->dumpable=0;
16959                         wmb();
16960                 }
16961 +
16962 +               gr_set_role_label(current, current->uid, gid);
16963 +
16964                 current->gid = current->egid = current->sgid = current->fsgid = gid;
16965         }
16966         else if ((gid == current->gid) || (gid == current->sgid))
16967 @@ -523,6 +537,9 @@
16968                 current->mm->dumpable = 0;
16969                 wmb();
16970         }
16971 +
16972 +       gr_set_role_label(current, new_ruid, current->gid);
16973 +
16974         current->uid = new_ruid;
16975         return 0;
16976  }
16977 @@ -617,6 +634,9 @@
16978         } else if ((uid != current->uid) && (uid != new_suid))
16979                 return -EPERM;
16980  
16981 +       if (gr_check_crash_uid(uid))
16982 +               return -EPERM;
16983 +
16984         if (old_euid != uid)
16985         {
16986                 current->mm->dumpable = 0;
16987 @@ -713,8 +733,10 @@
16988                 current->egid = egid;
16989         }
16990         current->fsgid = current->egid;
16991 -       if (rgid != (gid_t) -1)
16992 +       if (rgid != (gid_t) -1) {
16993 +               gr_set_role_label(current, current->uid, rgid);
16994                 current->gid = rgid;
16995 +       }
16996         if (sgid != (gid_t) -1)
16997                 current->sgid = sgid;
16998         return 0;
16999 @@ -1137,6 +1159,10 @@
17000         if (new_rlim.rlim_cur > new_rlim.rlim_max)
17001                 return -EINVAL;
17002         old_rlim = current->rlim + resource;
17003 +
17004 +       if (old_rlim->rlim_max < old_rlim->rlim_cur)
17005 +               return -EINVAL;
17006 +
17007         if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
17008              (new_rlim.rlim_max > old_rlim->rlim_max)) &&
17009             !capable(CAP_SYS_RESOURCE))
17010 diff -urN linux-2.4.24.org/kernel/sysctl.c linux-2.4.24/kernel/sysctl.c
17011 --- linux-2.4.24.org/kernel/sysctl.c    2004-02-04 23:04:22.948305427 +0100
17012 +++ linux-2.4.24/kernel/sysctl.c        2004-02-04 23:11:36.422172995 +0100
17013 @@ -39,6 +39,13 @@
17014  #endif
17015  
17016  #if defined(CONFIG_SYSCTL)
17017 +#include <linux/grsecurity.h>
17018 +#include <linux/grinternal.h>
17019 +
17020 +extern __u32 gr_handle_sysctl(const ctl_table * table, const void *oldval,
17021 +                             const void *newval);
17022 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op);
17023 +extern int gr_handle_chroot_sysctl(const int op);
17024  
17025  /* External variables not in a header file. */
17026  extern int panic_timeout;
17027 @@ -131,6 +138,8 @@
17028  static ctl_table debug_table[];
17029  extern ctl_table random_table[];
17030  
17031 +static ctl_table grsecurity_table[];
17032 +
17033  /* /proc declarations: */
17034  
17035  #ifdef CONFIG_PROC_FS
17036 @@ -277,8 +286,191 @@
17037         {KERN_EXCEPTION_TRACE,"exception-trace",
17038          &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
17039  #endif 
17040 +#ifdef CONFIG_GRKERNSEC_SYSCTL
17041 +       {KERN_GRSECURITY, "grsecurity", NULL, 0, 0500, grsecurity_table},
17042 +#endif
17043 +       {0}
17044 +};
17045 +
17046 +#ifdef CONFIG_GRKERNSEC_SYSCTL
17047 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL, 
17048 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
17049 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
17050 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS, 
17051 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL,
17052 +GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
17053 +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
17054 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
17055 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
17056 +GS_FINDTASK, GS_LOCK};
17057 +
17058 +static ctl_table grsecurity_table[] = {
17059 +#ifdef CONFIG_GRKERNSEC_LINK
17060 +       {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int),
17061 +        0600, NULL, &proc_dointvec}, 
17062 +#endif
17063 +#ifdef CONFIG_GRKERNSEC_FIFO
17064 +       {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int),
17065 +        0600, NULL, &proc_dointvec},
17066 +#endif
17067 +#ifdef CONFIG_GRKERNSEC_EXECVE
17068 +       {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int),
17069 +        0600, NULL, &proc_dointvec},
17070 +#endif
17071 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17072 +       {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int),
17073 +        0600, NULL, &proc_dointvec},
17074 +#endif
17075 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17076 +       {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int),
17077 +        0600, NULL, &proc_dointvec},
17078 +#endif
17079 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
17080 +       {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int),
17081 +        0600, NULL, &proc_dointvec},
17082 +#endif
17083 +#ifdef CONFIG_GRKERNSEC_TIME
17084 +       {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int),
17085 +        0600, NULL, &proc_dointvec},
17086 +#endif
17087 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17088 +       {GS_CHROOT_SHMAT, "chroot_deny_shmat", &grsec_enable_chroot_shmat, sizeof (int),
17089 +        0600, NULL, &proc_dointvec},
17090 +#endif
17091 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17092 +       {GS_CHROOT_UNIX, "chroot_deny_unix", &grsec_enable_chroot_unix, sizeof(int),
17093 +        0600, NULL, &proc_dointvec},
17094 +#endif
17095 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17096 +       {GS_CHROOT_MNT, "chroot_deny_mount", &grsec_enable_chroot_mount, sizeof (int),
17097 +        0600, NULL, &proc_dointvec},
17098 +#endif
17099 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17100 +       {GS_CHROOT_FCHDIR, "chroot_deny_fchdir", &grsec_enable_chroot_fchdir, sizeof (int),
17101 +        0600, NULL, &proc_dointvec},
17102 +#endif
17103 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17104 +       {GS_CHROOT_DBL, "chroot_deny_chroot", &grsec_enable_chroot_double, sizeof (int),
17105 +        0600, NULL, &proc_dointvec},
17106 +#endif
17107 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17108 +       {GS_CHROOT_PVT, "chroot_deny_pivot", &grsec_enable_chroot_pivot, sizeof (int),
17109 +        0600, NULL, &proc_dointvec},
17110 +#endif
17111 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17112 +       {GS_CHROOT_CD, "chroot_enforce_chdir", &grsec_enable_chroot_chdir, sizeof (int),
17113 +        0600, NULL, &proc_dointvec},
17114 +#endif
17115 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17116 +       {GS_CHROOT_CM, "chroot_deny_chmod", &grsec_enable_chroot_chmod, sizeof (int),
17117 +        0600, NULL, &proc_dointvec},
17118 +#endif
17119 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17120 +       {GS_CHROOT_MK, "chroot_deny_mknod", &grsec_enable_chroot_mknod, sizeof (int),
17121 +        0600, NULL, &proc_dointvec},
17122 +#endif
17123 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17124 +       {GS_CHROOT_NI, "chroot_restrict_nice", &grsec_enable_chroot_nice, sizeof (int),
17125 +        0600, NULL, &proc_dointvec},
17126 +#endif
17127 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17128 +       {GS_CHROOT_EXECLOG, "chroot_execlog",
17129 +        &grsec_enable_chroot_execlog, sizeof (int),
17130 +         0600, NULL, &proc_dointvec},
17131 +#endif
17132 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17133 +       {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int),
17134 +        0600, NULL, &proc_dointvec},
17135 +#endif
17136 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17137 +       {GS_CHROOT_SYSCTL, "chroot_deny_sysctl", &grsec_enable_chroot_sysctl, sizeof (int),
17138 +        0600, NULL, &proc_dointvec},
17139 +#endif
17140 +#ifdef CONFIG_GRKERNSEC_TPE
17141 +       {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int),
17142 +        0600, NULL, &proc_dointvec},
17143 +       {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int),
17144 +        0600, NULL, &proc_dointvec},
17145 +#endif
17146 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
17147 +       {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int),
17148 +        0600, NULL, &proc_dointvec},
17149 +#endif
17150 +#ifdef CONFIG_GRKERNSEC_RANDPID
17151 +       {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int),
17152 +        0600, NULL, &proc_dointvec},
17153 +#endif
17154 +#ifdef CONFIG_GRKERNSEC_RANDID
17155 +       {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int),
17156 +        0600, NULL, &proc_dointvec},
17157 +#endif
17158 +#ifdef CONFIG_GRKERNSEC_RANDSRC
17159 +       {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int),
17160 +        0600, NULL, &proc_dointvec},
17161 +#endif
17162 +#ifdef CONFIG_GRKERNSEC_RANDISN
17163 +       {GS_RANDISN, "rand_isns", &grsec_enable_randisn, sizeof (int),
17164 +        0600, NULL, &proc_dointvec},
17165 +#endif
17166 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
17167 +       {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int),
17168 +        0600, NULL, &proc_dointvec},
17169 +       {GS_SOCKET_ALL_GID, "socket_all_gid",
17170 +        &grsec_socket_all_gid, sizeof (int),
17171 +        0600, NULL, &proc_dointvec},
17172 +#endif
17173 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
17174 +       {GS_SOCKET_CLIENT, "socket_client", 
17175 +        &grsec_enable_socket_client, sizeof (int),
17176 +        0600, NULL, &proc_dointvec},
17177 +       {GS_SOCKET_CLIENT_GID, "socket_client_gid", 
17178 +        &grsec_socket_client_gid, sizeof (int),
17179 +        0600, NULL, &proc_dointvec},
17180 +#endif
17181 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17182 +       {GS_SOCKET_SERVER, "socket_server", 
17183 +        &grsec_enable_socket_server, sizeof (int),
17184 +        0600, NULL, &proc_dointvec},
17185 +       {GS_SOCKET_SERVER_GID, "socket_server_gid",
17186 +        &grsec_socket_server_gid, sizeof (int),
17187 +        0600, NULL, &proc_dointvec},
17188 +#endif
17189 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
17190 +       {GS_GROUP, "audit_group", &grsec_enable_group, sizeof (int),
17191 +        0600, NULL, &proc_dointvec},
17192 +       {GS_GID, "audit_gid",
17193 +        &grsec_audit_gid, sizeof (int),
17194 +        0600, NULL, &proc_dointvec},
17195 +#endif
17196 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17197 +       {GS_ACHDIR, "audit_chdir", &grsec_enable_chdir, sizeof (int),
17198 +        0600, NULL, &proc_dointvec},
17199 +#endif
17200 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17201 +       {GS_AMOUNT, "audit_mount", &grsec_enable_mount, sizeof (int),
17202 +        0600, NULL, &proc_dointvec},
17203 +#endif
17204 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17205 +       {GS_AIPC, "audit_ipc", &grsec_enable_audit_ipc, sizeof (int),
17206 +        0600, NULL, &proc_dointvec},
17207 +#endif
17208 +#ifdef CONFIG_GRKERNSEC_DMESG
17209 +       {GS_DMSG, "dmesg", &grsec_enable_dmesg, sizeof (int),
17210 +        0600, NULL, &proc_dointvec},
17211 +#endif
17212 +#ifdef CONFIG_GRKERNSEC_RANDRPC
17213 +       {GS_RANDRPC, "rand_rpc", &grsec_enable_randrpc, sizeof (int),
17214 +        0600, NULL, &proc_dointvec},
17215 +#endif
17216 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17217 +       {GS_FINDTASK, "chroot_findtask", &grsec_enable_chroot_findtask, 
17218 +        sizeof (int), 0600, NULL, &proc_dointvec},
17219 +#endif
17220 +       {GS_LOCK, "grsec_lock", &grsec_lock, sizeof (int), 0600, NULL,
17221 +        &proc_dointvec},
17222         {0}
17223  };
17224 +#endif
17225  
17226  static ctl_table vm_table[] = {
17227         {VM_GFP_DEBUG, "vm_gfp_debug", 
17228 @@ -427,6 +619,11 @@
17229  
17230  static inline int ctl_perm(ctl_table *table, int op)
17231  {
17232 +       if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
17233 +               return -EACCES;
17234 +       if (gr_handle_chroot_sysctl(op))
17235 +               return -EACCES;
17236 +
17237         return test_perm(table->mode, op);
17238  }
17239  
17240 @@ -460,6 +657,10 @@
17241                                 table = table->child;
17242                                 goto repeat;
17243                         }
17244 +
17245 +                       if (!gr_handle_sysctl(table, oldval, newval))
17246 +                               return -EACCES;
17247 +
17248                         error = do_sysctl_strategy(table, name, nlen,
17249                                                    oldval, oldlenp,
17250                                                    newval, newlen, context);
17251 diff -urN linux-2.4.24.org/kernel/time.c linux-2.4.24/kernel/time.c
17252 --- linux-2.4.24.org/kernel/time.c      2004-02-04 23:04:21.242660089 +0100
17253 +++ linux-2.4.24/kernel/time.c  2004-02-04 23:11:36.453166551 +0100
17254 @@ -27,6 +27,7 @@
17255  #include <linux/mm.h>
17256  #include <linux/timex.h>
17257  #include <linux/smp_lock.h>
17258 +#include <linux/grsecurity.h>
17259  
17260  #include <asm/uaccess.h>
17261  
17262 @@ -89,6 +90,9 @@
17263         time_maxerror = NTP_PHASE_LIMIT;
17264         time_esterror = NTP_PHASE_LIMIT;
17265         write_unlock_irq(&xtime_lock);
17266 +
17267 +       gr_log_timechange();
17268 +
17269         return 0;
17270  }
17271  
17272 @@ -167,6 +171,8 @@
17273                  * globally block out interrupts when it runs.
17274                  */
17275                 do_settimeofday(tv);
17276 +
17277 +               gr_log_timechange();
17278         }
17279         return 0;
17280  }
17281 diff -urN linux-2.4.24.org/kernel/timer.c linux-2.4.24/kernel/timer.c
17282 --- linux-2.4.24.org/kernel/timer.c     2004-02-04 23:04:22.499398770 +0100
17283 +++ linux-2.4.24/kernel/timer.c 2004-02-04 23:11:36.476161770 +0100
17284 @@ -565,6 +565,9 @@
17285  
17286         psecs = (p->times.tms_utime += user);
17287         psecs += (p->times.tms_stime += system);
17288 +
17289 +       gr_learn_resource(p, RLIMIT_CPU, psecs / HZ, 1);
17290 +
17291         if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
17292                 /* Send SIGXCPU every second.. */
17293                 if (!(psecs % HZ))
17294 diff -urN linux-2.4.24.org/Makefile linux-2.4.24/Makefile
17295 --- linux-2.4.24.org/Makefile   2004-02-04 23:10:23.789274365 +0100
17296 +++ linux-2.4.24/Makefile       2004-02-04 23:11:36.482160523 +0100
17297 @@ -134,9 +134,10 @@
17298  
17299  CORE_FILES     =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
17300  NETWORKS       =net/network.o
17301 +GRSECURITY     =grsecurity/grsec.o
17302  
17303  LIBS           =$(TOPDIR)/lib/lib.a
17304 -SUBDIRS                =kernel drivers mm fs net ipc lib crypto
17305 +SUBDIRS                =kernel drivers mm fs net ipc lib crypto grsecurity
17306  
17307  DRIVERS-n :=
17308  DRIVERS-y :=
17309 @@ -280,7 +281,7 @@
17310  
17311  export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
17312  
17313 -export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
17314 +export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS GRSECURITY
17315  
17316  .S.s:
17317         $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
17318 @@ -299,6 +300,7 @@
17319                 $(CORE_FILES) \
17320                 $(DRIVERS) \
17321                 $(NETWORKS) \
17322 +               $(GRSECURITY) \
17323                 $(LIBS) \
17324                 --end-group \
17325                 -o vmlinux
17326 diff -urN linux-2.4.24.org/mm/filemap.c linux-2.4.24/mm/filemap.c
17327 --- linux-2.4.24.org/mm/filemap.c       2004-02-04 23:04:29.156014631 +0100
17328 +++ linux-2.4.24/mm/filemap.c   2004-02-04 23:11:36.527151169 +0100
17329 @@ -2324,6 +2324,12 @@
17330         }
17331         if (!mapping->a_ops->readpage)
17332                 return -ENOEXEC;
17333 +
17334 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17335 +       if (current->flags & PF_PAX_PAGEEXEC)
17336 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
17337 +#endif
17338 +
17339         UPDATE_ATIME(inode);
17340         vma->vm_ops = &generic_file_vm_ops;
17341         return 0;
17342 @@ -2553,8 +2559,42 @@
17343   * We can potentially split a vm area into separate
17344   * areas, each area with its own behavior.
17345   */
17346 +
17347 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17348 +static long __madvise_behavior(struct vm_area_struct * vma,
17349 +       unsigned long start, unsigned long end, int behavior);
17350 +
17351 +static long madvise_behavior(struct vm_area_struct * vma,
17352 +       unsigned long start, unsigned long end, int behavior)
17353 +{
17354 +       if (vma->vm_flags & VM_MIRROR) {
17355 +               struct vm_area_struct * vma_m, * prev_m;
17356 +               unsigned long start_m, end_m;
17357 +               int error;
17358 +
17359 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17360 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
17361 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
17362 +                       start_m = start + (unsigned long)vma->vm_private_data;
17363 +                       end_m = end + (unsigned long)vma->vm_private_data;
17364 +                       error = __madvise_behavior(vma_m, start_m, end_m, behavior);
17365 +                       if (error)
17366 +                               return error;
17367 +               } else {
17368 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
17369 +                       return -ENOMEM;
17370 +               }
17371 +       }
17372 +
17373 +       return __madvise_behavior(vma, start, end, behavior);
17374 +}
17375 +
17376 +static long __madvise_behavior(struct vm_area_struct * vma,
17377 +       unsigned long start, unsigned long end, int behavior)
17378 +#else
17379  static long madvise_behavior(struct vm_area_struct * vma,
17380         unsigned long start, unsigned long end, int behavior)
17381 +#endif
17382  {
17383         int error = 0;
17384  
17385 @@ -2608,6 +2648,7 @@
17386         error = -EIO;
17387         rlim_rss = current->rlim ?  current->rlim[RLIMIT_RSS].rlim_cur :
17388                                 LONG_MAX; /* default: see resource.h */
17389 +       gr_learn_resource(current, RLIMIT_RSS, vma->vm_mm->rss + (end - start), 1);
17390         if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
17391                 return error;
17392  
17393 @@ -3083,6 +3124,7 @@
17394         err = -EFBIG;
17395         
17396         if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
17397 +               gr_learn_resource(current, RLIMIT_FSIZE, pos, 0);
17398                 if (pos >= limit) {
17399                         send_sig(SIGXFSZ, current, 0);
17400                         goto out;
17401 @@ -3118,6 +3160,7 @@
17402          */
17403          
17404         if (!S_ISBLK(inode->i_mode)) {
17405 +               gr_learn_resource(current, RLIMIT_FSIZE, *count + (u32)pos, 0);
17406                 if (pos >= inode->i_sb->s_maxbytes)
17407                 {
17408                         if (*count || pos > inode->i_sb->s_maxbytes) {
17409 diff -urN linux-2.4.24.org/mm/memory.c linux-2.4.24/mm/memory.c
17410 --- linux-2.4.24.org/mm/memory.c        2004-02-04 23:04:28.526145602 +0100
17411 +++ linux-2.4.24/mm/memory.c    2004-02-04 23:11:36.601135786 +0100
17412 @@ -925,6 +925,65 @@
17413         establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
17414  }
17415  
17416 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17417 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
17418 + *
17419 + * mm->page_table_lock is held on entry and is not released on exit or inside
17420 + * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
17421 + */
17422 +static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
17423 +       unsigned long address, pte_t *pte)
17424 +{
17425 +       unsigned long address_m;
17426 +       struct vm_area_struct * vma_m = NULL;
17427 +       pte_t * pte_m, entry_m;
17428 +       struct page * page_m;
17429 +
17430 +       if (!(vma->vm_flags & VM_MIRROR))
17431 +               return;
17432 +
17433 +       address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17434 +       vma_m = find_vma(mm, address_m);
17435 +       if (!vma_m || vma_m->vm_start != address_m)
17436 +               return;
17437 +
17438 +       address_m = address + (unsigned long)vma->vm_private_data;
17439 +
17440 +       {
17441 +               pgd_t *pgd_m;
17442 +               pmd_t *pmd_m;
17443 +
17444 +               pgd_m = pgd_offset(mm, address_m);
17445 +               pmd_m = pmd_offset(pgd_m, address_m);
17446 +               pte_m = pte_offset(pmd_m, address_m);
17447 +       }
17448 +
17449 +       if (pte_present(*pte_m)) {
17450 +               flush_cache_page(vma_m, address_m);
17451 +               flush_icache_page(vma_m, pte_page(*pte_m));
17452 +       }
17453 +       entry_m = ptep_get_and_clear(pte_m);
17454 +       if (pte_present(entry_m))
17455 +               flush_tlb_page(vma_m, address_m);  
17456 +
17457 +       if (pte_none(entry_m)) {
17458 +               ++mm->rss;
17459 +       } else if (pte_present(entry_m)) {
17460 +               page_cache_release(pte_page(entry_m));
17461 +       } else {
17462 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
17463 +               ++mm->rss;
17464 +       }
17465 +
17466 +       page_m = pte_page(*pte);
17467 +       page_cache_get(page_m);
17468 +       entry_m = mk_pte(page_m, vma_m->vm_page_prot);
17469 +       if (pte_write(*pte))
17470 +               entry_m = pte_mkdirty(pte_mkwrite(entry_m));
17471 +       establish_pte(vma_m, address_m, pte_m, entry_m);  
17472 +}                      
17473 +#endif
17474 +
17475  /*
17476   * This routine handles present pages, when users try to write
17477   * to a shared page. It is done by copying the page to a new address
17478 @@ -988,6 +1047,11 @@
17479  
17480                 /* Free the old page.. */
17481                 new_page = old_page;
17482 +
17483 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17484 +               pax_mirror_fault(mm, vma, address, page_table);
17485 +#endif
17486 +
17487         }
17488         spin_unlock(&mm->page_table_lock);
17489         page_cache_release(new_page);
17490 @@ -1065,6 +1129,7 @@
17491  
17492  do_expand:
17493         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
17494 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
17495         if (limit != RLIM_INFINITY && offset > limit)
17496                 goto out_sig;
17497         if (offset > inode->i_sb->s_maxbytes)
17498 @@ -1178,6 +1243,11 @@
17499  
17500         /* No need to invalidate - it was non-present before */
17501         update_mmu_cache(vma, address, pte);
17502 +
17503 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17504 +       pax_mirror_fault(mm, vma, address, page_table);
17505 +#endif
17506 +
17507         spin_unlock(&mm->page_table_lock);
17508         return ret;
17509  }
17510 @@ -1223,6 +1293,11 @@
17511  
17512         /* No need to invalidate - it was non-present before */
17513         update_mmu_cache(vma, addr, entry);
17514 +
17515 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17516 +       pax_mirror_fault(mm, vma, addr, page_table);
17517 +#endif
17518 +
17519         spin_unlock(&mm->page_table_lock);
17520         return 1;       /* Minor fault */
17521  
17522 @@ -1304,6 +1379,11 @@
17523  
17524         /* no need to invalidate: a not-present page shouldn't be cached */
17525         update_mmu_cache(vma, address, entry);
17526 +
17527 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17528 +       pax_mirror_fault(mm, vma, address, page_table);
17529 +#endif
17530 +
17531         spin_unlock(&mm->page_table_lock);
17532         return 2;       /* Major fault */
17533  }
17534 @@ -1368,6 +1448,11 @@
17535         pgd_t *pgd;
17536         pmd_t *pmd;
17537  
17538 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17539 +       unsigned long address_m = 0UL;
17540 +       struct vm_area_struct * vma_m = NULL;
17541 +#endif
17542 +
17543         current->state = TASK_RUNNING;
17544         pgd = pgd_offset(mm, address);
17545  
17546 @@ -1376,6 +1461,47 @@
17547          * and the SMP-safe atomic PTE updates.
17548          */
17549         spin_lock(&mm->page_table_lock);
17550 +
17551 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17552 +       if (vma->vm_flags & VM_MIRROR) {
17553 +               pgd_t *pgd_m;
17554 +               pmd_t *pmd_m;
17555 +               pte_t *pte_m;
17556 +
17557 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17558 +               vma_m = find_vma(mm, address_m);
17559 +
17560 +               /* PaX: sanity checks */
17561 +               if (!vma_m) {
17562 +                       spin_unlock(&mm->page_table_lock);
17563 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
17564 +                              address, vma, address_m, vma_m);
17565 +                       return 0;
17566 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
17567 +                          vma_m->vm_start != address_m ||
17568 +                          vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
17569 +               {
17570 +                       spin_unlock(&mm->page_table_lock);
17571 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
17572 +                               address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
17573 +                       return 0;
17574 +               }
17575 +
17576 +               address_m = address + (unsigned long)vma->vm_private_data;
17577 +               pgd_m = pgd_offset(mm, address_m);
17578 +               pmd_m = pmd_alloc(mm, pgd_m, address_m);
17579 +               if (!pmd_m) {
17580 +                       spin_unlock(&mm->page_table_lock);
17581 +                       return -1;
17582 +               }
17583 +               pte_m = pte_alloc(mm, pmd_m, address_m);
17584 +               if (!pte_m) {
17585 +                       spin_unlock(&mm->page_table_lock);
17586 +                       return -1;
17587 +               }
17588 +       }                       
17589 +#endif
17590 +
17591         pmd = pmd_alloc(mm, pgd, address);
17592  
17593         if (pmd) {
17594 diff -urN linux-2.4.24.org/mm/mlock.c linux-2.4.24/mm/mlock.c
17595 --- linux-2.4.24.org/mm/mlock.c 2004-02-04 23:04:28.980051219 +0100
17596 +++ linux-2.4.24/mm/mlock.c     2004-02-04 23:11:36.664122691 +0100
17597 @@ -114,9 +114,40 @@
17598         return 0;
17599  }
17600  
17601 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17602 +static int __mlock_fixup(struct vm_area_struct * vma,
17603 +       unsigned long start, unsigned long end, unsigned int newflags);
17604  static int mlock_fixup(struct vm_area_struct * vma, 
17605         unsigned long start, unsigned long end, unsigned int newflags)
17606  {
17607 +       if (vma->vm_flags & VM_MIRROR) {
17608 +               struct vm_area_struct * vma_m;
17609 +               unsigned long start_m, end_m;
17610 +               int error;
17611 +
17612 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17613 +               vma_m = find_vma(vma->vm_mm, start_m);
17614 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
17615 +                       start_m = start + (unsigned long)vma->vm_private_data;
17616 +                       end_m = end + (unsigned long)vma->vm_private_data;
17617 +                       error = __mlock_fixup(vma_m, start_m, end_m, newflags);
17618 +                       if (error)
17619 +                               return error;
17620 +               } else {
17621 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
17622 +                       return -ENOMEM;
17623 +               }
17624 +       }
17625 +       return __mlock_fixup(vma, start, end, newflags);
17626 +}
17627 +
17628 +static int __mlock_fixup(struct vm_area_struct * vma,
17629 +       unsigned long start, unsigned long end, unsigned int newflags)
17630 +#else
17631 +static int mlock_fixup(struct vm_area_struct * vma,
17632 +       unsigned long start, unsigned long end, unsigned int newflags)
17633 +#endif
17634 +{
17635         int pages, retval;
17636  
17637         if (newflags == vma->vm_flags)
17638 @@ -159,6 +190,17 @@
17639                 return -EINVAL;
17640         if (end == start)
17641                 return 0;
17642 +
17643 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17644 +       if (current->flags & PF_PAX_SEGMEXEC) {
17645 +               if (end > SEGMEXEC_TASK_SIZE)
17646 +                       return -EINVAL;
17647 +       } else
17648 +#endif
17649 +
17650 +       if (end > TASK_SIZE)
17651 +               return -EINVAL;
17652 +
17653         vma = find_vma(current->mm, start);
17654         if (!vma || vma->vm_start > start)
17655                 return -ENOMEM;
17656 @@ -209,6 +251,7 @@
17657         lock_limit >>= PAGE_SHIFT;
17658  
17659         /* check against resource limits */
17660 +       gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
17661         if (locked > lock_limit)
17662                 goto out;
17663  
17664 @@ -253,6 +296,16 @@
17665         for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
17666                 unsigned int newflags;
17667  
17668 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17669 +               if (current->flags & PF_PAX_SEGMEXEC) {
17670 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
17671 +                               break;
17672 +               } else
17673 +#endif
17674 +
17675 +               if (vma->vm_end > TASK_SIZE)
17676 +                       break;
17677 +
17678                 newflags = vma->vm_flags | VM_LOCKED;
17679                 if (!(flags & MCL_CURRENT))
17680                         newflags &= ~VM_LOCKED;
17681 @@ -276,6 +329,7 @@
17682         lock_limit >>= PAGE_SHIFT;
17683  
17684         ret = -ENOMEM;
17685 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
17686         if (current->mm->total_vm > lock_limit)
17687                 goto out;
17688  
17689 diff -urN linux-2.4.24.org/mm/mmap.c linux-2.4.24/mm/mmap.c
17690 --- linux-2.4.24.org/mm/mmap.c  2004-02-04 23:04:29.041038538 +0100
17691 +++ linux-2.4.24/mm/mmap.c      2004-02-04 23:11:36.702114792 +0100
17692 @@ -169,6 +169,7 @@
17693  
17694         /* Check against rlimit.. */
17695         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
17696 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
17697         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
17698                 goto out;
17699  
17700 @@ -206,6 +207,11 @@
17701                 _trans(prot, PROT_WRITE, VM_WRITE) |
17702                 _trans(prot, PROT_EXEC, VM_EXEC);
17703         flag_bits =
17704 +
17705 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17706 +               _trans(flags, MAP_MIRROR, VM_MIRROR) |
17707 +#endif
17708 +
17709                 _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
17710                 _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
17711                 _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
17712 @@ -401,6 +407,9 @@
17713         int correct_wcount = 0;
17714         int error;
17715         rb_node_t ** rb_link, * rb_parent;
17716 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17717 +       struct vm_area_struct * vma_m = NULL;
17718 +#endif
17719  
17720         if (file) {
17721                 if (!file->f_op || !file->f_op->mmap)
17722 @@ -410,6 +419,26 @@
17723                         return -EPERM;
17724         }
17725  
17726 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17727 +       if (flags & MAP_MIRROR) {
17728 +               /* PaX: sanity checks, to be removed when proved to be stable */
17729 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
17730 +                       return -EINVAL;
17731 +
17732 +               vma_m = find_vma(mm, pgoff);
17733 +
17734 +               if (!vma_m ||
17735 +                   vma_m->vm_start != pgoff ||
17736 +                   (vma_m->vm_flags & VM_MIRROR) ||
17737 +                   (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
17738 +                       return -EINVAL;
17739 +
17740 +               file = vma_m->vm_file;
17741 +               pgoff = vma_m->vm_pgoff;
17742 +               len = vma_m->vm_end - vma_m->vm_start;
17743 +       }
17744 + #endif
17745 +
17746         if (!len)
17747                 return addr;
17748  
17749 @@ -439,10 +468,32 @@
17750          */
17751         vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
17752  
17753 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
17754 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
17755 +
17756 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17757 +               if (current->flags & PF_PAX_MPROTECT) {
17758 +                       if (!file || (prot & PROT_WRITE))
17759 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
17760 +                       else
17761 +                               vm_flags &= ~VM_MAYWRITE;
17762 +
17763 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
17764 +                       if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
17765 +                               vma_m->vm_flags &= ~VM_MAYWRITE;
17766 +#endif
17767 +
17768 +               }
17769 +#endif
17770 +
17771 +       }
17772 +#endif
17773 +
17774         /* mlock MCL_FUTURE? */
17775         if (vm_flags & VM_LOCKED) {
17776                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
17777                 locked += len;
17778 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
17779                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
17780                         return -EAGAIN;
17781         }
17782 @@ -487,6 +538,9 @@
17783                 }
17784         }
17785  
17786 +       if (!gr_acl_handle_mmap(file, prot))
17787 +               return -EACCES;
17788 +
17789         /* Clear old maps */
17790  munmap_back:
17791         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
17792 @@ -497,10 +551,16 @@
17793         }
17794  
17795         /* Check against address space limit. */
17796 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17797 +       if (!(vm_flags & VM_MIRROR)) {
17798 +#endif
17799 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
17800         if ((mm->total_vm << PAGE_SHIFT) + len
17801             > current->rlim[RLIMIT_AS].rlim_cur)
17802                 return -ENOMEM;
17803 -
17804 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17805 +       }
17806 +#endif
17807         /* Private writable mapping? Check memory availability.. */
17808         if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
17809             !(flags & MAP_NORESERVE)                             &&
17810 @@ -524,6 +584,13 @@
17811         vma->vm_start = addr;
17812         vma->vm_end = addr + len;
17813         vma->vm_flags = vm_flags;
17814 +
17815 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17816 +       if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
17817 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
17818 +       else
17819 +#endif
17820 +
17821         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
17822         vma->vm_ops = NULL;
17823         vma->vm_pgoff = pgoff;
17824 @@ -552,6 +619,14 @@
17825                         goto free_vma;
17826         }
17827  
17828 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17829 +       if (flags & MAP_MIRROR) {
17830 +               vma_m->vm_flags |= VM_MIRROR;
17831 +               vma_m->vm_private_data = (void *)(vma->vm_start - vma_m->vm_start);
17832 +               vma->vm_private_data = (void *)(vma_m->vm_start - vma->vm_start);
17833 +       }
17834 +#endif
17835 +
17836         /* Can addr have changed??
17837          *
17838          * Answer: Yes, several device drivers can do it in their
17839 @@ -587,6 +662,9 @@
17840                 atomic_inc(&file->f_dentry->d_inode->i_writecount);
17841  
17842  out:   
17843 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17844 +       if (!(flags & MAP_MIRROR))
17845 +#endif
17846         mm->total_vm += len >> PAGE_SHIFT;
17847         if (vm_flags & VM_LOCKED) {
17848                 mm->locked_vm += len >> PAGE_SHIFT;
17849 @@ -623,20 +701,49 @@
17850  {
17851         struct vm_area_struct *vma;
17852  
17853 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17854 +       if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE)
17855 +               return -ENOMEM;
17856 +       else
17857 +#endif
17858 +
17859         if (len > TASK_SIZE)
17860                 return -ENOMEM;
17861  
17862 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
17863 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
17864 +#endif
17865 +
17866         if (addr) {
17867                 addr = PAGE_ALIGN(addr);
17868                 vma = find_vma(current->mm, addr);
17869 +
17870 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17871 +               if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)                
17872 +                       return -ENOMEM;
17873 +#endif
17874 +
17875                 if (TASK_SIZE - len >= addr &&
17876                     (!vma || addr + len <= vma->vm_start))
17877                         return addr;
17878         }
17879         addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
17880  
17881 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
17882 +       /* PaX: randomize base address if requested */
17883 +       if (current->flags & PF_PAX_RANDMMAP)
17884 +               addr += current->mm->delta_mmap;
17885 +#endif
17886 +
17887         for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
17888                 /* At this point:  (!vma || addr < vma->vm_end). */
17889 +
17890 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17891 +               if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)
17892 +                       return -ENOMEM;
17893 +               else
17894 +#endif
17895 +
17896                 if (TASK_SIZE - len < addr)
17897                         return -ENOMEM;
17898                 if (!vma || addr + len <= vma->vm_start)
17899 @@ -798,6 +905,9 @@
17900         struct vm_area_struct *mpnt;
17901         unsigned long end = addr + len;
17902  
17903 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17904 +       if (!(area->vm_flags & VM_MIRROR))
17905 +#endif
17906         area->vm_mm->total_vm -= len >> PAGE_SHIFT;
17907         if (area->vm_flags & VM_LOCKED)
17908                 area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
17909 @@ -923,6 +1033,83 @@
17910         }
17911  }
17912  
17913 +static inline struct vm_area_struct *unmap_vma(struct mm_struct *mm,
17914 +       unsigned long addr, size_t len, struct vm_area_struct *mpnt,
17915 +       struct vm_area_struct *extra)
17916 +{
17917 +       unsigned long st, end, size;
17918 +       struct file *file = NULL;
17919 +
17920 +       st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
17921 +       end = addr+len;
17922 +       end = end > mpnt->vm_end ? mpnt->vm_end : end;
17923 +       size = end - st;
17924 +
17925 +       if (mpnt->vm_flags & VM_DENYWRITE &&
17926 +           (st != mpnt->vm_start || end != mpnt->vm_end) &&
17927 +           (file = mpnt->vm_file) != NULL) {
17928 +               atomic_dec(&file->f_dentry->d_inode->i_writecount);
17929 +       }
17930 +       remove_shared_vm_struct(mpnt);
17931 +       zap_page_range(mm, st, size);
17932 +
17933 +       /*
17934 +        * Fix the mapping, and free the old area if it wasn't reused.
17935 +        */
17936 +       extra = unmap_fixup(mm, mpnt, st, size, extra);
17937 +       if (file)
17938 +               atomic_inc(&file->f_dentry->d_inode->i_writecount);
17939 +       return extra;
17940 +}
17941 +       
17942 +static struct vm_area_struct *unmap_vma_list(struct mm_struct *mm,
17943 +       unsigned long addr, size_t len, struct vm_area_struct *free,
17944 +       struct vm_area_struct *extra, struct vm_area_struct *prev)
17945 +{
17946 +       struct vm_area_struct *mpnt;
17947 +
17948 +       /* Ok - we have the memory areas we should free on the 'free' list,
17949 +        * so release them, and unmap the page range..
17950 +        * If the one of the segments is only being partially unmapped,
17951 +        * it will put new vm_area_struct(s) into the address space.
17952 +        * In that case we have to be careful with VM_DENYWRITE.
17953 +        */
17954 +       while ((mpnt = free) != NULL) {
17955 +               free = free->vm_next;
17956 +               extra = unmap_vma(mm, addr, len, mpnt, extra);
17957 +       }
17958 +
17959 +       free_pgtables(mm, prev, addr, addr+len);
17960 +
17961 +       return extra;
17962 +}
17963 +
17964 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17965 +static struct vm_area_struct *unmap_vma_mirror_list(struct mm_struct *mm,
17966 +       unsigned long addr, size_t len, struct vm_area_struct *free_m,
17967 +       struct vm_area_struct *extra_m)
17968 +{
17969 +       struct vm_area_struct *mpnt, *prev;
17970 +
17971 +       while ((mpnt = free_m) != NULL) {
17972 +               unsigned long addr_m, start, end;
17973 +
17974 +               free_m = free_m->vm_next;
17975 +
17976 +               addr_m = addr - (unsigned long)mpnt->vm_private_data;
17977 +               start = addr_m < mpnt->vm_start ? mpnt->vm_start : addr_m;
17978 +               end = addr_m+len;
17979 +               end = end > mpnt->vm_end ? mpnt->vm_end : end;
17980 +               find_vma_prev(mm, mpnt->vm_start, &prev);
17981 +               extra_m = unmap_vma(mm, addr_m, len, mpnt, extra_m);
17982 +
17983 +               free_pgtables(mm, prev, start, end);
17984 +       }               
17985 +
17986 +       return extra_m;
17987 +}
17988 +#endif
17989 +
17990  /* Munmap is split into 2 main parts -- this part which finds
17991   * what needs doing, and the areas themselves, which do the
17992   * work.  This now handles partial unmappings.
17993 @@ -932,6 +1119,10 @@
17994  {
17995         struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
17996  
17997 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17998 +       struct vm_area_struct *free_m, *extra_m;
17999 +#endif
18000 +
18001         if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr)
18002                 return -EINVAL;
18003  
18004 @@ -964,60 +1155,69 @@
18005         if (!extra)
18006                 return -ENOMEM;
18007  
18008 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18009 +       if (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) { 
18010 +               extra_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
18011 +               if (!extra_m) {
18012 +                       kmem_cache_free(vm_area_cachep, extra);
18013 +                       return -ENOMEM;
18014 +               }
18015 +       } else
18016 +               extra_m = NULL;
18017 +
18018 +       free_m = NULL;
18019 +#endif
18020 +
18021         npp = (prev ? &prev->vm_next : &mm->mmap);
18022         free = NULL;
18023         spin_lock(&mm->page_table_lock);
18024         for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) {
18025 +               mm->map_count--;
18026                 *npp = mpnt->vm_next;
18027                 mpnt->vm_next = free;
18028                 free = mpnt;
18029                 rb_erase(&mpnt->vm_rb, &mm->mm_rb);
18030 +
18031 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18032 +               if (free->vm_flags & VM_MIRROR) {
18033 +                       struct vm_area_struct *mpnt_m, *prev_m, **npp_m;
18034 +                       unsigned long addr_m = free->vm_start + (unsigned long)free->vm_private_data;
18035 +
18036 +                       mm->mmap_cache = NULL;  /* Kill the cache. */
18037 +                       mpnt_m = find_vma_prev(mm, addr_m, &prev_m);
18038 +                       if (mpnt_m && mpnt_m->vm_start == addr_m && (mpnt_m->vm_flags & VM_MIRROR)) {
18039 +                               mm->map_count--;
18040 +                               npp_m = (prev_m ? &prev_m->vm_next : &mm->mmap);
18041 +                               *npp_m = mpnt_m->vm_next;
18042 +                               mpnt_m->vm_next = free_m;
18043 +                               free_m = mpnt_m;
18044 +                               rb_erase(&mpnt_m->vm_rb, &mm->mm_rb);
18045 +                       } else
18046 +                               printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, free->vm_start);
18047 +               }
18048 +#endif
18049 +
18050         }
18051         mm->mmap_cache = NULL;  /* Kill the cache. */
18052         spin_unlock(&mm->page_table_lock);
18053  
18054 -       /* Ok - we have the memory areas we should free on the 'free' list,
18055 -        * so release them, and unmap the page range..
18056 -        * If the one of the segments is only being partially unmapped,
18057 -        * it will put new vm_area_struct(s) into the address space.
18058 -        * In that case we have to be careful with VM_DENYWRITE.
18059 -        */
18060 -       while ((mpnt = free) != NULL) {
18061 -               unsigned long st, end, size;
18062 -               struct file *file = NULL;
18063 -
18064 -               free = free->vm_next;
18065 -
18066 -               st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
18067 -               end = addr+len;
18068 -               end = end > mpnt->vm_end ? mpnt->vm_end : end;
18069 -               size = end - st;
18070 -
18071 -               if (mpnt->vm_flags & VM_DENYWRITE &&
18072 -                   (st != mpnt->vm_start || end != mpnt->vm_end) &&
18073 -                   (file = mpnt->vm_file) != NULL) {
18074 -                       atomic_dec(&file->f_dentry->d_inode->i_writecount);
18075 -               }
18076 -               remove_shared_vm_struct(mpnt);
18077 -               mm->map_count--;
18078 +       extra = unmap_vma_list(mm, addr, len, free, extra, prev);
18079  
18080 -               zap_page_range(mm, st, size);
18081 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18082 +       extra_m = unmap_vma_mirror_list(mm, addr, len, free_m, extra_m);
18083 +#endif
18084  
18085 -               /*
18086 -                * Fix the mapping, and free the old area if it wasn't reused.
18087 -                */
18088 -               extra = unmap_fixup(mm, mpnt, st, size, extra);
18089 -               if (file)
18090 -                       atomic_inc(&file->f_dentry->d_inode->i_writecount);
18091 -       }
18092         validate_mm(mm);
18093  
18094 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18095 +       if (extra_m)
18096 +               kmem_cache_free(vm_area_cachep, extra_m);
18097 +#endif
18098 +
18099         /* Release the extra vma struct if it wasn't used */
18100         if (extra)
18101                 kmem_cache_free(vm_area_cachep, extra);
18102  
18103 -       free_pgtables(mm, prev, addr, addr+len);
18104 -
18105         return 0;
18106  }
18107  
18108 @@ -1026,8 +1226,15 @@
18109         int ret;
18110         struct mm_struct *mm = current->mm;
18111  
18112 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
18113 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
18114 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
18115 +               return -EINVAL;
18116 +#endif
18117 +
18118         down_write(&mm->mmap_sem);
18119         ret = do_munmap(mm, addr, len);
18120 +
18121         up_write(&mm->mmap_sem);
18122         return ret;
18123  }
18124 @@ -1057,6 +1264,7 @@
18125         if (mm->def_flags & VM_LOCKED) {
18126                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
18127                 locked += len;
18128 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
18129                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
18130                         return -EAGAIN;
18131         }
18132 @@ -1073,6 +1281,7 @@
18133         }
18134  
18135         /* Check against address space limits *after* clearing old maps... */
18136 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
18137         if ((mm->total_vm << PAGE_SHIFT) + len
18138             > current->rlim[RLIMIT_AS].rlim_cur)
18139                 return -ENOMEM;
18140 @@ -1085,6 +1294,17 @@
18141  
18142         flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
18143  
18144 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
18145 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
18146 +               flags &= ~VM_EXEC;
18147 +
18148 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18149 +               if (current->flags & PF_PAX_MPROTECT)
18150 +                       flags &= ~VM_MAYEXEC;
18151 +#endif
18152 +
18153 +       }
18154 +#endif
18155         /* Can we just expand an old anonymous mapping? */
18156         if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
18157                 goto out;
18158 @@ -1100,6 +1320,12 @@
18159         vma->vm_start = addr;
18160         vma->vm_end = addr + len;
18161         vma->vm_flags = flags;
18162 +
18163 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
18164 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
18165 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
18166 +       else
18167 +#endif
18168         vma->vm_page_prot = protection_map[flags & 0x0f];
18169         vma->vm_ops = NULL;
18170         vma->vm_pgoff = 0;
18171 Pliki linux-2.4.24.org/mm/.mmap.c.swp i linux-2.4.24/mm/.mmap.c.swp ró¿ni± siê
18172 diff -urN linux-2.4.24.org/mm/mprotect.c linux-2.4.24/mm/mprotect.c
18173 --- linux-2.4.24.org/mm/mprotect.c      2004-02-04 23:04:28.395172836 +0100
18174 +++ linux-2.4.24/mm/mprotect.c  2004-02-04 23:11:36.709113337 +0100
18175 @@ -7,6 +7,12 @@
18176  #include <linux/smp_lock.h>
18177  #include <linux/shm.h>
18178  #include <linux/mman.h>
18179 +#include <linux/grsecurity.h>
18180 +
18181 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18182 +#include <linux/elf.h>
18183 +#include <linux/fs.h>
18184 +#endif
18185  
18186  #include <asm/uaccess.h>
18187  #include <asm/pgalloc.h>
18188 @@ -236,9 +242,45 @@
18189         return 0;
18190  }
18191  
18192 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18193 +static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18194 +       unsigned long start, unsigned long end, unsigned int newflags);
18195 +
18196  static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18197         unsigned long start, unsigned long end, unsigned int newflags)
18198  {
18199 +       if (vma->vm_flags & VM_MIRROR) {
18200 +               struct vm_area_struct * vma_m, * prev_m;
18201 +               unsigned long start_m, end_m;
18202 +               int error;
18203 +
18204 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
18205 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
18206 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
18207 +                       start_m = start + (unsigned long)vma->vm_private_data;
18208 +                       end_m = end + (unsigned long)vma->vm_private_data;
18209 +                       if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
18210 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
18211 +                       else
18212 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
18213 +                       if (error)
18214 +                               return error;
18215 +               } else {
18216 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
18217 +                       return -ENOMEM;
18218 +               }
18219 +       }
18220 +
18221 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
18222 +}
18223 +
18224 +static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18225 +       unsigned long start, unsigned long end, unsigned int newflags)
18226 +#else
18227 +static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18228 +       unsigned long start, unsigned long end, unsigned int newflags)
18229 +#endif
18230 +{
18231         pgprot_t newprot;
18232         int error;
18233  
18234 @@ -246,6 +288,12 @@
18235                 *pprev = vma;
18236                 return 0;
18237         }
18238 +
18239 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
18240 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
18241 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
18242 +       else
18243 +#endif
18244         newprot = protection_map[newflags & 0xf];
18245         if (start == vma->vm_start) {
18246                 if (end == vma->vm_end)
18247 @@ -277,6 +325,14 @@
18248         end = start + len;
18249         if (end < start)
18250                 return -ENOMEM;
18251 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
18252 +       if (current->flags & PF_PAX_SEGMEXEC) {
18253 +               if (end > SEGMEXEC_TASK_SIZE)
18254 +                       return -EINVAL;
18255 +       } else
18256 +#endif
18257 +       if (end > TASK_SIZE)
18258 +               return -EINVAL;
18259         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
18260                 return -EINVAL;
18261         if (end == start)
18262 @@ -288,7 +344,15 @@
18263         error = -ENOMEM;
18264         if (!vma || vma->vm_start > start)
18265                 goto out;
18266 -
18267 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
18268 +               error = -EACCES;
18269 +               goto out;
18270 +       }
18271 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18272 +       if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
18273 +               pax_handle_maywrite(vma, start);
18274 +#endif
18275 +       
18276         for (nstart = start ; ; ) {
18277                 unsigned int newflags;
18278                 int last = 0;
18279 @@ -301,6 +365,12 @@
18280                         goto out;
18281                 }
18282  
18283 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18284 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
18285 +               if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
18286 +                       newflags &= ~VM_MAYWRITE;
18287 +#endif
18288 +    
18289                 if (vma->vm_end > end) {
18290                         error = mprotect_fixup(vma, &prev, nstart, end, newflags);
18291                         goto out;
18292 @@ -337,6 +407,68 @@
18293         return error;
18294  }
18295  
18296 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18297 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
18298 + * therefore we'll grant them VM_MAYWRITE once during their life.
18299 + *
18300 + * The checks favor ld-linux.so behaviour which operates on a per ELF segment
18301 + * basis because we want to allow the common case and not the special ones.
18302 + */
18303 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
18304 +{
18305 +       struct elfhdr elf_h;
18306 +       struct elf_phdr elf_p, p_dyn;
18307 +       elf_dyn dyn;
18308 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
18309 +
18310 +#ifndef CONFIG_GRKERNSEC_PAX_NOELFRELOCS
18311 +       if ((vma->vm_start != start) ||
18312 +           !vma->vm_file ||
18313 +           !(vma->vm_flags & VM_MAYEXEC) ||
18314 +           (vma->vm_flags & VM_MAYNOTWRITE))
18315 +#endif
18316 +
18317 +               return;
18318 +
18319 +       if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
18320 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
18321 +
18322 +#ifdef CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
18323 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
18324 +#else
18325 +           elf_h.e_type != ET_DYN ||
18326 +#endif
18327 +
18328 +           !elf_check_arch(&elf_h) ||
18329 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
18330 +           elf_h.e_phnum > j)
18331 +               return;
18332 +
18333 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
18334 +               if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
18335 +                       return;
18336 +               if (elf_p.p_type == PT_DYNAMIC) {
18337 +                       p_dyn = elf_p;
18338 +                       j = i;
18339 +               }
18340 +       }
18341 +       if (elf_h.e_phnum <= j)
18342 +               return;
18343 +
18344 +       i = 0UL;
18345 +       do {
18346 +               if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
18347 +                       return;
18348 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
18349 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
18350 +                       return;
18351 +               }
18352 +               i++;
18353 +       } while (dyn.d_tag != DT_NULL);
18354 +       return;
18355 +}
18356 +#endif
18357 +
18358  asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
18359  {
18360          return(do_mprotect(current->mm, start, len, prot));
18361 diff -urN linux-2.4.24.org/mm/mremap.c linux-2.4.24/mm/mremap.c
18362 --- linux-2.4.24.org/mm/mremap.c        2004-02-04 23:04:28.015251834 +0100
18363 +++ linux-2.4.24/mm/mremap.c    2004-02-04 23:11:36.743106269 +0100
18364 @@ -193,7 +193,9 @@
18365                 }
18366  
18367                 do_munmap(current->mm, addr, old_len);
18368 -
18369 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18370 +               if (!(new_vma->vm_flags & VM_MIRROR))
18371 +#endif
18372                 current->mm->total_vm += new_len >> PAGE_SHIFT;
18373                 if (vm_locked) {
18374                         current->mm->locked_vm += new_len >> PAGE_SHIFT;
18375 @@ -232,6 +234,18 @@
18376         old_len = PAGE_ALIGN(old_len);
18377         new_len = PAGE_ALIGN(new_len);
18378  
18379 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
18380 +       if (current->flags & PF_PAX_SEGMEXEC) {
18381 +               if (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
18382 +                   old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)
18383 +                       goto out;
18384 +       } else
18385 +#endif
18386 +
18387 +       if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
18388 +           old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
18389 +               goto out;
18390 +
18391         /* new_addr is only valid if MREMAP_FIXED is specified */
18392         if (flags & MREMAP_FIXED) {
18393                 if (new_addr & ~PAGE_MASK)
18394 @@ -249,6 +263,16 @@
18395                 if (unlikely(!new_len && new_addr != addr))
18396                         goto out;
18397  
18398 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
18399 +               if (current->flags & PF_PAX_SEGMEXEC) {
18400 +                       if (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)
18401 +                       goto out;
18402 +               } else
18403 +#endif
18404 +
18405 +               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
18406 +                       goto out;
18407 +
18408                 /* Check if the location we're moving into overlaps the
18409                  * old location at all, and fail if it does.
18410                  */
18411 @@ -279,6 +303,16 @@
18412         vma = find_vma(current->mm, addr);
18413         if (!vma || vma->vm_start > addr)
18414                 goto out;
18415 +
18416 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18417 +       if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
18418 +           (vma->vm_flags & VM_MIRROR))
18419 +       {
18420 +               ret = -EINVAL;
18421 +               goto out;
18422 +       }
18423 +#endif
18424 +
18425         /* We can't remap across vm area boundaries */
18426         if (old_len > vma->vm_end - addr)
18427                 goto out;
18428 @@ -290,13 +324,22 @@
18429                 unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
18430                 locked += new_len - old_len;
18431                 ret = -EAGAIN;
18432 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
18433                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
18434                         goto out;
18435         }
18436         ret = -ENOMEM;
18437 +
18438 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18439 +       if (!(vma->vm_flags & VM_MIRROR)) {
18440 +#endif   
18441 +       gr_learn_resource(current, RLIMIT_AS, (current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len), 1);
18442         if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
18443             > current->rlim[RLIMIT_AS].rlim_cur)
18444                 goto out;
18445 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18446 +       }
18447 +#endif
18448         /* Private writable mapping? Check memory availability.. */
18449         if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
18450             !(flags & MAP_NORESERVE)                             &&
18451 @@ -318,6 +361,9 @@
18452                         spin_lock(&vma->vm_mm->page_table_lock);
18453                         vma->vm_end = addr + new_len;
18454                         spin_unlock(&vma->vm_mm->page_table_lock);
18455 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18456 +                       if (!(vma->vm_flags & VM_MIRROR))
18457 +#endif   
18458                         current->mm->total_vm += pages;
18459                         if (vma->vm_flags & VM_LOCKED) {
18460                                 current->mm->locked_vm += pages;
18461 diff -urN linux-2.4.24.org/net/ipv4/af_inet.c linux-2.4.24/net/ipv4/af_inet.c
18462 --- linux-2.4.24.org/net/ipv4/af_inet.c 2004-02-04 23:06:06.292816563 +0100
18463 +++ linux-2.4.24/net/ipv4/af_inet.c     2004-02-04 23:11:36.775099617 +0100
18464 @@ -83,6 +83,7 @@
18465  #include <linux/init.h>
18466  #include <linux/poll.h>
18467  #include <linux/netfilter_ipv4.h>
18468 +#include <linux/grsecurity.h>
18469  
18470  #include <asm/uaccess.h>
18471  #include <asm/system.h>
18472 @@ -374,7 +375,12 @@
18473         else
18474                 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
18475  
18476 -       sk->protinfo.af_inet.id = 0;
18477 +#ifdef CONFIG_GRKERNSEC_RANDID
18478 +       if(grsec_enable_randid)
18479 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18480 +       else
18481 +#endif
18482 +               sk->protinfo.af_inet.id = 0;
18483  
18484         sock_init_data(sock,sk);
18485  
18486 diff -urN linux-2.4.24.org/net/ipv4/ip_output.c linux-2.4.24/net/ipv4/ip_output.c
18487 --- linux-2.4.24.org/net/ipv4/ip_output.c       2004-02-04 23:06:06.386797021 +0100
18488 +++ linux-2.4.24/net/ipv4/ip_output.c   2004-02-04 23:11:36.803093797 +0100
18489 @@ -77,6 +77,7 @@
18490  #include <linux/netfilter_ipv4.h>
18491  #include <linux/mroute.h>
18492  #include <linux/netlink.h>
18493 +#include <linux/grsecurity.h>
18494  
18495  /*
18496   *      Shall we try to damage output packets if routing dev changes?
18497 @@ -514,7 +515,13 @@
18498          *      Begin outputting the bytes.
18499          */
18500  
18501 -       id = sk->protinfo.af_inet.id++;
18502 +#ifdef CONFIG_GRKERNSEC_RANDID
18503 +       if(grsec_enable_randid) { 
18504 +               id = htons(ip_randomid());      
18505 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18506 +       } else
18507 +#endif
18508 +               id = sk->protinfo.af_inet.id++;
18509  
18510         do {
18511                 char *data;
18512 diff -urN linux-2.4.24.org/net/ipv4/netfilter/Config.in linux-2.4.24/net/ipv4/netfilter/Config.in
18513 --- linux-2.4.24.org/net/ipv4/netfilter/Config.in       2004-02-04 23:06:06.236828204 +0100
18514 +++ linux-2.4.24/net/ipv4/netfilter/Config.in   2004-02-04 23:11:36.834087353 +0100
18515 @@ -73,6 +73,7 @@
18516    dep_tristate '  address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES
18517    dep_tristate '  tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES
18518    dep_tristate '  realm match support' CONFIG_IP_NF_MATCH_REALM $CONFIG_IP_NF_IPTABLES
18519 +  dep_tristate '  stealth match support' CONFIG_IP_NF_MATCH_STEALTH $CONFIG_IP_NF_IPTABLES
18520    if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
18521      dep_tristate '  Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES
18522    fi
18523 diff -urN linux-2.4.24.org/net/ipv4/netfilter/ipt_stealth.c linux-2.4.24/net/ipv4/netfilter/ipt_stealth.c
18524 --- linux-2.4.24.org/net/ipv4/netfilter/ipt_stealth.c   1970-01-01 01:00:00.000000000 +0100
18525 +++ linux-2.4.24/net/ipv4/netfilter/ipt_stealth.c       2004-02-04 23:11:36.838086522 +0100
18526 @@ -0,0 +1,109 @@
18527 +/* Kernel module to add stealth support.
18528 + *
18529 + * Copyright (C) 2002 Brad Spengler  <spender@grsecurity.net>
18530 + *
18531 + */
18532 +
18533 +#include <linux/kernel.h>
18534 +#include <linux/module.h>
18535 +#include <linux/skbuff.h>
18536 +#include <linux/net.h>
18537 +#include <linux/sched.h>
18538 +#include <linux/inet.h>
18539 +#include <linux/stddef.h>
18540 +
18541 +#include <net/ip.h>
18542 +#include <net/sock.h>
18543 +#include <net/tcp.h>
18544 +#include <net/udp.h>
18545 +#include <net/route.h>
18546 +#include <net/inet_common.h>
18547 +
18548 +#include <linux/netfilter_ipv4/ip_tables.h>
18549 +
18550 +MODULE_LICENSE("GPL");
18551 +
18552 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
18553 +
18554 +static int
18555 +match(const struct sk_buff *skb,
18556 +      const struct net_device *in,
18557 +      const struct net_device *out,
18558 +      const void *matchinfo,
18559 +      int offset,
18560 +      const void *hdr,
18561 +      u_int16_t datalen,
18562 +      int *hotdrop)
18563 +{
18564 +       struct iphdr *ip = skb->nh.iph;
18565 +       struct tcphdr *th = (struct tcphdr *) hdr;
18566 +       struct udphdr *uh = (struct udphdr *) hdr;
18567 +       struct sock *sk = NULL;
18568 +
18569 +       if (!ip || !hdr || offset) return 0;
18570 +
18571 +       switch(ip->protocol) {
18572 +       case IPPROTO_TCP:
18573 +               if (datalen < sizeof(struct tcphdr)) {
18574 +                       *hotdrop = 1;
18575 +                       return 0;
18576 +               }
18577 +               if (!(th->syn && !th->ack)) return 0;
18578 +               sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th->dest), ((struct rtable*)skb->dst)->rt_iif);    
18579 +               break;
18580 +       case IPPROTO_UDP:
18581 +               if (datalen < sizeof(struct udphdr)) {
18582 +                       *hotdrop = 1;
18583 +                       return 0;
18584 +               }
18585 +               sk = udp_v4_lookup(ip->saddr, uh->source, ip->daddr, uh->dest, skb->dev->ifindex);
18586 +               break;
18587 +       default:
18588 +               return 0;
18589 +       }
18590 +
18591 +       if(!sk) // port is being listened on, match this
18592 +               return 1;
18593 +       else {
18594 +               sock_put(sk);
18595 +               return 0;
18596 +       }
18597 +}
18598 +
18599 +/* Called when user tries to insert an entry of this type. */
18600 +static int
18601 +checkentry(const char *tablename,
18602 +           const struct ipt_ip *ip,
18603 +           void *matchinfo,
18604 +           unsigned int matchsize,
18605 +           unsigned int hook_mask)
18606 +{
18607 +        if (matchsize != IPT_ALIGN(0))
18608 +                return 0;
18609 +
18610 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
18611 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
18612 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
18613 +                       return 1;
18614 +
18615 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
18616 +
18617 +        return 0;
18618 +}
18619 +
18620 +
18621 +static struct ipt_match stealth_match
18622 += { { NULL, NULL }, "stealth", &match, &checkentry, NULL, THIS_MODULE };
18623 +
18624 +static int __init init(void)
18625 +{
18626 +       return ipt_register_match(&stealth_match);
18627 +}
18628 +
18629 +static void __exit fini(void)
18630 +{
18631 +       ipt_unregister_match(&stealth_match);
18632 +}
18633 +
18634 +module_init(init);
18635 +module_exit(fini);
18636 diff -urN linux-2.4.24.org/net/ipv4/netfilter/Makefile linux-2.4.24/net/ipv4/netfilter/Makefile
18637 --- linux-2.4.24.org/net/ipv4/netfilter/Makefile        2004-02-04 23:06:06.180839846 +0100
18638 +++ linux-2.4.24/net/ipv4/netfilter/Makefile    2004-02-04 23:11:36.861081741 +0100
18639 @@ -173,6 +173,7 @@
18640  obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
18641  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
18642  obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
18643 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
18644  
18645  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
18646  
18647 diff -urN linux-2.4.24.org/net/ipv4/tcp_ipv4.c linux-2.4.24/net/ipv4/tcp_ipv4.c
18648 --- linux-2.4.24.org/net/ipv4/tcp_ipv4.c        2004-02-04 23:06:01.500812983 +0100
18649 +++ linux-2.4.24/net/ipv4/tcp_ipv4.c    2004-02-04 23:11:36.995053886 +0100
18650 @@ -67,6 +67,7 @@
18651  #include <linux/inet.h>
18652  #include <linux/stddef.h>
18653  #include <linux/ipsec.h>
18654 +#include <linux/grsecurity.h>
18655  
18656  extern int sysctl_ip_dynaddr;
18657  extern int sysctl_ip_default_ttl;
18658 @@ -223,9 +224,18 @@
18659  
18660                 spin_lock(&tcp_portalloc_lock);
18661                 rover = tcp_port_rover;
18662 -               do {    rover++;
18663 -                       if ((rover < low) || (rover > high))
18664 -                               rover = low;
18665 +                do {
18666 +#ifdef CONFIG_GRKERNSEC_RANDSRC
18667 +                       if (grsec_enable_randsrc && (high > low)) {
18668 +                               rover = low + (get_random_long() % (high - low));
18669 +                       } else
18670 +#endif
18671 +                       {
18672 +                               rover++;
18673 +                               if ((rover < low) || (rover > high))
18674 +                                       rover = low;
18675 +                       }
18676 +
18677                         head = &tcp_bhash[tcp_bhashfn(rover)];
18678                         spin_lock(&head->lock);
18679                         for (tb = head->chain; tb; tb = tb->next)
18680 @@ -548,6 +558,11 @@
18681  
18682  static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
18683  {
18684 +#ifdef CONFIG_GRKERNSEC_RANDISN
18685 +       if (likely(grsec_enable_randisn))
18686 +               return ip_randomisn();
18687 +       else
18688 +#endif
18689         return secure_tcp_sequence_number(skb->nh.iph->daddr,
18690                                           skb->nh.iph->saddr,
18691                                           skb->h.th->dest,
18692 @@ -683,9 +698,16 @@
18693                 rover = tcp_port_rover;
18694  
18695                 do {
18696 -                       rover++;
18697 -                       if ((rover < low) || (rover > high))
18698 -                               rover = low;
18699 +#ifdef CONFIG_GRKERNSEC_RANDSRC
18700 +                       if(grsec_enable_randsrc && (high > low)) {
18701 +                               rover = low + (get_random_long() % (high - low));
18702 +                       } else
18703 +#endif
18704 +                       {
18705 +                               rover++;
18706 +                               if ((rover < low) || (rover > high))
18707 +                                       rover = low;
18708 +                       }
18709                         head = &tcp_bhash[tcp_bhashfn(rover)];
18710                         spin_lock(&head->lock);         
18711  
18712 @@ -734,6 +756,15 @@
18713                 }
18714                 spin_unlock(&head->lock);
18715  
18716 +#ifdef CONFIG_GRKERNSEC
18717 +               gr_del_task_from_ip_table(current);
18718 +               current->gr_saddr = sk->rcv_saddr;
18719 +               current->gr_daddr = sk->daddr;
18720 +               current->gr_sport = sk->sport;
18721 +               current->gr_dport = sk->dport;
18722 +               gr_add_to_task_ip_table(current);
18723 +#endif
18724 +
18725                 if (tw) {
18726                         tcp_tw_deschedule(tw);
18727                         tcp_timewait_kill(tw);
18728 @@ -846,11 +877,22 @@
18729         if (err)
18730                 goto failure;
18731  
18732 -       if (!tp->write_seq)
18733 +       if (!tp->write_seq) {
18734 +#ifdef CONFIG_GRKERNSEC_RANDISN
18735 +               if (likely(grsec_enable_randisn))
18736 +                       tp->write_seq = ip_randomisn();
18737 +               else
18738 +#endif
18739                 tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
18740                                                            sk->sport, usin->sin_port);
18741 +       }
18742  
18743 -       sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18744 +#ifdef CONFIG_GRKERNSEC_RANDID
18745 +       if(grsec_enable_randid)
18746 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18747 +       else
18748 +#endif
18749 +               sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18750  
18751         err = tcp_connect(sk);
18752         if (err)
18753 @@ -1572,7 +1614,13 @@
18754         newtp->ext_header_len = 0;
18755         if (newsk->protinfo.af_inet.opt)
18756                 newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen;
18757 -       newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18758 +
18759 +#ifdef CONFIG_GRKERNSEC_RANDID
18760 +       if(grsec_enable_randid)
18761 +               newsk->protinfo.af_inet.id = htons(ip_randomid());
18762 +       else
18763 +#endif
18764 +               newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18765  
18766         tcp_sync_mss(newsk, dst->pmtu);
18767         newtp->advmss = dst->advmss;
18768 diff -urN linux-2.4.24.org/net/ipv4/udp.c linux-2.4.24/net/ipv4/udp.c
18769 --- linux-2.4.24.org/net/ipv4/udp.c     2004-02-04 23:06:01.473818597 +0100
18770 +++ linux-2.4.24/net/ipv4/udp.c 2004-02-04 23:11:37.247001503 +0100
18771 @@ -91,6 +91,7 @@
18772  #include <net/ipv6.h>
18773  #include <net/protocol.h>
18774  #include <linux/skbuff.h>
18775 +#include <linux/grsecurity.h>
18776  #include <net/sock.h>
18777  #include <net/udp.h>
18778  #include <net/icmp.h>
18779 @@ -98,6 +99,11 @@
18780  #include <net/inet_common.h>
18781  #include <net/checksum.h>
18782  
18783 +extern int gr_search_udp_recvmsg(const struct sock *sk,
18784 +                                       const struct sk_buff *skb);
18785 +extern int gr_search_udp_sendmsg(const struct sock *sk,
18786 +                                       const struct sockaddr_in *addr);
18787 +
18788  /*
18789   *     Snmp MIB for the UDP layer
18790   */
18791 @@ -480,9 +486,16 @@
18792                 ufh.uh.dest = usin->sin_port;
18793                 if (ufh.uh.dest == 0)
18794                         return -EINVAL;
18795 +
18796 +               if (!gr_search_udp_sendmsg(sk, usin))
18797 +                       return -EPERM;
18798         } else {
18799                 if (sk->state != TCP_ESTABLISHED)
18800                         return -EDESTADDRREQ;
18801 +
18802 +               if (!gr_search_udp_sendmsg(sk, NULL))
18803 +                       return -EPERM;
18804 +
18805                 ufh.daddr = sk->daddr;
18806                 ufh.uh.dest = sk->dport;
18807                 /* Open fast path for connected socket.
18808 @@ -490,6 +503,7 @@
18809                  */
18810                 connected = 1;
18811         }
18812 +
18813         ipc.addr = sk->saddr;
18814         ufh.uh.source = sk->sport;
18815  
18816 @@ -661,6 +675,11 @@
18817         if (!skb)
18818                 goto out;
18819    
18820 +       if (!gr_search_udp_recvmsg(sk, skb)) {
18821 +               err = -EPERM;
18822 +               goto out_free;
18823 +       }
18824 +
18825         copied = skb->len - sizeof(struct udphdr);
18826         if (copied > len) {
18827                 copied = len;
18828 @@ -765,7 +784,13 @@
18829         sk->daddr = rt->rt_dst;
18830         sk->dport = usin->sin_port;
18831         sk->state = TCP_ESTABLISHED;
18832 -       sk->protinfo.af_inet.id = jiffies;
18833 +
18834 +#ifdef CONFIG_GRKERNSEC_RANDID
18835 +       if(grsec_enable_randid)
18836 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18837 +       else
18838 +#endif
18839 +               sk->protinfo.af_inet.id = jiffies;
18840  
18841         sk_dst_set(sk, &rt->u.dst);
18842         return(0);
18843 diff -urN linux-2.4.24.org/net/netlink/af_netlink.c linux-2.4.24/net/netlink/af_netlink.c
18844 --- linux-2.4.24.org/net/netlink/af_netlink.c   2004-02-04 23:06:11.236788542 +0100
18845 +++ linux-2.4.24/net/netlink/af_netlink.c       2004-02-04 23:11:37.272996099 +0100
18846 @@ -40,6 +40,7 @@
18847  #include <linux/proc_fs.h>
18848  #include <linux/smp_lock.h>
18849  #include <linux/notifier.h>
18850 +#include <linux/grsecurity.h>
18851  #include <net/sock.h>
18852  #include <net/scm.h>
18853  
18854 @@ -626,7 +627,8 @@
18855            check them, when this message will be delivered
18856            to corresponding kernel module.   --ANK (980802)
18857          */
18858 -       NETLINK_CB(skb).eff_cap = current->cap_effective;
18859 +
18860 +       NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
18861  
18862         err = -EFAULT;
18863         if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
18864 diff -urN linux-2.4.24.org/net/netsyms.c linux-2.4.24/net/netsyms.c
18865 --- linux-2.4.24.org/net/netsyms.c      2004-02-04 23:06:17.033583191 +0100
18866 +++ linux-2.4.24/net/netsyms.c  2004-02-04 23:11:37.298990694 +0100
18867 @@ -25,6 +25,7 @@
18868  #include <net/checksum.h>
18869  #include <linux/etherdevice.h>
18870  #include <net/route.h>
18871 +#include <linux/grsecurity.h>
18872  #ifdef CONFIG_HIPPI
18873  #include <linux/hippidevice.h>
18874  #endif
18875 @@ -609,6 +610,49 @@
18876  
18877  EXPORT_SYMBOL(softnet_data);
18878  
18879 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
18880 +#if !defined (CONFIG_IPV6_MODULE) && !defined (CONFIG_KHTTPD) && !defined (CONFIG_KHTTPD_MODULE)
18881 +EXPORT_SYMBOL(tcp_v4_lookup_listener);
18882 +#endif
18883 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
18884 +EXPORT_SYMBOL(udp_v4_lookup);
18885 +#endif
18886 +
18887 +#if defined(CONFIG_GRKERNSEC_RANDID)
18888 +EXPORT_SYMBOL(ip_randomid);
18889 +#endif
18890 +#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
18891 +EXPORT_SYMBOL(get_random_long);
18892 +#endif
18893 +#ifdef CONFIG_GRKERNSEC_RANDISN
18894 +EXPORT_SYMBOL(ip_randomisn);
18895 +EXPORT_SYMBOL(grsec_enable_randisn);
18896 +#endif
18897 +#ifdef CONFIG_GRKERNSEC_RANDID
18898 +EXPORT_SYMBOL(grsec_enable_randid);
18899 +#endif
18900 +#ifdef CONFIG_GRKERNSEC_RANDSRC
18901 +EXPORT_SYMBOL(grsec_enable_randsrc);
18902 +#endif
18903 +#ifdef CONFIG_GRKERNSEC_RANDRPC
18904 +EXPORT_SYMBOL(grsec_enable_randrpc);
18905 +#endif
18906 +
18907 +EXPORT_SYMBOL(gr_cap_rtnetlink);
18908 +
18909 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
18910 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
18911 +
18912 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
18913 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
18914 +
18915 +#ifdef CONFIG_UNIX_MODULE
18916 +EXPORT_SYMBOL(gr_acl_handle_unix);
18917 +EXPORT_SYMBOL(gr_acl_handle_mknod);
18918 +EXPORT_SYMBOL(gr_handle_chroot_unix);
18919 +EXPORT_SYMBOL(gr_handle_create);
18920 +#endif
18921 +
18922  #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
18923  #include <net/iw_handler.h>
18924  EXPORT_SYMBOL(wireless_send_event);
18925 diff -urN linux-2.4.24.org/net/socket.c linux-2.4.24/net/socket.c
18926 --- linux-2.4.24.org/net/socket.c       2004-02-04 23:05:57.002748285 +0100
18927 +++ linux-2.4.24/net/socket.c   2004-02-04 23:11:37.337982587 +0100
18928 @@ -85,6 +85,18 @@
18929  #include <net/scm.h>
18930  #include <linux/netfilter.h>
18931  
18932 +extern void gr_attach_curr_ip(const struct sock *sk);
18933 +extern int gr_handle_sock_all(const int family, const int type,
18934 +                             const int protocol);
18935 +extern int gr_handle_sock_server(const struct sockaddr *sck);  
18936 +extern int gr_handle_sock_client(const struct sockaddr *sck);
18937 +extern int gr_search_connect(const struct socket * sock,
18938 +                            const struct sockaddr_in * addr);  
18939 +extern int gr_search_bind(const struct socket * sock,
18940 +                         const struct sockaddr_in * addr);
18941 +extern int gr_search_socket(const int domain, const int type,
18942 +                           const int protocol);
18943 +
18944  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
18945  static ssize_t sock_read(struct file *file, char *buf,
18946                          size_t size, loff_t *ppos);
18947 @@ -711,6 +723,7 @@
18948         }
18949         sock_fasync(-1, filp, 0);
18950         sock_release(socki_lookup(inode));
18951 +
18952         return 0;
18953  }
18954  
18955 @@ -903,6 +916,16 @@
18956         int retval;
18957         struct socket *sock;
18958  
18959 +       if(!gr_search_socket(family, type, protocol)) {
18960 +               retval = -EACCES;
18961 +               goto out;
18962 +       }
18963 +
18964 +       if (gr_handle_sock_all(family, type, protocol)) {
18965 +               retval = -EACCES;
18966 +               goto out;
18967 +       }
18968 +
18969         retval = sock_create(family, type, protocol, &sock);
18970         if (retval < 0)
18971                 goto out;
18972 @@ -998,12 +1021,26 @@
18973  {
18974         struct socket *sock;
18975         char address[MAX_SOCK_ADDR];
18976 +       struct sockaddr * sck;
18977         int err;
18978  
18979         if((sock = sockfd_lookup(fd,&err))!=NULL)
18980         {
18981 -               if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
18982 +               if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
18983 +                       sck = (struct sockaddr *) address;
18984 +
18985 +                       if(!gr_search_bind(sock, (struct sockaddr_in *) sck)) {
18986 +                               sockfd_put(sock);
18987 +                               return -EACCES;
18988 +                       }
18989 +
18990 +                       if (gr_handle_sock_server(sck)) {
18991 +                               sockfd_put(sock);
18992 +                               return -EACCES;
18993 +                       }
18994 +
18995                         err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
18996 +               }
18997                 sockfd_put(sock);
18998         }                       
18999         return err;
19000 @@ -1081,6 +1118,8 @@
19001         if ((err = sock_map_fd(newsock)) < 0)
19002                 goto out_release;
19003  
19004 +       gr_attach_curr_ip(newsock->sk);
19005 +
19006  out_put:
19007         sockfd_put(sock);
19008  out:
19009 @@ -1108,6 +1147,7 @@
19010  {
19011         struct socket *sock;
19012         char address[MAX_SOCK_ADDR];
19013 +       struct sockaddr * sck;
19014         int err;
19015  
19016         sock = sockfd_lookup(fd, &err);
19017 @@ -1116,6 +1156,19 @@
19018         err = move_addr_to_kernel(uservaddr, addrlen, address);
19019         if (err < 0)
19020                 goto out_put;
19021 +
19022 +       sck = (struct sockaddr *) address;
19023 +
19024 +       if (!gr_search_connect(sock, (struct sockaddr_in *) sck)) {
19025 +               err = -EACCES;
19026 +               goto out_put;
19027 +       }
19028 +
19029 +       if (gr_handle_sock_client(sck)) {
19030 +               err = -EACCES;
19031 +               goto out_put;
19032 +       }
19033 +
19034         err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
19035                                  sock->file->f_flags);
19036  out_put:
19037 @@ -1335,6 +1388,7 @@
19038                 err=sock->ops->shutdown(sock, how);
19039                 sockfd_put(sock);
19040         }
19041 +
19042         return err;
19043  }
19044  
19045 diff -urN linux-2.4.24.org/net/sunrpc/xprt.c linux-2.4.24/net/sunrpc/xprt.c
19046 --- linux-2.4.24.org/net/sunrpc/xprt.c  2004-02-04 23:06:09.493151104 +0100
19047 +++ linux-2.4.24/net/sunrpc/xprt.c      2004-02-04 23:11:37.366976559 +0100
19048 @@ -59,6 +59,7 @@
19049  #include <linux/unistd.h>
19050  #include <linux/sunrpc/clnt.h>
19051  #include <linux/file.h>
19052 +#include <linux/grsecurity.h>
19053  
19054  #include <net/sock.h>
19055  #include <net/checksum.h>
19056 @@ -1297,6 +1298,12 @@
19057         }
19058         ret = xid++;
19059         spin_unlock(&xid_lock);
19060 +
19061 +#ifdef CONFIG_GRKERNSEC_RANDRPC
19062 +       if (grsec_enable_randrpc)
19063 +               ret = (u32) get_random_long();
19064 +#endif
19065 +
19066         return ret;
19067  }
19068  
19069 diff -urN linux-2.4.24.org/net/unix/af_unix.c linux-2.4.24/net/unix/af_unix.c
19070 --- linux-2.4.24.org/net/unix/af_unix.c 2004-02-04 23:05:58.256487589 +0100
19071 +++ linux-2.4.24/net/unix/af_unix.c     2004-02-04 23:11:37.407968036 +0100
19072 @@ -109,6 +109,7 @@
19073  #include <linux/poll.h>
19074  #include <linux/smp_lock.h>
19075  #include <linux/rtnetlink.h>
19076 +#include <linux/grsecurity.h>
19077  
19078  #include <asm/checksum.h>
19079  
19080 @@ -599,6 +600,11 @@
19081                 if (err)
19082                         goto put_fail;
19083  
19084 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
19085 +                       err = -EACCES;
19086 +                       goto put_fail;
19087 +               }
19088 +               
19089                 err = -ECONNREFUSED;
19090                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
19091                         goto put_fail;
19092 @@ -622,6 +628,13 @@
19093                 if (u) {
19094                         struct dentry *dentry;
19095                         dentry = u->protinfo.af_unix.dentry;
19096 +
19097 +                       if (!gr_handle_chroot_unix(u->peercred.pid)) {
19098 +                               err = -EPERM;
19099 +                               sock_put(u);
19100 +                               goto fail;
19101 +                       }
19102 +
19103                         if (dentry)
19104                                 UPDATE_ATIME(dentry->d_inode);
19105                 } else
19106 @@ -720,9 +733,19 @@
19107                  * All right, let's create it.
19108                  */
19109                 mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask);
19110 +       
19111 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
19112 +                       err = -EACCES;
19113 +                       goto out_mknod_dput;
19114 +               }       
19115 +
19116                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
19117 +
19118                 if (err)
19119                         goto out_mknod_dput;
19120 +
19121 +               gr_handle_create(dentry, nd.mnt);
19122 +
19123                 up(&nd.dentry->d_inode->i_sem);
19124                 dput(nd.dentry);
19125                 nd.dentry = dentry;
19126 @@ -740,6 +763,10 @@
19127                         goto out_unlock;
19128                 }
19129  
19130 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
19131 +               sk->peercred.pid = current->pid;
19132 +#endif
19133 +
19134                 list = &unix_socket_table[addr->hash];
19135         } else {
19136                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
19137 @@ -866,6 +893,9 @@
19138         int st;
19139         int err;
19140         long timeo;
19141 +#ifdef CONFIG_GRKERNSEC
19142 +       struct task_struct *p, **htable;
19143 +#endif
19144  
19145         err = unix_mkname(sunaddr, addr_len, &hash);
19146         if (err < 0)
19147 @@ -989,6 +1019,17 @@
19148         /* Set credentials */
19149         sk->peercred = other->peercred;
19150  
19151 +#ifdef CONFIG_GRKERNSEC
19152 +       read_lock(&tasklist_lock);
19153 +       htable = &pidhash[pid_hashfn(other->peercred.pid)];
19154 +       for (p = *htable; p && p->pid != other->peercred.pid; p = p->pidhash_next);
19155 +       if (p) {
19156 +               p->curr_ip = current->curr_ip;
19157 +               p->used_accept = 1;
19158 +       }
19159 +       read_unlock(&tasklist_lock);
19160 +#endif
19161 +
19162         sock_hold(newsk);
19163         unix_peer(sk)=newsk;
19164         sock->state=SS_CONNECTED;
This page took 1.794305 seconds and 3 git commands to generate.