]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.0-rc4-2.4.24-O1.patch
- obsolete
[packages/kernel.git] / grsecurity-2.0-rc4-2.4.24-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-01-05 18:40:20.201039728 +0100
3 +++ linux-2.4.24/arch/alpha/config.in   2004-01-05 18:43:03.272249136 +0100
4 @@ -469,3 +469,12 @@
5  
6  source crypto/Config.in
7  source lib/Config.in
8 +
9 +mainmenu_option next_comment
10 +comment 'Grsecurity'
11 +bool 'Grsecurity' CONFIG_GRKERNSEC
12 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
13 +       source grsecurity/Config.in
14 +fi
15 +endmenu
16 +
17 diff -urN linux-2.4.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-01-05 18:40:20.499994280 +0100
19 +++ linux-2.4.24/arch/alpha/kernel/osf_sys.c    2004-01-05 18:43:03.286247008 +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-01-05 18:40:20.409008112 +0100
85 +++ linux-2.4.24/arch/alpha/kernel/ptrace.c     2004-01-05 18:43:03.287246856 +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-01-05 18:40:20.183042464 +0100
107 +++ linux-2.4.24/arch/alpha/mm/fault.c  2004-01-05 18:43:03.300244880 +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-01-05 18:40:32.053237920 +0100
284 +++ linux-2.4.24/arch/arm/config.in     2004-01-05 18:43:03.309243512 +0100
285 @@ -737,3 +737,11 @@
286  
287  source crypto/Config.in
288  source lib/Config.in
289 +
290 +mainmenu_option next_comment
291 +comment 'Grsecurity'
292 +bool 'Grsecurity' CONFIG_GRKERNSEC
293 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
294 +       source grsecurity/Config.in
295 +fi
296 +endmenu
297 diff -urN linux-2.4.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-01-05 18:40:32.892110392 +0100
299 +++ linux-2.4.24/arch/cris/config.in    2004-01-05 18:43:03.334239712 +0100
300 @@ -277,3 +277,12 @@
301  source crypto/Config.in
302  source lib/Config.in
303  endmenu
304 +
305 +mainmenu_option next_comment
306 +comment 'Grsecurity'
307 +bool 'Grsecurity' CONFIG_GRKERNSEC
308 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
309 +    source grsecurity/Config.in
310 +fi
311 +endmenu
312 +
313 diff -urN linux-2.4.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-01-05 18:40:21.478845472 +0100
315 +++ linux-2.4.24/arch/i386/boot/bootsect.S      2004-01-05 18:43:03.354236672 +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-01-05 18:40:21.582829664 +0100
327 +++ linux-2.4.24/arch/i386/boot/setup.S 2004-01-05 18:43:03.358236064 +0100
328 @@ -616,7 +616,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-01-05 18:40:21.385859608 +0100
339 +++ linux-2.4.24/arch/i386/config.in    2004-01-05 18:43:03.381232568 +0100
340 @@ -103,6 +103,7 @@
341  if [ "$CONFIG_M686" = "y" ]; then
342     define_bool CONFIG_X86_CMPXCHG8 y
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 @@ -113,6 +114,7 @@
349  if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
350     define_bool CONFIG_X86_CMPXCHG8 y
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 @@ -123,6 +125,7 @@
357  if [ "$CONFIG_MPENTIUM4" = "y" ]; then
358     define_bool CONFIG_X86_CMPXCHG8 y
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 @@ -147,6 +150,7 @@
365  if [ "$CONFIG_MK7" = "y" ]; then
366     define_bool CONFIG_X86_CMPXCHG8 y
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 @@ -503,3 +507,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-01-05 18:40:22.218732992 +0100
386 +++ linux-2.4.24/arch/i386/kernel/apm.c 2004-01-05 18:43:03.398229984 +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-01-05 18:40:22.016763696 +0100
468 +++ linux-2.4.24/arch/i386/kernel/entry.S       2004-01-05 18:43:03.416227248 +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-01-05 18:40:22.242729344 +0100
555 +++ linux-2.4.24/arch/i386/kernel/head.S        2004-01-05 18:43:03.443223144 +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-01-05 18:40:22.245728888 +0100
791 +++ linux-2.4.24/arch/i386/kernel/i386_ksyms.c  2004-01-05 18:43:03.444222992 +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-01-05 18:40:21.619824040 +0100
804 +++ linux-2.4.24/arch/i386/kernel/ioport.c      2004-01-05 18:43:03.462220256 +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-01-05 18:40:22.002765824 +0100
846 +++ linux-2.4.24/arch/i386/kernel/ldt.c 2004-01-05 18:43:03.482217216 +0100
847 @@ -50,7 +50,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 @@ -124,6 +124,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 @@ -134,7 +141,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-01-05 18:40:22.128746672 +0100
881 +++ linux-2.4.24/arch/i386/kernel/pci-pc.c      2004-01-05 18:43:03.505213720 +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-01-05 18:40:22.099751080 +0100
929 +++ linux-2.4.24/arch/i386/kernel/process.c     2004-01-05 18:43:03.529210072 +0100
930 @@ -600,7 +600,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 @@ -661,6 +665,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 @@ -700,6 +714,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 @@ -842,3 +860,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-01-05 18:40:21.883783912 +0100
998 +++ linux-2.4.24/arch/i386/kernel/ptrace.c      2004-01-05 18:43:03.530209920 +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 @@ -182,6 +183,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 @@ -261,6 +265,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-01-05 18:40:21.859787560 +0100
1037 +++ linux-2.4.24/arch/i386/kernel/setup.c       2004-01-05 18:43:03.562205056 +0100
1038 @@ -3188,7 +3188,7 @@
1039         set_tss_desc(nr,t);
1040         gdt_table[__TSS(nr)].b &= 0xfffffdff;
1041         load_TR(nr);
1042 -       load_LDT(&init_mm);
1043 +       _load_LDT(&init_mm);
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-01-05 18:40:22.243729192 +0100
1049 +++ linux-2.4.24/arch/i386/kernel/sys_i386.c    2004-01-05 18:45:26.153527880 +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(&mm->mmap_sem);
1081 -       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
1082 +       error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
1083         up_write(&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-01-05 18:40:22.244729040 +0100
1088 +++ linux-2.4.24/arch/i386/kernel/trampoline.S  2004-01-05 18:43:03.565204600 +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-01-05 18:40:22.595675688 +0100
1100 +++ linux-2.4.24/arch/i386/kernel/traps.c       2004-01-05 18:43:03.567204296 +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-01-05 18:40:21.586829056 +0100
1263 +++ linux-2.4.24/arch/i386/Makefile     2004-01-05 18:43:03.350237280 +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-01-05 18:40:21.121899736 +0100
1284 +++ linux-2.4.24/arch/i386/mm/fault.c   2004-01-05 18:45:58.048679080 +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                 tsk->thread.error_code = error_code;
1394                 tsk->thread.trap_no = 14;
1395 @@ -276,7 +324,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 @@ -289,7 +337,7 @@
1405  
1406                 if (nr == 6) {
1407                         do_invalid_op(regs, 0);
1408 -                       return;
1409 +                       return 0;
1410                 }
1411         }
1412  
1413 @@ -297,7 +345,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 @@ -310,6 +358,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 @@ -364,7 +424,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 @@ -397,6 +457,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-01-05 18:40:21.364862800 +0100
1902 +++ linux-2.4.24/arch/i386/mm/init.c    2004-01-05 18:43:03.593200344 +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-01-05 18:40:21.443850792 +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-01-05 18:43:03.627195176 +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-01-05 18:40:25.489235800 +0100
2197 +++ linux-2.4.24/arch/ia64/config.in    2004-01-05 18:43:03.645192440 +0100
2198 @@ -296,3 +296,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-01-05 18:40:25.724200080 +0100
2213 +++ linux-2.4.24/arch/ia64/kernel/ptrace.c      2004-01-05 18:43:03.667189096 +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-01-05 18:40:25.930168768 +0100
2234 +++ linux-2.4.24/arch/ia64/kernel/sys_ia64.c    2004-01-05 18:43:03.687186056 +0100
2235 @@ -15,6 +15,7 @@
2236  #include <linux/smp.h>
2237  #include <linux/smp_lock.h>
2238  #include <linux/highuid.h>
2239 +#include <linux/grsecurity.h>
2240  
2241  #include <asm/shmparam.h>
2242  #include <asm/uaccess.h>
2243 @@ -206,6 +207,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(current->mm, 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-01-05 18:40:16.713569904 +0100
2257 +++ linux-2.4.24/arch/m68k/config.in    2004-01-05 18:43:03.714181952 +0100
2258 @@ -562,3 +562,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-01-05 18:40:36.570551184 +0100
2272 +++ linux-2.4.24/arch/mips/config.in    2004-01-05 18:43:03.725180280 +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-01-05 18:40:18.315326400 +0100
2287 +++ linux-2.4.24/arch/mips64/config.in  2004-01-05 18:43:03.744177392 +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-01-05 18:40:14.780863720 +0100
2302 +++ linux-2.4.24/arch/parisc/config.in  2004-01-05 18:43:03.766174048 +0100
2303 @@ -205,3 +205,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-01-05 18:40:14.985832560 +0100
2317 +++ linux-2.4.24/arch/parisc/kernel/ioctl32.c   2004-01-05 18:43:03.817166296 +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-01-05 18:40:15.055821920 +0100
2332 +++ linux-2.4.24/arch/parisc/kernel/ptrace.c    2004-01-05 18:43:03.842162496 +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-01-05 18:40:15.167804896 +0100
2354 +++ linux-2.4.24/arch/parisc/kernel/sys_parisc32.c      2004-01-05 18:43:03.882156416 +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-01-05 18:40:15.145808240 +0100
2463 +++ linux-2.4.24/arch/parisc/kernel/sys_parisc.c        2004-01-05 18:43:03.850161280 +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-01-05 18:40:15.215797600 +0100
2510 +++ linux-2.4.24/arch/parisc/kernel/traps.c     2004-01-05 18:43:03.887155656 +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-01-05 18:40:14.765866000 +0100
2524 +++ linux-2.4.24/arch/parisc/mm/fault.c 2004-01-05 18:43:03.908152464 +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-01-05 18:40:06.744085496 +0100
2721 +++ linux-2.4.24/arch/ppc/config.in     2004-01-05 18:43:03.932148816 +0100
2722 @@ -610,3 +610,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-01-05 18:40:07.281003872 +0100
2737 +++ linux-2.4.24/arch/ppc/kernel/ptrace.c       2004-01-05 18:43:03.941147448 +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-01-05 18:40:07.584957664 +0100
2758 +++ linux-2.4.24/arch/ppc/kernel/syscalls.c     2004-01-05 18:47:54.556967128 +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 +       if (gr_handle_mmap(file, prot)) {
2785 +               fput(file);
2786 +               ret = -EACCES;
2787 +               goto out;
2788 +       }
2789         
2790         down_write(&current->mm->mmap_sem);
2791 -       ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
2792 +       ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
2793         up_write(&current->mm->mmap_sem);
2794         if (file)
2795                 fput(file);
2796 diff -urN linux-2.4.24.org/arch/ppc/mm/fault.c linux-2.4.24/arch/ppc/mm/fault.c
2797 --- linux-2.4.24.org/arch/ppc/mm/fault.c        2004-01-05 18:40:06.196168792 +0100
2798 +++ linux-2.4.24/arch/ppc/mm/fault.c    2004-01-05 18:43:04.227103976 +0100
2799 @@ -26,6 +26,9 @@
2800  #include <linux/mman.h>
2801  #include <linux/mm.h>
2802  #include <linux/interrupt.h>
2803 +#include <linux/slab.h>
2804 +#include <linux/pagemap.h>
2805 +#include <linux/compiler.h>
2806  
2807  #include <asm/page.h>
2808  #include <asm/pgtable.h>
2809 @@ -52,6 +55,360 @@
2810  void bad_page_fault(struct pt_regs *, unsigned long, int sig);
2811  void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
2812  
2813 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2814 +void pax_syscall_close(struct vm_area_struct * vma)
2815 +{
2816 +       vma->vm_mm->call_syscall = 0UL;
2817 +}
2818 +
2819 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
2820 +{
2821 +       struct page* page;
2822 +       unsigned int *kaddr;
2823 +
2824 +       page = alloc_page(GFP_HIGHUSER);
2825 +       if (!page)
2826 +               return page;
2827 +
2828 +       kaddr = kmap(page);
2829 +       memset(kaddr, 0, PAGE_SIZE);
2830 +       kaddr[0] = 0x44000002U; /* sc */
2831 +       __flush_dcache_icache(kaddr);
2832 +       kunmap(page);
2833 +       return page;
2834 +}
2835 +
2836 +static struct vm_operations_struct pax_vm_ops = {
2837 +       close:          pax_syscall_close,
2838 +       nopage:         pax_syscall_nopage,
2839 +};
2840 +
2841 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2842 +{
2843 +       vma->vm_mm = current->mm;
2844 +       vma->vm_start = addr;
2845 +       vma->vm_end = addr + PAGE_SIZE;
2846 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2847 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
2848 +       vma->vm_ops = &pax_vm_ops;
2849 +       vma->vm_pgoff = 0UL;
2850 +       vma->vm_file = NULL;
2851 +       vma->vm_private_data = NULL;
2852 +       insert_vm_struct(current->mm, vma);
2853 +       ++current->mm->total_vm;
2854 +}
2855 +#endif
2856 +
2857 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2858 +/*
2859 + * PaX: decide what to do with offenders (regs->nip = fault address)
2860 + *
2861 + * returns 1 when task should be killed
2862 + *         2 when patched GOT trampoline was detected
2863 + *         3 when patched PLT trampoline was detected
2864 + *         4 when unpatched PLT trampoline was detected
2865 + *         5 when legitimate ET_EXEC was detected
2866 + *         6 when sigreturn trampoline was detected
2867 + *         7 when rt_sigreturn trampoline was detected
2868 + */
2869 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2870 +{
2871 +       int err;
2872 +
2873 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2874 +       if (current->flags & PF_PAX_RANDEXEC) {
2875 +               if (regs->nip >= current->mm->start_code &&
2876 +                   regs->nip < current->mm->end_code)
2877 +               {
2878 +                       if (regs->link == regs->nip)
2879 +                               return 1;
2880 +
2881 +                       regs->nip += current->mm->delta_exec;
2882 +                       return 5;
2883 +               }
2884 +       }
2885 +#endif
2886 +
2887 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2888 +       do { /* PaX: patched GOT emulation */
2889 +               unsigned int blrl;
2890 +
2891 +               err = get_user(blrl, (unsigned int*)regs->nip);
2892 +
2893 +               if (!err && blrl == 0x4E800021U) {
2894 +                       unsigned long temp = regs->nip;
2895 +
2896 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
2897 +                       regs->link = temp + 4UL;
2898 +                       return 2;
2899 +               }
2900 +       } while (0);
2901 +
2902 +       do { /* PaX: patched PLT emulation #1 */
2903 +               unsigned int b;
2904 +
2905 +               err = get_user(b, (unsigned int *)regs->nip);
2906 +
2907 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
2908 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
2909 +                       return 3;
2910 +               }
2911 +       } while (0);
2912 +
2913 +       do { /* PaX: unpatched PLT emulation #1 */
2914 +               unsigned int li, b;
2915 +
2916 +               err = get_user(li, (unsigned int *)regs->nip);
2917 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2918 +
2919 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2920 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2921 +                        unsigned long addr = b | 0xFC000000UL;
2922 +
2923 +                        addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2924 +                       err = get_user(rlwinm, (unsigned int*)addr);
2925 +                       err |= get_user(add, (unsigned int*)(addr+4));
2926 +                       err |= get_user(li2, (unsigned int*)(addr+8));
2927 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
2928 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
2929 +                       err |= get_user(li3, (unsigned int*)(addr+20));
2930 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
2931 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
2932 +
2933 +                       if (err)
2934 +                               break;
2935 +
2936 +                       if (rlwinm == 0x556C083CU &&
2937 +                           add == 0x7D6C5A14U &&
2938 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2939 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2940 +                           mtctr == 0x7D8903A6U &&
2941 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2942 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2943 +                           bctr == 0x4E800420U)
2944 +                       {
2945 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2946 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2947 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2948 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2949 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2950 +                               regs->nip = regs->ctr;
2951 +                               return 4;
2952 +                       }
2953 +               }
2954 +       } while (0);
2955 +
2956 +#if 0
2957 +       do { /* PaX: unpatched PLT emulation #2 */
2958 +               unsigned int lis, lwzu, b, bctr;
2959 +
2960 +               err = get_user(lis, (unsigned int *)regs->nip);
2961 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
2962 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
2963 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
2964 +
2965 +               if (err)
2966 +                       break;
2967 +
2968 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
2969 +                   (lwzu & 0xU) == 0xU &&
2970 +                   (b & 0xFC000003U) == 0x48000000U &&
2971 +                   bctr == 0x4E800420U)
2972 +               {
2973 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2974 +                        unsigned long addr = b | 0xFC000000UL;
2975 +
2976 +                        addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2977 +                       err = get_user(addis, (unsigned int*)addr);
2978 +                       err |= get_user(addi, (unsigned int*)(addr+4));
2979 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
2980 +                       err |= get_user(add, (unsigned int*)(addr+12));
2981 +                       err |= get_user(li2, (unsigned int*)(addr+16));
2982 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
2983 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
2984 +                       err |= get_user(li3, (unsigned int*)(addr+28));
2985 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
2986 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
2987 +
2988 +                       if (err)
2989 +                               break;
2990 +
2991 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2992 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
2993 +                           rlwinm == 0x556C083CU &&
2994 +                           add == 0x7D6C5A14U &&
2995 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2996 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2997 +                           mtctr == 0x7D8903A6U &&
2998 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2999 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3000 +                           bctr == 0x4E800420U)
3001 +                       {
3002 +                               regs->gpr[PT_R11] = 
3003 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3004 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3005 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3006 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3007 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
3008 +                               regs->nip = regs->ctr;
3009 +                               return 4;
3010 +                       }
3011 +               }
3012 +       } while (0);
3013 +#endif
3014 +
3015 +       do { /* PaX: unpatched PLT emulation #3 */
3016 +               unsigned int li, b;
3017 +
3018 +               err = get_user(li, (unsigned int *)regs->nip);
3019 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
3020 +
3021 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3022 +                       unsigned int addis, lwz, mtctr, bctr;
3023 +                       unsigned long addr = b | 0xFC000000UL;
3024 +
3025 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3026 +                       err = get_user(addis, (unsigned int*)addr);
3027 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
3028 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
3029 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
3030 +
3031 +                       if (err)
3032 +                               break;
3033 +
3034 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3035 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
3036 +                           mtctr == 0x7D6903A6U &&
3037 +                           bctr == 0x4E800420U)
3038 +                       {
3039 +                               unsigned int r11;
3040 +
3041 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3042 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3043 +
3044 +                               err = get_user(r11, (unsigned int*)addr);
3045 +                               if (err)
3046 +                                       break;
3047 +
3048 +                               regs->gpr[PT_R11] = r11;
3049 +                               regs->ctr = r11;
3050 +                               regs->nip = r11;
3051 +                               return 4;
3052 +                       }
3053 +               }
3054 +       } while (0);
3055 +#endif
3056 +
3057 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
3058 +       do { /* PaX: sigreturn emulation */
3059 +               unsigned int li, sc;
3060 +
3061 +               err = get_user(li, (unsigned int *)regs->nip);
3062 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
3063 +
3064 +               if (!err && li == 0x38007777U && sc == 0x44000002U) {
3065 +                       struct vm_area_struct *vma;
3066 +                       unsigned long call_syscall;
3067 +
3068 +                       down_read(&current->mm->mmap_sem);
3069 +                       call_syscall = current->mm->call_syscall;
3070 +                       up_read(&current->mm->mmap_sem);
3071 +                       if (likely(call_syscall))
3072 +                               goto emulate;
3073 +
3074 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3075 +
3076 +                       down_write(&current->mm->mmap_sem);
3077 +                       if (current->mm->call_syscall) {
3078 +                               call_syscall = current->mm->call_syscall;
3079 +                               up_write(&current->mm->mmap_sem);
3080 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3081 +                               goto emulate;
3082 +                       }
3083 +
3084 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3085 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
3086 +                               up_write(&current->mm->mmap_sem);
3087 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3088 +                               return 1;
3089 +                       }
3090 +
3091 +                       pax_insert_vma(vma, call_syscall);
3092 +                       current->mm->call_syscall = call_syscall;
3093 +                       up_write(&current->mm->mmap_sem);
3094 +
3095 +emulate:
3096 +                       regs->gpr[PT_R0] = 0x7777UL;
3097 +                       regs->nip = call_syscall;
3098 +                       return 6;
3099 +               }
3100 +       } while (0);
3101 +
3102 +       do { /* PaX: rt_sigreturn emulation */
3103 +               unsigned int li, sc;
3104 +
3105 +               err = get_user(li, (unsigned int *)regs->nip);
3106 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
3107 +
3108 +               if (!err && li == 0x38006666U && sc == 0x44000002U) {
3109 +                       struct vm_area_struct *vma;
3110 +                       unsigned int call_syscall;
3111 +
3112 +                       down_read(&current->mm->mmap_sem);
3113 +                       call_syscall = current->mm->call_syscall;
3114 +                       up_read(&current->mm->mmap_sem);
3115 +                       if (likely(call_syscall))
3116 +                               goto rt_emulate;
3117 +
3118 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3119 +
3120 +                       down_write(&current->mm->mmap_sem);
3121 +                       if (current->mm->call_syscall) {
3122 +                               call_syscall = current->mm->call_syscall;
3123 +                               up_write(&current->mm->mmap_sem);
3124 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3125 +                               goto rt_emulate;
3126 +                       }
3127 +
3128 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3129 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
3130 +                               up_write(&current->mm->mmap_sem);
3131 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3132 +                               return 1;
3133 +                       }
3134 +
3135 +                       pax_insert_vma(vma, call_syscall);
3136 +                       current->mm->call_syscall = call_syscall;
3137 +                       up_write(&current->mm->mmap_sem);
3138 +
3139 +rt_emulate:
3140 +                       regs->gpr[PT_R0] = 0x6666UL;
3141 +                       regs->nip = call_syscall;
3142 +                       return 7;
3143 +               }
3144 +       } while (0);
3145 +#endif
3146 +
3147 +        return 1;
3148 +}
3149 +
3150 +void pax_report_insns(void *pc)
3151 +{
3152 +       unsigned long i;
3153 +
3154 +       printk(KERN_ERR "PAX: bytes at PC: ");
3155 +       for (i = 0; i < 5; i++) {
3156 +               unsigned int c;
3157 +               if (get_user(c, (unsigned int*)pc+i)) {
3158 +                       printk("<invalid address>.");
3159 +                       break;
3160 +               }
3161 +               printk("%08x ", c);
3162 +       }
3163 +       printk("\n");
3164 +}
3165 +#endif
3166 +
3167  /*
3168   * Check whether the instruction at regs->nip is a store using
3169   * an update addressing form which will update r1.
3170 @@ -112,7 +469,7 @@
3171          * indicate errors in DSISR but can validly be set in SRR1.
3172          */
3173         if (regs->trap == 0x400)
3174 -               error_code &= 0x48200000;
3175 +               error_code &= 0x58200000;
3176         else
3177                 is_write = error_code & 0x02000000;
3178  #endif /* CONFIG_4xx || CONFIG_BOOKE */
3179 @@ -245,6 +602,38 @@
3180  
3181         /* User mode accesses cause a SIGSEGV */
3182         if (user_mode(regs)) {
3183 +
3184 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3185 +               if (current->flags & PF_PAX_PAGEEXEC) {
3186 +                       if ((regs->trap == 0x400) && (regs->nip == address)) {
3187 +                               switch (pax_handle_fetch_fault(regs)) {
3188 +
3189 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3190 +                               case 2:
3191 +                               case 3:
3192 +                               case 4:
3193 +                                       return;
3194 +#endif
3195 +
3196 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3197 +                               case 5:
3198 +                                       return;
3199 +#endif
3200 +
3201 +#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
3202 +                               case 6:
3203 +                               case 7:
3204 +                                       return;
3205 +#endif
3206 +
3207 +                               }
3208 +
3209 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
3210 +                               do_exit(SIGKILL);
3211 +                       }
3212 +               }
3213 +#endif
3214 +
3215                 info.si_signo = SIGSEGV;
3216                 info.si_errno = 0;
3217                 info.si_code = code;
3218 diff -urN linux-2.4.24.org/arch/ppc64/kernel/ioctl32.c linux-2.4.24/arch/ppc64/kernel/ioctl32.c
3219 --- linux-2.4.24.org/arch/ppc64/kernel/ioctl32.c        2004-01-05 18:40:29.951557424 +0100
3220 +++ linux-2.4.24/arch/ppc64/kernel/ioctl32.c    2004-01-05 18:43:04.495063240 +0100
3221 @@ -1801,7 +1801,11 @@
3222          * To have permissions to do most of the vt ioctls, we either have
3223          * to be the owner of the tty, or super-user.
3224          */
3225 +#ifdef CONFIG_GRKERNSEC
3226 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3227 +#else
3228         if (current->tty == tty || suser())
3229 +#endif
3230                 return 1;
3231         return 0;                                                    
3232  }
3233 diff -urN linux-2.4.24.org/arch/s390/config.in linux-2.4.24/arch/s390/config.in
3234 --- linux-2.4.24.org/arch/s390/config.in        2004-01-05 18:40:23.223580232 +0100
3235 +++ linux-2.4.24/arch/s390/config.in    2004-01-05 18:43:04.523058984 +0100
3236 @@ -87,3 +87,11 @@
3237  
3238  source crypto/Config.in
3239  source lib/Config.in
3240 +
3241 +mainmenu_option next_comment
3242 +comment 'Grsecurity'
3243 +bool 'Grsecurity' CONFIG_GRKERNSEC
3244 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3245 +       source grsecurity/Config.in
3246 +fi
3247 +endmenu
3248 diff -urN linux-2.4.24.org/arch/s390x/config.in linux-2.4.24/arch/s390x/config.in
3249 --- linux-2.4.24.org/arch/s390x/config.in       2004-01-05 18:40:15.349777232 +0100
3250 +++ linux-2.4.24/arch/s390x/config.in   2004-01-05 18:43:04.542056096 +0100
3251 @@ -91,3 +91,11 @@
3252  
3253  source crypto/Config.in
3254  source lib/Config.in
3255 +
3256 +mainmenu_option next_comment
3257 +comment 'Grsecurity'
3258 +bool 'Grsecurity' CONFIG_GRKERNSEC
3259 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3260 +       source grsecurity/Config.in
3261 +fi
3262 +endmenu
3263 diff -urN linux-2.4.24.org/arch/sh/config.in linux-2.4.24/arch/sh/config.in
3264 --- linux-2.4.24.org/arch/sh/config.in  2004-01-05 18:40:28.696748184 +0100
3265 +++ linux-2.4.24/arch/sh/config.in      2004-01-05 18:43:04.567052296 +0100
3266 @@ -492,3 +492,11 @@
3267  
3268  source crypto/Config.in
3269  source lib/Config.in
3270 +
3271 +mainmenu_option next_comment
3272 +comment 'Grsecurity'
3273 +bool 'Grsecurity' CONFIG_GRKERNSEC
3274 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3275 +       source grsecurity/Config.in
3276 +fi
3277 +endmenu
3278 diff -urN linux-2.4.24.org/arch/sparc/boot/Makefile linux-2.4.24/arch/sparc/boot/Makefile
3279 --- linux-2.4.24.org/arch/sparc/boot/Makefile   2004-01-05 18:40:18.953229424 +0100
3280 +++ linux-2.4.24/arch/sparc/boot/Makefile       2004-01-05 18:43:04.574051232 +0100
3281 @@ -24,7 +24,7 @@
3282  
3283  BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o
3284  BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
3285 -       $(DRIVERS) $(NETWORKS)
3286 +       $(DRIVERS) $(NETWORKS) $(GRSECURITY)
3287  
3288  # I wanted to make this depend upon BTOBJS so that a parallel
3289  # build would work, but this fails because $(HEAD) cannot work
3290 diff -urN linux-2.4.24.org/arch/sparc/config.in linux-2.4.24/arch/sparc/config.in
3291 --- linux-2.4.24.org/arch/sparc/config.in       2004-01-05 18:40:18.884239912 +0100
3292 +++ linux-2.4.24/arch/sparc/config.in   2004-01-05 18:43:04.585049560 +0100
3293 @@ -283,3 +283,11 @@
3294  
3295  source crypto/Config.in
3296  source lib/Config.in
3297 +
3298 +mainmenu_option next_comment
3299 +comment 'Grsecurity'
3300 +bool 'Grsecurity' CONFIG_GRKERNSEC
3301 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3302 +       source grsecurity/Config.in
3303 +fi
3304 +endmenu
3305 diff -urN linux-2.4.24.org/arch/sparc/kernel/ptrace.c linux-2.4.24/arch/sparc/kernel/ptrace.c
3306 --- linux-2.4.24.org/arch/sparc/kernel/ptrace.c 2004-01-05 18:40:19.090208600 +0100
3307 +++ linux-2.4.24/arch/sparc/kernel/ptrace.c     2004-01-05 18:43:04.601047128 +0100
3308 @@ -17,6 +17,7 @@
3309  #include <linux/user.h>
3310  #include <linux/smp.h>
3311  #include <linux/smp_lock.h>
3312 +#include <linux/grsecurity.h>
3313  
3314  #include <asm/pgtable.h>
3315  #include <asm/system.h>
3316 @@ -310,6 +311,9 @@
3317                 goto out;
3318         }
3319  
3320 +       if(gr_handle_ptrace(child, request))
3321 +               goto out_tsk;
3322 +
3323         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3324             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3325                 if (ptrace_attach(child)) {
3326 diff -urN linux-2.4.24.org/arch/sparc/kernel/sys_sparc.c linux-2.4.24/arch/sparc/kernel/sys_sparc.c
3327 --- linux-2.4.24.org/arch/sparc/kernel/sys_sparc.c      2004-01-05 18:40:19.115204800 +0100
3328 +++ linux-2.4.24/arch/sparc/kernel/sys_sparc.c  2004-01-05 18:43:04.616044848 +0100
3329 @@ -20,6 +20,7 @@
3330  #include <linux/utsname.h>
3331  #include <linux/smp.h>
3332  #include <linux/smp_lock.h>
3333 +#include <linux/grsecurity.h>
3334  
3335  #include <asm/uaccess.h>
3336  #include <asm/ipc.h>
3337 @@ -54,6 +55,13 @@
3338                 return -ENOMEM;
3339         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
3340                 return -ENOMEM;
3341 +
3342 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3343 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3344 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3345 +       else
3346 +#endif
3347 +
3348         if (!addr)
3349                 addr = TASK_UNMAPPED_BASE;
3350  
3351 @@ -225,6 +233,11 @@
3352         struct file * file = NULL;
3353         unsigned long retval = -EBADF;
3354  
3355 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3356 +       if (flags & MAP_MIRROR)
3357 +               return -EINVAL;
3358 +#endif
3359 +
3360         if (!(flags & MAP_ANONYMOUS)) {
3361                 file = fget(fd);
3362                 if (!file)
3363 @@ -243,6 +256,12 @@
3364         if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
3365                 goto out_putf;
3366  
3367 +       if (gr_handle_mmap(file, prot)) {
3368 +               fput(file);
3369 +               retval = -EACCES;
3370 +               goto out;
3371 +       }
3372 +
3373         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3374  
3375         down_write(&current->mm->mmap_sem);
3376 diff -urN linux-2.4.24.org/arch/sparc/kernel/sys_sunos.c linux-2.4.24/arch/sparc/kernel/sys_sunos.c
3377 --- linux-2.4.24.org/arch/sparc/kernel/sys_sunos.c      2004-01-05 18:40:19.091208448 +0100
3378 +++ linux-2.4.24/arch/sparc/kernel/sys_sunos.c  2004-01-05 18:43:04.618044544 +0100
3379 @@ -68,6 +68,11 @@
3380         struct file * file = NULL;
3381         unsigned long retval, ret_type;
3382  
3383 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3384 +       if (flags & MAP_MIRROR)
3385 +               return -EINVAL;
3386 +#endif
3387 +
3388         if(flags & MAP_NORESERVE) {
3389                 static int cnt;
3390                 if (cnt++ < 10)
3391 diff -urN linux-2.4.24.org/arch/sparc/mm/fault.c linux-2.4.24/arch/sparc/mm/fault.c
3392 --- linux-2.4.24.org/arch/sparc/mm/fault.c      2004-01-05 18:40:18.853244624 +0100
3393 +++ linux-2.4.24/arch/sparc/mm/fault.c  2004-01-05 18:43:04.646040288 +0100
3394 @@ -19,6 +19,9 @@
3395  #include <linux/smp.h>
3396  #include <linux/smp_lock.h>
3397  #include <linux/interrupt.h>
3398 +#include <linux/slab.h>
3399 +#include <linux/pagemap.h>
3400 +#include <linux/compiler.h>
3401  
3402  #include <asm/system.h>
3403  #include <asm/segment.h>
3404 @@ -200,6 +203,264 @@
3405         return 0;
3406  }
3407  
3408 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3409 +void pax_emuplt_close(struct vm_area_struct * vma)
3410 +{
3411 +       vma->vm_mm->call_dl_resolve = 0UL;
3412 +}
3413 +
3414 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
3415 +{
3416 +       struct page* page;
3417 +       unsigned int *kaddr;
3418 +
3419 +       page = alloc_page(GFP_HIGHUSER);
3420 +       if (!page)
3421 +               return page;
3422 +
3423 +       kaddr = kmap(page);
3424 +       memset(kaddr, 0, PAGE_SIZE);
3425 +       kaddr[0] = 0x9DE3BFA8U; /* save */
3426 +       flush_dcache_page(page);
3427 +       kunmap(page);
3428 +       return page;
3429 +}
3430 +
3431 +static struct vm_operations_struct pax_vm_ops = {
3432 +       close:          pax_emuplt_close,
3433 +       nopage:         pax_emuplt_nopage,
3434 +};
3435 +
3436 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3437 +{
3438 +       vma->vm_mm = current->mm;
3439 +       vma->vm_start = addr;
3440 +       vma->vm_end = addr + PAGE_SIZE;
3441 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3442 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3443 +       vma->vm_ops = &pax_vm_ops;
3444 +       vma->vm_pgoff = 0UL;
3445 +       vma->vm_file = NULL;
3446 +       vma->vm_private_data = NULL;
3447 +       insert_vm_struct(current->mm, vma);
3448 +       ++current->mm->total_vm;
3449 +}
3450 +
3451 +/*
3452 + * PaX: decide what to do with offenders (regs->pc = fault address)
3453 + *
3454 + * returns 1 when task should be killed
3455 + *         2 when patched PLT trampoline was detected
3456 + *         3 when unpatched PLT trampoline was detected
3457 + *        4 when legitimate ET_EXEC was detected
3458 + */
3459 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3460 +{
3461 +       int err;
3462 +
3463 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3464 +       if (current->flags & PF_PAX_RANDEXEC) {
3465 +               if (regs->pc >= current->mm->start_code &&
3466 +                   regs->pc < current->mm->end_code)
3467 +               {
3468 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
3469 +                               return 1;
3470 +
3471 +                       regs->pc += current->mm->delta_exec;
3472 +                       if (regs->npc >= current->mm->start_code &&
3473 +                           regs->npc < current->mm->end_code)
3474 +                               regs->npc += current->mm->delta_exec;
3475 +                       return 4;
3476 +               }
3477 +               if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
3478 +                   regs->pc < current->mm->end_code + current->mm->delta_exec)
3479 +               {
3480 +                       regs->pc -= current->mm->delta_exec;
3481 +                       if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
3482 +                           regs->npc < current->mm->end_code + current->mm->delta_exec)
3483 +                               regs->npc -= current->mm->delta_exec;
3484 +               }
3485 +       }
3486 +#endif
3487 +
3488 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3489 +       do { /* PaX: patched PLT emulation #1 */
3490 +               unsigned int sethi1, sethi2, jmpl;
3491 +
3492 +               err = get_user(sethi1, (unsigned int *)regs->pc);
3493 +               err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
3494 +               err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
3495 +
3496 +               if (err)
3497 +                       break;
3498 +
3499 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3500 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
3501 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
3502 +               {
3503 +                       unsigned int addr;
3504 +
3505 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3506 +                       addr = regs->u_regs[UREG_G1];
3507 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3508 +                       regs->pc = addr;
3509 +                       regs->npc = addr+4;
3510 +                       return 2;
3511 +               }
3512 +       } while (0);
3513 +
3514 +       { /* PaX: patched PLT emulation #2 */
3515 +               unsigned int ba;
3516 +
3517 +               err = get_user(ba, (unsigned int *)regs->pc);
3518 +
3519 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3520 +                       unsigned int addr;
3521 +
3522 +                       addr = regs->pc + 4 + (((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U);
3523 +                       regs->pc = addr;
3524 +                       regs->npc = addr+4;
3525 +                       return 2;
3526 +               }
3527 +       }
3528 +
3529 +       do { /* PaX: patched PLT emulation #3 */
3530 +               unsigned int sethi, jmpl, nop;
3531 +
3532 +               err = get_user(sethi, (unsigned int*)regs->pc);
3533 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
3534 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
3535 +
3536 +               if (err)
3537 +                       break;
3538 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3539 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3540 +                   nop == 0x01000000U)
3541 +               {
3542 +                       unsigned int addr;
3543 +
3544 +                       addr = (sethi & 0x003FFFFFU) << 10;
3545 +                       regs->u_regs[UREG_G1] = addr;
3546 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3547 +                       regs->pc = addr;
3548 +                       regs->npc = addr+4;
3549 +                       return 2;
3550 +               }
3551 +       } while (0);
3552 +
3553 +       do { /* PaX: unpatched PLT emulation step 1 */
3554 +               unsigned int sethi, ba, nop;
3555 +
3556 +               err = get_user(sethi, (unsigned int *)regs->pc);
3557 +               err |= get_user(ba, (unsigned int *)(regs->pc+4));
3558 +               err |= get_user(nop, (unsigned int *)(regs->pc+8));
3559 +
3560 +               if (err)
3561 +                       break;
3562 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3563 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3564 +                   nop == 0x01000000U)
3565 +               {
3566 +                       unsigned int addr, save, call;
3567 +
3568 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
3569 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3570 +                       else
3571 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
3572 +
3573 +                       err = get_user(save, (unsigned int *)addr);
3574 +                       err |= get_user(call, (unsigned int *)(addr+4));
3575 +                       err |= get_user(nop, (unsigned int *)(addr+8)); 
3576 +                       if (err)
3577 +                               break;
3578 +
3579 +                       if (save == 0x9DE3BFA8U &&
3580 +                           (call & 0xC0000000U) == 0x40000000U &&
3581 +                           nop == 0x01000000U)
3582 +                       {
3583 +                               struct vm_area_struct *vma;
3584 +                               unsigned long call_dl_resolve;
3585 +
3586 +                               down_read(&current->mm->mmap_sem);
3587 +                               call_dl_resolve = current->mm->call_dl_resolve;
3588 +                               up_read(&current->mm->mmap_sem);
3589 +                               if (likely(call_dl_resolve))
3590 +                                       goto emulate;
3591 +
3592 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3593 +
3594 +                               down_write(&current->mm->mmap_sem);
3595 +                               if (current->mm->call_dl_resolve) {
3596 +                                       call_dl_resolve = current->mm->call_dl_resolve;
3597 +                                       up_write(&current->mm->mmap_sem);
3598 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3599 +                                       goto emulate;
3600 +                               }
3601 +
3602 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3603 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3604 +                                       up_write(&current->mm->mmap_sem);
3605 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3606 +                                       return 1;
3607 +                               }
3608 +
3609 +                               pax_insert_vma(vma, call_dl_resolve);
3610 +                               current->mm->call_dl_resolve = call_dl_resolve;
3611 +                               up_write(&current->mm->mmap_sem);
3612 +
3613 +emulate:
3614 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3615 +                               regs->pc = call_dl_resolve;
3616 +                               regs->npc = addr+4;
3617 +                               return 3;
3618 +                       }
3619 +               }
3620 +       } while (0);
3621 +
3622 +       do { /* PaX: unpatched PLT emulation step 2 */
3623 +               unsigned int save, call, nop;
3624 +
3625 +               err = get_user(save, (unsigned int*)(regs->pc-4));
3626 +               err |= get_user(call, (unsigned int*)regs->pc);
3627 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
3628 +               if (err)
3629 +                       break;
3630 +
3631 +               if (save == 0x9DE3BFA8U &&
3632 +                   (call & 0xC0000000U) == 0x40000000U &&
3633 +                   nop == 0x01000000U)
3634 +               {
3635 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
3636 +
3637 +                       regs->u_regs[UREG_RETPC] = regs->pc;
3638 +                       regs->pc = dl_resolve;
3639 +                       regs->npc = dl_resolve+4;
3640 +                       return 3;
3641 +               }
3642 +       } while (0);
3643 +
3644 +#endif
3645 +
3646 +       return 1;
3647 +}
3648 +
3649 +void pax_report_insns(void *pc)
3650 +{
3651 +       unsigned long i;
3652 +
3653 +       printk(KERN_ERR "PAX: bytes at PC: ");
3654 +       for (i = 0; i < 5; i++) {
3655 +               unsigned int c;
3656 +               if (get_user(c, (unsigned int*)pc+i)) {
3657 +                       printk("<invalid address>.");
3658 +                       break;
3659 +               }
3660 +               printk("%08x ", c);
3661 +       }
3662 +       printk("\n");
3663 +}
3664 +#endif
3665 +
3666  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
3667                                unsigned long address)
3668  {
3669 @@ -263,6 +524,29 @@
3670                 if(!(vma->vm_flags & VM_WRITE))
3671                         goto bad_area;
3672         } else {
3673 +
3674 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3675 +               if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
3676 +                       up_read(&mm->mmap_sem);
3677 +                       switch (pax_handle_fetch_fault(regs)) {
3678 +
3679 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3680 +                       case 2:
3681 +                       case 3:
3682 +                               return;
3683 +#endif
3684 +
3685 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3686 +                       case 4:
3687 +                               return;
3688 +#endif
3689 +
3690 +                       }
3691 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
3692 +                       do_exit(SIGKILL);
3693 +               }
3694 +#endif
3695 +
3696                 /* Allow reads even for write-only mappings */
3697                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
3698                         goto bad_area;
3699 diff -urN linux-2.4.24.org/arch/sparc/mm/init.c linux-2.4.24/arch/sparc/mm/init.c
3700 --- linux-2.4.24.org/arch/sparc/mm/init.c       2004-01-05 18:40:18.854244472 +0100
3701 +++ linux-2.4.24/arch/sparc/mm/init.c   2004-01-05 18:43:04.647040136 +0100
3702 @@ -350,17 +350,17 @@
3703  
3704         /* Initialize the protection map with non-constant, MMU dependent values. */
3705         protection_map[0] = PAGE_NONE;
3706 -       protection_map[1] = PAGE_READONLY;
3707 -       protection_map[2] = PAGE_COPY;
3708 -       protection_map[3] = PAGE_COPY;
3709 +       protection_map[1] = PAGE_READONLY_NOEXEC;
3710 +       protection_map[2] = PAGE_COPY_NOEXEC;
3711 +       protection_map[3] = PAGE_COPY_NOEXEC;
3712         protection_map[4] = PAGE_READONLY;
3713         protection_map[5] = PAGE_READONLY;
3714         protection_map[6] = PAGE_COPY;
3715         protection_map[7] = PAGE_COPY;
3716         protection_map[8] = PAGE_NONE;
3717 -       protection_map[9] = PAGE_READONLY;
3718 -       protection_map[10] = PAGE_SHARED;
3719 -       protection_map[11] = PAGE_SHARED;
3720 +       protection_map[9] = PAGE_READONLY_NOEXEC;
3721 +       protection_map[10] = PAGE_SHARED_NOEXEC;
3722 +       protection_map[11] = PAGE_SHARED_NOEXEC;
3723         protection_map[12] = PAGE_READONLY;
3724         protection_map[13] = PAGE_READONLY;
3725         protection_map[14] = PAGE_SHARED;
3726 diff -urN linux-2.4.24.org/arch/sparc/mm/srmmu.c linux-2.4.24/arch/sparc/mm/srmmu.c
3727 --- linux-2.4.24.org/arch/sparc/mm/srmmu.c      2004-01-05 18:40:18.856244168 +0100
3728 +++ linux-2.4.24/arch/sparc/mm/srmmu.c  2004-01-05 18:43:04.658038464 +0100
3729 @@ -2047,6 +2047,13 @@
3730         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
3731         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
3732         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
3733 +
3734 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3735 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
3736 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
3737 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
3738 +#endif
3739 +
3740         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
3741         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
3742         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
3743 diff -urN linux-2.4.24.org/arch/sparc64/config.in linux-2.4.24/arch/sparc64/config.in
3744 --- linux-2.4.24.org/arch/sparc64/config.in     2004-01-05 18:40:09.493667496 +0100
3745 +++ linux-2.4.24/arch/sparc64/config.in 2004-01-05 18:43:04.671036488 +0100
3746 @@ -318,3 +318,11 @@
3747  
3748  source crypto/Config.in
3749  source lib/Config.in
3750 +
3751 +mainmenu_option next_comment
3752 +comment 'Grsecurity'
3753 +bool 'Grsecurity' CONFIG_GRKERNSEC
3754 +if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3755 +       source grsecurity/Config.in
3756 +fi
3757 +endmenu
3758 diff -urN linux-2.4.24.org/arch/sparc64/kernel/ioctl32.c linux-2.4.24/arch/sparc64/kernel/ioctl32.c
3759 --- linux-2.4.24.org/arch/sparc64/kernel/ioctl32.c      2004-01-05 18:40:10.999438584 +0100
3760 +++ linux-2.4.24/arch/sparc64/kernel/ioctl32.c  2004-01-05 18:43:04.747024936 +0100
3761 @@ -2047,7 +2047,11 @@
3762          * To have permissions to do most of the vt ioctls, we either have
3763          * to be the owner of the tty, or super-user.
3764          */
3765 +#ifdef CONFIG_GRKERNSEC
3766 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3767 +#else
3768         if (current->tty == tty || suser())
3769 +#endif
3770                 return 1;
3771         return 0;                                                    
3772  }
3773 diff -urN linux-2.4.24.org/arch/sparc64/kernel/itlb_base.S linux-2.4.24/arch/sparc64/kernel/itlb_base.S
3774 --- linux-2.4.24.org/arch/sparc64/kernel/itlb_base.S    2004-01-05 18:40:11.389379304 +0100
3775 +++ linux-2.4.24/arch/sparc64/kernel/itlb_base.S        2004-01-05 18:43:04.772021136 +0100
3776 @@ -41,7 +41,9 @@
3777         CREATE_VPTE_OFFSET2(%g4, %g6)                   ! Create VPTE offset
3778         ldxa            [%g3 + %g6] ASI_P, %g5          ! Load VPTE
3779  1:     brgez,pn        %g5, 3f                         ! Not valid, branch out
3780 -        nop                                            ! Delay-slot
3781 +       and             %g5, _PAGE_EXEC, %g4
3782 +       brz,pn          %g4, 3f                         ! Not executable, branch out
3783 +       nop                                             ! Delay-slot
3784  2:     stxa            %g5, [%g0] ASI_ITLB_DATA_IN     ! Load PTE into TLB
3785         retry                                           ! Trap return
3786  3:     rdpr            %pstate, %g4                    ! Move into alternate globals
3787 @@ -74,8 +76,6 @@
3788         nop
3789         nop
3790         nop
3791 -       nop
3792 -       nop
3793         CREATE_VPTE_NOP
3794  
3795  #undef CREATE_VPTE_OFFSET1
3796 diff -urN linux-2.4.24.org/arch/sparc64/kernel/ptrace.c linux-2.4.24/arch/sparc64/kernel/ptrace.c
3797 --- linux-2.4.24.org/arch/sparc64/kernel/ptrace.c       2004-01-05 18:40:11.831312120 +0100
3798 +++ linux-2.4.24/arch/sparc64/kernel/ptrace.c   2004-01-05 18:43:04.776020528 +0100
3799 @@ -18,6 +18,7 @@
3800  #include <linux/user.h>
3801  #include <linux/smp.h>
3802  #include <linux/smp_lock.h>
3803 +#include <linux/grsecurity.h>
3804  
3805  #include <asm/asi.h>
3806  #include <asm/pgtable.h>
3807 @@ -161,6 +162,11 @@
3808                 goto out;
3809         }
3810  
3811 +       if (gr_handle_ptrace(child, (long)request)) {
3812 +               pt_error_return(regs, EPERM);
3813 +               goto out_tsk;
3814 +       }
3815 +
3816         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3817             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3818                 if (ptrace_attach(child)) {
3819 diff -urN linux-2.4.24.org/arch/sparc64/kernel/sys_sparc32.c linux-2.4.24/arch/sparc64/kernel/sys_sparc32.c
3820 --- linux-2.4.24.org/arch/sparc64/kernel/sys_sparc32.c  2004-01-05 18:40:12.807163768 +0100
3821 +++ linux-2.4.24/arch/sparc64/kernel/sys_sparc32.c      2004-01-05 18:43:04.820013840 +0100
3822 @@ -52,6 +52,8 @@
3823  #include <linux/sysctl.h>
3824  #include <linux/dnotify.h>
3825  #include <linux/netfilter_ipv4/ip_tables.h>
3826 +#include <linux/random.h>
3827 +#include <linux/grsecurity.h>
3828  
3829  #include <asm/types.h>
3830  #include <asm/ipc.h>
3831 @@ -3235,8 +3237,18 @@
3832         struct file * file;
3833         int retval;
3834         int i;
3835 +#ifdef CONFIG_GRKERNSEC
3836 +       struct file *old_exec_file;
3837 +       struct acl_subject_label *old_acl;
3838 +       struct rlimit old_rlim[RLIM_NLIMITS];
3839 +#endif
3840  
3841         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3842 +
3843 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
3844 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
3845 +#endif
3846 +
3847         memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3848  
3849         file = open_exec(filename);
3850 @@ -3245,6 +3257,20 @@
3851         if (IS_ERR(file))
3852                 return retval;
3853  
3854 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
3855 +
3856 +       if (gr_handle_nproc()) {
3857 +               allow_write_access(file);
3858 +               fput(file);
3859 +               return -EAGAIN;
3860 +       }
3861 +
3862 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
3863 +               allow_write_access(file);
3864 +               fput(file);
3865 +               return -EACCES;
3866 +       }
3867 +
3868         bprm.file = file;
3869         bprm.filename = filename;
3870         bprm.sh_bang = 0;
3871 @@ -3265,11 +3291,24 @@
3872         if (retval < 0)
3873                 goto out;
3874         
3875 +       if(!gr_tpe_allow(file)) {
3876 +               retval = -EACCES;
3877 +               goto out;
3878 +       }
3879 +
3880 +       if (gr_check_crash_exec(file)) {
3881 +               retval = -EACCES;
3882 +               goto out;
3883 +       }
3884 +
3885         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3886         if (retval < 0)
3887                 goto out;
3888  
3889         bprm.exec = bprm.p;
3890 +
3891 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
3892 +
3893         retval = copy_strings32(bprm.envc, envp, &bprm);
3894         if (retval < 0)
3895                 goto out;
3896 @@ -3278,11 +3317,32 @@
3897         if (retval < 0)
3898                 goto out;
3899  
3900 +#ifdef CONFIG_GRKERNSEC
3901 +       old_acl = current->acl;
3902 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
3903 +       old_exec_file = current->exec_file;
3904 +       get_file(file);
3905 +       current->exec_file = file;
3906 +#endif
3907 +
3908 +        gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
3909 +
3910         retval = search_binary_handler(&bprm, regs);
3911 -       if (retval >= 0)
3912 +       if (retval >= 0) {
3913 +#ifdef CONFIG_GRKERNSEC
3914 +               if (old_exec_file)
3915 +                       fput(old_exec_file);
3916 +#endif
3917                 /* execve success */
3918                 return retval;
3919 +       }
3920  
3921 +#ifdef CONFIG_GRKERNSEC
3922 +       current->acl = old_acl;
3923 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
3924 +       fput(current->exec_file);
3925 +       current->exec_file = old_exec_file;
3926 +#endif
3927  out:
3928         /* Something went wrong, return the inode and free the argument pages*/
3929         allow_write_access(bprm.file);
3930 diff -urN linux-2.4.24.org/arch/sparc64/kernel/sys_sparc.c linux-2.4.24/arch/sparc64/kernel/sys_sparc.c
3931 --- linux-2.4.24.org/arch/sparc64/kernel/sys_sparc.c    2004-01-05 18:40:12.299240984 +0100
3932 +++ linux-2.4.24/arch/sparc64/kernel/sys_sparc.c        2004-01-05 18:43:04.787018856 +0100
3933 @@ -24,6 +24,7 @@
3934  #include <linux/slab.h>
3935  #include <linux/ipc.h>
3936  #include <linux/personality.h>
3937 +#include <linux/grsecurity.h>
3938  
3939  #include <asm/uaccess.h>
3940  #include <asm/ipc.h>
3941 @@ -63,6 +64,13 @@
3942                 task_size = 0xf0000000UL;
3943         if (len > task_size || len > -PAGE_OFFSET)
3944                 return -ENOMEM;
3945 +
3946 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3947 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3948 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3949 +       else
3950 +#endif
3951 +
3952         if (!addr)
3953                 addr = TASK_UNMAPPED_BASE;
3954  
3955 @@ -289,11 +297,22 @@
3956         struct file * file = NULL;
3957         unsigned long retval = -EBADF;
3958  
3959 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3960 +       if (flags & MAP_MIRROR)
3961 +               return -EINVAL;
3962 +#endif
3963 +
3964         if (!(flags & MAP_ANONYMOUS)) {
3965                 file = fget(fd);
3966                 if (!file)
3967                         goto out;
3968         }
3969 +
3970 +       if (gr_handle_mmap(file, prot)) {
3971 +               retval = -EACCES;
3972 +               goto out_putf;
3973 +       }
3974 +
3975         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3976         len = PAGE_ALIGN(len);
3977         retval = -EINVAL;
3978 diff -urN linux-2.4.24.org/arch/sparc64/kernel/sys_sunos32.c linux-2.4.24/arch/sparc64/kernel/sys_sunos32.c
3979 --- linux-2.4.24.org/arch/sparc64/kernel/sys_sunos32.c  2004-01-05 18:40:11.854308624 +0100
3980 +++ linux-2.4.24/arch/sparc64/kernel/sys_sunos32.c      2004-01-05 18:43:04.862007456 +0100
3981 @@ -68,6 +68,11 @@
3982         struct file *file = NULL;
3983         unsigned long retval, ret_type;
3984  
3985 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3986 +       if (flags & MAP_MIRROR)
3987 +               return -EINVAL;
3988 +#endif
3989 +
3990         if(flags & MAP_NORESERVE) {
3991                 static int cnt;
3992                 if (cnt++ < 10)
3993 diff -urN linux-2.4.24.org/arch/sparc64/mm/fault.c linux-2.4.24/arch/sparc64/mm/fault.c
3994 --- linux-2.4.24.org/arch/sparc64/mm/fault.c    2004-01-05 18:40:08.687790008 +0100
3995 +++ linux-2.4.24/arch/sparc64/mm/fault.c        2004-01-05 18:43:04.934996360 +0100
3996 @@ -16,6 +16,9 @@
3997  #include <linux/smp_lock.h>
3998  #include <linux/init.h>
3999  #include <linux/interrupt.h>
4000 +#include <linux/slab.h>
4001 +#include <linux/pagemap.h>
4002 +#include <linux/compiler.h>
4003  
4004  #include <asm/page.h>
4005  #include <asm/pgtable.h>
4006 @@ -299,6 +302,360 @@
4007         unhandled_fault (address, current, regs);
4008  }
4009  
4010 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
4011 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4012 +static void pax_emuplt_close(struct vm_area_struct * vma)
4013 +{
4014 +       vma->vm_mm->call_dl_resolve = 0UL;
4015 +}
4016 +
4017 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
4018 +{
4019 +       struct page* page;
4020 +       unsigned int *kaddr;
4021 +
4022 +       page = alloc_page(GFP_HIGHUSER);
4023 +       if (!page)
4024 +               return page;
4025 +
4026 +       kaddr = kmap(page);
4027 +       memset(kaddr, 0, PAGE_SIZE);
4028 +       kaddr[0] = 0x9DE3BFA8U; /* save */
4029 +       flush_dcache_page(page);
4030 +       kunmap(page);
4031 +       return page;
4032 +}
4033 +
4034 +static struct vm_operations_struct pax_vm_ops = {
4035 +       close:          pax_emuplt_close,
4036 +       nopage:         pax_emuplt_nopage,
4037 +};
4038 +
4039 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4040 +{
4041 +       vma->vm_mm = current->mm;
4042 +       vma->vm_start = addr;
4043 +       vma->vm_end = addr + PAGE_SIZE;
4044 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4045 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
4046 +       vma->vm_ops = &pax_vm_ops;
4047 +       vma->vm_pgoff = 0UL; 
4048 +       vma->vm_file = NULL;
4049 +       vma->vm_private_data = NULL;
4050 +       insert_vm_struct(current->mm, vma);
4051 +       ++current->mm->total_vm;
4052 +}
4053 +#endif
4054 +
4055 +/*
4056 + * PaX: decide what to do with offenders (regs->tpc = fault address)
4057 + *
4058 + * returns 1 when task should be killed
4059 + *         2 when patched PLT trampoline was detected
4060 + *         3 when unpatched PLT trampoline was detected
4061 + *        4 when legitimate ET_EXEC was detected
4062 + */
4063 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4064 +{
4065 +       int err;
4066 +
4067 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4068 +       if (current->flags & PF_PAX_RANDEXEC) {
4069 +               if (regs->tpc >= current->mm->start_code &&
4070 +                   regs->tpc < current->mm->end_code)
4071 +               {
4072 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
4073 +                               return 1;
4074 +
4075 +                       regs->tpc += current->mm->delta_exec;
4076 +                       if (regs->tnpc >= current->mm->start_code &&
4077 +                           regs->tnpc < current->mm->end_code)
4078 +                               regs->tnpc += current->mm->delta_exec;
4079 +                       return 4;
4080 +               }
4081 +               if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
4082 +                   regs->tpc < current->mm->end_code + current->mm->delta_exec)
4083 +               {
4084 +                       regs->tpc -= current->mm->delta_exec;
4085 +                       if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
4086 +                           regs->tnpc < current->mm->end_code + current->mm->delta_exec)
4087 +                               regs->tnpc -= current->mm->delta_exec;
4088 +               }
4089 +       }
4090 +#endif
4091 +
4092 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4093 +       do { /* PaX: patched PLT emulation #1 */
4094 +               unsigned int sethi1, sethi2, jmpl;
4095 +
4096 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4097 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4098 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
4099 +
4100 +               if (err)
4101 +                       break;
4102 +
4103 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4104 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
4105 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
4106 +               {
4107 +                       unsigned long addr;
4108 +
4109 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4110 +                       addr = regs->u_regs[UREG_G1];
4111 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4112 +                       regs->tpc = addr;
4113 +                       regs->tnpc = addr+4;
4114 +                       return 2;
4115 +               }
4116 +       } while (0);
4117 +
4118 +       { /* PaX: patched PLT emulation #2 */
4119 +               unsigned int ba;
4120 +
4121 +               err = get_user(ba, (unsigned int*)regs->tpc);
4122 +
4123 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4124 +                       unsigned long addr;
4125 +
4126 +                       addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL);
4127 +                       regs->tpc = addr;
4128 +                       regs->tnpc = addr+4;
4129 +                       return 2;
4130 +               }
4131 +       }
4132 +
4133 +       do { /* PaX: patched PLT emulation #3 */
4134 +               unsigned int sethi, jmpl, nop;
4135 +
4136 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4137 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
4138 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4139 +
4140 +               if (err)
4141 +                       break;
4142 +
4143 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4144 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4145 +                   nop == 0x01000000U)
4146 +               {
4147 +                       unsigned long addr;
4148 +
4149 +                       addr = (sethi & 0x003FFFFFU) << 10;
4150 +                       regs->u_regs[UREG_G1] = addr;
4151 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4152 +                       regs->tpc = addr;
4153 +                       regs->tnpc = addr+4;
4154 +                       return 2;
4155 +               }
4156 +       } while (0);
4157 +
4158 +       do { /* PaX: patched PLT emulation #4 */
4159 +               unsigned int mov1, call, mov2;
4160 +
4161 +               err = get_user(mov1, (unsigned int*)regs->tpc);
4162 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
4163 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
4164 +
4165 +               if (err)
4166 +                       break;
4167 +
4168 +               if (mov1 == 0x8210000FU &&
4169 +                   (call & 0xC0000000U) == 0x40000000U &&
4170 +                   mov2 == 0x9E100001U)
4171 +               {
4172 +                       unsigned long addr;
4173 +
4174 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4175 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4176 +                       regs->tpc = addr;
4177 +                       regs->tnpc = addr+4;
4178 +                       return 2;
4179 +               }
4180 +       } while (0);
4181 +
4182 +       do { /* PaX: patched PLT emulation #5 */
4183 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4184 +
4185 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4186 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4187 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
4188 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
4189 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
4190 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
4191 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
4192 +
4193 +               if (err)
4194 +                       break;
4195 +
4196 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4197 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4198 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
4199 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
4200 +                   sllx == 0x83287020 &&
4201 +                   jmpl == 0x81C04005U &&
4202 +                   nop == 0x01000000U)
4203 +               {
4204 +                       unsigned long addr;
4205 +
4206 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4207 +                       regs->u_regs[UREG_G1] <<= 32;
4208 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4209 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4210 +                       regs->tpc = addr;
4211 +                       regs->tnpc = addr+4;
4212 +                       return 2;
4213 +               }
4214 +       } while (0);
4215 +
4216 +       do { /* PaX: patched PLT emulation #6 */
4217 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
4218 +
4219 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4220 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4221 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
4222 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
4223 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
4224 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
4225 +
4226 +               if (err)
4227 +                       break;
4228 +
4229 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4230 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4231 +                   sllx == 0x83287020 &&
4232 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
4233 +                   jmpl == 0x81C04005U &&
4234 +                   nop == 0x01000000U)
4235 +               {
4236 +                       unsigned long addr;
4237 +
4238 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
4239 +                       regs->u_regs[UREG_G1] <<= 32;
4240 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
4241 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4242 +                       regs->tpc = addr;
4243 +                       regs->tnpc = addr+4;
4244 +                       return 2;
4245 +               }
4246 +       } while (0);
4247 +
4248 +       do { /* PaX: unpatched PLT emulation step 1 */
4249 +               unsigned int sethi, ba, nop;
4250 +
4251 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4252 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
4253 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4254 +
4255 +               if (err)
4256 +                       break;
4257 +
4258 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4259 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4260 +                   nop == 0x01000000U)
4261 +               {
4262 +                       unsigned long addr;
4263 +                       unsigned int save, call;
4264 +
4265 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
4266 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4267 +                       else
4268 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4269 +
4270 +                       err = get_user(save, (unsigned int*)addr);
4271 +                       err |= get_user(call, (unsigned int*)(addr+4));
4272 +                       err |= get_user(nop, (unsigned int*)(addr+8));
4273 +
4274 +                       if (err)
4275 +                               break;
4276 +
4277 +                       if (save == 0x9DE3BFA8U &&
4278 +                           (call & 0xC0000000U) == 0x40000000U &&
4279 +                           nop == 0x01000000U)
4280 +                       {
4281 +                               struct vm_area_struct *vma;
4282 +                               unsigned long call_dl_resolve;
4283 +
4284 +                               down_read(&current->mm->mmap_sem);
4285 +                               call_dl_resolve = current->mm->call_dl_resolve;
4286 +                               up_read(&current->mm->mmap_sem);
4287 +                               if (likely(call_dl_resolve))
4288 +                                       goto emulate;
4289 +
4290 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4291 +
4292 +                               down_write(&current->mm->mmap_sem);
4293 +                               if (current->mm->call_dl_resolve) {
4294 +                                       call_dl_resolve = current->mm->call_dl_resolve;
4295 +                                       up_write(&current->mm->mmap_sem);
4296 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4297 +                                       goto emulate;
4298 +                               }
4299 +
4300 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4301 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4302 +                                       up_write(&current->mm->mmap_sem);
4303 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4304 +                                       return 1;
4305 +                               }
4306 +
4307 +                               pax_insert_vma(vma, call_dl_resolve);
4308 +                               current->mm->call_dl_resolve = call_dl_resolve;
4309 +                               up_write(&current->mm->mmap_sem);
4310 +
4311 +emulate:
4312 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4313 +                               regs->tpc = call_dl_resolve;
4314 +                               regs->tnpc = addr+4;
4315 +                               return 3;
4316 +                       }
4317 +               }
4318 +       } while (0);
4319 +
4320 +       do { /* PaX: unpatched PLT emulation step 2 */
4321 +               unsigned int save, call, nop;
4322 +
4323 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
4324 +               err |= get_user(call, (unsigned int*)regs->tpc);
4325 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
4326 +               if (err)
4327 +                       break;
4328 +
4329 +               if (save == 0x9DE3BFA8U &&
4330 +                   (call & 0xC0000000U) == 0x40000000U &&
4331 +                   nop == 0x01000000U)
4332 +               {
4333 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4334 +
4335 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
4336 +                       regs->tpc = dl_resolve;
4337 +                       regs->tnpc = dl_resolve+4;
4338 +                       return 3;
4339 +               }
4340 +       } while (0);
4341 +#endif
4342 +
4343 +       return 1;
4344 +}
4345 +
4346 +void pax_report_insns(void *pc)
4347 +{
4348 +       unsigned long i;
4349 +
4350 +       printk(KERN_ERR "PAX: bytes at PC: ");
4351 +       for (i = 0; i < 5; i++) {
4352 +               unsigned int c;
4353 +               if (get_user(c, (unsigned int*)pc+i)) {
4354 +                       printk("<invalid address>.");
4355 +                       break;
4356 +               }
4357 +               printk("%08x ", c);
4358 +       }
4359 +       printk("\n");
4360 +}
4361 +#endif  
4362 +
4363 +
4364  asmlinkage void do_sparc64_fault(struct pt_regs *regs)
4365  {
4366         struct mm_struct *mm = current->mm;
4367 @@ -338,6 +695,7 @@
4368  
4369         if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
4370                 regs->tpc &= 0xffffffff;
4371 +               regs->tnpc &= 0xffffffff;
4372                 address &= 0xffffffff;
4373         }
4374  
4375 @@ -346,6 +704,34 @@
4376         if (!vma)
4377                 goto bad_area;
4378  
4379 +       /* PaX: detect ITLB misses on non-exec pages */
4380 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
4381 +       if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address && 
4382 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
4383 +       {
4384 +               if (address != regs->tpc)
4385 +                       goto good_area;
4386 +
4387 +               up_read(&mm->mmap_sem);
4388 +               switch (pax_handle_fetch_fault(regs)) {
4389 +
4390 +#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4391 +               case 2:
4392 +               case 3:
4393 +                       goto fault_done;
4394 +#endif
4395 +
4396 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4397 +               case 4:
4398 +                       goto fault_done;
4399 +#endif
4400 +
4401 +               }
4402 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
4403 +               do_exit(SIGKILL);
4404 +       }
4405 +#endif
4406 +
4407         /* Pure DTLB misses do not tell us whether the fault causing
4408          * load/store/atomic was a write or not, it only says that there
4409          * was no match.  So in such a case we (carefully) read the
4410 diff -urN linux-2.4.24.org/arch/sparc64/solaris/misc.c linux-2.4.24/arch/sparc64/solaris/misc.c
4411 --- linux-2.4.24.org/arch/sparc64/solaris/misc.c        2004-01-05 18:40:09.637645608 +0100
4412 +++ linux-2.4.24/arch/sparc64/solaris/misc.c    2004-01-05 18:43:04.954993320 +0100
4413 @@ -54,6 +54,11 @@
4414         struct file *file = NULL;
4415         unsigned long retval, ret_type;
4416  
4417 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4418 +       if (flags & MAP_MIRROR)
4419 +               return -EINVAL;
4420 +#endif
4421 +
4422         /* Do we need it here? */
4423         set_personality(PER_SVR4);
4424         if (flags & MAP_NORESERVE) {
4425 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
4426 --- linux-2.4.24.org/arch/x86_64/ia32/ia32_ioctl.c      2004-01-05 18:40:19.560137160 +0100
4427 +++ linux-2.4.24/arch/x86_64/ia32/ia32_ioctl.c  2004-01-05 18:43:04.992987544 +0100
4428 @@ -1933,7 +1933,11 @@
4429          * To have permissions to do most of the vt ioctls, we either have
4430          * to be the owner of the tty, or super-user.
4431          */
4432 +#ifdef CONFIG_GRKERNSEC
4433 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
4434 +#else
4435         if (current->tty == tty || suser())
4436 +#endif
4437                 return 1;
4438         return 0;                                                    
4439  }
4440 diff -urN linux-2.4.24.org/Documentation/Configure.help linux-2.4.24/Documentation/Configure.help
4441 --- linux-2.4.24.org/Documentation/Configure.help       2004-01-05 18:41:04.318332880 +0100
4442 +++ linux-2.4.24/Documentation/Configure.help   2004-01-05 18:43:03.254251872 +0100
4443 @@ -2984,6 +2984,20 @@
4444    If you want to compile it as a module, say M here and read
4445    Documentation/modules.txt.  If unsure, say `N'.
4446  
4447 +stealth networking support
4448 +CONFIG_IP_NF_MATCH_STEALTH
4449 +  Enabling this option will drop all syn packets coming to unserved tcp
4450 +  ports as well as all packets coming to unserved udp ports.  If you
4451 +  are using your system to route any type of packets (ie. via NAT)
4452 +  you should put this module at the end of your ruleset, since it will 
4453 +  drop packets that aren't going to ports that are listening on your 
4454 +  machine itself, it doesn't take into account that the packet might be 
4455 +  destined for someone on your internal network if you're using NAT for 
4456 +  instance.
4457 +
4458 +  If you want to compile it as a module, say M here and read
4459 +  Documentation/modules.txt.  If unsure, say `N'.
4460 +
4461  MAC address match support
4462  CONFIG_IP_NF_MATCH_MAC
4463    MAC matching allows you to match packets based on the source
4464 @@ -24213,6 +24227,897 @@
4465  
4466    "Area6" will work for most boards. For ADX, select "Area5".
4467  
4468 +Grsecurity
4469 +CONFIG_GRKERNSEC
4470 +  If you say Y here, you will be able to configure many features that
4471 +  will enhance the security of your system.  It is highly recommended
4472 +  that you say Y here and read through the help for each option so
4473 +  you fully understand the features and can evaluate their usefulness
4474 +  for your machine.
4475 +
4476 +Additional security levels
4477 +CONFIG_GRKERNSEC_LOW
4478 +
4479 +  Low additional security
4480 +  -----------------------------------------------------------------------
4481 +  If you choose this option, several of the grsecurity options will
4482 +  be enabled that will give you greater protection against a number
4483 +  of attacks, while assuring that none of your software will have any 
4484 +  conflicts with the additional security measures.  If you run a lot of 
4485 +  unusual software, or you are having problems with the higher security 
4486 +  levels, you should say Y here.  With this option, the following features
4487 +  are enabled:
4488 +  
4489 +  linking restrictions
4490 +  fifo restrictions
4491 +  random pids
4492 +  enforcing nproc on execve()
4493 +  restricted dmesg
4494 +  random ip ids
4495 +  enforced chdir("/") on chroot
4496 +
4497 +  Medium additional security
4498 +  -----------------------------------------------------------------------
4499 +  If you say Y here, several features in addition to those included in the 
4500 +  low additional security level will be enabled.  These features provide
4501 +  even more security to your system, though in rare cases they may
4502 +  be incompatible with very old or poorly written software.  If you 
4503 +  enable this option, make sure that your auth service (identd) is 
4504 +  running as gid 10 (usually group wheel). With this option the following 
4505 +  features (in addition to those provided in the low additional security 
4506 +  level) will be enabled:
4507 +
4508 +  random tcp source ports
4509 +  failed fork logging
4510 +  time change logging
4511 +  signal logging
4512 +  deny mounts in chroot
4513 +  deny double chrooting
4514 +  deny sysctl writes in chroot
4515 +  deny mknod in chroot
4516 +  deny access to abstract AF_UNIX sockets out of chroot
4517 +  deny pivot_root in chroot
4518 +  denied writes of /dev/kmem, /dev/mem, and /dev/port
4519 +  /proc restrictions with special gid set to 10 (usually wheel)
4520 +  address space layout randomization
4521 +  removal of addresses from /proc/<pid>/[maps|stat]
4522 +
4523 +  High additional security
4524 +  ----------------------------------------------------------------------
4525 +  If you say Y here, many of the features of grsecurity will be enabled,
4526 +  that will protect you against many kinds of attacks against
4527 +  your system.  The heightened security comes at a cost of an 
4528 +  increased chance of incompatibilities with rare software on your 
4529 +  machine.  Since this security level enables PaX, you should view 
4530 +  <http://pageexec.virtualave.net> and read about the PaX project.  While 
4531 +  you are there, download chpax and run it on binaries that cause 
4532 +  problems with PaX.  Also remember that since the /proc restrictions are 
4533 +  enabled, you must run your identd as group wheel (gid 10).  
4534 +  This security level enables the following features in addition to those
4535 +  listed in the low and medium security levels:
4536 +
4537 +  additional /proc restrictions
4538 +  chmod restrictions in chroot
4539 +  no signals, ptrace, or viewing processes outside of chroot
4540 +  capability restrictions in chroot
4541 +  deny fchdir out of chroot
4542 +  priority restrictions in chroot
4543 +  segmentation-based implementation of PaX
4544 +  mprotect restrictions
4545 +  kernel stack randomization
4546 +  mount/unmount/remount logging
4547 +  kernel symbol hiding
4548 +
4549 +Customized additional security
4550 +CONFIG_GRKERNSEC_CUSTOM
4551 +  If you say Y here, you will be able to configure every grsecurity 
4552 +  option, which allows you to enable many more features that aren't 
4553 +  covered in the basic security levels.  These additional features include 
4554 +  TPE, socket restrictions, and the sysctl system for grsecurity.  It is 
4555 +  advised that you read through the help for each option to determine its 
4556 +  usefulness in your situation.
4557 +
4558 +Enforce non-executable pages
4559 +CONFIG_GRKERNSEC_PAX_NOEXEC
4560 +  By design some architectures do not allow for protecting memory
4561 +  pages against execution or even if they do, Linux does not make
4562 +  use of this feature.  In practice this means that if a page is
4563 +  readable (such as the stack or heap) it is also executable.
4564 +
4565 +  There is a well known exploit technique that makes use of this
4566 +  fact and a common programming mistake where an attacker can
4567 +  introduce code of his choice somewhere in the attacked program's
4568 +  memory (typically the stack or the heap) and then execute it.
4569 +
4570 +  If the attacked program was running with different (typically
4571 +  higher) privileges than that of the attacker, then he can elevate
4572 +  his own privilege level (e.g. get a root shell, write to files for
4573 +  which he does not have write access to, etc).
4574 +
4575 +  Enabling this option will let you choose from various features
4576 +  that prevent the injection and execution of 'foreign' code in
4577 +  a program.
4578 +
4579 +  This will also break programs that rely on the old behaviour and
4580 +  expect that dynamically allocated memory via the malloc() family
4581 +  of functions is executable (which it is not).  Notable examples
4582 +  are the XFree86 4.x server, the java runtime and wine.
4583 +
4584 +  NOTE: you can use the 'chpax' utility to enable/disable this
4585 +  feature on a per file basis.  chpax is available at
4586 +  <http://pageexec.virtualave.net>
4587 +
4588 +Paging based non-executable pages
4589 +CONFIG_GRKERNSEC_PAX_PAGEEXEC
4590 +  This implementation is based on the paging feature of the CPU.
4591 +  On i386 it has a variable performance impact on applications
4592 +  depending on their memory usage pattern.  You should carefully
4593 +  test your applications before using this feature in production.
4594 +  On alpha, parisc, sparc and sparc64 there is no performance
4595 +  impact.  On ppc there is a slight performance impact.
4596 +
4597 +Segmentation based non-executable pages
4598 +CONFIG_GRKERNSEC_PAX_SEGMEXEC
4599 +  This implementation is based on the segmentation feature of the
4600 +  CPU and has little performance impact, however applications will
4601 +  be limited to a 1.5 GB address space instead of the normal 3 GB.
4602 +
4603 +Emulate trampolines
4604 +CONFIG_GRKERNSEC_PAX_EMUTRAMP
4605 +  There are some programs and libraries that for one reason or
4606 +  another attempt to execute special small code snippets from
4607 +  non-executable memory pages.  Most notable examples are the
4608 +  signal handler return code generated by the kernel itself and
4609 +  the GCC trampolines.
4610 +
4611 +  If you enabled CONFIG_GRKERNSEC_PAX_PAGEEXEC or 
4612 +  CONFIG_GRKERNSEC_PAX_SEGMEXEC then such programs will no longer
4613 +  work under your kernel.
4614 +
4615 +  As a remedy you can say Y here and use the 'chpax' utility to
4616 +  enable trampoline emulation for the affected programs yet still
4617 +  have the protection provided by the non-executable pages.
4618 +
4619 +  On parisc and ppc you MUST enable this option and EMUSIGRT as
4620 +  well, otherwise your system will not even boot.
4621 +
4622 +  Alternatively you can say N here and use the 'chpax' utility
4623 +  to disable CONFIG_GRKERNSEC_PAX_PAGEEXEC and 
4624 +  CONFIG_GRKERNSEC_PAX_SEGMEXEC for the affected files.
4625 +
4626 +  NOTE: enabling this feature *may* open up a loophole in the
4627 +  protection provided by non-executable pages that an attacker
4628 +  could abuse.  Therefore the best solution is to not have any
4629 +  files on your system that would require this option.  This can
4630 +  be achieved by not using libc5 (which relies on the kernel
4631 +  signal handler return code) and not using or rewriting programs
4632 +  that make use of the nested function implementation of GCC.
4633 +  Skilled users can just fix GCC itself so that it implements
4634 +  nested function calls in a way that does not interfere with PaX.
4635 +
4636 +Automatically emulate sigreturn trampolines
4637 +CONFIG_GRKERNSEC_PAX_EMUSIGRT
4638 +  Enabling this option will have the kernel automatically detect
4639 +  and emulate signal return trampolines executing on the stack
4640 +  that would otherwise lead to task termination.
4641 +
4642 +  This solution is intended as a temporary one for users with
4643 +  legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
4644 +  Modula-3 runtime, etc) or executables linked to such, basically
4645 +  everything that does not specify its own SA_RESTORER function in
4646 +  normal executable memory like glibc 2.1+ does.
4647 +
4648 +  On parisc and ppc you MUST enable this option, otherwise your
4649 +  system will not even boot.
4650 +
4651 +  NOTE: this feature cannot be disabled on a per executable basis
4652 +  and since it *does* open up a loophole in the protection provided
4653 +  by non-executable pages, the best solution is to not have any
4654 +  files on your system that would require this option.
4655 +
4656 +Restrict mprotect()
4657 +CONFIG_GRKERNSEC_PAX_MPROTECT
4658 +  Enabling this option will prevent programs from
4659 +   - changing the executable status of memory pages that were
4660 +     not originally created as executable,
4661 +   - making read-only executable pages writable again,
4662 +   - creating executable pages from anonymous memory.
4663 +
4664 +  You should say Y here to complete the protection provided by
4665 +  the enforcement of non-executable pages.
4666 +
4667 +  NOTE: you can use the 'chpax' utility to control this
4668 +  feature on a per file basis. chpax is available at
4669 +  <http://pageexec.virtualave.net>
4670 +
4671 +Disallow ELF text relocations
4672 +CONFIG_GRKERNSEC_PAX_NOELFRELOCS
4673 +  Non-executable pages and mprotect() restrictions are effective
4674 +  in preventing the introduction of new executable code into an
4675 +  attacked task's address space.  There remain only two venues
4676 +  for this kind of attack: if the attacker can execute already
4677 +  existing code in the attacked task then he can either have it
4678 +  create and mmap() a file containing his code or have it mmap()
4679 +  an already existing ELF library that does not have position
4680 +  independent code in it and use mprotect() on it to make it
4681 +  writable and copy his code there.  While protecting against
4682 +  the former approach is beyond PaX, the latter can be prevented
4683 +  by having only PIC ELF libraries on one's system (which do not
4684 +  need to relocate their code).  If you are sure this is your case,
4685 +  then enable this option otherwise be careful as you may not even
4686 +  be able to boot or log on your system (for example, some PAM
4687 +  modules are erroneously compiled as non-PIC by default).
4688 +
4689 +  NOTE: if you are using dynamic ELF executables (as suggested
4690 +  when using ASLR) then you must have made sure that you linked
4691 +  your files using the PIC version of crt1 (the et_dyn.zip package
4692 +  referenced there has already been updated to support this).
4693 +
4694 +Enforce non-executable kernel pages
4695 +CONFIG_GRKERNSEC_PAX_KERNEXEC
4696 +  This is the kernel land equivalent of PAGEEXEC and MPROTECT,
4697 +  that is, enabling this option will make it harder to inject
4698 +  and execute 'foreign' code in kernel memory itself.
4699 +
4700 +Address Space Layout Randomization
4701 +CONFIG_GRKERNSEC_PAX_ASLR
4702 +  Many if not most exploit techniques rely on the knowledge of
4703 +  certain addresses in the attacked program.  The following options
4704 +  will allow the kernel to apply a certain amount of randomization
4705 +  to specific parts of the program thereby forcing an attacker to
4706 +  guess them in most cases.  Any failed guess will most likely crash
4707 +  the attacked program which allows the kernel to detect such attempts
4708 +  and react on them.  PaX itself provides no reaction mechanisms,
4709 +  instead it is strongly encouraged that you make use of grsecurity's
4710 +  built-in crash detection features or develop one yourself.
4711 +
4712 +  By saying Y here you can choose to randomize the following areas:
4713 +   - top of the task's kernel stack
4714 +   - top of the task's userland stack
4715 +   - base address for mmap() requests that do not specify one
4716 +     (this includes all libraries)
4717 +   - base address of the main executable
4718 +
4719 +  It is strongly recommended to say Y here as address space layout
4720 +  randomization has negligible impact on performance yet it provides
4721 +  a very effective protection.
4722 +
4723 +  NOTE: you can use the 'chpax' utility to control most of these features
4724 +  on a per file basis.
4725 +
4726 +Randomize kernel stack base
4727 +CONFIG_GRKERNSEC_PAX_RANDKSTACK
4728 +  By saying Y here the kernel will randomize every task's kernel
4729 +  stack on every system call.  This will not only force an attacker
4730 +  to guess it but also prevent him from making use of possible
4731 +  leaked information about it.
4732 +
4733 +  Since the kernel stack is a rather scarce resource, randomization
4734 +  may cause unexpected stack overflows, therefore you should very
4735 +  carefully test your system.  Note that once enabled in the kernel
4736 +  configuration, this feature cannot be disabled on a per file basis.
4737 +
4738 +Randomize user stack base
4739 +CONFIG_GRKERNSEC_PAX_RANDUSTACK
4740 +  By saying Y here the kernel will randomize every task's userland
4741 +  stack.  The randomization is done in two steps where the second
4742 +  one may apply a big amount of shift to the top of the stack and
4743 +  cause problems for programs that want to use lots of memory (more
4744 +  than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
4745 +  For this reason the second step can be controlled by 'chpax' on
4746 +  a per file basis.
4747 +
4748 +Randomize ET_EXEC base
4749 +CONFIG_GRKERNSEC_PAX_RANDEXEC     
4750 +  By saying Y here the kernel will randomize the base address of normal
4751 +  ET_EXEC ELF executables as well.  This is accomplished by mapping the
4752 +  executable in memory in a special way which also allows for detecting
4753 +  attackers who attempt to execute its code for their purposes.  Since
4754 +  this special mapping causes performance degradation and the attack
4755 +  detection may create false alarms as well, you should carefully test
4756 +  your executables when this feature is enabled.
4757 +
4758 +  This solution is intended only as a temporary one until you relink
4759 +  your programs as a dynamic ELF file.
4760 +
4761 +  NOTE: you can use the 'chpax' utility to control this feature
4762 +  on a per file basis.
4763 +
4764 +Allow ELF ET_EXEC text relocations
4765 +CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
4766 +  On some architectures like the alpha there are incorrectly
4767 +  created applications that require text relocations and would
4768 +  not work without enabling this option.  If you are an alpha
4769 +  user, you should enable this option and disable it once you
4770 +  have made sure that none of your applications need it.
4771 +
4772 +Automatically emulate ELF PLT
4773 +CONFIG_GRKERNSEC_PAX_EMUPLT
4774 +  Enabling this option will have the kernel automatically detect
4775 +  and emulate the Procedure Linkage Table entries in ELF files.
4776 +  On some architectures such entries are in writable memory, and
4777 +  become non-executable leading to task termination.  Therefore
4778 +  it is mandatory that you enable this option on alpha, parisc, ppc,
4779 +  sparc and sparc64, otherwise your system would not even boot.
4780 +
4781 +  NOTE: this feature *does* open up a loophole in the protection
4782 +  provided by the non-executable pages, therefore the proper
4783 +  solution is to modify the toolchain to produce a PLT that does
4784 +  not need to be writable.
4785 +
4786 +Honor PT_GNU_STACK
4787 +CONFIG_GRKERNSEC_PAX_PT_GNU_STACK
4788 +  Enabling this option will have the kernel honor the PT_GNU_STACK
4789 +  ELF executable marking in the sense that it will automatically
4790 +  turn on EMUTRAMP for processes that need an executable stack
4791 +  due to the use of nested function trampolines.
4792 +
4793 +  This option should only be considered by users whose entire system
4794 +  has support for PT_GNU_STACK, otherwise it may unnecessarily enable
4795 +  EMUTRAMP for all userland applications.
4796 +
4797 +  NOTE: the same precautions apply as with EMUTRAMP however it is
4798 +  still the preferred solution to chpax because it places the burden
4799 +  of marking executables on the package/distribution makers and not
4800 +  end users.
4801 +
4802 +Honor PT_GNU_HEAP
4803 +CONFIG_GRKERNSEC_PAX_PT_GNU_HEAP
4804 +  Enabling this option will have the kernel honor the PT_GNU_HEAP
4805 +  ELF executable marking in the sense that it will automatically
4806 +  turn off MPROTECT for processes that need an executable heap
4807 +  due to runtime code generation.
4808 +
4809 +  This option should only be considered by users whose entire system
4810 +  has support for PT_GNU_HEAP.
4811 +
4812 +  Note: this is the preferred solution to chpax because it places
4813 +  the burden of marking executables on the package/distribution
4814 +  makers and not end users.
4815 +
4816 +Randomize mmap() base
4817 +CONFIG_GRKERNSEC_PAX_RANDMMAP
4818 +  By saying Y here the kernel will use a randomized base address for
4819 +  mmap() requests that do not specify one themselves.  As a result
4820 +  all dynamically loaded libraries will appear at random addresses
4821 +  and therefore be harder to exploit by a technique where an attacker
4822 +  attempts to execute library code for his purposes (e.g. spawn a
4823 +  shell from an exploited program that is running at an elevated
4824 +  privilege level).
4825 +
4826 +  Furthermore, if a program is relinked as a dynamic ELF file, its
4827 +  base address will be randomized as well, completing the full
4828 +  randomization of the address space layout.  Attacking such programs
4829 +  becomes a guess game.  You can find an example of doing this at
4830 +  <http://pageexec.virtualave.net/et_dyn.zip> and practical samples at
4831 +  <http://www.grsecurity.net/grsec-gcc-specs.tar.gz> .
4832 +
4833 +  NOTE: you can use the 'chpax' utility to control this feature
4834 +  on a per file basis.
4835 +
4836 +Deny writing to /dev/kmem, /dev/mem, and /dev/port
4837 +CONFIG_GRKERNSEC_KMEM
4838 +  If you say Y here, /dev/kmem and /dev/mem won't be allowed to
4839 +  be written to via mmap or otherwise to modify the running kernel.
4840 +  /dev/port will also not be allowed to be opened. If you have module
4841 +  support disabled, enabling this will close up four ways that are
4842 +  currently used  to insert malicious code into the running kernel.
4843 +  Even with all these features enabled, we still highly recommend that
4844 +  you use the ACL system, as it is still possible for an attacker to 
4845 +  modify the running kernel through privileged I/O granted by ioperm/iopl.
4846 +  If you are not using XFree86, you may be able to stop this additional
4847 +  case by enabling the 'Disable privileged I/O' option. Though nothing
4848 +  legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
4849 +  but only to video memory, which is the only writing we allow in this
4850 +  case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
4851 +  not be allowed to mprotect it with PROT_WRITE later.
4852 +  Enabling this feature could make certain apps like VMWare stop working,
4853 +  as they need to write to other locations in /dev/mem.
4854 +  It is highly recommended that you say Y here if you meet all the 
4855 +  conditions above.
4856 +
4857 +Disable privileged I/O
4858 +CONFIG_GRKERNSEC_IO
4859 +  If you say Y here, all ioperm and iopl calls will return an error.
4860 +  Ioperm and iopl can be used to modify the running kernel.
4861 +  Unfortunately, some programs need this access to operate properly,
4862 +  the most notable of which are XFree86 and hwclock.  hwclock can be
4863 +  remedied by having RTC support in the kernel, so CONFIG_RTC is
4864 +  enabled if this option is enabled, to ensure that hwclock operates
4865 +  correctly.  XFree86 still will not operate correctly with this option
4866 +  enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
4867 +  and you still want to protect your kernel against modification,
4868 +  use the ACL system.
4869 +
4870 +Hide kernel symbols
4871 +CONFIG_GRKERNSEC_HIDESYM
4872 +  If you say Y here, getting information on loaded modules, and 
4873 +  displaying all kernel symbols through a syscall will be restricted
4874 +  to users with CAP_SYS_MODULE.  This option is only effective 
4875 +  provided the following conditions are met:
4876 +  1) The kernel using grsecurity is not precompiled by some distribution
4877 +  2) You are using the ACL system and hiding other files such as your
4878 +     kernel image and System.map
4879 +  3) You have the additional /proc restrictions enabled, which removes
4880 +     /proc/kcore
4881 +  If the above conditions are met, this option will aid to provide a
4882 +  useful protection against local and remote kernel exploitation of
4883 +  overflows and arbitrary read/write vulnerabilities.
4884 +
4885 +/proc/<pid>/ipaddr support
4886 +CONFIG_GRKERNSEC_PROC_IPADDR
4887 +  If you say Y here, a new entry will be added to each /proc/<pid>
4888 +  directory that contains the IP address of the person using the task.
4889 +  The IP is carried across local TCP and AF_UNIX stream sockets.
4890 +  This information can be useful for IDS/IPSes to perform remote response
4891 +  to a local attack.  The entry is readable by only the owner of the 
4892 +  process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
4893 +  the RBAC system), and thus does not create privacy concerns.
4894 +
4895 +Proc Restrictions
4896 +CONFIG_GRKERNSEC_PROC
4897 +  If you say Y here, the permissions of the /proc filesystem
4898 +  will be altered to enhance system security and privacy.  Depending
4899 +  upon the options you choose, you can either restrict users to see
4900 +  only the processes they themselves run, or choose a group that can
4901 +  view all processes and files normally restricted to root if you choose
4902 +  the "restrict to user only" option.  NOTE: If you're running identd as 
4903 +  a non-root user, you will have to run it as the group you specify here.
4904 +
4905 +Restrict /proc to user only
4906 +CONFIG_GRKERNSEC_PROC_USER
4907 +  If you say Y here, non-root users will only be able to view their own 
4908 +  processes, and restricts them from viewing network-related information,  
4909 +  and viewing kernel symbol and module information.
4910 +
4911 +Restrict /proc to user and group
4912 +CONFIG_GRKERNSEC_PROC_USERGROUP
4913 +  If you say Y here, you will be able to select a group that will be
4914 +  able to view all processes, network-related information, and
4915 +  kernel and symbol information.  This option is useful if you want
4916 +  to run identd as a non-root user.
4917 +
4918 +Remove addresses from /proc/pid/[maps|stat]
4919 +CONFIG_GRKERNSEC_PROC_MEMMAP
4920 +  If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
4921 +  give no information about the addresses of its mappings if
4922 +  PaX features that rely on random addresses are enabled on the task.
4923 +  If you use PaX it is greatly recommended that you say Y here as it 
4924 +  closes up a hole that makes the full ASLR useless for suid 
4925 +  binaries.
4926 +
4927 +Additional proc restrictions
4928 +CONFIG_GRKERNSEC_PROC_ADD
4929 +  If you say Y here, additional restrictions will be placed on
4930 +  /proc that keep normal users from viewing cpu and device information.
4931 +
4932 +Dmesg(8) Restriction
4933 +CONFIG_GRKERNSEC_DMESG
4934 +  If you say Y here, non-root users will not be able to use dmesg(8)
4935 +  to view up to the last 4kb of messages in the kernel's log buffer.
4936 +  If the sysctl option is enabled, a sysctl option with name "dmesg" is 
4937 +  created.
4938 +
4939 +Linking restrictions
4940 +CONFIG_GRKERNSEC_LINK
4941 +  If you say Y here, /tmp race exploits will be prevented, since users
4942 +  will no longer be able to follow symlinks owned by other users in 
4943 +  world-writable +t directories (i.e. /tmp), unless the owner of the 
4944 +  symlink is the owner of the directory. users will also not be
4945 +  able to hardlink to files they do not own.  If the sysctl option is
4946 +  enabled, a sysctl option with name "linking_restrictions" is created.
4947 +
4948 +FIFO restrictions
4949 +CONFIG_GRKERNSEC_FIFO
4950 +  If you say Y here, users will not be able to write to FIFOs they don't
4951 +  own in world-writable +t directories (i.e. /tmp), unless the owner of
4952 +  the FIFO is the same owner of the directory it's held in.  If the sysctl
4953 +  option is enabled, a sysctl option with name "fifo_restrictions" is 
4954 +  created.
4955 +
4956 +Enforce RLIMIT_NPROC on execs
4957 +CONFIG_GRKERNSEC_EXECVE
4958 +  If you say Y here, users with a resource limit on processes will
4959 +  have the value checked during execve() calls.  The current system
4960 +  only checks the system limit during fork() calls.  If the sysctl option
4961 +  is enabled, a sysctl option with name "execve_limiting" is created.
4962 +
4963 +Single group for auditing
4964 +CONFIG_GRKERNSEC_AUDIT_GROUP
4965 +  If you say Y here, the exec, chdir, (un)mount, and ipc logging features
4966 +  will only operate on a group you specify.  This option is recommended
4967 +  if you only want to watch certain users instead of having a large
4968 +  amount of logs from the entire system.  If the sysctl option is enabled,
4969 +  a sysctl option with name "audit_group" is created.
4970 +
4971 +GID for auditing
4972 +CONFIG_GRKERNSEC_AUDIT_GID
4973 +  Here you can choose the GID that will be the target of kernel auditing.
4974 +  Remember to add the users you want to log to the GID specified here.
4975 +  If the sysctl option is enabled, whatever you choose here won't matter. 
4976 +  You'll have to specify the GID in your bootup script by echoing the GID 
4977 +  to the proper /proc entry.  View the help on the sysctl option for more 
4978 +  information.  If the sysctl option is enabled, a sysctl option with name 
4979 +  "audit_gid" is created.
4980 +
4981 +Chdir logging
4982 +CONFIG_GRKERNSEC_AUDIT_CHDIR
4983 +  If you say Y here, all chdir() calls will be logged.  If the sysctl 
4984 +  option is enabled, a sysctl option with name "audit_chdir" is created.
4985 +
4986 +(Un)Mount logging
4987 +CONFIG_GRKERNSEC_AUDIT_MOUNT
4988 +  If you say Y here, all mounts and unmounts will be logged.  If the 
4989 +  sysctl option is enabled, a sysctl option with name "audit_mount" is 
4990 +  created.
4991 +
4992 +IPC logging
4993 +CONFIG_GRKERNSEC_AUDIT_IPC
4994 +  If you say Y here, creation and removal of message queues, semaphores,
4995 +  and shared memory will be logged.  If the sysctl option is enabled, a
4996 +  sysctl option with name "audit_ipc" is created.
4997 +
4998 +Exec logging
4999 +CONFIG_GRKERNSEC_EXECLOG
5000 +  If you say Y here, all execve() calls will be logged (since the
5001 +  other exec*() calls are frontends to execve(), all execution
5002 +  will be logged).  Useful for shell-servers that like to keep track
5003 +  of their users.  If the sysctl option is enabled, a sysctl option with
5004 +  name "exec_logging" is created.
5005 +  WARNING: This option when enabled will produce a LOT of logs, especially
5006 +  on an active system.
5007 +
5008 +Resource logging
5009 +CONFIG_GRKERNSEC_RESLOG
5010 +  If you say Y here, all attempts to overstep resource limits will
5011 +  be logged with the resource name, the requested size, and the current
5012 +  limit.  It is highly recommended that you say Y here.
5013 +
5014 +Signal logging
5015 +CONFIG_GRKERNSEC_SIGNAL
5016 +  If you say Y here, certain important signals will be logged, such as
5017 +  SIGSEGV, which will as a result inform you of when a error in a program
5018 +  occurred, which in some cases could mean a possible exploit attempt.
5019 +  If the sysctl option is enabled, a sysctl option with name 
5020 +  "signal_logging" is created.
5021 +
5022 +Fork failure logging
5023 +CONFIG_GRKERNSEC_FORKFAIL
5024 +  If you say Y here, all failed fork() attempts will be logged.
5025 +  This could suggest a fork bomb, or someone attempting to overstep
5026 +  their process limit.  If the sysctl option is enabled, a sysctl option
5027 +  with name "forkfail_logging" is created.
5028 +
5029 +Time change logging
5030 +CONFIG_GRKERNSEC_TIME
5031 +  If you say Y here, any changes of the system clock will be logged.
5032 +  If the sysctl option is enabled, a sysctl option with name 
5033 +  "timechange_logging" is created.
5034 +
5035 +Chroot jail restrictions
5036 +CONFIG_GRKERNSEC_CHROOT
5037 +  If you say Y here, you will be able to choose several options that will
5038 +  make breaking out of a chrooted jail much more difficult.  If you
5039 +  encounter no software incompatibilities with the following options, it
5040 +  is recommended that you enable each one.
5041 +
5042 +Deny access to abstract AF_UNIX sockets out of chroot
5043 +CONFIG_GRKERNSEC_CHROOT_UNIX
5044 +  If you say Y here, processes inside a chroot will not be able to
5045 +  connect to abstract (meaning not belonging to a filesystem) Unix
5046 +  domain sockets that were bound outside of a chroot.  It is recommended
5047 +  that you say Y here.  If the sysctl option is enabled, a sysctl option
5048 +  with name "chroot_deny_unix" is created.
5049 +
5050 +Deny shmat() out of chroot
5051 +CONFIG_GRKERNSEC_CHROOT_SHMAT
5052 +  If you say Y here, processes inside a chroot will not be able to attach
5053 +  to shared memory segments that were created outside of the chroot jail.
5054 +  It is recommended that you say Y here.  If the sysctl option is enabled,
5055 +  a sysctl option with name "chroot_deny_shmat" is created.
5056 +
5057 +Protect outside processes
5058 +CONFIG_GRKERNSEC_CHROOT_FINDTASK
5059 +  If you say Y here, processes inside a chroot will not be able to
5060 +  kill, send signals with fcntl, ptrace, capget, setpgid, getpgid, 
5061 +  getsid, or view any process outside of the chroot.  If the sysctl 
5062 +  option is enabled, a sysctl option with name "chroot_findtask" is 
5063 +  created.
5064 +
5065 +Deny mounts in chroot
5066 +CONFIG_GRKERNSEC_CHROOT_MOUNT
5067 +  If you say Y here, processes inside a chroot will not be able to
5068 +  mount or remount filesystems.  If the sysctl option is enabled, a 
5069 +  sysctl option with name "chroot_deny_mount" is created.
5070 +
5071 +Deny pivot_root in chroot
5072 +CONFIG_GRKERNSEC_CHROOT_PIVOT
5073 +  If you say Y here, processes inside a chroot will not be able to use
5074 +  a function called pivot_root() that was introduced in Linux 2.3.41.  It 
5075 +  works similar to chroot in that it changes the root filesystem.  This 
5076 +  function could be misused in a chrooted process to attempt to break out 
5077 +  of the chroot, and therefore should not be allowed.  If the sysctl 
5078 +  option is enabled, a sysctl option with name "chroot_deny_pivot" is 
5079 +  created.
5080 +
5081 +Deny double-chroots
5082 +CONFIG_GRKERNSEC_CHROOT_DOUBLE
5083 +  If you say Y here, processes inside a chroot will not be able to chroot
5084 +  again.  This is a widely used method of breaking out of a chroot jail
5085 +  and should not be allowed.  If the sysctl option is enabled, a sysctl
5086 +  option with name "chroot_deny_chroot" is created.
5087 +
5088 +Deny fchdir outside of chroot
5089 +CONFIG_GRKERNSEC_CHROOT_FCHDIR
5090 +  If you say Y here, a well-known method of breaking chroots by fchdir'ing
5091 +  to a file descriptor of the chrooting process that points to a directory
5092 +  outside the filesystem will be stopped.  If the sysctl option
5093 +  is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
5094 +
5095 +Enforce chdir("/") on all chroots
5096 +CONFIG_GRKERNSEC_CHROOT_CHDIR
5097 +  If you say Y here, the current working directory of all newly-chrooted
5098 +  applications will be set to the the root directory of the chroot.
5099 +  The man page on chroot(2) states:
5100 +  Note that this call does not change  the  current  working
5101 +  directory,  so  that `.' can be outside the tree rooted at
5102 +  `/'.  In particular, the  super-user  can  escape  from  a
5103 +  `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.  
5104 +
5105 +  It is recommended that you say Y here, since it's not known to break
5106 +  any software.  If the sysctl option is enabled, a sysctl option with
5107 +  name "chroot_enforce_chdir" is created.
5108 +
5109 +Deny (f)chmod +s in chroot
5110 +CONFIG_GRKERNSEC_CHROOT_CHMOD
5111 +  If you say Y here, processes inside a chroot will not be able to chmod
5112 +  or fchmod files to make them have suid or sgid bits.  This protects 
5113 +  against another published method of breaking a chroot.  If the sysctl 
5114 +  option is enabled, a sysctl option with name "chroot_deny_chmod" is
5115 +  created.
5116 +
5117 +Deny mknod in chroot
5118 +CONFIG_GRKERNSEC_CHROOT_MKNOD
5119 +  If you say Y here, processes inside a chroot will not be allowed to
5120 +  mknod.  The problem with using mknod inside a chroot is that it
5121 +  would allow an attacker to create a device entry that is the same
5122 +  as one on the physical root of your system, which could range from
5123 +  anything from the console device to a device for your harddrive (which
5124 +  they could then use to wipe the drive or steal data).  It is recommended
5125 +  that you say Y here, unless you run into software incompatibilities.
5126 +  If the sysctl option is enabled, a sysctl option with name
5127 +  "chroot_deny_mknod" is created.
5128 +
5129 +Restrict priority changes in chroot
5130 +CONFIG_GRKERNSEC_CHROOT_NICE
5131 +  If you say Y here, processes inside a chroot will not be able to raise
5132 +  the priority of processes in the chroot, or alter the priority of 
5133 +  processes outside the chroot.  This provides more security than simply
5134 +  removing CAP_SYS_NICE from the process' capability set.  If the
5135 +  sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
5136 +  is created.
5137 +
5138 +Log all execs within chroot
5139 +CONFIG_GRKERNSEC_CHROOT_EXECLOG
5140 +  If you say Y here, all executions inside a chroot jail will be logged 
5141 +  to syslog.  This can cause a large amount of logs if certain
5142 +  applications (eg. djb's daemontools) are installed on the system, and
5143 +  is therefore left as an option.  If the sysctl option is enabled, a 
5144 +  sysctl option with name "chroot_execlog" is created.
5145 +
5146 +Deny sysctl writes in chroot
5147 +CONFIG_GRKERNSEC_CHROOT_SYSCTL
5148 +  If you say Y here, an attacker in a chroot will not be able to
5149 +  write to sysctl entries, either by sysctl(2) or through a /proc
5150 +  interface.  It is strongly recommended that you say Y here. If the
5151 +  sysctl option is enabled, a sysctl option with name 
5152 +  "chroot_deny_sysctl" is created.
5153 +
5154 +Chroot jail capability restrictions
5155 +CONFIG_GRKERNSEC_CHROOT_CAPS
5156 +  If you say Y here, the capabilities on all root processes within a
5157 +  chroot jail will be lowered to stop module insertion, raw i/o,
5158 +  system and net admin tasks, rebooting the system, modifying immutable 
5159 +  files, modifying IPC owned by another, and changing the system time.
5160 +  This is left an option because it can break some apps.  Disable this
5161 +  if your chrooted apps are having problems performing those kinds of
5162 +  tasks.  If the sysctl option is enabled, a sysctl option with
5163 +  name "chroot_caps" is created.
5164 +
5165 +Trusted path execution
5166 +CONFIG_GRKERNSEC_TPE
5167 +  If you say Y here, you will be able to choose a gid to add to the
5168 +  supplementary groups of users you want to mark as "untrusted."
5169 +  These users will not be able to execute any files that are not in
5170 +  root-owned directories writable only by root.  If the sysctl option
5171 +  is enabled, a sysctl option with name "tpe" is created.
5172 +
5173 +Group for trusted path execution
5174 +CONFIG_GRKERNSEC_TPE_GID
5175 +  Here you can choose the GID to enable trusted path protection for.
5176 +  Remember to add the users you want protection enabled for to the GID 
5177 +  specified here.  If the sysctl option is enabled, whatever you choose
5178 +  here won't matter. You'll have to specify the GID in your bootup 
5179 +  script by echoing the GID to the proper /proc entry.  View the help
5180 +  on the sysctl option for more information.  If the sysctl option is
5181 +  enabled, a sysctl option with name "tpe_gid" is created.
5182 +
5183 +Partially restrict non-root users
5184 +CONFIG_GRKERNSEC_TPE_ALL
5185 +  If you say Y here, All non-root users other than the ones in the 
5186 +  group specified in the main TPE option will only be allowed to
5187 +  execute files in directories they own that are not group or
5188 +  world-writable, or in directories owned by root and writable only by
5189 +  root.  If the sysctl option is enabled, a sysctl option with name 
5190 +  "tpe_restrict_all" is created.
5191 +
5192 +Randomized PIDs
5193 +CONFIG_GRKERNSEC_RANDPID
5194 +  If you say Y here, all PIDs created on the system will be
5195 +  pseudo-randomly generated.  This is extremely effective along
5196 +  with the /proc restrictions to disallow an attacker from guessing
5197 +  pids of daemons, etc.  PIDs are also used in some cases as part
5198 +  of a naming system for temporary files, so this option would keep
5199 +  those filenames from being predicted as well.  We also use code
5200 +  to make sure that PID numbers aren't reused too soon.  If the sysctl
5201 +  option is enabled, a sysctl option with name "rand_pids" is created.
5202 +
5203 +Larger entropy pools
5204 +CONFIG_GRKERNSEC_RANDNET
5205 +  If you say Y here, the entropy pools used for many features of Linux
5206 +  and grsecurity will be doubled in size.  Since several grsecurity 
5207 +  features use additional randomness, it is recommended that you say Y 
5208 +  here.  Saying Y here has a similar effect as modifying
5209 +  /proc/sys/kernel/random/poolsize.
5210 +
5211 +Truly random TCP ISN selection
5212 +CONFIG_GRKERNSEC_RANDISN
5213 +  If you say Y here, Linux's default selection of TCP Initial Sequence
5214 +  Numbers (ISNs) will be replaced with that of OpenBSD.  Linux uses
5215 +  an MD4 hash based on the connection plus a time value to create the
5216 +  ISN, while OpenBSD's selection is random.  If the sysctl option is 
5217 +  enabled, a sysctl option with name "rand_isns" is created.
5218 +
5219 +Randomized IP IDs
5220 +CONFIG_GRKERNSEC_RANDID
5221 +  If you say Y here, all the id field on all outgoing packets
5222 +  will be randomized.  This hinders os fingerprinters and
5223 +  keeps your machine from being used as a bounce for an untraceable
5224 +  portscan.  Ids are used for fragmented packets, fragments belonging
5225 +  to the same packet have the same id.  By default linux only
5226 +  increments the id value on each packet sent to an individual host.
5227 +  We use a port of the OpenBSD random ip id code to achieve the
5228 +  randomness, while keeping the possibility of id duplicates to
5229 +  near none.  If the sysctl option is enabled, a sysctl option with name
5230 +  "rand_ip_ids" is created.
5231 +
5232 +Randomized TCP source ports
5233 +CONFIG_GRKERNSEC_RANDSRC
5234 +  If you say Y here, situations where a source port is generated on the
5235 +  fly for the TCP protocol (ie. with connect() ) will be altered so that
5236 +  the source port is generated at random, instead of a simple incrementing
5237 +  algorithm.  If the sysctl option is enabled, a sysctl option with name
5238 +  "rand_tcp_src_ports" is created.
5239 +
5240 +Randomized RPC XIDs
5241 +CONFIG_GRKERNSEC_RANDRPC
5242 +  If you say Y here, the method of determining XIDs for RPC requests will
5243 +  be randomized, instead of using linux's default behavior of simply
5244 +  incrementing the XID.  If you want your RPC connections to be more
5245 +  secure, say Y here.  If the sysctl option is enabled, a sysctl option 
5246 +  with name "rand_rpc" is created.
5247 +
5248 +Socket restrictions
5249 +CONFIG_GRKERNSEC_SOCKET
5250 +  If you say Y here, you will be able to choose from several options.
5251 +  If you assign a GID on your system and add it to the supplementary
5252 +  groups of users you want to restrict socket access to, this patch
5253 +  will perform up to three things, based on the option(s) you choose.
5254 +
5255 +Deny all socket access
5256 +CONFIG_GRKERNSEC_SOCKET_ALL
5257 +  If you say Y here, you will be able to choose a GID of whose users will
5258 +  be unable to connect to other hosts from your machine or run server
5259 +  applications from your machine.  If the sysctl option is enabled, a
5260 +  sysctl option with name "socket_all" is created.
5261 +
5262 +Group for disabled socket access
5263 +CONFIG_GRKERNSEC_SOCKET_ALL_GID
5264 +  Here you can choose the GID to disable socket access for. Remember to 
5265 +  add the users you want socket access disabled for to the GID 
5266 +  specified here.  If the sysctl option is enabled, whatever you choose
5267 +  here won't matter. You'll have to specify the GID in your bootup 
5268 +  script by echoing the GID to the proper /proc entry.  View the help
5269 +  on the sysctl option for more information.  If the sysctl option is
5270 +  enabled, a sysctl option with name "socket_all_gid" is created.
5271 +
5272 +Deny all client socket access
5273 +CONFIG_GRKERNSEC_SOCKET_CLIENT
5274 +  If you say Y here, you will be able to choose a GID of whose users will
5275 +  be unable to connect to other hosts from your machine, but will be
5276 +  able to run servers.  If this option is enabled, all users in the group
5277 +  you specify will have to use passive mode when initiating ftp transfers
5278 +  from the shell on your machine.  If the sysctl option is enabled, a
5279 +  sysctl option with name "socket_client" is created.
5280 +
5281 +Group for disabled client socket access
5282 +CONFIG_GRKERNSEC_SOCKET_CLIENT_GID
5283 +  Here you can choose the GID to disable client socket access for. 
5284 +  Remember to add the users you want client socket access disabled for to 
5285 +  the GID specified here.  If the sysctl option is enabled, whatever you 
5286 +  choose here won't matter. You'll have to specify the GID in your bootup 
5287 +  script by echoing the GID to the proper /proc entry.  View the help
5288 +  on the sysctl option for more information.  If the sysctl option is
5289 +  enabled, a sysctl option with name "socket_client_gid" is created.
5290 +
5291 +Deny all server socket access
5292 +CONFIG_GRKERNSEC_SOCKET_SERVER
5293 +  If you say Y here, you will be able to choose a GID of whose users will
5294 +  be unable to run server applications from your machine.  If the sysctl 
5295 +  option is enabled, a sysctl option with name "socket_server" is created.
5296 +
5297 +Group for disabled server socket access
5298 +CONFIG_GRKERNSEC_SOCKET_SERVER_GID
5299 +  Here you can choose the GID to disable server socket access for. 
5300 +  Remember to add the users you want server socket access disabled for to 
5301 +  the GID specified here.  If the sysctl option is enabled, whatever you 
5302 +  choose here won't matter. You'll have to specify the GID in your bootup 
5303 +  script by echoing the GID to the proper /proc entry.  View the help
5304 +  on the sysctl option for more information.  If the sysctl option is
5305 +  enabled, a sysctl option with name "socket_server_gid" is created.
5306 +
5307 +Sysctl support
5308 +CONFIG_GRKERNSEC_SYSCTL
5309 +  If you say Y here, you will be able to change the options that
5310 +  grsecurity runs with at bootup, without having to recompile your
5311 +  kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
5312 +  to enable (1) or disable (0) various features.  All the sysctl entries
5313 +  are mutable until the "grsec_lock" entry is set to a non-zero value.
5314 +  All features are disabled by default. Please note that this option could 
5315 +  reduce the effectiveness of the added security of this patch if an ACL 
5316 +  system is not put in place.  Your init scripts should be read-only, and 
5317 +  root should not have access to adding modules or performing raw i/o 
5318 +  operations.  All options should be set at startup, and the grsec_lock 
5319 +  entry should be set to a non-zero value after all the options are set.  
5320 +  *THIS IS EXTREMELY IMPORTANT*
5321 +
5322 +Number of burst messages
5323 +CONFIG_GRKERNSEC_FLOODBURST
5324 +  This option allows you to choose the maximum number of messages allowed
5325 +  within the flood time interval you chose in a separate option.  The 
5326 +  default should be suitable for most people, however if you find that 
5327 +  many of your logs are being interpreted as flooding, you may want to 
5328 +  raise this value.
5329 +
5330 +Seconds in between log messages
5331 +CONFIG_GRKERNSEC_FLOODTIME
5332 +  This option allows you to enforce the number of seconds between
5333 +  grsecurity log messages.  The default should be suitable for most 
5334 +  people, however, if you choose to change it, choose a value small enough
5335 +  to allow informative logs to be produced, but large enough to
5336 +  prevent flooding.
5337 +
5338 +Hide kernel processes
5339 +CONFIG_GRKERNSEC_ACL_HIDEKERN
5340 +  If you say Y here, when the ACL system is enabled via gradm -E,
5341 +  an additional ACL will be passed to the kernel that hides all kernel
5342 +  processes.  These processes will only be viewable by the authenticated
5343 +  admin, or processes that have viewing access set.
5344 +
5345 +Maximum tries before password lockout
5346 +CONFIG_GRKERNSEC_ACL_MAXTRIES
5347 +  This option enforces the maximum number of times a user can attempt
5348 +  to authorize themselves with the grsecurity ACL system before being
5349 +  denied the ability to attempt authorization again for a specified time.  
5350 +  The lower the number, the harder it will be to brute-force a password.
5351 +
5352 +Time to wait after max password tries, in seconds
5353 +CONFIG_GRKERNSEC_ACL_TIMEOUT
5354 +  This option specifies the time the user must wait after attempting to 
5355 +  authorize to the ACL system with the maximum number of invalid 
5356 +  passwords.  The higher the number, the harder it will be to brute-force 
5357 +  a password.
5358 +
5359  Disable data cache
5360  CONFIG_DCACHE_DISABLE
5361    This option allows you to run the kernel with data cache disabled.
5362 diff -urN linux-2.4.24.org/drivers/char/keyboard.c linux-2.4.24/drivers/char/keyboard.c
5363 --- linux-2.4.24.org/drivers/char/keyboard.c    2004-01-05 18:38:57.371631712 +0100
5364 +++ linux-2.4.24/drivers/char/keyboard.c        2004-01-05 18:43:05.028982072 +0100
5365 @@ -545,6 +545,16 @@
5366         if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
5367             !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
5368                 return;
5369 +
5370 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
5371 +       {
5372 +               void *func = spec_fn_table[value];
5373 +               if (func == show_state || func == show_ptregs ||
5374 +                   func == show_mem)
5375 +                       return;
5376 +       }
5377 +#endif
5378 +
5379         spec_fn_table[value]();
5380  }
5381  
5382 diff -urN linux-2.4.24.org/drivers/char/mem.c linux-2.4.24/drivers/char/mem.c
5383 --- linux-2.4.24.org/drivers/char/mem.c 2004-01-05 18:38:55.910853784 +0100
5384 +++ linux-2.4.24/drivers/char/mem.c     2004-01-05 18:43:05.041980096 +0100
5385 @@ -22,6 +22,7 @@
5386  #include <linux/tty.h>
5387  #include <linux/capability.h>
5388  #include <linux/ptrace.h>
5389 +#include <linux/grsecurity.h>
5390  
5391  #include <asm/uaccess.h>
5392  #include <asm/io.h>
5393 @@ -42,6 +43,10 @@
5394  #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
5395  extern void tapechar_init(void);
5396  #endif
5397 +
5398 +#ifdef CONFIG_GRKERNSEC
5399 +extern struct file_operations grsec_fops;
5400 +#endif
5401       
5402  static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
5403                             const char * buf, size_t count, loff_t *ppos)
5404 @@ -115,6 +120,11 @@
5405         unsigned long p = *ppos;
5406         unsigned long end_mem;
5407  
5408 +#ifdef CONFIG_GRKERNSEC_KMEM
5409 +       gr_handle_mem_write();
5410 +       return -EPERM;
5411 +#endif
5412 +
5413         end_mem = __pa(high_memory);
5414         if (p >= end_mem)
5415                 return 0;
5416 @@ -187,6 +197,12 @@
5417  {
5418         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5419  
5420 +#ifdef CONFIG_GRKERNSEC_KMEM
5421 +       if (gr_handle_mem_mmap(offset, vma))
5422 +               return -EPERM;
5423 +#endif
5424 +
5425 +
5426         /*
5427          * Accessing memory above the top the kernel knows about or
5428          * through a file pointer that was marked O_SYNC will be
5429 @@ -286,6 +302,11 @@
5430         ssize_t virtr = 0;
5431         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
5432  
5433 +#ifdef CONFIG_GRKERNSEC_KMEM
5434 +       gr_handle_kmem_write();
5435 +       return -EPERM;
5436 +#endif
5437 +
5438         if (p < (unsigned long) high_memory) {
5439                 wrote = count;
5440                 if (count > (unsigned long) high_memory - p)
5441 @@ -402,7 +423,7 @@
5442                         count = size;
5443  
5444                 zap_page_range(mm, addr, count);
5445 -               zeromap_page_range(addr, count, PAGE_COPY);
5446 +               zeromap_page_range(addr, count, vma->vm_page_prot); 
5447  
5448                 size -= count;
5449                 buf += count;
5450 @@ -525,6 +546,15 @@
5451  
5452  static int open_port(struct inode * inode, struct file * filp)
5453  {
5454 +#ifdef CONFIG_GRKERNSEC_KMEM
5455 +       gr_handle_open_port();
5456 +       return -EPERM;
5457 +#endif
5458 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5459 +}
5460 +
5461 +static int open_mem(struct inode * inode, struct file * filp)
5462 +{
5463         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5464  }
5465  
5466 @@ -582,6 +612,11 @@
5467         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5468         unsigned long size = vma->vm_end - vma->vm_start;
5469  
5470 +#ifdef CONFIG_GRKERNSEC_KMEM
5471 +       if (gr_handle_mem_mmap(offset, vma))
5472 +               return -EPERM;
5473 +#endif
5474 +
5475         /*
5476          * If the user is not attempting to mmap a high memory address then
5477          * the standard mmap_mem mechanism will work.  High memory addresses
5478 @@ -617,7 +652,6 @@
5479  #define full_lseek      null_lseek
5480  #define write_zero     write_null
5481  #define read_full       read_zero
5482 -#define open_mem       open_port
5483  #define open_kmem      open_mem
5484  
5485  static struct file_operations mem_fops = {
5486 @@ -693,6 +727,11 @@
5487                 case 9:
5488                         filp->f_op = &urandom_fops;
5489                         break;
5490 +#ifdef CONFIG_GRKERNSEC
5491 +               case 10:
5492 +                       filp->f_op = &grsec_fops;
5493 +                       break;
5494 +#endif
5495                 default:
5496                         return -ENXIO;
5497         }
5498 @@ -719,7 +758,10 @@
5499         {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
5500         {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
5501         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
5502 -       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
5503 +       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
5504 +#ifdef CONFIG_GRKERNSEC
5505 +       {10,"grsec",   S_IRUSR | S_IWUGO,           &grsec_fops}
5506 +#endif
5507      };
5508      int i;
5509  
5510 diff -urN linux-2.4.24.org/drivers/char/random.c linux-2.4.24/drivers/char/random.c
5511 --- linux-2.4.24.org/drivers/char/random.c      2004-01-05 18:38:57.422623960 +0100
5512 +++ linux-2.4.24/drivers/char/random.c  2004-01-05 18:43:05.053978272 +0100
5513 @@ -262,9 +262,15 @@
5514  /*
5515   * Configuration information
5516   */
5517 +#ifdef CONFIG_GRKERNSEC_RANDNET
5518 +#define DEFAULT_POOL_SIZE 1024
5519 +#define SECONDARY_POOL_SIZE 256
5520 +#define BATCH_ENTROPY_SIZE 512
5521 +#else
5522  #define DEFAULT_POOL_SIZE 512
5523  #define SECONDARY_POOL_SIZE 128
5524  #define BATCH_ENTROPY_SIZE 256
5525 +#endif
5526  #define USE_SHA
5527  
5528  /*
5529 @@ -389,6 +395,7 @@
5530  /*
5531   * Static global variables
5532   */
5533 +
5534  static struct entropy_store *random_state; /* The default global store */
5535  static struct entropy_store *sec_random_state; /* secondary store */
5536  static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
5537 @@ -2202,6 +2209,29 @@
5538         return halfMD4Transform(hash, keyptr->secret);
5539  }
5540  
5541 +#ifdef CONFIG_GRKERNSEC
5542 +/* the following function is provided by PaX under the GPL */
5543 +unsigned long get_random_long(void)
5544 +{       
5545 +       static time_t rekey_time;
5546 +       static __u32 secret[12];
5547 +       time_t t;
5548 +
5549 +       /*
5550 +        * Pick a random secret every REKEY_INTERVAL seconds
5551 +        */
5552 +       t = CURRENT_TIME;
5553 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
5554 +               rekey_time = t;
5555 +               get_random_bytes(secret, sizeof(secret));
5556 +       }
5557 +
5558 +       secret[1] = halfMD4Transform(secret+8, secret);
5559 +       secret[0] = halfMD4Transform(secret+8, secret);
5560 +       return *(unsigned long *)secret;
5561 +}
5562 +#endif
5563 +
5564  #ifdef CONFIG_SYN_COOKIES
5565  /*
5566   * Secure SYN cookie computation. This is the algorithm worked out by
5567 diff -urN linux-2.4.24.org/drivers/char/tty_io.c linux-2.4.24/drivers/char/tty_io.c
5568 --- linux-2.4.24.org/drivers/char/tty_io.c      2004-01-05 18:38:56.911701632 +0100
5569 +++ linux-2.4.24/drivers/char/tty_io.c  2004-01-05 18:43:05.087973104 +0100
5570 @@ -99,7 +99,7 @@
5571  #include <linux/vt_kern.h>
5572  #include <linux/selection.h>
5573  #include <linux/devfs_fs_kernel.h>
5574 -
5575 +#include <linux/grsecurity.h>
5576  #include <linux/kmod.h>
5577  
5578  #ifdef CONFIG_VT
5579 @@ -1426,7 +1426,11 @@
5580                 retval = -ENODEV;
5581         filp->f_flags = saved_flags;
5582  
5583 +#ifdef CONFIG_GRKERNSEC
5584 +       if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG))
5585 +#else
5586         if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
5587 +#endif
5588                 retval = -EBUSY;
5589  
5590         if (retval) {
5591 @@ -1533,7 +1537,11 @@
5592  {
5593         char ch, mbz = 0;
5594  
5595 +#ifdef CONFIG_GRKERNSEC
5596 +       if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG))
5597 +#else
5598         if ((current->tty != tty) && !suser())
5599 +#endif
5600                 return -EPERM;
5601         if (get_user(ch, arg))
5602                 return -EFAULT;
5603 @@ -1571,7 +1579,11 @@
5604         if (inode->i_rdev == SYSCONS_DEV ||
5605             inode->i_rdev == CONSOLE_DEV) {
5606                 struct file *f;
5607 +#ifdef CONFIG_GRKERNSEC
5608 +               if (!capable(CAP_SYS_TTY_CONFIG))
5609 +#else
5610                 if (!suser())
5611 +#endif
5612                         return -EPERM;
5613                 spin_lock(&redirect_lock);
5614                 f = redirect;
5615 @@ -1623,7 +1635,11 @@
5616                  * This tty is already the controlling
5617                  * tty for another session group!
5618                  */
5619 +#ifdef CONFIG_GRKERNSEC
5620 +               if ((arg == 1) && capable(CAP_SYS_ADMIN)) {
5621 +#else
5622                 if ((arg == 1) && suser()) {
5623 +#endif
5624                         /*
5625                          * Steal it away
5626                          */
5627 diff -urN linux-2.4.24.org/drivers/char/vt.c linux-2.4.24/drivers/char/vt.c
5628 --- linux-2.4.24.org/drivers/char/vt.c  2004-01-05 18:38:57.229653296 +0100
5629 +++ linux-2.4.24/drivers/char/vt.c      2004-01-05 18:43:05.117968544 +0100
5630 @@ -32,6 +32,7 @@
5631  #include <linux/vt_kern.h>
5632  #include <linux/kbd_diacr.h>
5633  #include <linux/selection.h>
5634 +#include <linux/grsecurity.h>
5635  
5636  #ifdef CONFIG_FB_COMPAT_XPMAC
5637  #include <asm/vc_ioctl.h>
5638 @@ -443,7 +444,11 @@
5639          * to be the owner of the tty, or super-user.
5640          */
5641         perm = 0;
5642 +#ifdef CONFIG_GRKERNSEC
5643 +       if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
5644 +#else
5645         if (current->tty == tty || suser())
5646 +#endif
5647                 perm = 1;
5648   
5649         kbd = kbd_table + console;
5650 @@ -1038,12 +1043,20 @@
5651                 return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
5652  
5653         case VT_LOCKSWITCH:
5654 +#ifdef CONFIG_GRKERNSEC
5655 +               if (!capable(CAP_SYS_TTY_CONFIG))
5656 +#else
5657                 if (!suser())
5658 +#endif
5659                    return -EPERM;
5660                 vt_dont_switch = 1;
5661                 return 0;
5662         case VT_UNLOCKSWITCH:
5663 +#ifdef CONFIG_GRKERNSEC
5664 +               if (!capable(CAP_SYS_TTY_CONFIG))
5665 +#else
5666                 if (!suser())
5667 +#endif
5668                    return -EPERM;
5669                 vt_dont_switch = 0;
5670                 return 0;
5671 diff -urN linux-2.4.24.org/drivers/pci/proc.c linux-2.4.24/drivers/pci/proc.c
5672 --- linux-2.4.24.org/drivers/pci/proc.c 2004-01-05 18:39:03.000000000 +0100
5673 +++ linux-2.4.24/drivers/pci/proc.c     2004-01-05 18:43:05.139965200 +0100
5674 @@ -562,7 +562,15 @@
5675                 pci_for_each_dev(dev) {
5676                         pci_proc_attach_device(dev);
5677                 }
5678 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
5679 +#ifdef CONFIG_GRKERNSEC_PROC_USER
5680 +               entry = create_proc_entry("pci", S_IRUSR, NULL);
5681 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
5682 +               entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
5683 +#endif
5684 +#else
5685                 entry = create_proc_entry("pci", 0, NULL);
5686 +#endif
5687                 if (entry)
5688                         entry->proc_fops = &proc_pci_operations;
5689         }
5690 diff -urN linux-2.4.24.org/fs/binfmt_aout.c linux-2.4.24/fs/binfmt_aout.c
5691 --- linux-2.4.24.org/fs/binfmt_aout.c   2004-01-05 18:40:39.295136984 +0100
5692 +++ linux-2.4.24/fs/binfmt_aout.c       2004-01-05 18:43:05.178959272 +0100
5693 @@ -5,6 +5,7 @@
5694   */
5695  
5696  #include <linux/module.h>
5697 +#include <linux/config.h>
5698  
5699  #include <linux/sched.h>
5700  #include <linux/kernel.h>
5701 @@ -113,10 +114,12 @@
5702  /* If the size of the dump file exceeds the rlimit, then see what would happen
5703     if we wrote the stack, but not the data area.  */
5704  #ifdef __sparc__
5705 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
5706         if ((dump.u_dsize+dump.u_ssize) >
5707             current->rlim[RLIMIT_CORE].rlim_cur)
5708                 dump.u_dsize = 0;
5709  #else
5710 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
5711         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
5712             current->rlim[RLIMIT_CORE].rlim_cur)
5713                 dump.u_dsize = 0;
5714 @@ -124,10 +127,12 @@
5715  
5716  /* Make sure we have enough room to write the stack and data areas. */
5717  #ifdef __sparc__
5718 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
5719         if ((dump.u_ssize) >
5720             current->rlim[RLIMIT_CORE].rlim_cur)
5721                 dump.u_ssize = 0;
5722  #else
5723 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
5724         if ((dump.u_ssize+1) * PAGE_SIZE >
5725             current->rlim[RLIMIT_CORE].rlim_cur)
5726                 dump.u_ssize = 0;
5727 @@ -276,6 +281,8 @@
5728         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
5729         if (rlim >= RLIM_INFINITY)
5730                 rlim = ~0;
5731 +
5732 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
5733         if (ex.a_data + ex.a_bss > rlim)
5734                 return -ENOMEM;
5735  
5736 @@ -307,6 +314,24 @@
5737         current->mm->mmap = NULL;
5738         compute_creds(bprm);
5739         current->flags &= ~PF_FORKNOEXEC;
5740 +
5741 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5742 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
5743 +               current->flags |= PF_PAX_PAGEEXEC;
5744 +
5745 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5746 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
5747 +                       current->flags |= PF_PAX_EMUTRAMP;
5748 +#endif
5749 +
5750 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5751 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))        
5752 +                       current->flags |= PF_PAX_MPROTECT;
5753 +#endif
5754 +
5755 +       }
5756 +#endif
5757 +
5758  #ifdef __sparc__
5759         if (N_MAGIC(ex) == NMAGIC) {
5760                 loff_t pos = fd_offset;
5761 @@ -393,7 +418,7 @@
5762  
5763                 down_write(&current->mm->mmap_sem);
5764                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
5765 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
5766 +                               PROT_READ | PROT_WRITE,
5767                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
5768                                 fd_offset + ex.a_text);
5769                 up_write(&current->mm->mmap_sem);
5770 diff -urN linux-2.4.24.org/fs/binfmt_elf.c linux-2.4.24/fs/binfmt_elf.c
5771 --- linux-2.4.24.org/fs/binfmt_elf.c    2004-01-05 18:40:58.296248376 +0100
5772 +++ linux-2.4.24/fs/binfmt_elf.c        2004-01-05 18:43:05.181958816 +0100
5773 @@ -11,6 +11,7 @@
5774  
5775  #include <linux/module.h>
5776  
5777 +#include <linux/config.h>
5778  #include <linux/fs.h>
5779  #include <linux/stat.h>
5780  #include <linux/sched.h>
5781 @@ -33,10 +34,13 @@
5782  #include <linux/smp_lock.h>
5783  #include <linux/compiler.h>
5784  #include <linux/highmem.h>
5785 +#include <linux/random.h>
5786 +#include <linux/grsecurity.h>
5787  
5788  #include <asm/uaccess.h>
5789  #include <asm/param.h>
5790  #include <asm/pgalloc.h>
5791 +#include <asm/system.h>
5792  
5793  #define DLINFO_ITEMS 13
5794  
5795 @@ -86,6 +90,12 @@
5796         if (end <= start)
5797                 return;
5798         do_brk(start, end - start);
5799 +
5800 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5801 +       if (current->flags & PF_PAX_RANDEXEC)
5802 +               do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
5803 +#endif
5804 +
5805  }
5806  
5807  
5808 @@ -446,6 +456,11 @@
5809         struct exec interp_ex;
5810         char passed_fileno[6];
5811         struct files_struct *files;
5812 +
5813 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5814 +       unsigned long load_addr_random = 0UL;
5815 +       unsigned long load_bias_random = 0UL;
5816 +#endif
5817         
5818         /* Get the exec-header */
5819         elf_ex = *((struct elfhdr *) bprm->buf);
5820 @@ -618,7 +633,92 @@
5821         current->mm->end_data = 0;
5822         current->mm->end_code = 0;
5823         current->mm->mmap = NULL;
5824 +
5825 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5826 +       current->mm->delta_mmap = 0UL;
5827 +       current->mm->delta_exec = 0UL;
5828 +       current->mm->delta_stack = 0UL;
5829 +#endif
5830 +
5831         current->flags &= ~PF_FORKNOEXEC;
5832 +
5833 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5834 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
5835 +               current->flags |= PF_PAX_PAGEEXEC;
5836 +#endif
5837 +
5838 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5839 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
5840 +               current->flags &= ~PF_PAX_PAGEEXEC;
5841 +               current->flags |= PF_PAX_SEGMEXEC;
5842 +       }
5843 +#endif
5844 +
5845 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5846 +       if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && (elf_ex.e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
5847 +               current->flags |= PF_PAX_EMUTRAMP;
5848 +#endif
5849 +
5850 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5851 +       if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex.e_ident[EI_PAX] & EF_PAX_MPROTECT))
5852 +               current->flags |= PF_PAX_MPROTECT;
5853 +#endif
5854 +
5855 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5856 +       if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_RANDMMAP))
5857 +               current->flags |= PF_PAX_RANDMMAP;
5858 +#endif
5859 +
5860 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5861 +       if ((elf_ex.e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC) &&
5862 +           (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)))
5863 +               current->flags |= PF_PAX_RANDEXEC;
5864 +#endif
5865 +
5866 +#ifdef CONFIG_GRKERNSEC_PAX_PT_GNU_HEAP
5867 +       elf_ppnt = elf_phdata;
5868 +       for (i = 0; i < elf_ex.e_phnum; i++, elf_ppnt++)
5869 +               if (elf_ppnt->p_type == PT_GNU_HEAP) {
5870 +                       if (elf_ppnt->p_flags & PF_X)
5871 +                               current->flags & ~PF_PAX_MPROTECT;
5872 +                       break;
5873 +               }
5874 +#endif
5875 +
5876 +#ifdef CONFIG_GRKERNSEC_PAX_PT_GNU_STACK
5877 +       elf_ppnt = elf_phdata;
5878 +       for (i = 0; i < elf_ex.e_phnum; i++, elf_ppnt++)
5879 +               if (elf_ppnt->p_type == PT_GNU_STACK) {
5880 +                       if ((elf_ppnt->p_flags & PF_X) && (current->flags & PF_PAX_MPROTECT))
5881 +                               current->flags |= PF_PAX_EMUTRAMP;
5882 +                       break;
5883 +               }
5884 +#endif
5885 +
5886 +#ifdef CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS
5887 +       pax_set_flags(bprm);
5888 +#elif defined(CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS)
5889 +       if (pax_set_flags_func)
5890 +               (*pax_set_flags_func)(bprm);
5891 +#endif
5892 +
5893 +#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
5894 +       if (current->flags & PF_PAX_PAGEEXEC)
5895 +               current->mm->call_dl_resolve = 0UL;
5896 +#endif
5897 +
5898 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5899 +       if (current->flags & PF_PAX_RANDMMAP) {
5900 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
5901 +
5902 +               current->mm->delta_mmap = pax_delta_mask(get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
5903 +               current->mm->delta_exec = pax_delta_mask(get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
5904 +               current->mm->delta_stack = pax_delta_mask(get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
5905 +       }
5906 +#endif
5907 +
5908 +       gr_set_pax_flags(current);      
5909 +
5910         elf_entry = (unsigned long) elf_ex.e_entry;
5911  
5912         /* Do this so that we can load the interpreter, if need be.  We will
5913 @@ -627,7 +727,7 @@
5914         retval = setup_arg_pages(bprm);
5915         if (retval < 0) {
5916                 send_sig(SIGKILL, current, 0);
5917 -               return retval;
5918 +               goto out_free_dentry;
5919         }
5920         
5921         current->mm->start_stack = bprm->p;
5922 @@ -674,11 +774,84 @@
5923                            base, as well as whatever program they might try to exec.  This
5924                            is because the brk will follow the loader, and is not movable.  */
5925                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
5926 +
5927 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
5928 +                       /* PaX: randomize base address at the default exe base if requested */
5929 +                       if (current->flags & PF_PAX_RANDMMAP) {
5930 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
5931 +                               elf_flags |= MAP_FIXED;
5932 +                       }
5933 +#endif
5934 +
5935                 }
5936  
5937 -               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5938 -               if (BAD_ADDR(error))
5939 -                       continue;
5940 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5941 +               if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
5942 +                       error = -ENOMEM;
5943 +
5944 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5945 +                       if (current->flags & PF_PAX_PAGEEXEC)
5946 +                               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
5947 +#endif
5948 +
5949 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5950 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5951 +                               unsigned long addr, len;
5952 +
5953 +                               addr = ELF_PAGESTART(load_bias + vaddr);
5954 +                               len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
5955 +                               if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
5956 +                                       continue;
5957 +                               down_write(&current->mm->mmap_sem);
5958 +                               error = do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
5959 +                               up_write(&current->mm->mmap_sem);
5960 +                       }
5961 +#endif
5962 +
5963 +                       if (BAD_ADDR(error))
5964 +                               continue;
5965 +
5966 +                       /* PaX: mirror at a randomized base */
5967 +                       down_write(&current->mm->mmap_sem);
5968 +
5969 +                       if (!load_addr_set) {
5970 +                               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);
5971 +                               if (BAD_ADDR(load_addr_random)) {
5972 +                                       up_write(&current->mm->mmap_sem);
5973 +                                       continue;
5974 +                               }
5975 +                               load_bias_random = load_addr_random - vaddr;
5976 +                       }
5977 +
5978 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5979 +                       if (current->flags & PF_PAX_PAGEEXEC)
5980 +                               load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5981 +#endif
5982 +
5983 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5984 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5985 +                               if (elf_prot & PROT_EXEC) {
5986 +                                       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);
5987 +                                       if (!BAD_ADDR(load_addr_random)) {
5988 +                                               load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5989 +                                               if (!BAD_ADDR(load_addr_random))
5990 +                                                       load_addr_random -= SEGMEXEC_TASK_SIZE;
5991 +                                       }
5992 +                               } else
5993 +                                       load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5994 +                       }
5995 +#endif
5996 +
5997 +                       up_write(&current->mm->mmap_sem);
5998 +                       if (BAD_ADDR(load_addr_random))
5999 +                               continue;
6000 +               } else
6001 +#endif
6002 +               {
6003 +                       error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
6004 +                       if (BAD_ADDR(error))
6005 +                               continue;
6006 +               }
6007  
6008                 if (!load_addr_set) {
6009                         load_addr_set = 1;
6010 @@ -689,6 +862,11 @@
6011                                 load_addr += load_bias;
6012                                 reloc_func_desc = load_addr;
6013                         }
6014 +
6015 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
6016 +                       current->mm->delta_exec = load_addr_random - load_addr;
6017 +#endif
6018 +
6019                 }
6020                 k = elf_ppnt->p_vaddr;
6021                 if (k < start_code) start_code = k;
6022 @@ -715,6 +893,18 @@
6023         start_data += load_bias;
6024         end_data += load_bias;
6025  
6026 +#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
6027 +       elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT);
6028 +#undef pax_delta_mask
6029 +#endif
6030 +
6031 +       /* Calling set_brk effectively mmaps the pages that we need
6032 +        * for the bss and break sections
6033 +        */
6034 +       set_brk(elf_bss, elf_brk);
6035 +
6036 +       padzero(elf_bss);
6037 +
6038         if (elf_interpreter) {
6039                 if (interpreter_type == INTERPRETER_AOUT)
6040                         elf_entry = load_aout_interp(&interp_ex,
6041 @@ -763,13 +953,6 @@
6042         current->mm->end_data = end_data;
6043         current->mm->start_stack = bprm->p;
6044  
6045 -       /* Calling set_brk effectively mmaps the pages that we need
6046 -        * for the bss and break sections
6047 -        */
6048 -       set_brk(elf_bss, elf_brk);
6049 -
6050 -       padzero(elf_bss);
6051 -
6052  #if 0
6053         printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
6054         printk("(end_code) %lx\n" , (long) current->mm->end_code);
6055 @@ -806,6 +989,10 @@
6056         ELF_PLAT_INIT(regs, reloc_func_desc);
6057  #endif
6058  
6059 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
6060 +       pax_switch_segments(current);
6061 +#endif
6062 +
6063         start_thread(regs, elf_entry, bprm->p);
6064         if (current->ptrace & PT_PTRACED)
6065                 send_sig(SIGTRAP, current, 0);
6066 @@ -1033,8 +1220,11 @@
6067  #undef DUMP_SEEK
6068  
6069  #define DUMP_WRITE(addr, nr)   \
6070 +       do { \
6071 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
6072         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
6073 -               goto end_coredump;
6074 +               goto end_coredump; \
6075 +       } while (0);
6076  #define DUMP_SEEK(off) \
6077         if (!dump_seek(file, (off))) \
6078                 goto end_coredump;
6079 diff -urN linux-2.4.24.org/fs/buffer.c linux-2.4.24/fs/buffer.c
6080 --- linux-2.4.24.org/fs/buffer.c        2004-01-05 18:40:39.577094120 +0100
6081 +++ linux-2.4.24/fs/buffer.c    2004-01-05 18:43:05.205955168 +0100
6082 @@ -1906,6 +1906,9 @@
6083         int err;
6084  
6085         err = -EFBIG;
6086 +
6087 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
6088 +
6089          limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
6090         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
6091                 send_sig(SIGXFSZ, current, 0);
6092 diff -urN linux-2.4.24.org/fs/exec.c linux-2.4.24/fs/exec.c
6093 --- linux-2.4.24.org/fs/exec.c  2004-01-05 18:40:59.569054880 +0100
6094 +++ linux-2.4.24/fs/exec.c      2004-01-05 18:43:05.207954864 +0100
6095 @@ -43,6 +43,9 @@
6096  #include <asm/uaccess.h>
6097  #include <asm/pgalloc.h>
6098  #include <asm/mmu_context.h>
6099 +#include <linux/major.h>
6100 +#include <linux/random.h>
6101 +#include <linux/grsecurity.h>
6102  
6103  #ifdef CONFIG_KMOD
6104  #include <linux/kmod.h>
6105 @@ -56,6 +59,11 @@
6106  static struct linux_binfmt *formats;
6107  static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
6108  
6109 +#ifdef CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS
6110 +void (*pax_set_flags_func)(struct linux_binprm *bprm);
6111 +EXPORT_SYMBOL(pax_set_flags_func);
6112 +#endif
6113 +
6114  int register_binfmt(struct linux_binfmt * fmt)
6115  {
6116         struct linux_binfmt ** tmp = &formats;
6117 @@ -346,6 +354,11 @@
6118                 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
6119                 mpnt->vm_end = STACK_TOP;
6120                 mpnt->vm_flags = VM_STACK_FLAGS;
6121 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
6122 +               if (!(current->flags & PF_PAX_PAGEEXEC))
6123 +                       mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7];
6124 +               else
6125 +#endif
6126                 mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
6127                 mpnt->vm_ops = NULL;
6128                 mpnt->vm_pgoff = 0;
6129 @@ -606,6 +619,30 @@
6130         }
6131         current->comm[i] = '\0';
6132  
6133 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
6134 +       current->flags &= ~PF_PAX_PAGEEXEC;
6135 +#endif
6136 +
6137 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
6138 +       current->flags &= ~PF_PAX_EMUTRAMP;
6139 +#endif
6140 +
6141 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
6142 +       current->flags &= ~PF_PAX_MPROTECT;
6143 +#endif
6144 +
6145 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
6146 +       current->flags &= ~PF_PAX_RANDMMAP;
6147 +#endif
6148 +
6149 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
6150 +       current->flags &= ~PF_PAX_RANDEXEC;
6151 +#endif
6152 +
6153 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
6154 +       current->flags &= ~PF_PAX_SEGMEXEC;
6155 +#endif
6156 +
6157         flush_thread();
6158  
6159         de_thread(current);
6160 @@ -705,6 +742,9 @@
6161                         cap_set_full(bprm->cap_effective);
6162         }
6163  
6164 +       if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
6165 +               return -EACCES;
6166 +
6167         memset(bprm->buf,0,BINPRM_BUF_SIZE);
6168         return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
6169  }
6170 @@ -770,6 +810,8 @@
6171          current->suid = current->euid = current->fsuid = bprm->e_uid;
6172          current->sgid = current->egid = current->fsgid = bprm->e_gid;
6173  
6174 +       gr_handle_chroot_caps(current);
6175 +
6176         if(do_unlock)
6177                 unlock_kernel();
6178         current->keep_capabilities = 0;
6179 @@ -903,6 +945,11 @@
6180         struct file *file;
6181         int retval;
6182         int i;
6183 +#ifdef CONFIG_GRKERNSEC
6184 +       struct file *old_exec_file;
6185 +       struct acl_subject_label *old_acl;
6186 +       struct rlimit old_rlim[RLIM_NLIMITS];
6187 +#endif
6188  
6189         file = open_exec(filename);
6190  
6191 @@ -910,7 +957,26 @@
6192         if (IS_ERR(file))
6193                 return retval;
6194  
6195 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
6196 +
6197 +       if (gr_handle_nproc()) {
6198 +               allow_write_access(file);
6199 +               fput(file);
6200 +               return -EAGAIN;
6201 +       }
6202 +
6203 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
6204 +               allow_write_access(file);
6205 +               fput(file);
6206 +               return -EACCES;
6207 +       }
6208 +
6209         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
6210 +
6211 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
6212 +       bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
6213 +#endif
6214 +
6215         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
6216  
6217         bprm.file = file;
6218 @@ -934,11 +1000,26 @@
6219         if (retval < 0) 
6220                 goto out; 
6221  
6222 +       if (!gr_tpe_allow(file)) {
6223 +               retval = -EACCES;
6224 +               goto out;
6225 +       }
6226 +
6227 +       if(gr_check_crash_exec(file)) {
6228 +               retval = -EACCES;
6229 +               goto out;
6230 +       }
6231 +
6232         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
6233         if (retval < 0) 
6234                 goto out; 
6235  
6236         bprm.exec = bprm.p;
6237 +
6238 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
6239 +
6240 +       gr_handle_exec_args(&bprm, argv);
6241 +
6242         retval = copy_strings(bprm.envc, envp, &bprm);
6243         if (retval < 0) 
6244                 goto out; 
6245 @@ -947,11 +1028,32 @@
6246         if (retval < 0) 
6247                 goto out; 
6248  
6249 +#ifdef CONFIG_GRKERNSEC
6250 +       old_acl = current->acl;
6251 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
6252 +       old_exec_file = current->exec_file;
6253 +       get_file(file);
6254 +       current->exec_file = file;
6255 +#endif
6256 +
6257 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
6258 +
6259         retval = search_binary_handler(&bprm,regs);
6260 -       if (retval >= 0)
6261 +       if (retval >= 0) {
6262 +#ifdef CONFIG_GRKERNSEC
6263 +               if (old_exec_file)
6264 +                       fput(old_exec_file);
6265 +#endif
6266                 /* execve success */
6267                 return retval;
6268 +       }
6269  
6270 +#ifdef CONFIG_GRKERNSEC
6271 +       current->acl = old_acl;
6272 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
6273 +       fput(current->exec_file);
6274 +       current->exec_file = old_exec_file;
6275 +#endif
6276  out:
6277         /* Something went wrong, return the inode and free the argument pages*/
6278         allow_write_access(bprm.file);
6279 @@ -1093,6 +1195,130 @@
6280         *out_ptr = 0;
6281  }
6282  
6283 +int pax_check_flags(unsigned long * flags)
6284 +{
6285 +       int retval = 0;
6286 +
6287 +#if !defined(__i386__) || !defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
6288 +       if (*flags & PF_PAX_SEGMEXEC)
6289 +       {
6290 +               *flags &= ~PF_PAX_SEGMEXEC;
6291 +               retval = -EINVAL;
6292 +       }
6293 +#endif
6294 +
6295 +       if ((*flags & PF_PAX_PAGEEXEC)
6296 +
6297 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEXEC
6298 +           &&  (*flags & PF_PAX_SEGMEXEC)
6299 +#endif
6300 +
6301 +          )
6302 +       {
6303 +               *flags &= ~PF_PAX_PAGEEXEC;
6304 +               retval = -EINVAL;
6305 +       }
6306 +
6307 +       if ((*flags & PF_PAX_MPROTECT)
6308 +
6309 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
6310 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
6311 +#endif
6312 +
6313 +          )
6314 +       {
6315 +               *flags &= ~PF_PAX_MPROTECT;
6316 +               retval = -EINVAL;
6317 +       }
6318 +
6319 +       if ((*flags & PF_PAX_EMUTRAMP)
6320 +
6321 +#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
6322 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
6323 +#endif
6324 +
6325 +          )
6326 +       {
6327 +               *flags &= ~PF_PAX_EMUTRAMP;
6328 +               retval = -EINVAL;
6329 +       }
6330 +
6331 +       if ((*flags & PF_PAX_RANDEXEC)
6332 +
6333 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
6334 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
6335 +#endif
6336 +
6337 +          )
6338 +       {
6339 +               *flags &= ~PF_PAX_RANDEXEC;
6340 +               retval = -EINVAL;
6341 +       }
6342 +
6343 +       return retval;
6344 +}
6345 +
6346 +EXPORT_SYMBOL(pax_check_flags);
6347 +
6348 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
6349 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
6350 +{
6351 +       struct task_struct *tsk = current;
6352 +       struct mm_struct *mm = current->mm;
6353 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
6354 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
6355 +       char* path_exec=NULL;
6356 +       char* path_fault=NULL;
6357 +       unsigned long start=0UL, end=0UL, offset=0UL;
6358 +
6359 +       if (buffer_exec && buffer_fault) {
6360 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
6361 +
6362 +               down_read(&mm->mmap_sem);
6363 +               vma = mm->mmap;
6364 +               while (vma && (!vma_exec || !vma_fault)) {
6365 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
6366 +                               vma_exec = vma;
6367 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
6368 +                               vma_fault = vma;
6369 +                       vma = vma->vm_next;
6370 +               }
6371 +               if (vma_exec) {
6372 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
6373 +                       if (IS_ERR(path_exec))
6374 +                               path_exec = "<path too long>";
6375 +               }
6376 +               if (vma_fault) {
6377 +                       start = vma_fault->vm_start;
6378 +                       end = vma_fault->vm_end;
6379 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
6380 +                       if (vma_fault->vm_file) {
6381 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
6382 +                               if (IS_ERR(path_fault))
6383 +                                       path_fault = "<path too long>";
6384 +                       } else
6385 +                               path_fault = "<anonymous mapping>";
6386 +               }
6387 +               up_read(&mm->mmap_sem);
6388 +       }
6389 +       if (tsk->curr_ip) {
6390 +               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);
6391 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: terminating task: %s(%s):%d, uid/euid: %u/%u, "
6392 +                               "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), path_exec, tsk->comm, tsk->pid,
6393 +                               tsk->uid, tsk->euid, pc, sp);
6394 +       } else {
6395 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
6396 +               printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
6397 +                               "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
6398 +                               tsk->uid, tsk->euid, pc, sp);
6399 +       }
6400 +       if (buffer_exec) free_page((unsigned long)buffer_exec);
6401 +       if (buffer_fault) free_page((unsigned long)buffer_fault);
6402 +       pax_report_insns(pc);
6403 +       do_coredump(SIGKILL, regs);
6404 +}
6405 +#endif
6406 +
6407  int do_coredump(long signr, struct pt_regs * regs)
6408  {
6409         struct linux_binfmt * binfmt;
6410 @@ -1113,6 +1339,7 @@
6411                 current->fsuid = 0;
6412         }
6413         current->mm->dumpable = 0;
6414 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
6415         if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
6416                 goto fail;
6417  
6418 @@ -1132,7 +1359,7 @@
6419                 goto close_fail;
6420         if (!file->f_op->write)
6421                 goto close_fail;
6422 -       if (do_truncate(file->f_dentry, 0) != 0)
6423 +       if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
6424                 goto close_fail;
6425  
6426         retval = binfmt->core_dump(signr, regs, file);
6427 diff -urN linux-2.4.24.org/fs/fcntl.c linux-2.4.24/fs/fcntl.c
6428 --- linux-2.4.24.org/fs/fcntl.c 2004-01-05 18:40:39.222148080 +0100
6429 +++ linux-2.4.24/fs/fcntl.c     2004-01-05 18:43:05.233950912 +0100
6430 @@ -12,6 +12,7 @@
6431  #include <linux/slab.h>
6432  #include <linux/iobuf.h>
6433  #include <linux/ptrace.h>
6434 +#include <linux/grsecurity.h>
6435  
6436  #include <asm/poll.h>
6437  #include <asm/siginfo.h>
6438 @@ -65,6 +66,8 @@
6439         int error;
6440         int start;
6441  
6442 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
6443 +
6444         write_lock(&files->file_lock);
6445         
6446         error = -EINVAL;
6447 @@ -87,6 +90,7 @@
6448         }
6449         
6450         error = -EMFILE;
6451 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6452         if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6453                 goto out;
6454  
6455 @@ -142,6 +146,8 @@
6456         struct file * file, *tofree;
6457         struct files_struct * files = current->files;
6458  
6459 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6460 +
6461         write_lock(&files->file_lock);
6462         if (!(file = fcheck(oldfd)))
6463                 goto out_unlock;
6464 @@ -450,6 +456,10 @@
6465                         match = -p->pgrp;
6466                 if (pid != match)
6467                         continue;
6468 +               if (gr_check_protected_task(p))
6469 +                       continue;
6470 +               if (gr_pid_is_chrooted(p))
6471 +                       continue;
6472                 send_sigio_to_task(p, fown, fd, band);
6473         }
6474  out:
6475 diff -urN linux-2.4.24.org/fs/locks.c linux-2.4.24/fs/locks.c
6476 --- linux-2.4.24.org/fs/locks.c 2004-01-05 18:40:58.184265400 +0100
6477 +++ linux-2.4.24/fs/locks.c     2004-01-05 18:50:06.125965600 +0100
6478 @@ -137,6 +137,8 @@
6479  /* Allocate an empty lock structure. */
6480  static struct file_lock *locks_alloc_lock(void)
6481  {
6482 +// XXX?
6483 +//     if(account) gr_learn_resource(current, RLIMIT_LOCKS, current->locks, 0);
6484         return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
6485  }
6486  
6487 diff -urN linux-2.4.24.org/fs/Makefile linux-2.4.24/fs/Makefile
6488 --- linux-2.4.24.org/fs/Makefile        2004-01-05 18:40:59.351088016 +0100
6489 +++ linux-2.4.24/fs/Makefile    2004-01-05 18:48:24.870358792 +0100
6490 @@ -7,7 +7,7 @@
6491  
6492  O_TARGET := fs.o
6493  
6494 -export-objs := filesystems.o open.o dcache.o buffer.o dquot.o
6495 +export-objs := filesystems.o open.o dcache.o buffer.o dquot.o exec.o
6496  mod-subdirs := nls xfs
6497  
6498  obj-y :=       open.o read_write.o devices.o file_table.o buffer.o \
6499 diff -urN linux-2.4.24.org/fs/namei.c linux-2.4.24/fs/namei.c
6500 --- linux-2.4.24.org/fs/namei.c 2004-01-05 18:41:00.110972496 +0100
6501 +++ linux-2.4.24/fs/namei.c     2004-01-05 18:56:09.000800240 +0100
6502 @@ -22,6 +22,7 @@
6503  #include <linux/dnotify.h>
6504  #include <linux/smp_lock.h>
6505  #include <linux/personality.h>
6506 +#include <linux/grsecurity.h>
6507  
6508  #include <asm/namei.h>
6509  #include <asm/uaccess.h>
6510 @@ -343,6 +344,13 @@
6511                 current->state = TASK_RUNNING;
6512                 schedule();
6513         }
6514 +
6515 +       if (gr_handle_follow_link(dentry->d_parent->d_inode,
6516 +                                 dentry->d_inode, dentry, nd->mnt)) {
6517 +               path_release(nd);
6518 +               return -EACCES;
6519 +       }
6520 +
6521         current->link_count++;
6522         current->total_link_count++;
6523         UPDATE_ATIME(dentry->d_inode);
6524 @@ -643,6 +651,10 @@
6525                         }
6526                 }
6527  return_base:
6528 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
6529 +                       path_release(nd);
6530 +                       return -ENOENT;
6531 +               }
6532                 return 0;
6533  out_dput:
6534                 dput(dentry);
6535 @@ -1005,7 +1017,7 @@
6536         struct dentry *dentry;
6537         struct dentry *dir;
6538         int count = 0;
6539 -
6540 +       
6541         acc_mode = ACC_MODE(flag);
6542  
6543         /*
6544 @@ -1015,7 +1027,19 @@
6545                 error = path_lookup(pathname, lookup_flags(flag), nd);
6546                 if (error)
6547                         return error;
6548 +
6549 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
6550 +                       error = -EPERM;
6551 +                       goto exit;
6552 +               }
6553 +       
6554 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
6555 +                       error = -EACCES;
6556 +                       goto exit;
6557 +               }
6558 +
6559                 dentry = nd->dentry;
6560 +
6561                 goto ok;
6562         }
6563  
6564 @@ -1048,9 +1072,21 @@
6565  
6566         /* Negative dentry, just create the file */
6567         if (!dentry->d_inode) {
6568 -               if (!IS_POSIXACL(dir->d_inode))
6569 -                       mode &= ~current->fs->umask;
6570 +               if (!IS_POSIXACL(dir->d_inode))
6571 +                       mode &= ~current->fs->umask;
6572 +               if (gr_handle_chroot_chmod(dentry, nd->mnt, mode)) {
6573 +                       error = -EACCES;
6574 +                       up(&dir->d_inode->i_sem);
6575 +                       goto exit_dput;
6576 +               }
6577 +               if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
6578 +                       error = -EACCES;
6579 +                       up(&dir->d_inode->i_sem);
6580 +                       goto exit_dput;
6581 +               }                   
6582                 error = vfs_create(dir->d_inode, dentry, mode);
6583 +               if (!error)
6584 +                       gr_handle_create(dentry, nd->mnt);
6585                 up(&dir->d_inode->i_sem);
6586                 dput(nd->dentry);
6587                 nd->dentry = dentry;
6588 @@ -1059,12 +1095,34 @@
6589                 /* Don't check for write permission, don't truncate */
6590                 acc_mode = 0;
6591                 flag &= ~O_TRUNC;
6592 +
6593                 goto ok;
6594         }
6595  
6596         /*
6597          * It already exists.
6598          */
6599 +
6600 +       if (gr_handle_rawio(dentry->d_inode)) {
6601 +               error = -EPERM;
6602 +               up(&dir->d_inode->i_sem);
6603 +               goto exit_dput;
6604 +       }
6605 +
6606 +       if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
6607 +               error = -EACCES;
6608 +               up(&dir->d_inode->i_sem);
6609 +               goto exit_dput;
6610 +       }
6611 +
6612 +       inode = dentry->d_inode;
6613 +
6614 +       if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
6615 +               up(&dir->d_inode->i_sem);
6616 +               error = -EACCES;
6617 +               goto exit_dput;
6618 +       }
6619 +
6620         up(&dir->d_inode->i_sem);
6621  
6622         error = -EEXIST;
6623 @@ -1154,7 +1212,7 @@
6624                 if (!error) {
6625                         DQUOT_INIT(inode);
6626                         
6627 -                       error = do_truncate(dentry, 0);
6628 +                       error = do_truncate(dentry,0,nd->mnt);
6629                 }
6630                 put_write_access(inode);
6631                 if (error)
6632 @@ -1185,6 +1243,13 @@
6633          * stored in nd->last.name and we will have to putname() it when we
6634          * are done. Procfs-like symlinks just set LAST_BIND.
6635          */
6636 +
6637 +       if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
6638 +                                 dentry, nd->mnt)) {
6639 +               error = -EACCES;
6640 +               goto exit_dput;
6641 +       }
6642 +
6643         UPDATE_ATIME(dentry->d_inode);
6644         error = dentry->d_inode->i_op->follow_link(dentry, nd);
6645         dput(dentry);
6646 @@ -1284,6 +1349,19 @@
6647         if (!IS_POSIXACL(nd.dentry->d_inode))
6648                 mode &= ~current->fs->umask;
6649         if (!IS_ERR(dentry)) {
6650 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode) ||
6651 +                   gr_handle_chroot_chmod(dentry, nd.mnt, mode)) {
6652 +                       error = -EPERM;
6653 +                       dput(dentry);
6654 +                       goto out_dput;
6655 +               }
6656 +
6657 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
6658 +                       error = -EACCES;
6659 +                       dput(dentry);
6660 +                       goto out_dput;
6661 +               }
6662 +       
6663                 switch (mode & S_IFMT) {
6664                 case 0: case S_IFREG:
6665                         error = vfs_create(nd.dentry->d_inode,dentry,mode);
6666 @@ -1297,8 +1375,13 @@
6667                 default:
6668                         error = -EINVAL;
6669                 }
6670 +
6671 +               if(!error)
6672 +                       gr_handle_create(dentry, nd.mnt);
6673 +
6674                 dput(dentry);
6675         }
6676 +out_dput:
6677         up(&nd.dentry->d_inode->i_sem);
6678         path_release(&nd);
6679  out:
6680 @@ -1350,9 +1433,15 @@
6681                 dentry = lookup_create(&nd, 1);
6682                 error = PTR_ERR(dentry);
6683                 if (!IS_ERR(dentry)) {
6684 +                       error = 0;
6685                         if (!IS_POSIXACL(nd.dentry->d_inode))
6686 -                               mode &= ~current->fs->umask;
6687 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6688 +                               mode &= ~current->fs->umask;
6689 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
6690 +                               error = -EACCES;
6691 +                       if (!error)
6692 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6693 +                       if(!error)
6694 +                               gr_handle_create(dentry, nd.mnt);
6695                         dput(dentry);
6696                 }
6697                 up(&nd.dentry->d_inode->i_sem);
6698 @@ -1436,6 +1525,8 @@
6699         char * name;
6700         struct dentry *dentry;
6701         struct nameidata nd;
6702 +       ino_t saved_ino = 0;
6703 +       kdev_t saved_dev = 0;
6704  
6705         name = getname(pathname);
6706         if(IS_ERR(name))
6707 @@ -1460,7 +1551,22 @@
6708         dentry = lookup_hash(&nd.last, nd.dentry);
6709         error = PTR_ERR(dentry);
6710         if (!IS_ERR(dentry)) {
6711 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
6712 +               error = 0;
6713 +               if (dentry->d_inode) {
6714 +                       if (dentry->d_inode->i_nlink <= 1) {
6715 +                               saved_ino = dentry->d_inode->i_ino;
6716 +                               saved_dev = dentry->d_inode->i_dev;
6717 +                       }
6718 +
6719 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
6720 +                               error = -EACCES;
6721 +               }
6722 +
6723 +               if (!error)
6724 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
6725 +               if (!error && (saved_dev || saved_ino))
6726 +                       gr_handle_delete(saved_ino,saved_dev);
6727 +
6728                 dput(dentry);
6729         }
6730         up(&nd.dentry->d_inode->i_sem);
6731 @@ -1505,6 +1611,8 @@
6732         char * name;
6733         struct dentry *dentry;
6734         struct nameidata nd;
6735 +       ino_t saved_ino = 0;
6736 +       kdev_t saved_dev = 0;
6737  
6738         name = getname(pathname);
6739         if(IS_ERR(name))
6740 @@ -1523,7 +1631,21 @@
6741                 /* Why not before? Because we want correct error value */
6742                 if (nd.last.name[nd.last.len])
6743                         goto slashes;
6744 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
6745 +               error = 0;
6746 +               if (dentry->d_inode) {
6747 +                       if (dentry->d_inode->i_nlink <= 1) {
6748 +                               saved_ino = dentry->d_inode->i_ino;
6749 +                               saved_dev = dentry->d_inode->i_dev;
6750 +                       }
6751 +
6752 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
6753 +                               error = -EACCES;
6754 +               }
6755 +
6756 +               if (!error)
6757 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
6758 +               if (!error && (saved_ino || saved_dev))
6759 +                       gr_handle_delete(saved_ino,saved_dev);
6760         exit2:
6761                 dput(dentry);
6762         }
6763 @@ -1587,7 +1709,15 @@
6764                 dentry = lookup_create(&nd, 0);
6765                 error = PTR_ERR(dentry);
6766                 if (!IS_ERR(dentry)) {
6767 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6768 +                       error = 0;
6769 +
6770 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
6771 +                               error = -EACCES;
6772 +
6773 +                       if(!error)      
6774 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6775 +                       if (!error)
6776 +                               gr_handle_create(dentry, nd.mnt);
6777                         dput(dentry);
6778                 }
6779                 up(&nd.dentry->d_inode->i_sem);
6780 @@ -1671,7 +1801,27 @@
6781                 new_dentry = lookup_create(&nd, 0);
6782                 error = PTR_ERR(new_dentry);
6783                 if (!IS_ERR(new_dentry)) {
6784 -                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
6785 +                       error = 0;
6786 +
6787 +                       if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
6788 +                                              old_nd.dentry->d_inode,
6789 +                                              old_nd.dentry->d_inode->i_mode, to)) {
6790 +                               error = -EPERM;
6791 +                               goto out_error;
6792 +                       }
6793 +
6794 +                       if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
6795 +                                                old_nd.dentry, old_nd.mnt, to)) {
6796 +                               error = -EACCES;
6797 +                               goto out_error;
6798 +                       }
6799 +
6800 +                       error = vfs_link(old_nd.dentry, 
6801 +                                       nd.dentry->d_inode, new_dentry);
6802 +
6803 +                       if (!error)
6804 +                               gr_handle_create(new_dentry, nd.mnt);
6805 +out_error:
6806                         dput(new_dentry);
6807                 }
6808                 up(&nd.dentry->d_inode->i_sem);
6809 @@ -1907,10 +2057,15 @@
6810         if (IS_ERR(new_dentry))
6811                 goto exit4;
6812  
6813 -       lock_kernel();
6814 -       error = vfs_rename(old_dir->d_inode, old_dentry,
6815 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
6816 +                                    old_dentry, old_dir->d_inode, oldnd.mnt, newname);
6817 +
6818 +       if (error == 1) {
6819 +               lock_kernel();
6820 +               error = vfs_rename(old_dir->d_inode, old_dentry,
6821                                    new_dir->d_inode, new_dentry);
6822 -       unlock_kernel();
6823 +               unlock_kernel();
6824 +       }
6825  
6826         dput(new_dentry);
6827  exit4:
6828 diff -urN linux-2.4.24.org/fs/namespace.c linux-2.4.24/fs/namespace.c
6829 --- linux-2.4.24.org/fs/namespace.c     2004-01-05 18:40:57.993294432 +0100
6830 +++ linux-2.4.24/fs/namespace.c 2004-01-05 18:43:05.242949544 +0100
6831 @@ -15,6 +15,8 @@
6832  #include <linux/quotaops.h>
6833  #include <linux/acct.h>
6834  #include <linux/module.h>
6835 +#include <linux/sched.h>
6836 +#include <linux/grsecurity.h>
6837  
6838  #include <asm/uaccess.h>
6839  
6840 @@ -325,6 +327,8 @@
6841                         lock_kernel();
6842                         retval = do_remount_sb(sb, MS_RDONLY, 0);
6843                         unlock_kernel();
6844 +
6845 +                       gr_log_remount(mnt->mnt_devname, retval);
6846                 }
6847                 up_write(&sb->s_umount);
6848                 return retval;
6849 @@ -350,6 +354,9 @@
6850         }
6851         spin_unlock(&dcache_lock);
6852         up_write(&current->namespace->sem);
6853 +
6854 +       gr_log_unmount(mnt->mnt_devname, retval);
6855 +
6856         return retval;
6857  }
6858  
6859 @@ -729,6 +736,12 @@
6860         if (retval)
6861                 return retval;
6862  
6863 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
6864 +               retval = -EPERM;
6865 +               path_release(&nd);
6866 +               return retval;
6867 +       }
6868 +
6869         if (flags & MS_REMOUNT)
6870                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
6871                                     data_page);
6872 @@ -740,6 +753,9 @@
6873                 retval = do_add_mount(&nd, type_page, flags, mnt_flags,
6874                                       dev_name, data_page);
6875         path_release(&nd);
6876 +
6877 +       gr_log_mount(dev_name, dir_name, retval);
6878 +
6879         return retval;
6880  }
6881  
6882 @@ -909,6 +925,9 @@
6883         if (!capable(CAP_SYS_ADMIN))
6884                 return -EPERM;
6885  
6886 +       if (gr_handle_chroot_pivot())
6887 +               return -EPERM;
6888 +
6889         lock_kernel();
6890  
6891         error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
6892 diff -urN linux-2.4.24.org/fs/open.c linux-2.4.24/fs/open.c
6893 --- linux-2.4.24.org/fs/open.c  2004-01-05 18:40:59.647043024 +0100
6894 +++ linux-2.4.24/fs/open.c      2004-01-05 18:43:05.244949240 +0100
6895 @@ -15,6 +15,7 @@
6896  #include <linux/slab.h>
6897  #include <linux/tty.h>
6898  #include <linux/iobuf.h>
6899 +#include <linux/grsecurity.h>
6900  
6901  #include <asm/uaccess.h>
6902  
6903 @@ -95,7 +96,7 @@
6904         write_unlock(&files->file_lock);
6905  }
6906  
6907 -int do_truncate(struct dentry *dentry, loff_t length)
6908 +int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
6909  {
6910         struct inode *inode = dentry->d_inode;
6911         int error;
6912 @@ -105,6 +106,9 @@
6913         if (length < 0)
6914                 return -EINVAL;
6915  
6916 +       if (!gr_acl_handle_truncate(dentry, mnt))
6917 +               return -EACCES;
6918 +
6919         down_write(&inode->i_alloc_sem);
6920         down(&inode->i_sem);
6921         newattrs.ia_size = length;
6922 @@ -165,7 +169,7 @@
6923         error = locks_verify_truncate(inode, NULL, length);
6924         if (!error) {
6925                 DQUOT_INIT(inode);
6926 -               error = do_truncate(nd.dentry, length);
6927 +               error = do_truncate(nd.dentry, length, nd.mnt);
6928         }
6929         put_write_access(inode);
6930  
6931 @@ -217,7 +221,7 @@
6932  
6933         error = locks_verify_truncate(inode, file, length);
6934         if (!error)
6935 -               error = do_truncate(dentry, length);
6936 +               error = do_truncate(dentry, length, file->f_vfsmnt);
6937  out_putf:
6938         fput(file);
6939  out:
6940 @@ -292,6 +296,12 @@
6941                     (error = permission(inode,MAY_WRITE)) != 0)
6942                         goto dput_and_out;
6943         }
6944 +
6945 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6946 +               error = -EACCES;
6947 +               goto dput_and_out;
6948 +       }
6949 +
6950         error = notify_change(nd.dentry, &newattrs);
6951  dput_and_out:
6952         path_release(&nd);
6953 @@ -344,6 +354,12 @@
6954                     (error = permission(inode,MAY_WRITE)) != 0)
6955                         goto dput_and_out;
6956         }
6957 +
6958 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6959 +               error = -EACCES;
6960 +               goto dput_and_out;
6961 +       }
6962 +
6963         error = notify_change(nd.dentry, &newattrs);
6964  dput_and_out:
6965         path_release(&nd);
6966 @@ -386,6 +402,10 @@
6967                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
6968                    && !special_file(nd.dentry->d_inode->i_mode))
6969                         res = -EROFS;
6970 +               
6971 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
6972 +                       res =  -EACCES;
6973 +
6974                 path_release(&nd);
6975         }
6976  
6977 @@ -409,6 +429,8 @@
6978         if (error)
6979                 goto dput_and_out;
6980  
6981 +       gr_log_chdir(nd.dentry, nd.mnt);
6982 +
6983         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
6984  
6985  dput_and_out:
6986 @@ -439,6 +461,13 @@
6987                 goto out_putf;
6988  
6989         error = permission(inode, MAY_EXEC);
6990 +
6991 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
6992 +               error = -EPERM;
6993 +
6994 +       if (!error)
6995 +               gr_log_chdir(dentry, mnt);
6996 +
6997         if (!error)
6998                 set_fs_pwd(current->fs, mnt, dentry);
6999  out_putf:
7000 @@ -465,8 +494,16 @@
7001         if (!capable(CAP_SYS_CHROOT))
7002                 goto dput_and_out;
7003  
7004 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
7005 +               goto dput_and_out;
7006 +
7007         set_fs_root(current->fs, nd.mnt, nd.dentry);
7008         set_fs_altroot();
7009 +
7010 +       gr_handle_chroot_caps(current);
7011 +
7012 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
7013 +
7014         error = 0;
7015  dput_and_out:
7016         path_release(&nd);
7017 @@ -495,8 +532,20 @@
7018         err = -EPERM;
7019         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7020                 goto out_putf;
7021 +
7022 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
7023 +               err = -EACCES;
7024 +               goto out_putf;
7025 +       }
7026 +
7027         if (mode == (mode_t) -1)
7028                 mode = inode->i_mode;
7029 +
7030 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
7031 +               err = -EPERM;
7032 +               goto out_putf;
7033 +       }           
7034 +
7035         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
7036         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
7037         err = notify_change(dentry, &newattrs);
7038 @@ -527,8 +576,19 @@
7039         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7040                 goto dput_and_out;
7041  
7042 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
7043 +               error = -EACCES;
7044 +               goto dput_and_out;
7045 +       }
7046 +
7047         if (mode == (mode_t) -1)
7048                 mode = inode->i_mode;
7049 +
7050 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
7051 +               error = -EACCES;
7052 +               goto dput_and_out;
7053 +       }
7054 +
7055         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
7056         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
7057         error = notify_change(nd.dentry, &newattrs);
7058 @@ -539,7 +599,7 @@
7059         return error;
7060  }
7061  
7062 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
7063 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
7064  {
7065         struct inode * inode;
7066         int error;
7067 @@ -556,6 +616,12 @@
7068         error = -EPERM;
7069         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
7070                 goto out;
7071 +
7072 +       if (!gr_acl_handle_chown(dentry, mnt)) {
7073 +               error = -EACCES;
7074 +               goto out;
7075 +       }
7076 +
7077         if (user == (uid_t) -1)
7078                 user = inode->i_uid;
7079         if (group == (gid_t) -1)
7080 @@ -606,7 +672,7 @@
7081  
7082         error = user_path_walk(filename, &nd);
7083         if (!error) {
7084 -               error = chown_common(nd.dentry, user, group);
7085 +               error = chown_common(nd.dentry, user, group, nd.mnt);
7086                 path_release(&nd);
7087         }
7088         return error;
7089 @@ -619,7 +685,7 @@
7090  
7091         error = user_path_walk_link(filename, &nd);
7092         if (!error) {
7093 -               error = chown_common(nd.dentry, user, group);
7094 +               error = chown_common(nd.dentry, user, group, nd.mnt);
7095                 path_release(&nd);
7096         }
7097         return error;
7098 @@ -633,7 +699,8 @@
7099  
7100         file = fget(fd);
7101         if (file) {
7102 -               error = chown_common(file->f_dentry, user, group);
7103 +               error = chown_common(file->f_dentry, user,
7104 +                               group, file->f_vfsmnt);
7105                 fput(file);
7106         }
7107         return error;
7108 @@ -753,6 +820,7 @@
7109          * N.B. For clone tasks sharing a files structure, this test
7110          * will limit the total number of files that can be opened.
7111          */
7112 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
7113         if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
7114                 goto out;
7115  
7116 diff -urN linux-2.4.24.org/fs/proc/array.c linux-2.4.24/fs/proc/array.c
7117 --- linux-2.4.24.org/fs/proc/array.c    2004-01-05 18:40:54.257862304 +0100
7118 +++ linux-2.4.24/fs/proc/array.c        2004-01-05 18:43:05.245949088 +0100
7119 @@ -298,6 +298,12 @@
7120         return buffer - orig;
7121  }
7122  
7123 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7124 +#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
7125 +                       task->flags & PF_PAX_SEGMEXEC || \
7126 +                       task->flags & PF_PAX_RANDEXEC)
7127 +#endif
7128 +
7129  int proc_pid_stat(struct task_struct *task, char * buffer)
7130  {
7131         unsigned long vsize, eip, esp, wchan;
7132 @@ -335,6 +341,19 @@
7133  
7134         wchan = get_wchan(task);
7135  
7136 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7137 +       if (PAX_RAND_FLAGS) {
7138 +               eip = 0;
7139 +               esp = 0;
7140 +               wchan = 0;
7141 +       }
7142 +#endif
7143 +#ifdef CONFIG_GRKERNSEC_HIDESYM
7144 +       wchan = 0;
7145 +       eip = 0;
7146 +       esp = 0;
7147 +#endif
7148 +
7149         collect_sigign_sigcatch(task, &sigign, &sigcatch);
7150  
7151         /* scale priority and nice values from timeslices to -20..20 */
7152 @@ -373,9 +392,15 @@
7153                 vsize,
7154                 mm ? mm->rss : 0, /* you might want to shift this left 3 */
7155                 task->rlim[RLIMIT_RSS].rlim_cur,
7156 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7157 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
7158 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
7159 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
7160 +#else
7161                 mm ? mm->start_code : 0,
7162                 mm ? mm->end_code : 0,
7163                 mm ? mm->start_stack : 0,
7164 +#endif
7165                 esp,
7166                 eip,
7167                 /* The signal information here is obsolete.
7168 @@ -513,6 +538,7 @@
7169  
7170  static int show_map(struct seq_file *m, void *v)
7171  {
7172 +       struct task_struct *task = m->private;
7173         struct vm_area_struct *map = v;
7174         struct file *file = map->vm_file;
7175         int flags = map->vm_flags;
7176 @@ -527,8 +553,13 @@
7177         }
7178  
7179         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
7180 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7181 +                       PAX_RAND_FLAGS ? 0UL : map->vm_start,
7182 +                       PAX_RAND_FLAGS ? 0UL : map->vm_end,
7183 +#else
7184                         map->vm_start,
7185                         map->vm_end,
7186 +#endif
7187                         flags & VM_READ ? 'r' : '-',
7188                         flags & VM_WRITE ? 'w' : '-',
7189                         flags & VM_EXEC ? 'x' : '-',
7190 @@ -601,6 +632,16 @@
7191         .show   = show_map
7192  };
7193  
7194 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR     
7195 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)    
7196 +{       
7197 +       int len;         
7198 +
7199 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));  
7200 +       return len;      
7201 +}       
7202 +#endif
7203 +
7204  #ifdef CONFIG_SMP
7205  int proc_pid_cpu(struct task_struct *task, char * buffer)
7206  {
7207 diff -urN linux-2.4.24.org/fs/proc/base.c linux-2.4.24/fs/proc/base.c
7208 --- linux-2.4.24.org/fs/proc/base.c     2004-01-05 18:40:54.166876136 +0100
7209 +++ linux-2.4.24/fs/proc/base.c 2004-01-05 18:43:05.246948936 +0100
7210 @@ -25,6 +25,7 @@
7211  #include <linux/string.h>
7212  #include <linux/seq_file.h>
7213  #include <linux/namespace.h>
7214 +#include <linux/grsecurity.h>
7215  
7216  /*
7217   * For hysterical raisins we keep the same inumbers as in the old procfs.
7218 @@ -40,6 +41,9 @@
7219  int proc_pid_status(struct task_struct*,char*);
7220  int proc_pid_statm(struct task_struct*,char*);
7221  int proc_pid_cpu(struct task_struct*,char*);
7222 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7223 +int proc_pid_ipaddr(struct task_struct*,char*);
7224 +#endif
7225  
7226  static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
7227  {
7228 @@ -263,9 +267,22 @@
7229  
7230  static int proc_permission(struct inode *inode, int mask)
7231  {
7232 +       int ret;
7233 +       struct task_struct *task;
7234 +
7235         if (vfs_permission(inode, mask) != 0)
7236                 return -EACCES;
7237 -       return proc_check_root(inode);
7238 +       ret = proc_check_root(inode);
7239 +
7240 +       if (ret)
7241 +               return ret;
7242 +
7243 +       task = inode->u.proc_i.task;
7244 +
7245 +       if (!task)
7246 +               return 0;
7247 +
7248 +       return gr_acl_handle_procpidmem(task);
7249  }
7250  
7251  extern struct seq_operations proc_pid_maps_op;
7252 @@ -598,6 +615,9 @@
7253         PROC_PID_STATM,
7254         PROC_PID_MAPS,
7255         PROC_PID_CPU,
7256 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7257 +       PROC_PID_IPADDR,
7258 +#endif
7259         PROC_PID_MOUNTS,
7260         PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
7261  };
7262 @@ -613,6 +633,9 @@
7263  #ifdef CONFIG_SMP
7264    E(PROC_PID_CPU,      "cpu",          S_IFREG|S_IRUGO),
7265  #endif
7266 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7267 +  E(PROC_PID_IPADDR,   "ipaddr",       S_IFREG|S_IRUSR),
7268 +#endif
7269    E(PROC_PID_MAPS,     "maps",         S_IFREG|S_IRUGO),
7270    E(PROC_PID_MEM,      "mem",          S_IFREG|S_IRUSR|S_IWUSR),
7271    E(PROC_PID_CWD,      "cwd",          S_IFLNK|S_IRWXUGO),
7272 @@ -769,10 +792,17 @@
7273         get_task_struct(task);
7274         inode->u.proc_i.task = task;
7275         inode->i_uid = 0;
7276 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7277 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7278 +#else
7279         inode->i_gid = 0;
7280 +#endif
7281 +
7282         if (ino == PROC_PID_INO || task_dumpable(task)) {
7283                 inode->i_uid = task->euid;
7284 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
7285                 inode->i_gid = task->egid;
7286 +#endif
7287         }
7288  
7289  out:
7290 @@ -980,6 +1010,12 @@
7291                         inode->u.proc_i.op.proc_read = proc_pid_cpu;
7292                         break;
7293  #endif
7294 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
7295 +               case PROC_PID_IPADDR:
7296 +                       inode->i_fop = &proc_info_file_operations;
7297 +                       inode->u.proc_i.op.proc_read = proc_pid_ipaddr;
7298 +                       break;
7299 +#endif
7300                 case PROC_PID_MEM:
7301                         inode->i_op = &proc_mem_inode_operations;
7302                         inode->i_fop = &proc_mem_operations;
7303 @@ -1078,13 +1114,35 @@
7304         if (!task)
7305                 goto out;
7306  
7307 +       if(gr_check_hidden_task(task)) {
7308 +               free_task_struct(task);
7309 +               goto out;
7310 +       }
7311 +       
7312 +#ifdef CONFIG_GRKERNSEC_PROC
7313 +       if (current->uid && (task->uid != current->uid)
7314 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7315 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7316 +#endif
7317 +       ) {
7318 +               free_task_struct(task);
7319 +               goto out;
7320 +       }       
7321 +#endif
7322         inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
7323  
7324         free_task_struct(task);
7325  
7326         if (!inode)
7327                 goto out;
7328 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7329 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
7330 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7331 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
7332 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7333 +#else
7334         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
7335 +#endif
7336         inode->i_op = &proc_base_inode_operations;
7337         inode->i_fop = &proc_base_operations;
7338         inode->i_nlink = 3;
7339 @@ -1124,6 +1182,18 @@
7340                 int pid = p->pid;
7341                 if (!pid)
7342                         continue;
7343 +               if(gr_pid_is_chrooted(p))
7344 +                       continue;
7345 +               if(gr_check_hidden_task(p)) 
7346 +                       continue;
7347 +#ifdef CONFIG_GRKERNSEC_PROC
7348 +               if (current->uid && (p->uid != current->uid)
7349 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7350 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7351 +#endif
7352 +               )
7353 +                       continue;       
7354 +#endif
7355                 if (--index >= 0)
7356                         continue;
7357                 pids[nr_pids] = pid;
7358 diff -urN linux-2.4.24.org/fs/proc/generic.c linux-2.4.24/fs/proc/generic.c
7359 --- linux-2.4.24.org/fs/proc/generic.c  2004-01-05 18:40:54.483827952 +0100
7360 +++ linux-2.4.24/fs/proc/generic.c      2004-01-05 18:43:05.247948784 +0100
7361 @@ -504,6 +504,32 @@
7362         return ent;
7363  }
7364  
7365 +#ifdef CONFIG_GRKERNSEC_PROC
7366 +struct proc_dir_entry *proc_priv_mkdir(const char *name, struct proc_dir_entry *parent)
7367 +{
7368 +       struct proc_dir_entry *ent;
7369 +       mode_t mode = 0;
7370 +
7371 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7372 +       mode = S_IFDIR | S_IRUSR | S_IXUSR;
7373 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7374 +       mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP;
7375 +#endif
7376 +
7377 +       ent = proc_create(&parent, name, mode, 2);
7378 +       if (ent) {
7379 +               ent->proc_fops = &proc_dir_operations;
7380 +               ent->proc_iops = &proc_dir_inode_operations;
7381 +
7382 +               if (proc_register(parent, ent) < 0) {
7383 +                       kfree(ent);
7384 +                       ent = NULL;
7385 +               }
7386 +       }
7387 +       return ent;
7388 +}
7389 +#endif
7390 +
7391  struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
7392                                          struct proc_dir_entry *parent)
7393  {
7394 diff -urN linux-2.4.24.org/fs/proc/inode.c linux-2.4.24/fs/proc/inode.c
7395 --- linux-2.4.24.org/fs/proc/inode.c    2004-01-05 18:40:54.192872184 +0100
7396 +++ linux-2.4.24/fs/proc/inode.c        2004-01-05 18:43:05.247948784 +0100
7397 @@ -152,7 +152,11 @@
7398                 if (de->mode) {
7399                         inode->i_mode = de->mode;
7400                         inode->i_uid = de->uid;
7401 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7402 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7403 +#else
7404                         inode->i_gid = de->gid;
7405 +#endif                 
7406                 }
7407                 if (de->size)
7408                         inode->i_size = de->size;
7409 diff -urN linux-2.4.24.org/fs/proc/proc_misc.c linux-2.4.24/fs/proc/proc_misc.c
7410 --- linux-2.4.24.org/fs/proc/proc_misc.c        2004-01-05 18:40:54.441834336 +0100
7411 +++ linux-2.4.24/fs/proc/proc_misc.c    2004-01-05 18:43:05.248948632 +0100
7412 @@ -590,6 +590,7 @@
7413  void __init proc_misc_init(void)
7414  {
7415         struct proc_dir_entry *entry;
7416 +       int gr_mode = 0;
7417         static struct {
7418                 char *name;
7419                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
7420 @@ -604,17 +605,21 @@
7421  #ifdef CONFIG_STRAM_PROC
7422                 {"stram",       stram_read_proc},
7423  #endif
7424 -#ifdef CONFIG_MODULES
7425 +#if defined(CONFIG_MODULES) && !defined(CONFIG_GRKERNSEC_PROC)
7426                 {"modules",     modules_read_proc},
7427  #endif
7428                 {"stat",        kstat_read_proc},
7429 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7430                 {"devices",     devices_read_proc},
7431 -#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
7432 +#endif
7433 +#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
7434                 {"interrupts",  interrupts_read_proc},
7435  #endif
7436                 {"filesystems", filesystems_read_proc},
7437 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7438                 {"dma",         dma_read_proc},
7439                 {"cmdline",     cmdline_read_proc},
7440 +#endif
7441  #ifdef CONFIG_SGI_DS1286
7442                 {"rtc",         ds1286_read_proc},
7443  #endif
7444 @@ -626,29 +631,60 @@
7445         for (p = simple_ones; p->name; p++)
7446                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
7447  
7448 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7449 +       gr_mode = S_IRUSR;
7450 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7451 +       gr_mode = S_IRUSR | S_IRGRP;
7452 +#endif
7453 +#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES)
7454 +       create_proc_read_entry("modules", gr_mode, NULL, &modules_read_proc, NULL);
7455 +#endif
7456 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7457 +       create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
7458 +       create_proc_read_entry("dma", gr_mode, NULL, &dma_read_proc, NULL);
7459 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
7460 +#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
7461 +       create_proc_read_entry("interrupts", gr_mode, NULL, &interrupts_read_proc, NULL);
7462 +#endif
7463 +#endif
7464 +
7465         proc_symlink("mounts", NULL, "self/mounts");
7466  
7467         /* And now for trickier ones */
7468         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
7469         if (entry)
7470                 entry->proc_fops = &proc_kmsg_operations;
7471 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7472 +       create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
7473 +#else
7474         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
7475 -#if defined(CONFIG_X86)
7476 +#endif
7477 +#if defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
7478         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
7479 +#elif defined(CONFIG_X86)
7480 +       create_seq_entry("interrupts", gr_mode, &proc_interrupts_operations);
7481  #endif
7482 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7483 +       create_seq_entry("ioports", gr_mode, &proc_ioports_operations);
7484 +       create_seq_entry("iomem", gr_mode, &proc_iomem_operations);
7485 +       create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
7486 +#else
7487         create_seq_entry("ioports", 0, &proc_ioports_operations);
7488         create_seq_entry("iomem", 0, &proc_iomem_operations);
7489 -       create_seq_entry("partitions", 0, &proc_partitions_operations);
7490         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
7491 +#endif
7492 +       create_seq_entry("partitions", 0, &proc_partitions_operations);
7493  #ifdef CONFIG_MODULES
7494 -       create_seq_entry("ksyms", 0, &proc_ksyms_operations);
7495 +       create_seq_entry("ksyms", gr_mode, &proc_ksyms_operations);
7496  #endif
7497 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7498         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
7499         if (proc_root_kcore) {
7500                 proc_root_kcore->proc_fops = &proc_kcore_operations;
7501                 proc_root_kcore->size =
7502                                 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
7503         }
7504 +#endif
7505         if (prof_shift) {
7506                 entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
7507                 if (entry) {
7508 diff -urN linux-2.4.24.org/fs/proc/proc_tty.c linux-2.4.24/fs/proc/proc_tty.c
7509 --- linux-2.4.24.org/fs/proc/proc_tty.c 2004-01-05 18:40:54.513823392 +0100
7510 +++ linux-2.4.24/fs/proc/proc_tty.c     2004-01-05 18:43:05.248948632 +0100
7511 @@ -174,7 +174,11 @@
7512         if (!proc_mkdir("tty", 0))
7513                 return;
7514         proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
7515 +#ifdef CONFIG_GRKERNSEC_PROC
7516 +       proc_tty_driver = proc_priv_mkdir("tty/driver", 0);
7517 +#else
7518         proc_tty_driver = proc_mkdir("tty/driver", 0);
7519 +#endif
7520  
7521         create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
7522         create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
7523 diff -urN linux-2.4.24.org/fs/proc/root.c linux-2.4.24/fs/proc/root.c
7524 --- linux-2.4.24.org/fs/proc/root.c     2004-01-05 18:40:54.481828256 +0100
7525 +++ linux-2.4.24/fs/proc/root.c 2004-01-05 18:43:05.249948480 +0100
7526 @@ -37,13 +37,21 @@
7527                 return;
7528         }
7529         proc_misc_init();
7530 +#ifdef CONFIG_GRKERNSEC_PROC
7531 +       proc_net = proc_priv_mkdir("net", 0);
7532 +#else
7533         proc_net = proc_mkdir("net", 0);
7534 +#endif
7535  #ifdef CONFIG_SYSVIPC
7536         proc_mkdir("sysvipc", 0);
7537  #endif
7538  #ifdef CONFIG_SYSCTL
7539 +#ifdef CONFIG_GRKERNSEC_PROC
7540 +       proc_sys_root = proc_priv_mkdir("sys", 0);
7541 +#else
7542         proc_sys_root = proc_mkdir("sys", 0);
7543  #endif
7544 +#endif
7545  #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
7546         proc_mkdir("sys/fs", 0);
7547         proc_mkdir("sys/fs/binfmt_misc", 0);
7548 @@ -67,7 +75,12 @@
7549  #ifdef CONFIG_PPC_RTAS
7550         proc_rtas_init();
7551  #endif
7552 +
7553 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7554 +       proc_bus = proc_priv_mkdir("bus", 0);
7555 +#else
7556         proc_bus = proc_mkdir("bus", 0);
7557 +#endif
7558  }
7559  
7560  static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
7561 diff -urN linux-2.4.24.org/fs/readdir.c linux-2.4.24/fs/readdir.c
7562 --- linux-2.4.24.org/fs/readdir.c       2004-01-05 18:40:59.630045608 +0100
7563 +++ linux-2.4.24/fs/readdir.c   2004-01-05 18:43:05.250948328 +0100
7564 @@ -10,6 +10,7 @@
7565  #include <linux/stat.h>
7566  #include <linux/file.h>
7567  #include <linux/smp_lock.h>
7568 +#include <linux/grsecurity.h>
7569  
7570  #include <asm/uaccess.h>
7571  
7572 @@ -181,6 +182,7 @@
7573  struct readdir_callback {
7574         struct old_linux_dirent * dirent;
7575         int count;
7576 +       struct nameidata nd;
7577  };
7578  
7579  static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
7580 @@ -191,6 +193,10 @@
7581  
7582         if (buf->count)
7583                 return -EINVAL;
7584 +
7585 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7586 +               return 0;
7587 +           
7588         buf->count++;
7589         dirent = buf->dirent;
7590         put_user(ino, &dirent->d_ino);
7591 @@ -215,6 +221,9 @@
7592         buf.count = 0;
7593         buf.dirent = dirent;
7594  
7595 +       buf.nd.dentry = file->f_dentry;
7596 +       buf.nd.mnt = file->f_vfsmnt;
7597 +
7598         error = vfs_readdir(file, fillonedir, &buf);
7599         if (error >= 0)
7600                 error = buf.count;
7601 @@ -242,6 +251,7 @@
7602         struct linux_dirent * previous;
7603         int count;
7604         int error;
7605 +       struct nameidata nd;
7606  };
7607  
7608  static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
7609 @@ -254,6 +264,10 @@
7610         buf->error = -EINVAL;   /* only used if we fail.. */
7611         if (reclen > buf->count)
7612                 return -EINVAL;
7613 +
7614 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7615 +               return 0;
7616 +
7617         dirent = buf->previous;
7618         if (dirent)
7619                 put_user(offset, &dirent->d_off);
7620 @@ -286,6 +300,9 @@
7621         buf.count = count;
7622         buf.error = 0;
7623  
7624 +       buf.nd.dentry = file->f_dentry;
7625 +       buf.nd.mnt = file->f_vfsmnt;
7626 +
7627         error = vfs_readdir(file, filldir, &buf);
7628         if (error < 0)
7629                 goto out_putf;
7630 @@ -320,6 +337,7 @@
7631         struct linux_dirent64 * previous;
7632         int count;
7633         int error;
7634 +       struct nameidata nd;
7635  };
7636  
7637  static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
7638 @@ -332,6 +350,10 @@
7639         buf->error = -EINVAL;   /* only used if we fail.. */
7640         if (reclen > buf->count)
7641                 return -EINVAL;
7642 +
7643 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7644 +               return 0;
7645 +       
7646         dirent = buf->previous;
7647         if (dirent) {
7648                 d.d_off = offset;
7649 @@ -369,6 +391,9 @@
7650         buf.count = count;
7651         buf.error = 0;
7652  
7653 +       buf.nd.mnt = file->f_vfsmnt;
7654 +       buf.nd.dentry = file->f_dentry;
7655 +
7656         error = vfs_readdir(file, filldir64, &buf);
7657         if (error < 0)
7658                 goto out_putf;
7659 diff -urN linux-2.4.24.org/grsecurity/Config.in linux-2.4.24/grsecurity/Config.in
7660 --- linux-2.4.24.org/grsecurity/Config.in       1970-01-01 01:00:00.000000000 +0100
7661 +++ linux-2.4.24/grsecurity/Config.in   2004-01-05 18:43:05.253947872 +0100
7662 @@ -0,0 +1,372 @@
7663 +define_bool CONFIG_CRYPTO y
7664 +define_bool CONFIG_CRYPTO_SHA256 y
7665 +choice 'Security level' \
7666 +        "Low           CONFIG_GRKERNSEC_LOW \
7667 +         Medium                CONFIG_GRKERNSEC_MID \
7668 +         High          CONFIG_GRKERNSEC_HI \
7669 +         Customized    CONFIG_GRKERNSEC_CUSTOM" Customized
7670 +if [ "$CONFIG_GRKERNSEC_LOW" = "y" ]; then
7671 +define_bool CONFIG_GRKERNSEC_RANDSRC n
7672 +define_bool CONFIG_GRKERNSEC_RANDRPC n
7673 +define_bool CONFIG_GRKERNSEC_FORKFAIL n
7674 +define_bool CONFIG_GRKERNSEC_TIME n
7675 +define_bool CONFIG_GRKERNSEC_SIGNAL n
7676 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7677 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT n
7678 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7679 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE n
7680 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT n
7681 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD n
7682 +define_bool CONFIG_GRKERNSEC_PROC n
7683 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7684 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
7685 +define_bool CONFIG_GRKERNSEC_HIDESYM n
7686 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7687 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n
7688 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n
7689 +define_bool CONFIG_GRKERNSEC_KMEM n
7690 +define_bool CONFIG_GRKERNSEC_PROC_ADD n
7691 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7692 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7693 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7694 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK n
7695 +define_bool CONFIG_GRKERNSEC_PAX_ASLR n
7696 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP n
7697 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7698 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7699 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7700 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7701 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7702 +if [ "$CONFIG_X86" = "y" ]; then
7703 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7704 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7705 +define_bool CONFIG_GRKERNSEC_IO n
7706 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7707 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7708 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7709 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7710 +fi
7711 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7712 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7713 +define_bool CONFIG_GRKERNSEC_RESLOG n
7714 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7715 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7716 +
7717 +define_int  CONFIG_GRKERNSEC_FLOODTIME 10
7718 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7719 +define_bool CONFIG_GRKERNSEC_LINK y
7720 +define_bool CONFIG_GRKERNSEC_FIFO y
7721 +define_bool CONFIG_GRKERNSEC_RANDPID y
7722 +define_bool CONFIG_GRKERNSEC_EXECVE y
7723 +define_bool CONFIG_GRKERNSEC_RANDNET y
7724 +define_bool CONFIG_GRKERNSEC_RANDISN n
7725 +define_bool CONFIG_GRKERNSEC_DMESG y
7726 +define_bool CONFIG_GRKERNSEC_RANDID y
7727 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7728 +fi
7729 +if [ "$CONFIG_GRKERNSEC_MID" = "y" ]; then
7730 +define_bool CONFIG_GRKERNSEC_KMEM n
7731 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7732 +define_bool CONFIG_GRKERNSEC_HIDESYM n
7733 +define_bool CONFIG_GRKERNSEC_PROC_ADD n
7734 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7735 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7736 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7737 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7738 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7739 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7740 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7741 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7742 +if [ "$CONFIG_X86" = "y" ]; then
7743 +define_bool CONFIG_GRKERNSEC_IO n
7744 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7745 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7746 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7747 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7748 +fi
7749 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7750 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7751 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7752 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7753 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7754 +define_bool CONFIG_GRKERNSEC_RESLOG n
7755 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7756 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7757 +
7758 +define_int  CONFIG_GRKERNSEC_FLOODTIME 10
7759 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7760 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y
7761 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7762 +define_bool CONFIG_GRKERNSEC_LINK y
7763 +define_bool CONFIG_GRKERNSEC_FIFO y
7764 +define_bool CONFIG_GRKERNSEC_RANDPID y
7765 +define_bool CONFIG_GRKERNSEC_EXECVE y
7766 +define_bool CONFIG_GRKERNSEC_DMESG y
7767 +define_bool CONFIG_GRKERNSEC_RANDID y
7768 +define_bool CONFIG_GRKERNSEC_RANDNET y
7769 +define_bool CONFIG_GRKERNSEC_RANDISN y
7770 +define_bool CONFIG_GRKERNSEC_RANDSRC y
7771 +define_bool CONFIG_GRKERNSEC_RANDRPC y
7772 +define_bool CONFIG_GRKERNSEC_FORKFAIL y
7773 +define_bool CONFIG_GRKERNSEC_TIME y
7774 +define_bool CONFIG_GRKERNSEC_SIGNAL y
7775 +define_bool CONFIG_GRKERNSEC_CHROOT y
7776 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7777 +define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7778 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7779 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7780 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7781 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7782 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7783 +define_bool CONFIG_GRKERNSEC_PROC y
7784 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7785 +define_int  CONFIG_GRKERNSEC_PROC_GID 10
7786 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7787 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7788 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7789 +define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7790 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7791 +fi
7792 +if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then
7793 +define_int CONFIG_GRKERNSEC_FLOODTIME 10
7794 +define_int  CONFIG_GRKERNSEC_FLOODBURST 4
7795 +define_bool CONFIG_GRKERNSEC_LINK y
7796 +define_bool CONFIG_GRKERNSEC_FIFO y
7797 +define_bool CONFIG_GRKERNSEC_RANDPID y
7798 +define_bool CONFIG_GRKERNSEC_EXECVE y
7799 +define_bool CONFIG_GRKERNSEC_DMESG y
7800 +define_bool CONFIG_GRKERNSEC_RANDID y
7801 +define_bool CONFIG_GRKERNSEC_RANDSRC y
7802 +define_bool CONFIG_GRKERNSEC_RANDRPC y
7803 +define_bool CONFIG_GRKERNSEC_FORKFAIL y
7804 +define_bool CONFIG_GRKERNSEC_TIME y
7805 +define_bool CONFIG_GRKERNSEC_SIGNAL y
7806 +define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT y
7807 +define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7808 +define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7809 +define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR y
7810 +define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7811 +define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7812 +define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7813 +define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7814 +define_bool CONFIG_GRKERNSEC_CHROOT_CAPS y
7815 +define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7816 +define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK y
7817 +define_bool CONFIG_GRKERNSEC_PROC y
7818 +define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7819 +define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y
7820 +define_bool CONFIG_GRKERNSEC_HIDESYM y
7821 +define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7822 +define_int  CONFIG_GRKERNSEC_PROC_GID 10
7823 +define_bool CONFIG_GRKERNSEC_KMEM y
7824 +define_bool CONFIG_GRKERNSEC_RESLOG y
7825 +define_bool CONFIG_GRKERNSEC_RANDNET y
7826 +define_bool CONFIG_GRKERNSEC_RANDISN y
7827 +
7828 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7829 +define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7830 +define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7831 +define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7832 +
7833 +define_bool CONFIG_GRKERNSEC_PROC_ADD y
7834 +define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD y
7835 +define_bool CONFIG_GRKERNSEC_CHROOT_NICE y
7836 +define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7837 +define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7838 +define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7839 +define_bool CONFIG_GRKERNSEC_PAX_NOEXEC y
7840 +define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7841 +define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7842 +define_bool CONFIG_GRKERNSEC_PAX_MPROTECT y
7843 +define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7844 +if [ "$CONFIG_X86" = "y" ]; then
7845 +define_bool CONFIG_GRKERNSEC_IO n
7846 +if [ "$CONFIG_MODULES" = "n" ]; then
7847 +define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC y
7848 +fi
7849 +define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK y
7850 +define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC y
7851 +define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC y
7852 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7853 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7854 +fi
7855 +if [ "$CONFIG_PARISC" = "y" ]; then
7856 +define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP y
7857 +define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT y
7858 +fi
7859 +define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT y
7860 +fi
7861 +if [ "$CONFIG_GRKERNSEC_CUSTOM" = "y" ]; then
7862 +mainmenu_option next_comment
7863 +comment 'Address Space Protection'
7864 +bool 'Enforce non-executable pages' CONFIG_GRKERNSEC_PAX_NOEXEC
7865 +if [ "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7866 +  bool 'Paging based non-executable pages' CONFIG_GRKERNSEC_PAX_PAGEEXEC
7867 +  if [ "$CONFIG_X86" = "y" ]; then
7868 +    bool 'Segmentation based non-executable pages' CONFIG_GRKERNSEC_PAX_SEGMEXEC
7869 +  fi
7870 +  if [ "$CONFIG_X86" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7871 +    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7872 +      bool '   Emulate trampolines' CONFIG_GRKERNSEC_PAX_EMUTRAMP
7873 +      if [ "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then
7874 +        bool '    Automatically emulate sigreturn trampolines' CONFIG_GRKERNSEC_PAX_EMUSIGRT
7875 +      fi
7876 +    fi
7877 +  fi
7878 +  bool '   Restrict mprotect()' CONFIG_GRKERNSEC_PAX_MPROTECT
7879 +  if [ "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then
7880 +    if [ "$CONFIG_X86" = "y" ]; then
7881 +      bool '    Disallow ELF text relocations (DANGEROUS)' CONFIG_GRKERNSEC_PAX_NOELFRELOCS
7882 +    else
7883 +    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" ]; then
7884 +      bool '    Allow ELF ET_EXEC text relocations' CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
7885 +    fi
7886 +    if [ "$CONFIG_X86" = "y" -a "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" -a "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then
7887 +      bool '    Honor PT_GNU_STACK' CONFIG_GRKERNSEC_PAX_PT_GNU_STACK
7888 +    fi
7889 +    if [ "$CONFIG_X86" = "y" -a "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then
7890 +      bool '    Honor PT_GNU_HEAP' CONFIG_GRKERNSEC_PAX_PT_GNU_HEAP
7891 +    fi
7892 +    if [ "$CONFIG_PPC32" = "y" ]; then
7893 +      define_bool CONFIG_GRKERNSEC_PAX_SYSCALL y
7894 +    fi
7895 +    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7896 +      bool '    Automatically emulate ELF PLT' CONFIG_GRKERNSEC_PAX_EMUPLT
7897 +      if [ "$CONFIG_GRKERNSEC_PAX_EMUPLT" = "y" ]; then
7898 +        if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
7899 +         define_bool CONFIG_GRKERNSEC_PAX_DLRESOLVE y
7900 +        fi
7901 +      fi
7902 +    fi
7903 +    fi
7904 +  fi
7905 +fi
7906 +if [ "$CONFIG_X86" = "y" -a "$CONFIG_MODULES" = "n" ]; then
7907 +  bool 'Enforce non-executable kernel pages' CONFIG_GRKERNSEC_PAX_KERNEXEC
7908 +fi
7909 +bool 'Address Space Layout Randomization' CONFIG_GRKERNSEC_PAX_ASLR
7910 +if [ "$CONFIG_GRKERNSEC_PAX_ASLR" = "y" ]; then
7911 +  if [ "$CONFIG_X86_TSC" = "y" ]; then
7912 +    bool '  Randomize kernel stack base' CONFIG_GRKERNSEC_PAX_RANDKSTACK
7913 +  fi
7914 +  bool '  Randomize user stack base' CONFIG_GRKERNSEC_PAX_RANDUSTACK
7915 +  bool '  Randomize mmap() base' CONFIG_GRKERNSEC_PAX_RANDMMAP
7916 +  if [ "$CONFIG_GRKERNSEC_PAX_RANDMMAP" = "y" -a "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7917 +    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7918 +      bool '  Randomize ET_EXEC base' CONFIG_GRKERNSEC_PAX_RANDEXEC
7919 +    fi
7920 +  fi
7921 +fi
7922 +bool 'Deny writing to /dev/kmem, /dev/mem, and /dev/port' CONFIG_GRKERNSEC_KMEM
7923 +if [ "$CONFIG_X86" = "y" ]; then
7924 +  bool 'Disable privileged I/O' CONFIG_GRKERNSEC_IO
7925 +  if [ "$CONFIG_GRKERNSEC_IO" = "y" ]; then
7926 +    define_bool CONFIG_RTC y
7927 +  fi
7928 +fi
7929 +bool 'Remove addresses from /proc/pid/[maps|stat]' CONFIG_GRKERNSEC_PROC_MEMMAP
7930 +bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM
7931 +endmenu
7932 +mainmenu_option next_comment
7933 +comment 'Role Based Access Control Options'
7934 +bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN
7935 +int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7936 +int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7937 +endmenu
7938 +mainmenu_option next_comment
7939 +comment 'Filesystem Protections'
7940 +bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC
7941 +if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then
7942 + bool '   Restrict to user only' CONFIG_GRKERNSEC_PROC_USER
7943 + if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then
7944 +  bool '   Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP
7945 +  if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7946 +   int  '   GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001
7947 +  fi
7948 + fi
7949 + if [ "$CONFIG_GRKERNSEC_PROC_USER" != "n" -o "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7950 +  bool '   Additional restrictions' CONFIG_GRKERNSEC_PROC_ADD
7951 + fi
7952 +fi
7953 +bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK
7954 +bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO
7955 +bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT
7956 +if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then
7957 +bool '   Deny mounts' CONFIG_GRKERNSEC_CHROOT_MOUNT
7958 +bool '   Deny double-chroots' CONFIG_GRKERNSEC_CHROOT_DOUBLE
7959 +bool '   Deny pivot_root in chroot' CONFIG_GRKERNSEC_CHROOT_PIVOT
7960 +bool '   Enforce chdir("/") on all chroots' CONFIG_GRKERNSEC_CHROOT_CHDIR
7961 +bool '   Deny (f)chmod +s' CONFIG_GRKERNSEC_CHROOT_CHMOD
7962 +bool '   Deny fchdir out of chroot' CONFIG_GRKERNSEC_CHROOT_FCHDIR
7963 +bool '   Deny mknod' CONFIG_GRKERNSEC_CHROOT_MKNOD
7964 +bool '   Deny shmat() out of chroot' CONFIG_GRKERNSEC_CHROOT_SHMAT
7965 +bool '   Deny access to abstract AF_UNIX sockets out of chroot' CONFIG_GRKERNSEC_CHROOT_UNIX
7966 +bool '   Protect outside processes' CONFIG_GRKERNSEC_CHROOT_FINDTASK
7967 +bool '   Restrict priority changes' CONFIG_GRKERNSEC_CHROOT_NICE
7968 +bool '   Deny sysctl writes in chroot' CONFIG_GRKERNSEC_CHROOT_SYSCTL
7969 +bool '   Capability restrictions within chroot' CONFIG_GRKERNSEC_CHROOT_CAPS
7970 +fi
7971 +endmenu
7972 +mainmenu_option next_comment
7973 +comment 'Kernel Auditing'
7974 +bool 'Single group for auditing' CONFIG_GRKERNSEC_AUDIT_GROUP
7975 +if [ "$CONFIG_GRKERNSEC_AUDIT_GROUP" != "n" ]; then
7976 +int  '   GID for auditing' CONFIG_GRKERNSEC_AUDIT_GID 1007
7977 +fi
7978 +bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG
7979 +bool 'Resource logging' CONFIG_GRKERNSEC_RESLOG
7980 +bool 'Log execs within chroot' CONFIG_GRKERNSEC_CHROOT_EXECLOG
7981 +bool 'Chdir logging' CONFIG_GRKERNSEC_AUDIT_CHDIR
7982 +bool '(Un)Mount logging' CONFIG_GRKERNSEC_AUDIT_MOUNT
7983 +bool 'IPC logging' CONFIG_GRKERNSEC_AUDIT_IPC
7984 +bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL
7985 +bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL
7986 +bool 'Time change logging' CONFIG_GRKERNSEC_TIME
7987 +bool '/proc/<pid>/ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR
7988 +endmenu
7989 +mainmenu_option next_comment
7990 +comment 'Executable Protections'
7991 +bool 'Enforce RLIMIT_NPROC on execs' CONFIG_GRKERNSEC_EXECVE
7992 +bool 'Dmesg(8) restriction' CONFIG_GRKERNSEC_DMESG
7993 +bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID
7994 +bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE
7995 +if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then
7996 +bool '   Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
7997 +int  '   GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
7998 +fi
7999 +endmenu
8000 +mainmenu_option next_comment
8001 +comment 'Network Protections'
8002 +bool 'Larger entropy pools' CONFIG_GRKERNSEC_RANDNET
8003 +bool 'Truly random TCP ISN selection' CONFIG_GRKERNSEC_RANDISN
8004 +bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID
8005 +bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC
8006 +bool 'Randomized RPC XIDs' CONFIG_GRKERNSEC_RANDRPC
8007 +bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET
8008 +if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then
8009 +bool '  Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL
8010 +if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then
8011 +int  '   GID to deny all sockets for:' CONFIG_GRKERNSEC_SOCKET_ALL_GID 1004
8012 +fi
8013 +bool '  Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT
8014 +if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then
8015 +int  '   GID to deny client sockets for:' CONFIG_GRKERNSEC_SOCKET_CLIENT_GID 1003
8016 +fi
8017 +bool '  Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER
8018 +if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then
8019 +int  '   GID to deny server sockets for:' CONFIG_GRKERNSEC_SOCKET_SERVER_GID 1002
8020 +fi
8021 +fi
8022 +endmenu
8023 +if [ "$CONFIG_SYSCTL" != "n" ]; then
8024 +mainmenu_option next_comment
8025 +comment 'Sysctl support'
8026 +bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL
8027 +endmenu
8028 +fi
8029 +mainmenu_option next_comment
8030 +comment 'Logging options'
8031 +int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10
8032 +int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4
8033 +endmenu
8034 +fi
8035 diff -urN linux-2.4.24.org/grsecurity/gracl_alloc.c linux-2.4.24/grsecurity/gracl_alloc.c
8036 --- linux-2.4.24.org/grsecurity/gracl_alloc.c   1970-01-01 01:00:00.000000000 +0100
8037 +++ linux-2.4.24/grsecurity/gracl_alloc.c       2004-01-05 18:43:05.260946808 +0100
8038 @@ -0,0 +1,93 @@
8039 +/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
8040 +
8041 +#include <linux/kernel.h>
8042 +#include <linux/mm.h>
8043 +#include <linux/slab.h>
8044 +#include <linux/vmalloc.h>
8045 +#include <linux/gracl.h>
8046 +#include <linux/grsecurity.h>
8047 +
8048 +static unsigned long alloc_stack_next = 1;
8049 +static unsigned long alloc_stack_size = 1;
8050 +static void **alloc_stack;
8051 +
8052 +static __inline__ int
8053 +alloc_pop(void)
8054 +{
8055 +       if (alloc_stack_next == 1)
8056 +               return 0;
8057 +
8058 +       kfree(alloc_stack[alloc_stack_next - 2]);
8059 +
8060 +       alloc_stack_next--;
8061 +
8062 +       return 1;
8063 +}
8064 +
8065 +static __inline__ void
8066 +alloc_push(void *buf)
8067 +{
8068 +       if (alloc_stack_next >= alloc_stack_size)
8069 +               BUG();
8070 +
8071 +       alloc_stack[alloc_stack_next - 1] = buf;
8072 +
8073 +       alloc_stack_next++;
8074 +
8075 +       return;
8076 +}
8077 +
8078 +void *
8079 +acl_alloc(unsigned long len)
8080 +{
8081 +       void *ret;
8082 +
8083 +       if (len > PAGE_SIZE)
8084 +               BUG();
8085 +
8086 +       ret = kmalloc(len, GFP_KERNEL);
8087 +
8088 +       if (ret)
8089 +               alloc_push(ret);
8090 +
8091 +       return ret;
8092 +}
8093 +
8094 +void
8095 +acl_free_all(void)
8096 +{
8097 +       if (gr_acl_is_enabled() || !alloc_stack)
8098 +               return;
8099 +
8100 +       while (alloc_pop()) ;
8101 +
8102 +       if (alloc_stack) {
8103 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
8104 +                       kfree(alloc_stack);
8105 +               else
8106 +                       vfree(alloc_stack);
8107 +       }
8108 +
8109 +       alloc_stack = NULL;
8110 +       alloc_stack_size = 1;
8111 +       alloc_stack_next = 1;
8112 +
8113 +       return;
8114 +}
8115 +
8116 +int
8117 +acl_alloc_stack_init(unsigned long size)
8118 +{
8119 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
8120 +               alloc_stack =
8121 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
8122 +       else
8123 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
8124 +
8125 +       alloc_stack_size = size;
8126 +
8127 +       if (!alloc_stack)
8128 +               return 0;
8129 +       else
8130 +               return 1;
8131 +}
8132 diff -urN linux-2.4.24.org/grsecurity/gracl.c linux-2.4.24/grsecurity/gracl.c
8133 --- linux-2.4.24.org/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100
8134 +++ linux-2.4.24/grsecurity/gracl.c     2004-01-05 18:43:05.259946960 +0100
8135 @@ -0,0 +1,2766 @@
8136 +/* 
8137 + * grsecurity/gracl.c
8138 + * Copyright Brad Spengler 2001, 2002, 2003
8139 + *
8140 + */
8141 +
8142 +#include <linux/kernel.h>
8143 +#include <linux/sched.h>
8144 +#include <linux/mm.h>
8145 +#include <linux/file.h>
8146 +#include <linux/fs.h>
8147 +#include <linux/proc_fs.h>
8148 +#include <linux/smp_lock.h>
8149 +#include <linux/slab.h>
8150 +#include <linux/vmalloc.h>
8151 +#include <linux/types.h>
8152 +#include <linux/capability.h>
8153 +#include <linux/sysctl.h>
8154 +#include <linux/gracl.h>
8155 +#include <linux/gralloc.h>
8156 +#include <linux/grsecurity.h>
8157 +#include <linux/grinternal.h>
8158 +
8159 +#include <asm/uaccess.h>
8160 +#include <asm/errno.h>
8161 +#include <asm/mman.h>
8162 +
8163 +static struct acl_role_db acl_role_set;
8164 +static struct acl_role_label *role_list_head;
8165 +static struct name_db name_set;
8166 +static struct name_db inodev_set;
8167 +
8168 +static struct acl_role_label *default_role;
8169 +
8170 +static u16 acl_sp_role_value;
8171 +
8172 +static DECLARE_MUTEX(gr_dev_sem);
8173 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
8174 +
8175 +extern char *gr_shared_page[4][NR_CPUS];
8176 +struct gr_arg *gr_usermode;
8177 +
8178 +static unsigned long gr_status = GR_STATUS_INIT;
8179 +
8180 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
8181 +extern void gr_clear_learn_entries(void);
8182 +
8183 +#ifdef CONFIG_GRKERNSEC_RESLOG
8184 +extern __inline__ void gr_log_resource(const struct task_struct *task,
8185 +                                      const int res,
8186 +                                      const unsigned long wanted, const int gt);
8187 +#endif
8188 +
8189 +unsigned char *gr_system_salt;
8190 +unsigned char *gr_system_sum;
8191 +
8192 +static struct sprole_pw **acl_special_roles = NULL;
8193 +static __u16 num_sprole_pws = 0;
8194 +
8195 +static struct acl_role_label *kernel_role = NULL;
8196 +
8197 +/* The following are used to keep a place held in the hash table when we move
8198 +   entries around.  They can be replaced during insert. */
8199 +
8200 +static struct acl_subject_label *deleted_subject;
8201 +static struct acl_object_label *deleted_object;
8202 +static struct name_entry *deleted_inodev;
8203 +
8204 +/* for keeping track of the last and final allocated subjects, since
8205 +   nested subject parsing is tricky
8206 +*/
8207 +static struct acl_subject_label *s_last = NULL;
8208 +static struct acl_subject_label *s_final = NULL;
8209 +
8210 +static unsigned int gr_auth_attempts = 0;
8211 +static unsigned long gr_auth_expires = 0UL;
8212 +
8213 +extern int gr_init_uidset(void);
8214 +extern void gr_free_uidset(void);
8215 +extern void gr_remove_uid(uid_t uid);
8216 +extern int gr_find_uid(uid_t uid);
8217 +
8218 +__inline__ int
8219 +gr_acl_is_enabled(void)
8220 +{
8221 +       return (gr_status & GR_READY);
8222 +}
8223 +
8224 +__inline__ int
8225 +gr_acl_tpe_check(void)
8226 +{
8227 +       if (unlikely(!(gr_status & GR_READY)))
8228 +               return 0;
8229 +       if (current->role->roletype & GR_ROLE_TPE)
8230 +               return 1;
8231 +       else
8232 +               return 0;
8233 +}
8234 +
8235 +int
8236 +gr_handle_rawio(const struct inode *inode)
8237 +{
8238 +       if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
8239 +           ((gr_status & GR_READY)
8240 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
8241 +            || (grsec_enable_chroot_caps && proc_is_chrooted(current))
8242 +#endif
8243 +           ))
8244 +               return 1;
8245 +       return 0;
8246 +}
8247 +
8248 +
8249 +static __inline__ int
8250 +gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
8251 +{
8252 +       int i;
8253 +       unsigned long *l1;
8254 +       unsigned long *l2;
8255 +       unsigned char *c1;
8256 +       unsigned char *c2;
8257 +       int num_longs;
8258 +
8259 +       if (likely(lena != lenb))
8260 +               return 0;
8261 +
8262 +       l1 = (unsigned long *)a;
8263 +       l2 = (unsigned long *)b;
8264 +
8265 +       num_longs = lena / sizeof(unsigned long);
8266 +
8267 +       for (i = num_longs; i--; l1++, l2++) {
8268 +               if (unlikely(*l1 != *l2))
8269 +                       return 0;
8270 +       }
8271 +
8272 +       c1 = (unsigned char *) l1;
8273 +       c2 = (unsigned char *) l2;
8274 +
8275 +       i = lena - (num_longs * sizeof(unsigned long)); 
8276 +
8277 +       for (; i--; c1++, c2++) {
8278 +               if (unlikely(*c1 != *c2))
8279 +                       return 0;
8280 +       }
8281 +
8282 +       return 1;
8283 +}
8284 +               
8285 +static __inline__ char *
8286 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
8287 +           char *buf, int buflen)
8288 +{
8289 +       char *res;
8290 +       struct dentry *our_dentry;
8291 +       struct vfsmount *our_mount;
8292 +       struct vfsmount *rootmnt;
8293 +       struct dentry *root;
8294 +
8295 +       our_dentry = (struct dentry *) dentry;
8296 +       our_mount = (struct vfsmount *) vfsmnt;
8297 +
8298 +       read_lock(&child_reaper->fs->lock);
8299 +       rootmnt = mntget(child_reaper->fs->rootmnt);
8300 +       root = dget(child_reaper->fs->root);
8301 +       read_unlock(&child_reaper->fs->lock);
8302 +
8303 +       spin_lock(&dcache_lock);
8304 +       res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
8305 +       spin_unlock(&dcache_lock);
8306 +       if (unlikely(IS_ERR(res)))
8307 +               res = strcpy(buf, "<path too long>");
8308 +       dput(root);
8309 +       mntput(rootmnt);
8310 +       return res;
8311 +}
8312 +
8313 +char *
8314 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
8315 +{
8316 +       return d_real_path(dentry, mnt, gr_shared_page[0][smp_processor_id()],
8317 +                          PAGE_SIZE);
8318 +}
8319 +
8320 +char *
8321 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
8322 +{
8323 +       return d_real_path(dentry, mnt, gr_shared_page[1][smp_processor_id()],
8324 +                          PAGE_SIZE);
8325 +}
8326 +
8327 +char *
8328 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
8329 +{
8330 +       return d_real_path(dentry, mnt, gr_shared_page[2][smp_processor_id()],
8331 +                          PAGE_SIZE);
8332 +}
8333 +
8334 +char *
8335 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
8336 +{
8337 +       return d_real_path(dentry, mnt, gr_shared_page[3][smp_processor_id()],
8338 +                          PAGE_SIZE);
8339 +}
8340 +
8341 +__inline__ __u32
8342 +to_gr_audit(const __u32 reqmode)
8343 +{
8344 +       __u32 retmode = 0;
8345 +
8346 +       retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
8347 +       retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
8348 +       retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
8349 +       retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
8350 +       retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
8351 +       retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
8352 +       retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
8353 +       retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
8354 +       retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
8355 +
8356 +       return retmode;
8357 +}
8358 +
8359 +__inline__ struct acl_role_label *
8360 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
8361 +                     const gid_t gid)
8362 +{
8363 +       unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
8364 +       struct acl_role_label *match;
8365 +       struct role_allowed_ip *ipp;
8366 +       __u8 i = 0;
8367 +
8368 +       match = acl_role_set.r_hash[index];
8369 +
8370 +       while (match
8371 +              && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
8372 +               index = (index + (1 << i)) % acl_role_set.r_size;
8373 +               match = acl_role_set.r_hash[index];
8374 +               i = (i + 1) % 32;
8375 +       }
8376 +
8377 +       if (!match || match->uidgid != uid || !(match->roletype & GR_ROLE_USER)) {
8378 +             try_group:
8379 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
8380 +               match = acl_role_set.r_hash[index];
8381 +               i = 0;
8382 +
8383 +               while (match
8384 +                      && (match->uidgid != gid
8385 +                          || !(match->roletype & GR_ROLE_GROUP))) {
8386 +                       index = (index + (1 << i)) % acl_role_set.r_size;
8387 +                       match = acl_role_set.r_hash[index];
8388 +                       i = (i + 1) % 32;
8389 +               }
8390 +
8391 +               if (!match || match->uidgid != gid
8392 +                   || !(match->roletype & GR_ROLE_GROUP))
8393 +                       match = default_role;
8394 +               else if (likely(!match->allowed_ips)) {
8395 +                       return match;
8396 +               } else {
8397 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
8398 +                               if (likely
8399 +                                   ((task->curr_ip & ipp->netmask) ==
8400 +                                    (ipp->addr & ipp->netmask)))
8401 +                                       return match;
8402 +                       }
8403 +                       match = default_role;
8404 +               }
8405 +       } else if (likely(!match->allowed_ips)) {
8406 +               return match;
8407 +       } else {
8408 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
8409 +                       if (likely
8410 +                           ((task->curr_ip & ipp->netmask) ==
8411 +                            (ipp->addr & ipp->netmask)))
8412 +                               return match;
8413 +               }
8414 +               goto try_group;
8415 +       }
8416 +
8417 +       return match;
8418 +}
8419 +
8420 +__inline__ struct acl_subject_label *
8421 +lookup_acl_subj_label(const ino_t ino, const kdev_t dev,
8422 +                     const struct acl_role_label *role)
8423 +{
8424 +       unsigned long subj_size = role->subj_hash_size;
8425 +       struct acl_subject_label **s_hash = role->subj_hash;
8426 +       unsigned long index = fhash(ino, dev, subj_size);
8427 +       struct acl_subject_label *match;
8428 +       __u8 i = 0;
8429 +
8430 +       match = s_hash[index];
8431 +
8432 +       while (match && (match->inode != ino || match->device != dev ||
8433 +              (match->mode & GR_DELETED))) {
8434 +               index = (index + (1 << i)) % subj_size;
8435 +               match = s_hash[index];
8436 +               i = (i + 1) % 32;
8437 +       }
8438 +
8439 +       if (unlikely(match && (match != deleted_subject) &&
8440 +                    (match->inode == ino) && (match->device == dev) &&
8441 +                    !(match->mode & GR_DELETED)))
8442 +               return match;
8443 +       else
8444 +               return NULL;
8445 +}
8446 +
8447 +static __inline__ struct acl_object_label *
8448 +lookup_acl_obj_label(const ino_t ino, const kdev_t dev,
8449 +                    const struct acl_subject_label *subj)
8450 +{
8451 +       unsigned long obj_size = subj->obj_hash_size;
8452 +       struct acl_object_label **o_hash = subj->obj_hash;
8453 +       unsigned long index = fhash(ino, dev, obj_size);
8454 +       struct acl_object_label *match;
8455 +       __u8 i = 0;
8456 +
8457 +       match = o_hash[index];
8458 +
8459 +       while (match && (match->inode != ino || match->device != dev ||
8460 +              (match->mode & GR_DELETED))) {
8461 +               index = (index + (1 << i)) % obj_size;
8462 +               match = o_hash[index];
8463 +               i = (i + 1) % 32;
8464 +       }
8465 +
8466 +       if (unlikely(match && (match != deleted_object) &&
8467 +                    (match->inode == ino) && (match->device == dev) &&
8468 +                    !(match->mode & GR_DELETED)))
8469 +               return match;
8470 +       else
8471 +               return NULL;
8472 +}
8473 +
8474 +static __inline__ struct acl_object_label *
8475 +lookup_acl_obj_label_create(const ino_t ino, const kdev_t dev,
8476 +                    const struct acl_subject_label *subj)
8477 +{
8478 +       unsigned long obj_size = subj->obj_hash_size;
8479 +       struct acl_object_label **o_hash = subj->obj_hash;
8480 +       unsigned long index = fhash(ino, dev, obj_size);
8481 +       struct acl_object_label *match;
8482 +       __u8 i = 0;
8483 +
8484 +       match = o_hash[index];
8485 +
8486 +       while (match && (match->inode != ino || match->device != dev ||
8487 +              !(match->mode & GR_DELETED))) {
8488 +               index = (index + (1 << i)) % obj_size;
8489 +               match = o_hash[index];
8490 +               i = (i + 1) % 32;
8491 +       }
8492 +
8493 +       if (unlikely(match && (match != deleted_object) &&
8494 +                    (match->inode == ino) && (match->device == dev) &&
8495 +                    (match->mode & GR_DELETED)))
8496 +               return match;
8497 +
8498 +       i = 0;
8499 +       index = fhash(ino, dev, obj_size);
8500 +       match = o_hash[index];
8501 +
8502 +       while (match && (match->inode != ino || match->device != dev ||
8503 +              (match->mode & GR_DELETED))) {
8504 +               index = (index + (1 << i)) % obj_size;
8505 +               match = o_hash[index];
8506 +               i = (i + 1) % 32;
8507 +       }
8508 +
8509 +       if (unlikely(match && (match != deleted_object) &&
8510 +                    (match->inode == ino) && (match->device == dev) &&
8511 +                    !(match->mode & GR_DELETED)))
8512 +               return match;
8513 +       else
8514 +               return NULL;
8515 +}
8516 +
8517 +static __inline__ struct name_entry *
8518 +lookup_name_entry(const char *name)
8519 +{
8520 +       __u16 len = strlen(name);
8521 +       unsigned long index = nhash(name, len, name_set.n_size);
8522 +       struct name_entry *match;
8523 +       __u8 i = 0;
8524 +
8525 +       match = name_set.n_hash[index];
8526 +
8527 +       while (match && !gr_streq(match->name, name, match->len, len)) {
8528 +               index = (index + (1 << i)) % name_set.n_size;
8529 +               match = name_set.n_hash[index];
8530 +               i = (i + 1) % 32;
8531 +       }
8532 +
8533 +       if (unlikely(!match || !gr_streq(match->name, name, match->len, len)))
8534 +               return NULL;
8535 +       else
8536 +               return match;
8537 +}
8538 +
8539 +static __inline__ struct name_entry *
8540 +lookup_inodev_entry(const ino_t ino, const kdev_t dev)
8541 +{
8542 +       unsigned long index = fhash(ino, dev, inodev_set.n_size);
8543 +       struct name_entry *match;
8544 +       __u8 i = 0;
8545 +
8546 +       match = inodev_set.n_hash[index];
8547 +
8548 +       while (match && (match->inode != ino || match->device != dev)) {
8549 +               index = (index + (1 << i)) % inodev_set.n_size;
8550 +               match = inodev_set.n_hash[index];
8551 +               i = (i + 1) % 32;
8552 +       }
8553 +
8554 +       if (unlikely(match && (match != deleted_inodev) &&
8555 +                    (match->inode == ino) && (match->device == dev)))
8556 +               return match;
8557 +       else
8558 +               return NULL;
8559 +}
8560 +
8561 +static void
8562 +insert_inodev_entry(struct name_entry *nentry)
8563 +{
8564 +       unsigned long index = fhash(nentry->inode, nentry->device,
8565 +                                   inodev_set.n_size);
8566 +       struct name_entry **curr;
8567 +       __u8 i = 0;
8568 +
8569 +       curr = &inodev_set.n_hash[index];
8570 +
8571 +       while (*curr && *curr != deleted_inodev) {
8572 +               index = (index + (1 << i)) % inodev_set.n_size;
8573 +               curr = &inodev_set.n_hash[index];
8574 +               i = (i + 1) % 32;
8575 +       }
8576 +
8577 +       *curr = nentry;
8578 +
8579 +       return;
8580 +}
8581 +
8582 +static void
8583 +insert_acl_role_label(struct acl_role_label *role)
8584 +{
8585 +       unsigned long index =
8586 +           rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
8587 +       struct acl_role_label **curr;
8588 +       __u8 i = 0;
8589 +
8590 +       curr = &acl_role_set.r_hash[index];
8591 +
8592 +       while (*curr) {
8593 +               index = (index + (1 << i)) % acl_role_set.r_size;
8594 +               curr = &acl_role_set.r_hash[index];
8595 +               i = (i + 1) % 32;
8596 +       }
8597 +
8598 +       *curr = role;
8599 +
8600 +       return;
8601 +}
8602 +
8603 +static int
8604 +insert_name_entry(char *name, const ino_t inode, const kdev_t device)
8605 +{
8606 +       struct name_entry **curr;
8607 +       __u8 i = 0;
8608 +       __u16 len = strlen(name);
8609 +       unsigned long index = nhash(name, len, name_set.n_size);
8610 +
8611 +       curr = &name_set.n_hash[index];
8612 +
8613 +       while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
8614 +               index = (index + (1 << i)) % name_set.n_size;
8615 +               curr = &name_set.n_hash[index];
8616 +               i = (i + 1) % 32;
8617 +       }
8618 +
8619 +       if (!(*curr)) {
8620 +               struct name_entry *nentry =
8621 +                   acl_alloc(sizeof (struct name_entry));
8622 +               if (!nentry)
8623 +                       return 0;
8624 +               nentry->name = name;
8625 +               nentry->inode = inode;
8626 +               nentry->device = device;
8627 +               nentry->len = len;
8628 +               *curr = nentry;
8629 +               /* insert us into the table searchable by inode/dev */
8630 +               insert_inodev_entry(nentry);
8631 +       }
8632 +
8633 +       return 1;
8634 +}
8635 +
8636 +static void
8637 +insert_acl_obj_label(struct acl_object_label *obj,
8638 +                    struct acl_subject_label *subj)
8639 +{
8640 +       unsigned long index =
8641 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
8642 +       struct acl_object_label **curr;
8643 +       __u8 i = 0;
8644 +
8645 +       curr = &subj->obj_hash[index];
8646 +
8647 +       while (*curr && *curr != deleted_object) {
8648 +               index = (index + (1 << i)) % subj->obj_hash_size;
8649 +               curr = &subj->obj_hash[index];
8650 +               i = (i + 1) % 32;
8651 +       }
8652 +
8653 +       *curr = obj;
8654 +
8655 +       return;
8656 +}
8657 +
8658 +static void
8659 +insert_acl_subj_label(struct acl_subject_label *obj,
8660 +                     struct acl_role_label *role)
8661 +{
8662 +       unsigned long subj_size = role->subj_hash_size;
8663 +       struct acl_subject_label **s_hash = role->subj_hash;
8664 +       unsigned long index = fhash(obj->inode, obj->device, subj_size);
8665 +       struct acl_subject_label **curr;
8666 +       __u8 i = 0;
8667 +
8668 +       curr = &s_hash[index];
8669 +
8670 +       while (*curr && *curr != deleted_subject) {
8671 +               index = (index + (1 << i)) % subj_size;
8672 +               curr = &s_hash[index];
8673 +               i = (i + 1) % 32;
8674 +       }
8675 +
8676 +       *curr = obj;
8677 +
8678 +       return;
8679 +}
8680 +
8681 +static void **
8682 +create_table(__u32 * len)
8683 +{
8684 +       unsigned long table_sizes[] = {
8685 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
8686 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
8687 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
8688 +               268435399, 536870909, 1073741789, 2147483647
8689 +       };
8690 +       void *newtable = NULL;
8691 +       unsigned int pwr = 0;
8692 +
8693 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
8694 +              table_sizes[pwr] <= (2 * (*len)))
8695 +               pwr++;
8696 +
8697 +       if (table_sizes[pwr] <= (2 * (*len)))
8698 +               return newtable;
8699 +
8700 +       if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
8701 +               newtable =
8702 +                   kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
8703 +       else
8704 +               newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
8705 +
8706 +       *len = table_sizes[pwr];
8707 +
8708 +       return newtable;
8709 +}
8710 +
8711 +static int
8712 +init_variables(const unsigned long acl_obj_size,
8713 +              const unsigned long acl_subj_size,
8714 +              const unsigned long acl_ip_size,
8715 +              const unsigned long acl_role_size,
8716 +              const unsigned long allowed_ip_size,
8717 +              const unsigned long acl_trans_size,
8718 +              const __u16 num_sprole_pws)
8719 +{
8720 +       unsigned long stacksize;
8721 +
8722 +       acl_role_set.r_size = acl_role_size;
8723 +       name_set.n_size = (acl_obj_size + acl_subj_size);
8724 +       inodev_set.n_size = (acl_obj_size + acl_subj_size);
8725 +
8726 +       if (!gr_init_uidset())
8727 +               return 1;
8728 +
8729 +       /* set up the stack that holds allocation info */
8730 +
8731 +       stacksize = (3 * acl_obj_size) + (2 * acl_role_size) +
8732 +           (4 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
8733 +           allowed_ip_size + (2 * num_sprole_pws) + 5;
8734 +
8735 +       if (!acl_alloc_stack_init(stacksize))
8736 +               return 1;
8737 +
8738 +       /* create our empty, fake deleted acls */
8739 +       deleted_subject =
8740 +           (struct acl_subject_label *)
8741 +           acl_alloc(sizeof (struct acl_subject_label));
8742 +       deleted_object =
8743 +           (struct acl_object_label *)
8744 +           acl_alloc(sizeof (struct acl_object_label));
8745 +       deleted_inodev =
8746 +           (struct name_entry *) acl_alloc(sizeof (struct name_entry));
8747 +
8748 +       if (!deleted_subject || !deleted_object || !deleted_inodev)
8749 +               return 1;
8750 +
8751 +       memset(deleted_subject, 0, sizeof (struct acl_subject_label));
8752 +       memset(deleted_object, 0, sizeof (struct acl_object_label));
8753 +       memset(deleted_inodev, 0, sizeof (struct name_entry));
8754 +
8755 +       /* We only want 50% full tables for now */
8756 +
8757 +       acl_role_set.r_hash =
8758 +           (struct acl_role_label **) create_table(&acl_role_set.r_size);
8759 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
8760 +       inodev_set.n_hash =
8761 +           (struct name_entry **) create_table(&inodev_set.n_size);
8762 +
8763 +       if (!acl_role_set.r_hash || !name_set.n_hash || !inodev_set.n_hash)
8764 +               return 1;
8765 +       memset(acl_role_set.r_hash, 0,
8766 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
8767 +       memset(name_set.n_hash, 0,
8768 +              sizeof (struct name_entry *) * name_set.n_size);
8769 +       memset(inodev_set.n_hash, 0,
8770 +              sizeof (struct name_entry *) * inodev_set.n_size);
8771 +
8772 +       return 0;
8773 +}
8774 +
8775 +static void
8776 +free_variables(void)
8777 +{
8778 +       struct acl_subject_label *s;
8779 +       struct acl_role_label *r;
8780 +       struct task_struct *task;
8781 +
8782 +       gr_clear_learn_entries();
8783 +
8784 +       read_lock(&tasklist_lock);
8785 +       for_each_task(task) {
8786 +               task->acl_sp_role = 0;
8787 +               task->acl_role_id = 0;
8788 +               task->acl = NULL;
8789 +               task->role = NULL;
8790 +       }
8791 +       read_unlock(&tasklist_lock);
8792 +
8793 +       /* free all object hash tables */
8794 +
8795 +       if (role_list_head) {
8796 +               for (r = role_list_head; r; r = r->next) {
8797 +                       if (!r->subj_hash)
8798 +                               break;
8799 +                       for (s = r->proc_subject; s; s = s->next) {
8800 +                               if (!s->obj_hash)
8801 +                                       break;
8802 +                               if ((s->obj_hash_size *
8803 +                                    sizeof (struct acl_object_label *)) <=
8804 +                                   PAGE_SIZE)
8805 +                                       kfree(s->obj_hash);
8806 +                               else
8807 +                                       vfree(s->obj_hash);
8808 +                       }
8809 +                       if ((r->subj_hash_size *
8810 +                            sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
8811 +                               kfree(r->subj_hash);
8812 +                       else
8813 +                               vfree(r->subj_hash);
8814 +               }
8815 +       }
8816 +
8817 +       acl_free_all();
8818 +
8819 +       if (acl_role_set.r_hash) {
8820 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
8821 +                   PAGE_SIZE)
8822 +                       kfree(acl_role_set.r_hash);
8823 +               else
8824 +                       vfree(acl_role_set.r_hash);
8825 +       }
8826 +       if (name_set.n_hash) {
8827 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
8828 +                   PAGE_SIZE)
8829 +                       kfree(name_set.n_hash);
8830 +               else
8831 +                       vfree(name_set.n_hash);
8832 +       }
8833 +
8834 +       if (inodev_set.n_hash) {
8835 +               if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
8836 +                   PAGE_SIZE)
8837 +                       kfree(inodev_set.n_hash);
8838 +               else
8839 +                       vfree(inodev_set.n_hash);
8840 +       }
8841 +
8842 +       gr_free_uidset();
8843 +
8844 +       memset(&name_set, 0, sizeof (struct name_db));
8845 +       memset(&inodev_set, 0, sizeof (struct name_db));
8846 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
8847 +
8848 +       role_list_head = NULL;
8849 +       default_role = NULL;
8850 +
8851 +       return;
8852 +}
8853 +
8854 +static __u32
8855 +count_user_objs(struct acl_object_label *userp)
8856 +{
8857 +       struct acl_object_label o_tmp;
8858 +       __u32 num = 0;
8859 +
8860 +       while (userp) {
8861 +               if (copy_from_user(&o_tmp, userp,
8862 +                                  sizeof (struct acl_object_label)))
8863 +                       break;
8864 +
8865 +               userp = o_tmp.prev;
8866 +               num++;
8867 +       }
8868 +
8869 +       return num;
8870 +}
8871 +
8872 +static struct acl_subject_label *
8873 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
8874 +
8875 +static int
8876 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
8877 +              struct acl_role_label *role)
8878 +{
8879 +       struct acl_object_label *o_tmp;
8880 +       unsigned int len;
8881 +       char *tmp;
8882 +
8883 +       while (userp) {
8884 +               if ((o_tmp = (struct acl_object_label *)
8885 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
8886 +                       return -ENOMEM;
8887 +
8888 +               if (copy_from_user(o_tmp, userp,
8889 +                                  sizeof (struct acl_object_label)))
8890 +                       return -EFAULT;
8891 +
8892 +               userp = o_tmp->prev;
8893 +
8894 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
8895 +
8896 +               if (!len || len >= PATH_MAX)
8897 +                       return -EINVAL;
8898 +
8899 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
8900 +                       return -ENOMEM;
8901 +
8902 +               if (copy_from_user(tmp, o_tmp->filename, len))
8903 +                       return -EFAULT;
8904 +
8905 +               o_tmp->filename = tmp;
8906 +
8907 +               insert_acl_obj_label(o_tmp, subj);
8908 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
8909 +                                      o_tmp->device))
8910 +                       return -ENOMEM;
8911 +
8912 +               if (o_tmp->nested) {
8913 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
8914 +                       if (IS_ERR(o_tmp->nested))
8915 +                               return PTR_ERR(o_tmp->nested);
8916 +
8917 +                       s_final = o_tmp->nested;
8918 +               }
8919 +       }
8920 +
8921 +       return 0;
8922 +}
8923 +
8924 +static __u32
8925 +count_user_subjs(struct acl_subject_label *userp)
8926 +{
8927 +       struct acl_subject_label s_tmp;
8928 +       __u32 num = 0;
8929 +
8930 +       while (userp) {
8931 +               if (copy_from_user(&s_tmp, userp,
8932 +                                  sizeof (struct acl_subject_label)))
8933 +                       break;
8934 +
8935 +               userp = s_tmp.prev;
8936 +               /* do not count nested subjects against this count, since
8937 +                  they are not included in the hash table, but are
8938 +                  attached to objects.  We have already counted
8939 +                  the subjects in userspace for the allocation 
8940 +                  stack
8941 +               */
8942 +               if (!s_tmp.parent_subject)
8943 +                       num++;
8944 +       }
8945 +
8946 +       return num;
8947 +}
8948 +
8949 +static int
8950 +copy_user_allowedips(struct acl_role_label *rolep)
8951 +{
8952 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
8953 +
8954 +       ruserip = rolep->allowed_ips;
8955 +
8956 +       while (ruserip) {
8957 +               rlast = rtmp;
8958 +
8959 +               if ((rtmp = (struct role_allowed_ip *)
8960 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
8961 +                       return -ENOMEM;
8962 +
8963 +               if (copy_from_user(rtmp, ruserip,
8964 +                                  sizeof (struct role_allowed_ip)))
8965 +                       return -EFAULT;
8966 +
8967 +               ruserip = rtmp->prev;
8968 +
8969 +               if (!rlast) {
8970 +                       rtmp->prev = NULL;
8971 +                       rolep->allowed_ips = rtmp;
8972 +               } else {
8973 +                       rlast->next = rtmp;
8974 +                       rtmp->prev = rlast;
8975 +               }
8976 +
8977 +               if (!ruserip)
8978 +                       rtmp->next = NULL;
8979 +       }
8980 +
8981 +       return 0;
8982 +}
8983 +
8984 +static int
8985 +copy_user_transitions(struct acl_role_label *rolep)
8986 +{
8987 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
8988 +       unsigned int len;
8989 +       char *tmp;
8990 +
8991 +       rusertp = rolep->transitions;
8992 +
8993 +       while (rusertp) {
8994 +               rlast = rtmp;
8995 +
8996 +               if ((rtmp = (struct role_transition *)
8997 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
8998 +                       return -ENOMEM;
8999 +
9000 +               if (copy_from_user(rtmp, rusertp,
9001 +                                  sizeof (struct role_transition)))
9002 +                       return -EFAULT;
9003 +
9004 +               rusertp = rtmp->prev;
9005 +
9006 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
9007 +
9008 +               if (!len || len >= GR_SPROLE_LEN)
9009 +                       return -EINVAL;
9010 +
9011 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
9012 +                       return -ENOMEM;
9013 +
9014 +               if (copy_from_user(tmp, rtmp->rolename, len))
9015 +                       return -EFAULT;
9016 +
9017 +               rtmp->rolename = tmp;
9018 +
9019 +               if (!rlast) {
9020 +                       rtmp->prev = NULL;
9021 +                       rolep->transitions = rtmp;
9022 +               } else {
9023 +                       rlast->next = rtmp;
9024 +                       rtmp->prev = rlast;
9025 +               }
9026 +
9027 +               if (!rusertp)
9028 +                       rtmp->next = NULL;
9029 +       }
9030 +
9031 +       return 0;
9032 +}
9033 +
9034 +static struct acl_subject_label *
9035 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
9036 +{
9037 +       struct acl_subject_label *s_tmp = NULL;
9038 +       unsigned int len;
9039 +       char *tmp;
9040 +       __u32 num_objs;
9041 +       struct acl_ip_label **i_tmp, *i_utmp2;
9042 +       unsigned long i_num;
9043 +       int err;
9044 +
9045 +
9046 +       if ((s_tmp = (struct acl_subject_label *)
9047 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
9048 +               return ERR_PTR(-ENOMEM);
9049 +
9050 +       if (copy_from_user(s_tmp, userp,
9051 +                          sizeof (struct acl_subject_label)))
9052 +               return ERR_PTR(-EFAULT);
9053 +
9054 +       if (!s_last) {
9055 +               s_tmp->prev = NULL;
9056 +               role->proc_subject = s_tmp;
9057 +       } else {
9058 +               s_last->next = s_tmp;
9059 +               s_tmp->prev = s_last;
9060 +       }
9061 +
9062 +       s_last = s_tmp;
9063 +
9064 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
9065 +
9066 +       if (!len || len >= PATH_MAX)
9067 +               return ERR_PTR(-EINVAL);
9068 +
9069 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
9070 +               return ERR_PTR(-ENOMEM);
9071 +
9072 +       if (copy_from_user(tmp, s_tmp->filename, len))
9073 +               return ERR_PTR(-EFAULT);
9074 +
9075 +       s_tmp->filename = tmp;
9076 +
9077 +       if (!strcmp(s_tmp->filename, "/"))
9078 +               role->root_label = s_tmp;
9079 +
9080 +       /* set up object hash table */
9081 +       num_objs = count_user_objs(s_tmp->proc_object);
9082 +
9083 +       s_tmp->obj_hash_size = num_objs;
9084 +       s_tmp->obj_hash =
9085 +           (struct acl_object_label **)
9086 +           create_table(&(s_tmp->obj_hash_size));
9087 +
9088 +       if (!s_tmp->obj_hash)
9089 +               return ERR_PTR(-ENOMEM);
9090 +
9091 +       memset(s_tmp->obj_hash, 0,
9092 +              s_tmp->obj_hash_size *
9093 +              sizeof (struct acl_object_label *));
9094 +
9095 +       /* copy before adding in objects, since a nested
9096 +          acl could be found and be the final subject
9097 +          copied
9098 +       */
9099 +
9100 +       s_final = s_tmp;
9101 +
9102 +       /* add in objects */
9103 +       err = copy_user_objs(s_tmp->proc_object, s_tmp, role);
9104 +
9105 +       if (err)
9106 +               return ERR_PTR(err);
9107 +
9108 +       /* add in ip acls */
9109 +
9110 +       if (!s_tmp->ip_num) {
9111 +               s_tmp->ips = NULL;
9112 +               goto insert;
9113 +       }
9114 +
9115 +       i_tmp =
9116 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
9117 +                                              sizeof (struct
9118 +                                                      acl_ip_label *));
9119 +
9120 +       if (!i_tmp)
9121 +               return ERR_PTR(-ENOMEM);
9122 +
9123 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
9124 +               *(i_tmp + i_num) =
9125 +                   (struct acl_ip_label *)
9126 +                   acl_alloc(sizeof (struct acl_ip_label));
9127 +               if (!*(i_tmp + i_num))
9128 +                       return ERR_PTR(-ENOMEM);
9129 +
9130 +               if (copy_from_user
9131 +                   (&i_utmp2, s_tmp->ips + i_num,
9132 +                    sizeof (struct acl_ip_label *)))
9133 +                       return ERR_PTR(-EFAULT);
9134 +
9135 +               if (copy_from_user
9136 +                   (*(i_tmp + i_num), i_utmp2,
9137 +                    sizeof (struct acl_ip_label)))
9138 +                       return ERR_PTR(-EFAULT);
9139 +       }
9140 +
9141 +       s_tmp->ips = i_tmp;
9142 +
9143 +insert:
9144 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
9145 +                              s_tmp->device))
9146 +               return ERR_PTR(-ENOMEM);
9147 +
9148 +       return s_tmp;
9149 +}
9150 +
9151 +static int
9152 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
9153 +{
9154 +       struct acl_subject_label s_pre;
9155 +       struct acl_subject_label * ret;
9156 +       int err;
9157 +
9158 +       while (userp) {
9159 +               if (copy_from_user(&s_pre, userp,
9160 +                                  sizeof (struct acl_subject_label)))
9161 +                       return -EFAULT;
9162 +               
9163 +               /* do not add nested subjects here, add
9164 +                  while parsing objects
9165 +               */
9166 +
9167 +               if (s_pre.parent_subject) {
9168 +                       userp = s_pre.prev;
9169 +                       continue;
9170 +               }
9171 +
9172 +               ret = do_copy_user_subj(userp, role);
9173 +
9174 +               err = PTR_ERR(ret);
9175 +               if (IS_ERR(ret))
9176 +                       return err;
9177 +
9178 +               insert_acl_subj_label(ret, role);
9179 +
9180 +               userp = s_pre.prev;
9181 +       }
9182 +
9183 +       s_final->next = NULL;
9184 +
9185 +       return 0;
9186 +}
9187 +
9188 +static int
9189 +copy_user_acl(struct gr_arg *arg)
9190 +{
9191 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
9192 +       struct sprole_pw *sptmp;
9193 +       unsigned long r_num;
9194 +       unsigned int len;
9195 +       char *tmp;
9196 +       int err = 0;
9197 +       __u16 i;
9198 +       __u32 num_subjs;
9199 +
9200 +       /* we need a default and kernel role */
9201 +       if (arg->role_db.r_entries < 2)
9202 +               return -EINVAL;
9203 +
9204 +       /* copy special role authentication info from userspace */
9205 +
9206 +       num_sprole_pws = arg->num_sprole_pws;
9207 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
9208 +
9209 +       if (!acl_special_roles) {
9210 +               err = -ENOMEM;
9211 +               goto cleanup;
9212 +       }
9213 +
9214 +       for (i = 0; i < num_sprole_pws; i++) {
9215 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
9216 +               if (!sptmp) {
9217 +                       err = -ENOMEM;
9218 +                       goto cleanup;
9219 +               }
9220 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
9221 +                                  sizeof (struct sprole_pw))) {
9222 +                       err = -EFAULT;
9223 +                       goto cleanup;
9224 +               }
9225 +
9226 +               len =
9227 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
9228 +
9229 +               if (!len || len >= GR_SPROLE_LEN) {
9230 +                       err = -EINVAL;
9231 +                       goto cleanup;
9232 +               }
9233 +
9234 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
9235 +                       err = -ENOMEM;
9236 +                       goto cleanup;
9237 +               }
9238 +
9239 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
9240 +                       err = -EFAULT;
9241 +                       goto cleanup;
9242 +               }
9243 +
9244 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9245 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
9246 +#endif
9247 +               sptmp->rolename = tmp;
9248 +               acl_special_roles[i] = sptmp;
9249 +       }
9250 +
9251 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
9252 +
9253 +       for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
9254 +               r_last = r_tmp;
9255 +
9256 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
9257 +
9258 +               if (!r_tmp) {
9259 +                       err = -ENOMEM;
9260 +                       goto cleanup;
9261 +               }
9262 +
9263 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
9264 +                                  sizeof (struct acl_role_label *))) {
9265 +                       err = -EFAULT;
9266 +                       goto cleanup;
9267 +               }
9268 +
9269 +               if (copy_from_user(r_tmp, r_utmp2,
9270 +                                  sizeof (struct acl_role_label))) {
9271 +                       err = -EFAULT;
9272 +                       goto cleanup;
9273 +               }
9274 +
9275 +               if (!r_last) {
9276 +                       r_tmp->prev = NULL;
9277 +                       role_list_head = r_tmp;
9278 +               } else {
9279 +                       r_last->next = r_tmp;
9280 +                       r_tmp->prev = r_last;
9281 +               }
9282 +
9283 +               if (r_num == (arg->role_db.r_entries - 1))
9284 +                       r_tmp->next = NULL;
9285 +
9286 +               len = strnlen_user(r_tmp->rolename, PATH_MAX);
9287 +
9288 +               if (!len || len >= PATH_MAX) {
9289 +                       err = -EINVAL;
9290 +                       goto cleanup;
9291 +               }
9292 +
9293 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
9294 +                       err = -ENOMEM;
9295 +                       goto cleanup;
9296 +               }
9297 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
9298 +                       err = -EFAULT;
9299 +                       goto cleanup;
9300 +               }
9301 +               r_tmp->rolename = tmp;
9302 +
9303 +               if (!strcmp(r_tmp->rolename, "default")
9304 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
9305 +                       default_role = r_tmp;
9306 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
9307 +                       kernel_role = r_tmp;
9308 +               }
9309 +
9310 +               num_subjs = count_user_subjs(r_tmp->proc_subject);
9311 +
9312 +               r_tmp->subj_hash_size = num_subjs;
9313 +               r_tmp->subj_hash =
9314 +                   (struct acl_subject_label **)
9315 +                   create_table(&(r_tmp->subj_hash_size));
9316 +
9317 +               if (!r_tmp->subj_hash) {
9318 +                       err = -ENOMEM;
9319 +                       goto cleanup;
9320 +               }
9321 +
9322 +               err = copy_user_allowedips(r_tmp);
9323 +               if (err)
9324 +                       goto cleanup;
9325 +
9326 +               err = copy_user_transitions(r_tmp);
9327 +               if (err)
9328 +                       goto cleanup;
9329 +
9330 +               memset(r_tmp->subj_hash, 0,
9331 +                      r_tmp->subj_hash_size *
9332 +                      sizeof (struct acl_subject_label *));
9333 +
9334 +               s_last = NULL;
9335 +
9336 +               err = copy_user_subjs(r_tmp->proc_subject, r_tmp);
9337 +
9338 +               if (err)
9339 +                       goto cleanup;
9340 +
9341 +               insert_acl_role_label(r_tmp);
9342 +       }
9343 +
9344 +      cleanup:
9345 +       return err;
9346 +
9347 +}
9348 +
9349 +static int
9350 +gracl_init(struct gr_arg *args)
9351 +{
9352 +       int error = 0;
9353 +
9354 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
9355 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
9356 +
9357 +       if (init_variables(args->role_db.o_entries, args->role_db.s_entries,
9358 +                          args->role_db.i_entries, args->role_db.r_entries,
9359 +                          args->role_db.a_entries, args->role_db.t_entries,
9360 +                          args->num_sprole_pws)) {
9361 +               security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
9362 +               error = -ENOMEM;
9363 +               free_variables();
9364 +               goto out;
9365 +       }
9366 +
9367 +       error = copy_user_acl(args);
9368 +       if (error) {
9369 +               free_variables();
9370 +               goto out;
9371 +       }
9372 +
9373 +       if ((error = gr_set_acls(0))) {
9374 +               free_variables();
9375 +               goto out;
9376 +       }
9377 +
9378 +       gr_status |= GR_READY;
9379 +      out:
9380 +       return error;
9381 +}
9382 +
9383 +static struct acl_object_label *
9384 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
9385 +             const struct acl_subject_label *subj)
9386 +{
9387 +       struct dentry *dentry = (struct dentry *) l_dentry;
9388 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
9389 +       struct dentry *root;
9390 +       struct vfsmount *rootmnt;
9391 +       struct acl_object_label *retval;
9392 +
9393 +       read_lock(&child_reaper->fs->lock);
9394 +       rootmnt = mntget(child_reaper->fs->rootmnt);
9395 +       root = dget(child_reaper->fs->root);
9396 +       read_unlock(&child_reaper->fs->lock);
9397 +       spin_lock(&dcache_lock);
9398 +
9399 +       for (;;) {
9400 +               if (unlikely(dentry == root && mnt == rootmnt))
9401 +                       break;
9402 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
9403 +                       if (mnt->mnt_parent == mnt)
9404 +                               break;
9405 +
9406 +                       read_lock(&gr_inode_lock);
9407 +                       retval =
9408 +                           lookup_acl_obj_label(dentry->d_inode->i_ino,
9409 +                                                dentry->d_inode->i_dev, subj);
9410 +                       read_unlock(&gr_inode_lock);
9411 +                       if (unlikely(retval != NULL))
9412 +                               goto out;
9413 +
9414 +                       dentry = mnt->mnt_mountpoint;
9415 +                       mnt = mnt->mnt_parent;
9416 +                       continue;
9417 +               }
9418 +
9419 +               read_lock(&gr_inode_lock);
9420 +               retval =
9421 +                   lookup_acl_obj_label(dentry->d_inode->i_ino,
9422 +                                        dentry->d_inode->i_dev, subj);
9423 +               read_unlock(&gr_inode_lock);
9424 +               if (unlikely(retval != NULL))
9425 +                       goto out;
9426 +
9427 +               dentry = dentry->d_parent;
9428 +       }
9429 +
9430 +       read_lock(&gr_inode_lock);
9431 +       retval =
9432 +           lookup_acl_obj_label(dentry->d_inode->i_ino, dentry->d_inode->i_dev,
9433 +                                subj);
9434 +       read_unlock(&gr_inode_lock);
9435 +
9436 +       if (unlikely(retval == NULL)) {
9437 +               read_lock(&gr_inode_lock);
9438 +               retval =
9439 +                   lookup_acl_obj_label(root->d_inode->i_ino,
9440 +                                        root->d_inode->i_dev, subj);
9441 +               read_unlock(&gr_inode_lock);
9442 +       }
9443 +      out:
9444 +       spin_unlock(&dcache_lock);
9445 +       dput(root);
9446 +       mntput(rootmnt);
9447 +
9448 +       return retval;
9449 +}
9450 +
9451 +static struct acl_subject_label *
9452 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
9453 +              const struct acl_role_label *role)
9454 +{
9455 +       struct dentry *dentry = (struct dentry *) l_dentry;
9456 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
9457 +       struct dentry *root;
9458 +       struct vfsmount *rootmnt;
9459 +       struct acl_subject_label *retval;
9460 +
9461 +       read_lock(&child_reaper->fs->lock);
9462 +       rootmnt = mntget(child_reaper->fs->rootmnt);
9463 +       root = dget(child_reaper->fs->root);
9464 +       read_unlock(&child_reaper->fs->lock);
9465 +       spin_lock(&dcache_lock);
9466 +
9467 +       for (;;) {
9468 +               if (unlikely(dentry == root && mnt == rootmnt))
9469 +                       break;
9470 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
9471 +                       if (mnt->mnt_parent == mnt)
9472 +                               break;
9473 +
9474 +                       read_lock(&gr_inode_lock);
9475 +                       retval =
9476 +                           lookup_acl_subj_label(dentry->d_inode->i_ino,
9477 +                                                 dentry->d_inode->i_dev, role);
9478 +                       read_unlock(&gr_inode_lock);
9479 +                       if (unlikely(retval != NULL))
9480 +                               goto out;
9481 +
9482 +                       dentry = mnt->mnt_mountpoint;
9483 +                       mnt = mnt->mnt_parent;
9484 +                       continue;
9485 +               }
9486 +
9487 +               read_lock(&gr_inode_lock);
9488 +               retval =
9489 +                   lookup_acl_subj_label(dentry->d_inode->i_ino,
9490 +                                         dentry->d_inode->i_dev, role);
9491 +               read_unlock(&gr_inode_lock);
9492 +               if (unlikely(retval != NULL))
9493 +                       goto out;
9494 +
9495 +               dentry = dentry->d_parent;
9496 +       }
9497 +
9498 +       read_lock(&gr_inode_lock);
9499 +       retval =
9500 +           lookup_acl_subj_label(dentry->d_inode->i_ino,
9501 +                                 dentry->d_inode->i_dev, role);
9502 +       read_unlock(&gr_inode_lock);
9503 +
9504 +       if (unlikely(retval == NULL)) {
9505 +               read_lock(&gr_inode_lock);
9506 +               retval =
9507 +                   lookup_acl_subj_label(root->d_inode->i_ino,
9508 +                                         root->d_inode->i_dev, role);
9509 +               read_unlock(&gr_inode_lock);
9510 +       }
9511 +      out:
9512 +       spin_unlock(&dcache_lock);
9513 +       dput(root);
9514 +       mntput(rootmnt);
9515 +
9516 +       return retval;
9517 +}
9518 +
9519 +static __inline__ void
9520 +gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
9521 +            const struct task_struct *task, const char *pathname,
9522 +            const __u32 mode)
9523 +{
9524 +       security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
9525 +                      uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
9526 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
9527 +                      1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
9528 +
9529 +       return;
9530 +}
9531 +
9532 +__u32
9533 +gr_check_link(const struct dentry * new_dentry,
9534 +             const struct dentry * parent_dentry,
9535 +             const struct vfsmount * parent_mnt,
9536 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
9537 +{
9538 +       struct acl_object_label *obj;
9539 +       __u32 oldmode, newmode;
9540 +
9541 +       if (unlikely(!(gr_status & GR_READY)))
9542 +               return (GR_WRITE | GR_CREATE);
9543 +
9544 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
9545 +       oldmode = obj->mode;
9546 +
9547 +       if (current->acl->mode & GR_LEARN)
9548 +               oldmode |= (GR_WRITE | GR_CREATE);
9549 +       newmode =
9550 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
9551 +                           oldmode | GR_CREATE | GR_AUDIT_CREATE |
9552 +                           GR_AUDIT_WRITE | GR_SUPPRESS);
9553 +
9554 +       if ((newmode & oldmode) == oldmode)
9555 +               return newmode;
9556 +       else if (current->acl->mode & GR_LEARN) {
9557 +               gr_log_learn(current->role, current->uid, current->gid,
9558 +                       current, gr_to_filename(old_dentry, old_mnt), oldmode);
9559 +               return (GR_WRITE | GR_CREATE);
9560 +       } else if (newmode & GR_SUPPRESS)
9561 +               return GR_SUPPRESS;
9562 +       else
9563 +               return 0;
9564 +}
9565 +
9566 +__u32
9567 +gr_search_file(const struct dentry * dentry, const __u32 mode,
9568 +              const struct vfsmount * mnt)
9569 +{
9570 +       __u32 retval = mode;
9571 +       struct acl_subject_label *curracl;
9572 +       struct acl_object_label *currobj;
9573 +
9574 +       if (unlikely(!(gr_status & GR_READY)))
9575 +               return (mode & ~GR_AUDITS);
9576 +
9577 +       curracl = current->acl;
9578 +
9579 +       currobj = chk_obj_label(dentry, mnt, curracl);
9580 +       retval = currobj->mode & mode;
9581 +
9582 +       if (unlikely
9583 +           ((curracl->mode & GR_LEARN) && (mode != GR_PTRACERD)
9584 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
9585 +               __u32 new_mode = mode;
9586 +
9587 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9588 +
9589 +               retval = new_mode;
9590 +
9591 +               if (!(mode & GR_NOLEARN))
9592 +                       gr_log_learn(current->role, current->uid, current->gid,
9593 +                                    current, gr_to_filename(dentry, mnt), new_mode);
9594 +       }
9595 +
9596 +       return retval;
9597 +}
9598 +
9599 +__u32
9600 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
9601 +               const struct vfsmount * mnt, const __u32 mode)
9602 +{
9603 +       struct name_entry *match;
9604 +       struct acl_object_label *matchpo;
9605 +       struct acl_subject_label *curracl;
9606 +       __u32 retval;
9607 +
9608 +       if (unlikely(!(gr_status & GR_READY)))
9609 +               return (mode & ~GR_AUDITS);
9610 +
9611 +       match = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9612 +
9613 +       if (!match)
9614 +               goto check_parent;
9615 +
9616 +       curracl = current->acl;
9617 +
9618 +       read_lock(&gr_inode_lock);
9619 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
9620 +       read_unlock(&gr_inode_lock);
9621 +
9622 +       if (matchpo) {
9623 +               if ((matchpo->mode & mode) !=
9624 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
9625 +                   && curracl->mode & GR_LEARN) {
9626 +                       __u32 new_mode = mode;
9627 +
9628 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9629 +
9630 +                       gr_log_learn(current->role, current->uid, current->gid,
9631 +                                    current, gr_to_filename(new_dentry, mnt), new_mode);
9632 +
9633 +                       return new_mode;
9634 +               }
9635 +               return (matchpo->mode & mode);
9636 +       }
9637 +
9638 +      check_parent:
9639 +       curracl = current->acl;
9640 +
9641 +       matchpo = chk_obj_label(parent, mnt, curracl);
9642 +       retval = matchpo->mode & mode;
9643 +
9644 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
9645 +           && (curracl->mode & GR_LEARN)) {
9646 +               __u32 new_mode = mode;
9647 +
9648 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9649 +
9650 +               gr_log_learn(current->role, current->uid, current->gid, 
9651 +                            current, gr_to_filename(new_dentry, mnt), new_mode);
9652 +               return new_mode;
9653 +       }
9654 +
9655 +       return retval;
9656 +}
9657 +
9658 +int
9659 +gr_check_hidden_task(const struct task_struct *task)
9660 +{
9661 +       if (unlikely(!(gr_status & GR_READY)))
9662 +               return 0;
9663 +
9664 +       if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
9665 +               return 1;
9666 +
9667 +       return 0;
9668 +}
9669 +
9670 +int
9671 +gr_check_protected_task(const struct task_struct *task)
9672 +{
9673 +       if (unlikely(!(gr_status & GR_READY) || !task))
9674 +               return 0;
9675 +
9676 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
9677 +               return 1;
9678 +
9679 +       return 0;
9680 +}
9681 +
9682 +__inline__ void
9683 +gr_copy_label(struct task_struct *tsk)
9684 +{
9685 +       tsk->used_accept = 0;
9686 +       tsk->acl_sp_role = 0;
9687 +       tsk->acl_role_id = current->acl_role_id;
9688 +       tsk->acl = current->acl;
9689 +       tsk->role = current->role;
9690 +       tsk->curr_ip = current->curr_ip;
9691 +       if (current->exec_file)
9692 +               get_file(current->exec_file);
9693 +       tsk->exec_file = current->exec_file;
9694 +       tsk->is_writable = current->is_writable;
9695 +       if (unlikely(current->used_accept))
9696 +               current->curr_ip = 0;
9697 +
9698 +       return;
9699 +}
9700 +
9701 +static __inline__ void
9702 +gr_set_proc_res(void)
9703 +{
9704 +       struct acl_subject_label *proc;
9705 +       unsigned short i;
9706 +
9707 +       proc = current->acl;
9708 +
9709 +       if (proc->mode & GR_LEARN)
9710 +               return;
9711 +
9712 +       for (i = 0; i < RLIM_NLIMITS; i++) {
9713 +               if (!(proc->resmask & (1 << i)))
9714 +                       continue;
9715 +
9716 +               current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
9717 +               current->rlim[i].rlim_max = proc->res[i].rlim_max;
9718 +       }
9719 +
9720 +       return;
9721 +}
9722 +
9723 +void
9724 +gr_set_pax_flags(struct task_struct *task)
9725 +{
9726 +       struct acl_subject_label *proc;
9727 +
9728 +       if (unlikely(!(gr_status & GR_READY)))
9729 +               return;
9730 +
9731 +       proc = task->acl;
9732 +
9733 +       if (proc->mode & GR_PAXPAGE)
9734 +               task->flags &= ~PF_PAX_PAGEEXEC;
9735 +       if (proc->mode & GR_PAXSEGM)
9736 +               task->flags &= ~PF_PAX_SEGMEXEC;
9737 +       if (proc->mode & GR_PAXGCC)
9738 +               task->flags |= PF_PAX_EMUTRAMP;
9739 +       if (proc->mode & GR_PAXMPROTECT)
9740 +               task->flags &= ~PF_PAX_MPROTECT;
9741 +       if (proc->mode & GR_PAXRANDMMAP)
9742 +               task->flags &= ~PF_PAX_RANDMMAP;
9743 +       if (proc->mode & GR_PAXRANDEXEC)
9744 +               task->flags |= PF_PAX_RANDEXEC;
9745 +
9746 +       return;
9747 +}
9748 +
9749 +static __inline__ void
9750 +do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
9751 +{
9752 +       task->role = lookup_acl_role_label(task, uid, gid);
9753 +
9754 +       return;
9755 +}
9756 +
9757 +void
9758 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
9759 +{
9760 +       struct acl_object_label *obj;
9761 +       struct file *filp;
9762 +
9763 +       if (unlikely(!(gr_status & GR_READY)))
9764 +               return;
9765 +
9766 +       filp = task->exec_file;
9767 +
9768 +       /* kernel process, we'll give them the kernel role */
9769 +       if (unlikely(!filp)) {
9770 +               task->role = kernel_role;
9771 +               task->acl = kernel_role->root_label;
9772 +               return;
9773 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
9774 +               do_set_role_label(task, uid, gid);
9775 +
9776 +       task->acl =
9777 +           chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
9778 +
9779 +       task->is_writable = 0;
9780 +
9781 +       /* ignore additional mmap checks for processes that are writable 
9782 +          by the default ACL */
9783 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9784 +       if (unlikely(obj->mode & GR_WRITE))
9785 +               task->is_writable = 1;
9786 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9787 +       if (unlikely(obj->mode & GR_WRITE))
9788 +               task->is_writable = 1;
9789 +
9790 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9791 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9792 +#endif
9793 +
9794 +       gr_set_proc_res();
9795 +
9796 +       return;
9797 +}
9798 +
9799 +void
9800 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
9801 +{
9802 +       struct acl_subject_label *newacl;
9803 +       struct acl_object_label *obj;
9804 +       __u32 retmode;
9805 +
9806 +       if (unlikely(!(gr_status & GR_READY)))
9807 +               return;
9808 +
9809 +       newacl = chk_subj_label(dentry, mnt, current->role);
9810 +
9811 +       obj = chk_obj_label(dentry, mnt, current->acl);
9812 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
9813 +
9814 +       if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
9815 +               if (obj->nested)
9816 +                       current->acl = obj->nested;
9817 +               else
9818 +                       current->acl = newacl;
9819 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
9820 +               security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
9821 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
9822 +
9823 +       current->is_writable = 0;
9824 +
9825 +       /* ignore additional mmap checks for processes that are writable 
9826 +          by the default ACL */
9827 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
9828 +       if (unlikely(obj->mode & GR_WRITE))
9829 +               current->is_writable = 1;
9830 +       obj = chk_obj_label(dentry, mnt, current->role->root_label);
9831 +       if (unlikely(obj->mode & GR_WRITE))
9832 +               current->is_writable = 1;
9833 +
9834 +       gr_set_proc_res();
9835 +
9836 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9837 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
9838 +#endif
9839 +       return;
9840 +}
9841 +
9842 +static __inline__ void
9843 +do_handle_delete(const ino_t ino, const kdev_t dev)
9844 +{
9845 +       struct acl_object_label *matchpo;
9846 +       struct acl_subject_label *matchps;
9847 +       struct acl_subject_label *i;
9848 +       struct acl_role_label *role;
9849 +
9850 +       for (role = role_list_head; role; role = role->next) {
9851 +               for (i = role->proc_subject; i; i = i->next) {
9852 +                       if (unlikely(i->parent_subject &&
9853 +                                    (i->inode == ino) &&
9854 +                                    (i->device == dev)))
9855 +                               i->mode |= GR_DELETED;
9856 +                       if (unlikely((matchpo =
9857 +                            lookup_acl_obj_label(ino, dev, i)) != NULL))
9858 +                               matchpo->mode |= GR_DELETED;
9859 +               }
9860 +
9861 +               if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
9862 +                       matchps->mode |= GR_DELETED;
9863 +       }
9864 +
9865 +       return;
9866 +}
9867 +
9868 +void
9869 +gr_handle_delete(const ino_t ino, const kdev_t dev)
9870 +{
9871 +       if (unlikely(!(gr_status & GR_READY)))
9872 +               return;
9873 +
9874 +       write_lock(&gr_inode_lock);
9875 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
9876 +               do_handle_delete(ino, dev);
9877 +       write_unlock(&gr_inode_lock);
9878 +
9879 +       return;
9880 +}
9881 +
9882 +static __inline__ void
9883 +update_acl_obj_label(const ino_t oldinode, const kdev_t olddevice,
9884 +                    const ino_t newinode, const kdev_t newdevice,
9885 +                    struct acl_subject_label *subj)
9886 +{
9887 +       unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
9888 +       struct acl_object_label **match;
9889 +       struct acl_object_label *tmp;
9890 +       __u8 i = 0;
9891 +
9892 +       match = &subj->obj_hash[index];
9893 +
9894 +       while (*match && ((*match)->inode != oldinode ||
9895 +              (*match)->device != olddevice ||
9896 +              !((*match)->mode & GR_DELETED))) {
9897 +               index = (index + (1 << i)) % subj->obj_hash_size;
9898 +               match = &subj->obj_hash[index];
9899 +               i = (i + 1) % 32;
9900 +       }
9901 +
9902 +       if (*match && ((*match) != deleted_object)
9903 +           && ((*match)->inode == oldinode)
9904 +           && ((*match)->device == olddevice)
9905 +           && ((*match)->mode & GR_DELETED)) {
9906 +               tmp = *match;
9907 +               tmp->inode = newinode;
9908 +               tmp->device = newdevice;
9909 +               tmp->mode &= ~GR_DELETED;
9910 +
9911 +               *match = deleted_object;
9912 +
9913 +               insert_acl_obj_label(tmp, subj);
9914 +       }
9915 +
9916 +       return;
9917 +}
9918 +
9919 +static __inline__ void
9920 +update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice,
9921 +                     const ino_t newinode, const kdev_t newdevice,
9922 +                     struct acl_role_label *role)
9923 +{
9924 +       struct acl_subject_label **s_hash = role->subj_hash;
9925 +       unsigned long subj_size = role->subj_hash_size;
9926 +       unsigned long index = fhash(oldinode, olddevice, subj_size);
9927 +       struct acl_subject_label **match;
9928 +       struct acl_subject_label *tmp;
9929 +       __u8 i = 0;
9930 +
9931 +       match = &s_hash[index];
9932 +
9933 +       while (*match && ((*match)->inode != oldinode ||
9934 +              (*match)->device != olddevice ||
9935 +              !((*match)->mode & GR_DELETED))) {
9936 +               index = (index + (1 << i)) % subj_size;
9937 +               i = (i + 1) % 32;
9938 +               match = &s_hash[index];
9939 +       }
9940 +
9941 +       if (*match && (*match != deleted_subject)
9942 +           && ((*match)->inode == oldinode)
9943 +           && ((*match)->device == olddevice)
9944 +           && ((*match)->mode & GR_DELETED)) {
9945 +               tmp = *match;
9946 +
9947 +               tmp->inode = newinode;
9948 +               tmp->device = newdevice;
9949 +               tmp->mode &= ~GR_DELETED;
9950 +
9951 +               *match = deleted_subject;
9952 +
9953 +               insert_acl_subj_label(tmp, role);
9954 +       }
9955 +
9956 +       return;
9957 +}
9958 +
9959 +static __inline__ void
9960 +update_inodev_entry(const ino_t oldinode, const kdev_t olddevice,
9961 +                   const ino_t newinode, const kdev_t newdevice)
9962 +{
9963 +       unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
9964 +       struct name_entry **match;
9965 +       struct name_entry *tmp;
9966 +       __u8 i = 0;
9967 +
9968 +       match = &inodev_set.n_hash[index];
9969 +
9970 +       while (*match
9971 +              && ((*match)->inode != oldinode
9972 +                  || (*match)->device != olddevice)) {
9973 +               index = (index + (1 << i)) % inodev_set.n_size;
9974 +               i = (i + 1) % 32;
9975 +               match = &inodev_set.n_hash[index];
9976 +       }
9977 +
9978 +       if (*match && (*match != deleted_inodev)
9979 +           && ((*match)->inode == oldinode)
9980 +           && ((*match)->device == olddevice)) {
9981 +               tmp = *match;
9982 +
9983 +               tmp->inode = newinode;
9984 +               tmp->device = newdevice;
9985 +
9986 +               *match = deleted_inodev;
9987 +
9988 +               insert_inodev_entry(tmp);
9989 +       }
9990 +
9991 +       return;
9992 +}
9993 +
9994 +static __inline__ void
9995 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
9996 +                const struct vfsmount *mnt)
9997 +{
9998 +       struct acl_subject_label *i;
9999 +       struct acl_role_label *role;
10000 +
10001 +       for (role = role_list_head; role; role = role->next) {
10002 +               update_acl_subj_label(matchn->inode, matchn->device,
10003 +                                     dentry->d_inode->i_ino,
10004 +                                     dentry->d_inode->i_dev, role);
10005 +
10006 +               for (i = role->proc_subject; i; i = i->next) {
10007 +                       if (unlikely(i->parent_subject &&
10008 +                                    (i->inode == dentry->d_inode->i_ino) &&
10009 +                                    (i->device == dentry->d_inode->i_dev))) {
10010 +                               i->inode = dentry->d_inode->i_ino;
10011 +                               i->device = dentry->d_inode->i_dev;
10012 +                       }
10013 +                       update_acl_obj_label(matchn->inode, matchn->device,
10014 +                                            dentry->d_inode->i_ino,
10015 +                                            dentry->d_inode->i_dev, i);
10016 +               }
10017 +       }
10018 +
10019 +       update_inodev_entry(matchn->inode, matchn->device,
10020 +                           dentry->d_inode->i_ino, dentry->d_inode->i_dev);
10021 +
10022 +       return;
10023 +}
10024 +
10025 +void
10026 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
10027 +{
10028 +       struct name_entry *matchn;
10029 +
10030 +       if (unlikely(!(gr_status & GR_READY)))
10031 +               return;
10032 +
10033 +       matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
10034 +
10035 +       if (unlikely((unsigned long)matchn)) {
10036 +               write_lock(&gr_inode_lock);
10037 +               do_handle_create(matchn, dentry, mnt);
10038 +               write_unlock(&gr_inode_lock);
10039 +       }
10040 +
10041 +       return;
10042 +}
10043 +
10044 +int
10045 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
10046 +                struct dentry *old_dentry,
10047 +                struct dentry *new_dentry,
10048 +                struct vfsmount *mnt, const __u8 replace)
10049 +{
10050 +       struct name_entry *matchn;
10051 +       int error = 0;
10052 +
10053 +       matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
10054 +
10055 +       lock_kernel();
10056 +       error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
10057 +       unlock_kernel();
10058 +
10059 +       if (unlikely(error))
10060 +               return error;
10061 +
10062 +       /* we wouldn't have to check d_inode if it weren't for
10063 +          NFS silly-renaming
10064 +        */
10065 +
10066 +       write_lock(&gr_inode_lock);
10067 +       if (unlikely(replace && new_dentry->d_inode)) {
10068 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
10069 +                                       new_dentry->d_inode->i_dev) &&
10070 +                   (old_dentry->d_inode->i_nlink <= 1)))
10071 +                       do_handle_delete(new_dentry->d_inode->i_ino,
10072 +                                        new_dentry->d_inode->i_dev);
10073 +       }
10074 +
10075 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
10076 +                               old_dentry->d_inode->i_dev) &&
10077 +           (old_dentry->d_inode->i_nlink <= 1)))
10078 +               do_handle_delete(old_dentry->d_inode->i_ino,
10079 +                                old_dentry->d_inode->i_dev);
10080 +
10081 +       if (unlikely((unsigned long)matchn))
10082 +               do_handle_create(matchn, old_dentry, mnt);
10083 +       write_unlock(&gr_inode_lock);
10084 +
10085 +       return error;
10086 +}
10087 +
10088 +static int
10089 +lookup_special_role_auth(const char *rolename, unsigned char **salt,
10090 +                        unsigned char **sum)
10091 +{
10092 +       struct acl_role_label *r;
10093 +       struct role_transition *trans;
10094 +       __u16 i;
10095 +       int found = 0;
10096 +
10097 +       /* check transition table */
10098 +
10099 +       for (trans = current->role->transitions; trans; trans = trans->next) {
10100 +               if (!strcmp(rolename, trans->rolename)) {
10101 +                       found = 1;
10102 +                       break;
10103 +               }
10104 +       }
10105 +
10106 +       if (!found)
10107 +               return 0;
10108 +
10109 +       /* handle special roles that do not require authentication */
10110 +
10111 +       for (r = role_list_head; r; r = r->next) {
10112 +               if (!strcmp(rolename, r->rolename)
10113 +                   && (r->roletype & GR_ROLE_NOPW)) {
10114 +                       *salt = NULL;
10115 +                       *sum = NULL;
10116 +                       return 1;
10117 +               }
10118 +       }
10119 +
10120 +       for (i = 0; i < num_sprole_pws; i++) {
10121 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
10122 +                       *salt = acl_special_roles[i]->salt;
10123 +                       *sum = acl_special_roles[i]->sum;
10124 +                       return 1;
10125 +               }
10126 +       }
10127 +
10128 +       return 0;
10129 +}
10130 +
10131 +static void
10132 +assign_special_role(char *rolename)
10133 +{
10134 +       struct acl_object_label *obj;
10135 +       struct acl_role_label *r;
10136 +       struct acl_role_label *assigned = NULL;
10137 +       struct task_struct *tsk;
10138 +       struct file *filp;
10139 +
10140 +       for (r = role_list_head; r; r = r->next)
10141 +               if (!strcmp(rolename, r->rolename) &&
10142 +                   (r->roletype & GR_ROLE_SPECIAL))
10143 +                       assigned = r;
10144 +
10145 +       if (!assigned)
10146 +               return;
10147 +
10148 +       tsk = current->p_pptr;
10149 +       filp = tsk->exec_file;
10150 +
10151 +       if (tsk && filp) {
10152 +               tsk->is_writable = 0;
10153 +
10154 +               acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
10155 +               tsk->acl_sp_role = 1;
10156 +               tsk->acl_role_id = acl_sp_role_value;
10157 +               tsk->role = assigned;
10158 +               tsk->acl =
10159 +                   chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
10160 +
10161 +               /* ignore additional mmap checks for processes that are writable 
10162 +                  by the default ACL */
10163 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10164 +               if (unlikely(obj->mode & GR_WRITE))
10165 +                       tsk->is_writable = 1;
10166 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
10167 +               if (unlikely(obj->mode & GR_WRITE))
10168 +                       tsk->is_writable = 1;
10169 +
10170 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10171 +               printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
10172 +#endif
10173 +       }
10174 +
10175 +       return;
10176 +}
10177 +
10178 +ssize_t
10179 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
10180 +{
10181 +       struct gr_arg *arg;
10182 +       unsigned char *sprole_salt;
10183 +       unsigned char *sprole_sum;
10184 +       int error = sizeof (struct gr_arg);
10185 +       int error2 = 0;
10186 +
10187 +       down(&gr_dev_sem);
10188 +
10189 +       arg = (struct gr_arg *) buf;
10190 +
10191 +       if (count != sizeof (struct gr_arg)) {
10192 +               security_alert_good(GR_DEV_ACL_MSG, count,
10193 +                                   (int) sizeof (struct gr_arg));
10194 +               error = -EINVAL;
10195 +               goto out;
10196 +       }
10197 +
10198 +       if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10199 +           && time_before_eq(gr_auth_expires, jiffies)) {
10200 +               gr_auth_expires = 0;
10201 +               gr_auth_attempts = 0;
10202 +       }
10203 +
10204 +       if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
10205 +               error = -EFAULT;
10206 +               goto out;
10207 +       }
10208 +
10209 +       if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) {
10210 +               error = -EBUSY;
10211 +               goto out;
10212 +       }
10213 +
10214 +       /* if non-root trying to do anything other than use a special role,
10215 +          do not attempt authentication, do not count towards authentication
10216 +          locking
10217 +        */
10218 +
10219 +       if (gr_usermode->mode != SPROLE && current->uid) {
10220 +               error = -EPERM;
10221 +               goto out;
10222 +       }
10223 +
10224 +       /* ensure pw and special role name are null terminated */
10225 +
10226 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
10227 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
10228 +
10229 +       /* Okay. 
10230 +        * We have our enough of the argument structure..(we have yet
10231 +        * to copy_from_user the tables themselves) . Copy the tables
10232 +        * only if we need them, i.e. for loading operations. */
10233 +
10234 +       switch (gr_usermode->mode) {
10235 +       case STATUS:
10236 +                       if (gr_status & GR_READY)
10237 +                               error = 1;
10238 +                       else
10239 +                               error = 2;
10240 +                       goto out;
10241 +       case SHUTDOWN:
10242 +               if ((gr_status & GR_READY)
10243 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10244 +                       gr_status &= ~GR_READY;
10245 +                       security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
10246 +                       free_variables();
10247 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
10248 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
10249 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
10250 +               } else if (gr_status & GR_READY) {
10251 +                       security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
10252 +                       error = -EPERM;
10253 +               } else {
10254 +                       security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
10255 +                       error = -EAGAIN;
10256 +               }
10257 +               break;
10258 +       case ENABLE:
10259 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
10260 +                       security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
10261 +               else {
10262 +                       if (gr_status & GR_READY)
10263 +                               error = -EAGAIN;
10264 +                       else
10265 +                               error = error2;
10266 +                       security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
10267 +                                      DEFAULTSECARGS);
10268 +               }
10269 +               break;
10270 +       case RELOAD:
10271 +               if (!(gr_status & GR_READY)) {
10272 +                       security_alert_good(GR_RELOADI_ACL_MSG);
10273 +                       error = -EAGAIN;
10274 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10275 +                       lock_kernel();
10276 +                       gr_status &= ~GR_READY;
10277 +                       free_variables();
10278 +                       if (!(error2 = gracl_init(gr_usermode))) {
10279 +                               unlock_kernel();
10280 +                               security_alert_good(GR_RELOAD_ACL_MSG,
10281 +                                                   GR_VERSION);
10282 +                       } else {
10283 +                               unlock_kernel();
10284 +                               error = error2;
10285 +                               security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
10286 +                                              DEFAULTSECARGS);
10287 +                       }
10288 +               } else {
10289 +                       security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
10290 +                                      DEFAULTSECARGS);
10291 +                       error = -EPERM;
10292 +               }
10293 +               break;
10294 +       case SEGVMOD:
10295 +               if (unlikely(!(gr_status & GR_READY))) {
10296 +                       security_alert_good(GR_SEGVMODI_ACL_MSG,
10297 +                                           DEFAULTSECARGS);
10298 +                       error = -EAGAIN;
10299 +                       break;
10300 +               }
10301 +
10302 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10303 +                       security_alert_good(GR_SEGVMODS_ACL_MSG,
10304 +                                           DEFAULTSECARGS);
10305 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
10306 +                               struct acl_subject_label *segvacl;
10307 +                               segvacl =
10308 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
10309 +                                                         gr_usermode->segv_device,
10310 +                                                         current->role);
10311 +                               if (segvacl) {
10312 +                                       segvacl->crashes = 0;
10313 +                                       segvacl->expires = 0;
10314 +                               }
10315 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
10316 +                               gr_remove_uid(gr_usermode->segv_uid);
10317 +                       }
10318 +               } else {
10319 +                       security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
10320 +                       error = -EPERM;
10321 +               }
10322 +               break;
10323 +       case SPROLE:
10324 +               if (unlikely(!(gr_status & GR_READY))) {
10325 +                       security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
10326 +                       error = -EAGAIN;
10327 +                       break;
10328 +               }
10329 +
10330 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10331 +                   && time_before_eq(current->role->expires, jiffies)) {
10332 +                       current->role->expires = 0;
10333 +                       current->role->auth_attempts = 0;
10334 +               }
10335 +
10336 +               if (time_after(current->role->expires, jiffies)) {
10337 +                       error = -EBUSY;
10338 +                       goto out;
10339 +               }
10340 +
10341 +               if (lookup_special_role_auth
10342 +                   (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
10343 +                   && ((!sprole_salt && !sprole_sum)
10344 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
10345 +                       assign_special_role(gr_usermode->sp_role);
10346 +                       security_alert_good(GR_SPROLES_ACL_MSG,
10347 +                                           (current->p_pptr) ? current->
10348 +                                           p_pptr->role->rolename : "",
10349 +                                           acl_sp_role_value, DEFAULTSECARGS);
10350 +               } else {
10351 +                       security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
10352 +                                      DEFAULTSECARGS);
10353 +                       error = -EPERM;
10354 +                       current->role->auth_attempts++;
10355 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10356 +                               current->role->expires =
10357 +                                   jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
10358 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
10359 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
10360 +                                      gr_usermode->sp_role, DEFAULTSECARGS);
10361 +                       }
10362 +
10363 +                       goto out;
10364 +               }
10365 +               break;
10366 +       case UNSPROLE:
10367 +               if (unlikely(!(gr_status & GR_READY))) {
10368 +                       security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
10369 +                       error = -EAGAIN;
10370 +                       break;
10371 +               }
10372 +
10373 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10374 +                   && time_before_eq(current->role->expires, jiffies)) {
10375 +                       current->role->expires = 0;
10376 +                       current->role->auth_attempts = 0;
10377 +               }
10378 +
10379 +               if (time_after(current->role->expires, jiffies)) {
10380 +                       error = -EBUSY;
10381 +                       goto out;
10382 +               }
10383 +
10384 +               if ((current->role->roletype & GR_ROLE_SPECIAL) && 
10385 +                   lookup_special_role_auth
10386 +                   (current->role->rolename, &sprole_salt, &sprole_sum)
10387 +                   && ((!sprole_salt && !sprole_sum)
10388 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
10389 +                       security_alert_good(GR_UNSPROLES_ACL_MSG,
10390 +                                           (current->p_pptr) ? current->
10391 +                                           p_pptr->role->rolename : "",
10392 +                                           (current->p_pptr) ? current->
10393 +                                           p_pptr->acl_role_id : 0, DEFAULTSECARGS);
10394 +                       gr_set_acls(1);
10395 +                       if (current->p_pptr)
10396 +                               current->p_pptr->acl_sp_role = 0;
10397 +               } else {
10398 +                       security_alert(GR_UNSPROLEF_ACL_MSG, gr_usermode->sp_role,
10399 +                                      DEFAULTSECARGS);
10400 +                       error = -EPERM;
10401 +                       current->role->auth_attempts++;
10402 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10403 +                               current->role->expires =
10404 +                                   jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
10405 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
10406 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
10407 +                                      current->role->rolename, DEFAULTSECARGS);
10408 +                       }
10409 +
10410 +                       goto out;
10411 +               }
10412 +               break;
10413 +       default:
10414 +               security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
10415 +                              DEFAULTSECARGS);
10416 +               error = -EINVAL;
10417 +               break;
10418 +       }
10419 +
10420 +       if (error != -EPERM)
10421 +               goto out;
10422 +
10423 +       gr_auth_attempts++;
10424 +
10425 +       if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10426 +               security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
10427 +               gr_auth_expires = jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
10428 +       }
10429 +
10430 +      out:
10431 +       up(&gr_dev_sem);
10432 +       return error;
10433 +}
10434 +
10435 +int
10436 +gr_set_acls(const int type)
10437 +{
10438 +       struct acl_object_label *obj;
10439 +       struct task_struct *task;
10440 +       struct file *filp;
10441 +       unsigned short i;
10442 +
10443 +       read_lock(&tasklist_lock);
10444 +       for_each_task(task) {
10445 +               /* check to see if we're called from the exit handler,
10446 +                  if so, only replace ACLs that have inherited the admin
10447 +                  ACL */
10448 +
10449 +               if (type && (task->role != current->role ||
10450 +                            task->acl_role_id != current->acl_role_id))
10451 +                       continue;
10452 +
10453 +               task->acl_role_id = 0;
10454 +
10455 +               if ((filp = task->exec_file)) {
10456 +                       do_set_role_label(task, task->uid, task->gid);
10457 +
10458 +                       task->acl =
10459 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
10460 +                                          task->role);
10461 +                       if (task->acl) {
10462 +                               struct acl_subject_label *curr;
10463 +                               curr = task->acl;
10464 +
10465 +                               task->is_writable = 0;
10466 +                               /* ignore additional mmap checks for processes that are writable 
10467 +                                  by the default ACL */
10468 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10469 +                               if (unlikely(obj->mode & GR_WRITE))
10470 +                                       task->is_writable = 1;
10471 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
10472 +                               if (unlikely(obj->mode & GR_WRITE))
10473 +                                       task->is_writable = 1;
10474 +
10475 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10476 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
10477 +#endif
10478 +                               if (!(curr->mode & GR_LEARN))
10479 +                                       for (i = 0; i < RLIM_NLIMITS; i++) {
10480 +                                               if (!(curr->resmask & (1 << i)))
10481 +                                                       continue;
10482 +
10483 +                                               task->rlim[i].rlim_cur =
10484 +                                                   curr->res[i].rlim_cur;
10485 +                                               task->rlim[i].rlim_max =
10486 +                                                   curr->res[i].rlim_max;
10487 +                                       }
10488 +                       } else {
10489 +                               read_unlock(&tasklist_lock);
10490 +                               security_alert_good(GR_DEFACL_MSG, task->comm,
10491 +                                                   task->pid);
10492 +                               return 1;
10493 +                       }
10494 +               } else {
10495 +                       // it's a kernel process
10496 +                       task->role = kernel_role;
10497 +                       task->acl = kernel_role->root_label;
10498 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
10499 +                       task->acl->mode &= ~GR_FIND;
10500 +#endif
10501 +               }
10502 +       }
10503 +       read_unlock(&tasklist_lock);
10504 +       return 0;
10505 +}
10506 +
10507 +void
10508 +gr_learn_resource(const struct task_struct *task,
10509 +                 const int res, const unsigned long wanted, const int gt)
10510 +{
10511 +       struct acl_subject_label *acl;
10512 +
10513 +       if (unlikely((gr_status & GR_READY) &&
10514 +                    task->acl && (task->acl->mode & GR_LEARN)))
10515 +               goto skip_reslog;
10516 +
10517 +#ifdef CONFIG_GRKERNSEC_RESLOG
10518 +       gr_log_resource(task, res, wanted, gt);
10519 +#endif
10520 +      skip_reslog:
10521 +
10522 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
10523 +               return;
10524 +
10525 +       acl = task->acl;
10526 +
10527 +       if (likely(!acl || !(acl->mode & GR_LEARN) ||
10528 +                  !(acl->resmask & (1 << (unsigned short) res))))
10529 +               return;
10530 +
10531 +       if (wanted >= acl->res[res].rlim_cur) {
10532 +               unsigned long res_add;
10533 +
10534 +               res_add = wanted;
10535 +               switch (res) {
10536 +               case RLIMIT_CPU:
10537 +                       res_add += GR_RLIM_CPU_BUMP;
10538 +                       break;
10539 +               case RLIMIT_FSIZE:
10540 +                       res_add += GR_RLIM_FSIZE_BUMP;
10541 +                       break;
10542 +               case RLIMIT_DATA:
10543 +                       res_add += GR_RLIM_DATA_BUMP;
10544 +                       break;
10545 +               case RLIMIT_STACK:
10546 +                       res_add += GR_RLIM_STACK_BUMP;
10547 +                       break;
10548 +               case RLIMIT_CORE:
10549 +                       res_add += GR_RLIM_CORE_BUMP;
10550 +                       break;
10551 +               case RLIMIT_RSS:
10552 +                       res_add += GR_RLIM_RSS_BUMP;
10553 +                       break;
10554 +               case RLIMIT_NPROC:
10555 +                       res_add += GR_RLIM_NPROC_BUMP;
10556 +                       break;
10557 +               case RLIMIT_NOFILE:
10558 +                       res_add += GR_RLIM_NOFILE_BUMP;
10559 +                       break;
10560 +               case RLIMIT_MEMLOCK:
10561 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
10562 +                       break;
10563 +               case RLIMIT_AS:
10564 +                       res_add += GR_RLIM_AS_BUMP;
10565 +                       break;
10566 +               case RLIMIT_LOCKS:
10567 +                       res_add += GR_RLIM_LOCKS_BUMP;
10568 +                       break;
10569 +               }
10570 +
10571 +               acl->res[res].rlim_cur = res_add;
10572 +
10573 +               if (wanted > acl->res[res].rlim_max)
10574 +                       acl->res[res].rlim_max = res_add;
10575 +
10576 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10577 +                              current->role->roletype, acl->filename,
10578 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
10579 +                              "", (unsigned long) res);
10580 +       }
10581 +
10582 +       return;
10583 +}
10584 +
10585 +#ifdef CONFIG_SYSCTL
10586 +extern struct proc_dir_entry *proc_sys_root;
10587 +
10588 +__u32
10589 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
10590 +                const void *newval)
10591 +{
10592 +       struct proc_dir_entry *tmp;
10593 +       struct nameidata nd;
10594 +       const char *proc_sys = "/proc/sys";
10595 +       char *path = gr_shared_page[0][smp_processor_id()];
10596 +       struct acl_object_label *obj;
10597 +       unsigned short len = 0, pos = 0, depth = 0, i;
10598 +       __u32 err = 0;
10599 +       __u32 mode = 0;
10600 +
10601 +       if (unlikely(!(gr_status & GR_READY)))
10602 +               return 1;
10603 +
10604 +       if (oldval)
10605 +               mode |= GR_READ;
10606 +       if (newval)
10607 +               mode |= GR_WRITE;
10608 +
10609 +       /* convert the requested sysctl entry into a pathname */
10610 +
10611 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
10612 +               len += strlen(tmp->name);
10613 +               len++;
10614 +               depth++;
10615 +       }
10616 +
10617 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
10618 +               return 0;       // deny
10619 +
10620 +       memset(path, 0, PAGE_SIZE);
10621 +
10622 +       memcpy(path, proc_sys, strlen(proc_sys));
10623 +
10624 +       pos += strlen(proc_sys);
10625 +
10626 +       for (; depth > 0; depth--) {
10627 +               path[pos] = '/';
10628 +               pos++;
10629 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
10630 +                    tmp = tmp->parent) {
10631 +                       if (depth == i) {
10632 +                               memcpy(path + pos, tmp->name,
10633 +                                      strlen(tmp->name));
10634 +                               pos += strlen(tmp->name);
10635 +                       }
10636 +                       i++;
10637 +               }
10638 +       }
10639 +
10640 +       if (path_init(path, LOOKUP_FOLLOW, &nd))
10641 +               err = path_walk(path, &nd);
10642 +
10643 +       if (err)
10644 +               goto out;
10645 +
10646 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
10647 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
10648 +
10649 +       if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
10650 +               __u32 new_mode = mode;
10651 +
10652 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10653 +
10654 +               err = new_mode;
10655 +               gr_log_learn(current->role, current->uid, current->gid,
10656 +                            current, path, new_mode);
10657 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
10658 +               security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
10659 +                              (mode & GR_READ) ? " reading" : "",
10660 +                              (mode & GR_WRITE) ? " writing" : "",
10661 +                              DEFAULTSECARGS);
10662 +               err = 0;
10663 +       } else if ((err & mode) != mode) {
10664 +               err = 0;
10665 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
10666 +               security_audit(GR_SYSCTL_ACL_MSG, "successful",
10667 +                              path, (mode & GR_READ) ? " reading" : "",
10668 +                              (mode & GR_WRITE) ? " writing" : "",
10669 +                              DEFAULTSECARGS);
10670 +       }
10671 +
10672 +       path_release(&nd);
10673 +
10674 +      out:
10675 +       return err;
10676 +}
10677 +#endif
10678 +
10679 +int
10680 +gr_handle_ptrace(struct task_struct *task, const long request)
10681 +{
10682 +       struct file *filp;
10683 +       __u32 retmode;
10684 +
10685 +       if (unlikely(!(gr_status & GR_READY)))
10686 +               return 0;
10687 +
10688 +       filp = task->exec_file;
10689 +
10690 +       if (unlikely(!filp))
10691 +               return 0;
10692 +
10693 +       retmode = gr_search_file(filp->f_dentry, GR_PTRACERD, filp->f_vfsmnt);
10694 +
10695 +       if (retmode & GR_PTRACERD) {
10696 +               switch (request) {
10697 +               case PTRACE_POKETEXT:
10698 +               case PTRACE_POKEDATA:
10699 +               case PTRACE_POKEUSR:
10700 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
10701 +               case PTRACE_SETREGS:
10702 +               case PTRACE_SETFPREGS:
10703 +#endif
10704 +#ifdef CONFIG_X86
10705 +               case PTRACE_SETFPXREGS:
10706 +#endif
10707 +#ifdef CONFIG_ALTIVEC
10708 +               case PTRACE_SETVRREGS:
10709 +#endif
10710 +                       return 1;
10711 +               default:
10712 +                       return 0;
10713 +               }
10714 +       } else if (!(current->acl->mode & GR_OVERRIDE) &&
10715 +                  !(current->role->roletype & GR_ROLE_GOD)
10716 +                  && (current->acl != task->acl
10717 +                      || (current->acl != current->role->root_label
10718 +                          && current->pid != task->pid))) {
10719 +               security_alert(GR_PTRACE_ACL_MSG,
10720 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10721 +                              task->comm, task->pid, DEFAULTSECARGS);
10722 +               return 1;
10723 +       }
10724 +
10725 +       return 0;
10726 +}
10727 +
10728 +int
10729 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
10730 +{
10731 +       __u32 retmode;
10732 +       struct acl_subject_label *subj;
10733 +
10734 +       if (unlikely(!(gr_status & GR_READY)))
10735 +               return 0;
10736 +
10737 +       if (unlikely
10738 +           ((current->ptrace & PT_PTRACED)
10739 +            && !(current->acl->mode & GR_OVERRIDE)))
10740 +               retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
10741 +       else
10742 +               return 0;
10743 +
10744 +       subj = chk_subj_label(dentry, mnt, current->role);
10745 +
10746 +       if (!(retmode & GR_PTRACERD) &&
10747 +           !(current->role->roletype & GR_ROLE_GOD) &&
10748 +           (current->acl != subj)) {
10749 +               security_alert(GR_PTRACE_EXEC_ACL_MSG,
10750 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
10751 +               return 1;
10752 +       }
10753 +
10754 +       return 0;
10755 +}
10756 +
10757 +int
10758 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
10759 +{
10760 +       struct acl_object_label *obj, *obj2;
10761 +
10762 +       if (unlikely(!(gr_status & GR_READY) ||
10763 +                    (current->acl->mode & GR_OVERRIDE) || !filp ||
10764 +                    !(prot & PROT_EXEC)))
10765 +               return 0;
10766 +
10767 +       if (unlikely(current->is_writable))
10768 +               return 0;
10769 +
10770 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10771 +       obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
10772 +                            current->role->root_label);
10773 +       if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
10774 +               security_alert(GR_WRITLIB_ACL_MSG,
10775 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10776 +                              DEFAULTSECARGS);
10777 +               return 1;
10778 +       }
10779 +
10780 +       return 0;
10781 +}
10782 +
10783 +int
10784 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
10785 +{
10786 +       __u32 mode;
10787 +
10788 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10789 +               return 1;
10790 +
10791 +       mode =
10792 +           gr_search_file(file->f_dentry,
10793 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10794 +                          file->f_vfsmnt);
10795 +
10796 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10797 +               security_alert(GR_MMAP_ACL_MSG, "denied",
10798 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10799 +                              DEFAULTSECARGS);
10800 +               return 0;
10801 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10802 +               return 0;
10803 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10804 +               security_audit(GR_MMAP_ACL_MSG, "successful",
10805 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10806 +                              DEFAULTSECARGS);
10807 +               return 1;
10808 +       }
10809 +
10810 +       return 1;
10811 +}
10812 +
10813 +int
10814 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
10815 +{
10816 +       __u32 mode;
10817 +
10818 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10819 +               return 1;
10820 +
10821 +       mode =
10822 +           gr_search_file(file->f_dentry,
10823 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10824 +                          file->f_vfsmnt);
10825 +
10826 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10827 +               security_alert(GR_MPROTECT_ACL_MSG, "denied",
10828 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10829 +                              DEFAULTSECARGS);
10830 +               return 0;
10831 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10832 +               return 0;
10833 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10834 +               security_audit(GR_MPROTECT_ACL_MSG, "successful",
10835 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10836 +                              DEFAULTSECARGS);
10837 +               return 1;
10838 +       }
10839 +
10840 +       return 1;
10841 +}
10842 +
10843 +void
10844 +gr_acl_handle_psacct(struct task_struct *task, const long code)
10845 +{
10846 +       unsigned long runtime;
10847 +       unsigned long cputime;
10848 +       unsigned int wday, cday;
10849 +       __u8 whr, chr;
10850 +       __u8 wmin, cmin;
10851 +       __u8 wsec, csec;
10852 +       char cur_tty[64] = { 0 };
10853 +       char parent_tty[64] = { 0 };
10854 +
10855 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
10856 +                    !(task->acl->mode & GR_PROCACCT)))
10857 +               return;
10858 +
10859 +       runtime = (jiffies - task->start_time) / HZ;
10860 +       wday = runtime / (3600 * 24);
10861 +       runtime -= wday * (3600 * 24);
10862 +       whr = runtime / 3600;
10863 +       runtime -= whr * 3600;
10864 +       wmin = runtime / 60;
10865 +       runtime -= wmin * 60;
10866 +       wsec = runtime;
10867 +
10868 +       cputime = (task->times.tms_utime + task->times.tms_stime) / HZ;
10869 +       cday = cputime / (3600 * 24);
10870 +       cputime -= cday * (3600 * 24);
10871 +       chr = cputime / 3600;
10872 +       cputime -= chr * 3600;
10873 +       cmin = cputime / 60;
10874 +       cputime -= cmin * 60;
10875 +       csec = cputime;
10876 +
10877 +       security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
10878 +                      task->pid, NIPQUAD(task->curr_ip), tty_name(task->tty,
10879 +                                                                  cur_tty),
10880 +                      task->uid, task->euid, task->gid, task->egid, wday, whr,
10881 +                      wmin, wsec, cday, chr, cmin, csec,
10882 +                      (task->
10883 +                       flags & PF_SIGNALED) ? "killed by signal" : "exited",
10884 +                      code, gr_parent_task_fullpath(task), 
10885 +                      task->p_pptr->comm, task->p_pptr->pid,
10886 +                      NIPQUAD(task->p_pptr->curr_ip),
10887 +                      tty_name(task->p_pptr->tty, parent_tty),
10888 +                      task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid,
10889 +                      task->p_pptr->egid);
10890 +
10891 +       return;
10892 +}
10893 +
10894 +void gr_set_kernel_label(struct task_struct *task)
10895 +{
10896 +       if (gr_status & GR_READY) {
10897 +               task->role = kernel_role;
10898 +               task->acl = kernel_role->root_label;
10899 +       }
10900 +       return;
10901 +}
10902 diff -urN linux-2.4.24.org/grsecurity/gracl_cap.c linux-2.4.24/grsecurity/gracl_cap.c
10903 --- linux-2.4.24.org/grsecurity/gracl_cap.c     1970-01-01 01:00:00.000000000 +0100
10904 +++ linux-2.4.24/grsecurity/gracl_cap.c 2004-01-05 18:43:05.261946656 +0100
10905 @@ -0,0 +1,71 @@
10906 +/* capability handling routines, (c) Brad Spengler 2002,2003 */
10907 +
10908 +#include <linux/kernel.h>
10909 +#include <linux/sched.h>
10910 +#include <linux/capability.h>
10911 +#include <linux/gracl.h>
10912 +#include <linux/grsecurity.h>
10913 +#include <linux/grinternal.h>
10914 +
10915 +static const char *captab_log[29] = {
10916 +       "CAP_CHOWN",
10917 +       "CAP_DAC_OVERRIDE",
10918 +       "CAP_DAC_READ_SEARCH",
10919 +       "CAP_FOWNER",
10920 +       "CAP_FSETID",
10921 +       "CAP_KILL",
10922 +       "CAP_SETGID",
10923 +       "CAP_SETUID",
10924 +       "CAP_SETPCAP",
10925 +       "CAP_LINUX_IMMUTABLE",
10926 +       "CAP_NET_BIND_SERVICE",
10927 +       "CAP_NET_BROADCAST",
10928 +       "CAP_NET_ADMIN",
10929 +       "CAP_NET_RAW",
10930 +       "CAP_IPC_LOCK",
10931 +       "CAP_IPC_OWNER",
10932 +       "CAP_SYS_MODULE",
10933 +       "CAP_SYS_RAWIO",
10934 +       "CAP_SYS_CHROOT",
10935 +       "CAP_SYS_PTRACE",
10936 +       "CAP_SYS_PACCT",
10937 +       "CAP_SYS_ADMIN",
10938 +       "CAP_SYS_BOOT",
10939 +       "CAP_SYS_NICE",
10940 +       "CAP_SYS_RESOURCE",
10941 +       "CAP_SYS_TIME",
10942 +       "CAP_SYS_TTY_CONFIG",
10943 +       "CAP_MKNOD",
10944 +       "CAP_LEASE"
10945 +};
10946 +
10947 +int
10948 +gr_is_capable(const int cap)
10949 +{
10950 +       struct acl_subject_label *curracl;
10951 +
10952 +       if (!gr_acl_is_enabled())
10953 +               return 1;
10954 +
10955 +       curracl = current->acl;
10956 +
10957 +       if (!cap_raised(curracl->cap_lower, cap))
10958 +               return 1;
10959 +
10960 +       if ((curracl->mode & GR_LEARN)
10961 +           && cap_raised(current->cap_effective, cap)) {
10962 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10963 +                              current->role->roletype, current->uid,
10964 +                              current->gid, current->exec_file ?
10965 +                              gr_to_filename(current->exec_file->f_dentry,
10966 +                              current->exec_file->f_vfsmnt) : curracl->filename,
10967 +                              curracl->filename, 0UL,
10968 +                              0UL, "", (unsigned long) cap, NIPQUAD(current->curr_ip));
10969 +               return 1;
10970 +       }
10971 +
10972 +       if ((cap >= 0) && (cap < 29) && cap_raised(current->cap_effective, cap))
10973 +               security_alert(GR_CAP_ACL_MSG, captab_log[cap], DEFAULTSECARGS);
10974 +
10975 +       return 0;
10976 +}
10977 diff -urN linux-2.4.24.org/grsecurity/gracl_fs.c linux-2.4.24/grsecurity/gracl_fs.c
10978 --- linux-2.4.24.org/grsecurity/gracl_fs.c      1970-01-01 01:00:00.000000000 +0100
10979 +++ linux-2.4.24/grsecurity/gracl_fs.c  2004-01-05 18:43:05.262946504 +0100
10980 @@ -0,0 +1,469 @@
10981 +#include <linux/kernel.h>
10982 +#include <linux/sched.h>
10983 +#include <linux/types.h>
10984 +#include <linux/fs.h>
10985 +#include <linux/file.h>
10986 +#include <linux/grsecurity.h>
10987 +#include <linux/grinternal.h>
10988 +#include <linux/gracl.h>
10989 +
10990 +__u32
10991 +gr_acl_handle_hidden_file(const struct dentry * dentry,
10992 +                         const struct vfsmount * mnt)
10993 +{
10994 +       __u32 mode;
10995 +
10996 +       if (unlikely(!dentry->d_inode))
10997 +               return GR_FIND;
10998 +
10999 +       mode =
11000 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
11001 +
11002 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
11003 +               security_audit(GR_HIDDEN_ACL_MSG, "successful",
11004 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
11005 +               return mode;
11006 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
11007 +               security_alert(GR_HIDDEN_ACL_MSG, "denied",
11008 +                              gr_to_filename(dentry, mnt),
11009 +                              DEFAULTSECARGS);
11010 +               return 0;
11011 +       } else if (unlikely(!(mode & GR_FIND)))
11012 +               return 0;
11013 +
11014 +       return GR_FIND;
11015 +}
11016 +
11017 +__u32
11018 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
11019 +                  const int fmode)
11020 +{
11021 +       __u32 reqmode = GR_FIND;
11022 +       __u32 mode;
11023 +
11024 +       if (unlikely(!dentry->d_inode))
11025 +               return reqmode;
11026 +
11027 +       if (unlikely(fmode & O_APPEND))
11028 +               reqmode |= GR_APPEND;
11029 +       else if (unlikely(fmode & FMODE_WRITE))
11030 +               reqmode |= GR_WRITE;
11031 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
11032 +               reqmode |= GR_READ;
11033 +
11034 +       mode =
11035 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
11036 +                          mnt);
11037 +
11038 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11039 +               security_audit(GR_OPEN_ACL_MSG, "successful",
11040 +                              gr_to_filename(dentry, mnt),
11041 +                              reqmode & GR_READ ? " reading" : "",
11042 +                              reqmode & GR_WRITE ? " writing" :
11043 +                              reqmode & GR_APPEND ? " appending" : "",
11044 +                              DEFAULTSECARGS);
11045 +               return reqmode;
11046 +       } else
11047 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11048 +       {
11049 +               security_alert(GR_OPEN_ACL_MSG, "denied",
11050 +                              gr_to_filename(dentry, mnt),
11051 +                              reqmode & GR_READ ? " reading" : "",
11052 +                              reqmode & GR_WRITE ? " writing" : reqmode &
11053 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
11054 +               return 0;
11055 +       } else if (unlikely((mode & reqmode) != reqmode))
11056 +               return 0;
11057 +
11058 +       return reqmode;
11059 +}
11060 +
11061 +__u32
11062 +gr_acl_handle_creat(const struct dentry * dentry,
11063 +                   const struct dentry * p_dentry,
11064 +                   const struct vfsmount * p_mnt, const int fmode,
11065 +                   const int imode)
11066 +{
11067 +       __u32 reqmode = GR_WRITE | GR_CREATE;
11068 +       __u32 mode;
11069 +
11070 +       if (unlikely(fmode & O_APPEND))
11071 +               reqmode |= GR_APPEND;
11072 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
11073 +               reqmode |= GR_READ;
11074 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
11075 +               reqmode |= GR_SETID;
11076 +
11077 +       mode =
11078 +           gr_check_create(dentry, p_dentry, p_mnt,
11079 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
11080 +
11081 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11082 +               security_audit(GR_CREATE_ACL_MSG, "successful",
11083 +                              gr_to_filename(dentry, p_mnt),
11084 +                              reqmode & GR_READ ? " reading" : "",
11085 +                              reqmode & GR_WRITE ? " writing" :
11086 +                              reqmode & GR_APPEND ? " appending" : "",
11087 +                              DEFAULTSECARGS);
11088 +               return reqmode;
11089 +       } else
11090 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11091 +       {
11092 +               security_alert(GR_CREATE_ACL_MSG, "denied",
11093 +                              gr_to_filename(dentry, p_mnt),
11094 +                              reqmode & GR_READ ? " reading" : "",
11095 +                              reqmode & GR_WRITE ? " writing" : reqmode &
11096 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
11097 +               return 0;
11098 +       } else if (unlikely((mode & reqmode) != reqmode))
11099 +               return 0;
11100 +
11101 +       return reqmode;
11102 +}
11103 +
11104 +__u32
11105 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
11106 +                    const int fmode)
11107 +{
11108 +       __u32 mode, reqmode = GR_FIND;
11109 +
11110 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
11111 +               reqmode |= GR_EXEC;
11112 +       if (fmode & S_IWOTH)
11113 +               reqmode |= GR_WRITE;
11114 +       if (fmode & S_IROTH)
11115 +               reqmode |= GR_READ;
11116 +
11117 +       mode =
11118 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
11119 +                          mnt);
11120 +
11121 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11122 +               security_audit(GR_ACCESS_ACL_MSG, "successful",
11123 +                              gr_to_filename(dentry, mnt),
11124 +                              reqmode & GR_READ ? " reading" : "",
11125 +                              reqmode & GR_WRITE ? " writing" : "",
11126 +                              reqmode & GR_EXEC ? " executing" : "",
11127 +                              DEFAULTSECARGS);
11128 +               return reqmode;
11129 +       } else
11130 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11131 +       {
11132 +               security_alert(GR_ACCESS_ACL_MSG, "denied",
11133 +                              gr_to_filename(dentry, mnt),
11134 +                              reqmode & GR_READ ? " reading" : "",
11135 +                              reqmode & GR_WRITE ? " writing" : "",
11136 +                              reqmode & GR_EXEC ? " executing" : "",
11137 +                              DEFAULTSECARGS);
11138 +               return 0;
11139 +       } else if (unlikely((mode & reqmode) != reqmode))
11140 +               return 0;
11141 +
11142 +       return reqmode;
11143 +}
11144 +
11145 +#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
11146 +{ \
11147 +       __u32 mode; \
11148 +       \
11149 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
11150 +       \
11151 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
11152 +               security_audit(fmt, "successful", \
11153 +                               gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
11154 +               return mode; \
11155 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
11156 +               security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
11157 +                               DEFAULTSECARGS); \
11158 +               return 0; \
11159 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
11160 +               return 0; \
11161 +       \
11162 +       return (reqmode); \
11163 +}
11164 +
11165 +__u32
11166 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
11167 +{
11168 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
11169 +}
11170 +
11171 +__u32
11172 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
11173 +{
11174 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
11175 +}
11176 +
11177 +__u32
11178 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
11179 +{
11180 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
11181 +}
11182 +
11183 +__u32
11184 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
11185 +{
11186 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
11187 +}
11188 +
11189 +__u32
11190 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
11191 +                    mode_t mode)
11192 +{
11193 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
11194 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
11195 +                                  GR_FCHMOD_ACL_MSG);
11196 +       } else {
11197 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
11198 +       }
11199 +}
11200 +
11201 +__u32
11202 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
11203 +                   mode_t mode)
11204 +{
11205 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
11206 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
11207 +                                  GR_CHMOD_ACL_MSG);
11208 +       } else {
11209 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
11210 +       }
11211 +}
11212 +
11213 +__u32
11214 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
11215 +{
11216 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
11217 +}
11218 +
11219 +__u32
11220 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
11221 +{
11222 +       generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
11223 +}
11224 +
11225 +__u32
11226 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
11227 +{
11228 +       generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
11229 +                          GR_UNIXCONNECT_ACL_MSG);
11230 +}
11231 +
11232 +__u32
11233 +gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
11234 +                     const ino_t ino)
11235 +{
11236 +       if (likely((unsigned long)(dentry->d_inode))) {
11237 +               struct dentry d = *dentry;
11238 +               struct inode inode = *(dentry->d_inode);
11239 +
11240 +               inode.i_ino = ino;
11241 +               d.d_inode = &inode;
11242 +
11243 +               if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
11244 +                       return 0;
11245 +       }
11246 +
11247 +       return 1;
11248 +}
11249 +
11250 +__u32
11251 +gr_acl_handle_link(const struct dentry * new_dentry,
11252 +                  const struct dentry * parent_dentry,
11253 +                  const struct vfsmount * parent_mnt,
11254 +                  const struct dentry * old_dentry,
11255 +                  const struct vfsmount * old_mnt, const char *to)
11256 +{
11257 +       __u32 needmode = GR_WRITE | GR_CREATE;
11258 +       __u32 mode;
11259 +
11260 +       mode =
11261 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
11262 +                         old_mnt);
11263 +
11264 +       if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
11265 +               security_audit(GR_LINK_ACL_MSG, "successful",
11266 +                              gr_to_filename(old_dentry, old_mnt), to,
11267 +                              DEFAULTSECARGS);
11268 +               return mode;
11269 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
11270 +               security_alert(GR_LINK_ACL_MSG, "denied",
11271 +                              gr_to_filename(old_dentry, old_mnt), to,
11272 +                              DEFAULTSECARGS);
11273 +               return 0;
11274 +       } else if (unlikely((mode & needmode) != needmode))
11275 +               return 0;
11276 +
11277 +       return (GR_WRITE | GR_CREATE);
11278 +}
11279 +
11280 +__u32
11281 +gr_acl_handle_symlink(const struct dentry * new_dentry,
11282 +                     const struct dentry * parent_dentry,
11283 +                     const struct vfsmount * parent_mnt, const char *from)
11284 +{
11285 +       __u32 needmode = GR_WRITE | GR_CREATE;
11286 +       __u32 mode;
11287 +
11288 +       mode =
11289 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
11290 +                           GR_CREATE | GR_AUDIT_CREATE |
11291 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
11292 +
11293 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
11294 +               security_audit(GR_SYMLINK_ACL_MSG, "successful",
11295 +                              from, gr_to_filename(new_dentry, parent_mnt),
11296 +                              DEFAULTSECARGS);
11297 +               return mode;
11298 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
11299 +               security_alert(GR_SYMLINK_ACL_MSG, "denied",
11300 +                              from, gr_to_filename(new_dentry, parent_mnt),
11301 +                              DEFAULTSECARGS);
11302 +               return 0;
11303 +       } else if (unlikely((mode & needmode) != needmode))
11304 +               return 0;
11305 +
11306 +       return (GR_WRITE | GR_CREATE);
11307 +}
11308 +
11309 +#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
11310 +{ \
11311 +       __u32 mode; \
11312 +       \
11313 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
11314 +       \
11315 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
11316 +               security_audit(fmt, "successful", \
11317 +                               gr_to_filename(new_dentry, parent_mnt), \
11318 +                               DEFAULTSECARGS); \
11319 +               return mode; \
11320 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
11321 +               security_alert(fmt, "denied", \
11322 +                               gr_to_filename(new_dentry, parent_mnt), \
11323 +                               DEFAULTSECARGS); \
11324 +               return 0; \
11325 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
11326 +               return 0; \
11327 +       \
11328 +       return (reqmode); \
11329 +}
11330 +
11331 +__u32
11332 +gr_acl_handle_mknod(const struct dentry * new_dentry,
11333 +                   const struct dentry * parent_dentry,
11334 +                   const struct vfsmount * parent_mnt,
11335 +                   const int mode)
11336 +{
11337 +       __u32 reqmode = GR_WRITE | GR_CREATE;
11338 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
11339 +               reqmode |= GR_SETID;
11340 +
11341 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
11342 +                                 reqmode, GR_MKNOD_ACL_MSG);
11343 +}
11344 +
11345 +__u32
11346 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
11347 +                   const struct dentry *parent_dentry,
11348 +                   const struct vfsmount *parent_mnt)
11349 +{
11350 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
11351 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
11352 +}
11353 +
11354 +#define RENAME_CHECK_SUCCESS(old, new) \
11355 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
11356 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
11357 +
11358 +int
11359 +gr_acl_handle_rename(struct dentry *new_dentry,
11360 +                    struct dentry *parent_dentry,
11361 +                    const struct vfsmount *parent_mnt,
11362 +                    struct dentry *old_dentry,
11363 +                    struct inode *old_parent_inode,
11364 +                    struct vfsmount *old_mnt, const char *newname)
11365 +{
11366 +       __u8 gr_replace = 1;
11367 +       __u32 comp1, comp2;
11368 +       int error = 0;
11369 +
11370 +       if (unlikely(!gr_acl_is_enabled()))
11371 +               return 1;
11372 +
11373 +       if (!new_dentry->d_inode) {
11374 +               gr_replace = 0;
11375 +
11376 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
11377 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
11378 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
11379 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
11380 +                                      GR_DELETE | GR_AUDIT_DELETE |
11381 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
11382 +                                      GR_SUPPRESS, old_mnt);
11383 +       } else {
11384 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
11385 +                                      GR_CREATE | GR_DELETE |
11386 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
11387 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
11388 +                                      GR_SUPPRESS, parent_mnt);
11389 +               comp2 =
11390 +                   gr_search_file(old_dentry,
11391 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
11392 +                                  GR_DELETE | GR_AUDIT_DELETE |
11393 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
11394 +       }
11395 +
11396 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
11397 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
11398 +               security_audit(GR_RENAME_ACL_MSG, "successful",
11399 +                              gr_to_filename(old_dentry, old_mnt),
11400 +                              newname, DEFAULTSECARGS);
11401 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
11402 +                && !(comp2 & GR_SUPPRESS)) {
11403 +               security_alert(GR_RENAME_ACL_MSG, "denied",
11404 +                              gr_to_filename(old_dentry, old_mnt), newname,
11405 +                              DEFAULTSECARGS);
11406 +               error = -EACCES;
11407 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
11408 +               error = -EACCES;
11409 +
11410 +       if (error)
11411 +               return error;
11412 +
11413 +       error = gr_handle_rename(old_parent_inode, parent_dentry->d_inode,
11414 +                                old_dentry, new_dentry, old_mnt, gr_replace);
11415 +
11416 +       return error;
11417 +}
11418 +
11419 +void
11420 +gr_acl_handle_exit(void)
11421 +{
11422 +       u16 id;
11423 +       char *rolename;
11424 +
11425 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
11426 +               id = current->acl_role_id;
11427 +               rolename = current->role->rolename;
11428 +               gr_set_acls(1);
11429 +               security_alert_good(GR_SPROLEL_ACL_MSG,
11430 +                                   rolename, id, DEFAULTSECARGS);
11431 +       }
11432 +
11433 +       if (current->exec_file) {
11434 +               fput(current->exec_file);
11435 +               current->exec_file = NULL;
11436 +       }
11437 +}
11438 +
11439 +int
11440 +gr_acl_handle_procpidmem(const struct task_struct *task)
11441 +{
11442 +       if (unlikely(!gr_acl_is_enabled()))
11443 +               return 0;
11444 +
11445 +       if (task->acl->mode & GR_PROTPROCFD)
11446 +               return -EACCES;
11447 +
11448 +       return 0;
11449 +}
11450 diff -urN linux-2.4.24.org/grsecurity/gracl_ip.c linux-2.4.24/grsecurity/gracl_ip.c
11451 --- linux-2.4.24.org/grsecurity/gracl_ip.c      1970-01-01 01:00:00.000000000 +0100
11452 +++ linux-2.4.24/grsecurity/gracl_ip.c  2004-01-05 18:43:05.263946352 +0100
11453 @@ -0,0 +1,235 @@
11454 +/* 
11455 + * grsecurity/gracl_ip.c
11456 + * Copyright Brad Spengler 2002, 2003
11457 + *
11458 + */
11459 +
11460 +#include <linux/kernel.h>
11461 +#include <asm/uaccess.h>
11462 +#include <asm/errno.h>
11463 +#include <net/sock.h>
11464 +#include <linux/file.h>
11465 +#include <linux/fs.h>
11466 +#include <linux/net.h>
11467 +#include <linux/in.h>
11468 +#include <linux/skbuff.h>
11469 +#include <linux/ip.h>
11470 +#include <linux/udp.h>
11471 +#include <linux/smp_lock.h>
11472 +#include <linux/types.h>
11473 +#include <linux/sched.h>
11474 +#include <linux/gracl.h>
11475 +#include <linux/grsecurity.h>
11476 +#include <linux/grinternal.h>
11477 +
11478 +#define GR_BIND        0x01
11479 +#define GR_CONNECT     0x02
11480 +
11481 +static const char * gr_protocols[256] = {
11482 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
11483 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
11484 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
11485 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
11486 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
11487 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
11488 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
11489 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
11490 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
11491 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
11492 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
11493 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
11494 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
11495 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
11496 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
11497 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
11498 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
11499 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
11500 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
11501 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
11502 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
11503 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
11504 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
11505 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
11506 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
11507 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
11508 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
11509 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
11510 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
11511 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
11512 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
11513 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
11514 +       };
11515 +
11516 +static const char * gr_socktypes[11] = {
11517 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
11518 +       "unknown:7", "unknown:8", "unknown:9", "packet"
11519 +       };
11520 +
11521 +__inline__ const char *
11522 +gr_proto_to_name(unsigned char proto)
11523 +{
11524 +       return gr_protocols[proto];
11525 +}
11526 +
11527 +__inline__ const char *
11528 +gr_socktype_to_name(unsigned char type)
11529 +{
11530 +       return gr_socktypes[type];
11531 +}
11532 +
11533 +int
11534 +gr_search_socket(const int domain, const int type, const int protocol)
11535 +{
11536 +       struct acl_subject_label *curr;
11537 +
11538 +       if (unlikely(!gr_acl_is_enabled()))
11539 +               goto exit;
11540 +
11541 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
11542 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
11543 +               goto exit;      // let the kernel handle it
11544 +
11545 +       curr = current->acl;
11546 +
11547 +       if (!curr->ips)
11548 +               goto exit;
11549 +
11550 +       if ((curr->ip_type & (1 << type)) &&
11551 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
11552 +               goto exit;
11553 +
11554 +       if (curr->mode & GR_LEARN) {
11555 +               /* we don't place acls on raw sockets , and sometimes
11556 +                  dgram/ip sockets are opened for ioctl and not
11557 +                  bind/connect, so we'll fake a bind learn log */
11558 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
11559 +                       __u32 fakeip = 0;
11560 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11561 +                                      current->role->roletype, current->uid,
11562 +                                      current->gid, current->exec_file ?
11563 +                                      gr_to_filename(current->exec_file->f_dentry,
11564 +                                      current->exec_file->f_vfsmnt) :
11565 +                                      curr->filename, curr->filename,
11566 +                                      NIPQUAD(fakeip), 0, type,
11567 +                                      protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
11568 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
11569 +                       __u32 fakeip = 0;
11570 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11571 +                                      current->role->roletype, current->uid,
11572 +                                      current->gid, current->exec_file ?
11573 +                                      gr_to_filename(current->exec_file->f_dentry,
11574 +                                      current->exec_file->f_vfsmnt) :
11575 +                                      curr->filename, curr->filename,
11576 +                                      NIPQUAD(fakeip), 0, type,
11577 +                                      protocol, GR_BIND, NIPQUAD(current->curr_ip));
11578 +               }
11579 +               /* we'll log when they use connect or bind */
11580 +               goto exit;
11581 +       }
11582 +
11583 +       security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
11584 +                      gr_proto_to_name(protocol), DEFAULTSECARGS);
11585 +
11586 +       return 0;
11587 +      exit:
11588 +       return 1;
11589 +}
11590 +
11591 +static __inline__ int
11592 +gr_search_connectbind(const int mode, const struct sock *sk,
11593 +                     const struct sockaddr_in *addr, const int type)
11594 +{
11595 +       struct acl_subject_label *curr;
11596 +       struct acl_ip_label *ip;
11597 +       unsigned long i;
11598 +       __u32 ip_addr = 0;
11599 +       __u16 ip_port = 0;
11600 +
11601 +       if (unlikely(!gr_acl_is_enabled() || sk->family != PF_INET))
11602 +               return 1;
11603 +
11604 +       curr = current->acl;
11605 +
11606 +       if (!curr->ips)
11607 +               return 1;
11608 +
11609 +       ip_addr = addr->sin_addr.s_addr;
11610 +       ip_port = ntohs(addr->sin_port);
11611 +
11612 +       for (i = 0; i < curr->ip_num; i++) {
11613 +               ip = *(curr->ips + i);
11614 +               if ((ip->mode & mode) &&
11615 +                   (ip_port >= ip->low) &&
11616 +                   (ip_port <= ip->high) &&
11617 +                   ((ntohl(ip_addr) & ip->netmask) ==
11618 +                    (ntohl(ip->addr) & ip->netmask))
11619 +                   && (ip->
11620 +                       proto[sk->protocol / 32] & (1 << (sk->protocol % 32)))
11621 +                   && (ip->type & (1 << type)))
11622 +                       return 1;
11623 +       }
11624 +
11625 +       if (curr->mode & GR_LEARN) {
11626 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11627 +                              current->role->roletype, current->uid,
11628 +                              current->gid, current->exec_file ?
11629 +                              gr_to_filename(current->exec_file->f_dentry,
11630 +                              current->exec_file->f_vfsmnt) :
11631 +                              curr->filename, curr->filename,
11632 +                              NIPQUAD(ip_addr), ip_port, type,
11633 +                              sk->protocol, mode, NIPQUAD(current->curr_ip));
11634 +               return 1;
11635 +       }
11636 +
11637 +       if (mode == GR_BIND)
11638 +               security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11639 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11640 +                              DEFAULTSECARGS);
11641 +       else if (mode == GR_CONNECT)
11642 +               security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11643 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11644 +                              DEFAULTSECARGS);
11645 +
11646 +       return 0;
11647 +}
11648 +
11649 +int
11650 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
11651 +{
11652 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
11653 +}
11654 +
11655 +int
11656 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
11657 +{
11658 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
11659 +}
11660 +
11661 +int
11662 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
11663 +{
11664 +       if (addr)
11665 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
11666 +       else {
11667 +               struct sockaddr_in sin;
11668 +
11669 +               sin.sin_addr.s_addr = sk->daddr;
11670 +               sin.sin_port = sk->dport;
11671 +
11672 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11673 +       }
11674 +}
11675 +
11676 +int
11677 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
11678 +{
11679 +       struct sockaddr_in sin;
11680 +
11681 +       if (unlikely(skb->len < sizeof (struct udphdr)))
11682 +               return 1;       // skip this packet
11683 +
11684 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
11685 +       sin.sin_port = skb->h.uh->source;
11686 +
11687 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11688 +}
11689 diff -urN linux-2.4.24.org/grsecurity/gracl_learn.c linux-2.4.24/grsecurity/gracl_learn.c
11690 --- linux-2.4.24.org/grsecurity/gracl_learn.c   1970-01-01 01:00:00.000000000 +0100
11691 +++ linux-2.4.24/grsecurity/gracl_learn.c       2004-01-05 18:43:05.264946200 +0100
11692 @@ -0,0 +1,228 @@
11693 +#include <linux/kernel.h>
11694 +#include <linux/mm.h>
11695 +#include <linux/sched.h>
11696 +#include <linux/poll.h>
11697 +#include <linux/smp_lock.h>
11698 +#include <linux/string.h>
11699 +#include <linux/file.h>
11700 +#include <linux/types.h>
11701 +#include <linux/vmalloc.h>
11702 +#include <linux/grinternal.h>
11703 +
11704 +extern ssize_t write_grsec_handler(struct file * file, const char * buf,
11705 +                                  size_t count, loff_t *ppos);
11706 +extern int gr_acl_is_enabled(void);
11707 +
11708 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
11709 +static DECLARE_WAIT_QUEUE_HEAD(input_wait);
11710 +static atomic_t learn_buffer_count = ATOMIC_INIT(0);
11711 +static int gr_learn_attached;
11712 +
11713 +#define LEARN_BUFFER_SLOTS 256
11714 +#define LEARN_BUFFER_SIZE 16384
11715 +
11716 +static spinlock_t learn_buffer_lock[LEARN_BUFFER_SLOTS] = { [0 ... (LEARN_BUFFER_SLOTS - 1)] = SPIN_LOCK_UNLOCKED };
11717 +static char *learn_buffer[LEARN_BUFFER_SLOTS];
11718 +static int learn_buffer_len[LEARN_BUFFER_SLOTS];
11719 +
11720 +static ssize_t
11721 +read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
11722 +{
11723 +       DECLARE_WAITQUEUE(wait, current);
11724 +       ssize_t retval = 0;
11725 +       char *tmp;
11726 +       unsigned int len;
11727 +       int i;
11728 +
11729 +       add_wait_queue(&learn_wait, &wait);
11730 +       set_current_state(TASK_INTERRUPTIBLE);
11731 +       do {
11732 +               if (atomic_read(&learn_buffer_count) > 1)
11733 +                       break;
11734 +
11735 +               if (file->f_flags & O_NONBLOCK) {
11736 +                       retval = -EAGAIN;
11737 +                       goto out;
11738 +               }
11739 +               if (signal_pending(current)) {
11740 +                       retval = -ERESTARTSYS;
11741 +                       goto out;
11742 +               }
11743 +
11744 +               schedule();
11745 +       } while (1);
11746 +
11747 +
11748 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11749 +               spin_lock(&learn_buffer_lock[i]);
11750 +               len = learn_buffer_len[i];
11751 +               tmp = learn_buffer[i];
11752 +               if (!len || !tmp) {
11753 +                       spin_unlock(&learn_buffer_lock[i]);
11754 +                       continue;
11755 +               }
11756 +               learn_buffer[i] = NULL;
11757 +               learn_buffer_len[i] = 0;
11758 +               spin_unlock(&learn_buffer_lock[i]);
11759 +
11760 +               if (count < ((i * LEARN_BUFFER_SIZE) + len)) {
11761 +                       retval = -EINVAL;
11762 +                       vfree(tmp);
11763 +                       goto out;
11764 +               }
11765 +               if (copy_to_user(buf + (i * LEARN_BUFFER_SIZE), tmp, len)) {
11766 +                       retval = -EFAULT;
11767 +                       vfree(tmp);
11768 +                       goto out;
11769 +               }
11770 +
11771 +               retval += len;
11772 +               vfree(tmp);
11773 +               atomic_dec(&learn_buffer_count);
11774 +               atomic_dec(&learn_buffer_count);
11775 +       }
11776 +
11777 +       wake_up(&input_wait);
11778 +out:
11779 +       set_current_state(TASK_RUNNING);
11780 +       remove_wait_queue(&learn_wait, &wait);
11781 +       return retval;
11782 +}
11783 +
11784 +static unsigned int
11785 +poll_learn(struct file * file, poll_table * wait)
11786 +{
11787 +       poll_wait(file, &learn_wait, wait);
11788 +
11789 +       if (atomic_read(&learn_buffer_count) > 1)
11790 +               return (POLLIN | POLLRDNORM);
11791 +
11792 +       return 0;
11793 +}
11794 +
11795 +void
11796 +gr_clear_learn_entries(void)
11797 +{
11798 +       int i;
11799 +
11800 +       atomic_set(&learn_buffer_count, 0);
11801 +       wake_up(&input_wait);
11802 +       
11803 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11804 +               if (learn_buffer_len[i]) {
11805 +                       vfree(learn_buffer[i]);
11806 +                       learn_buffer[i] = NULL;
11807 +                       learn_buffer_len[i] = 0;
11808 +               }
11809 +       }
11810 +
11811 +       return;
11812 +}
11813 +
11814 +void
11815 +gr_add_learn_entry(const char *fmt, ...)
11816 +{
11817 +       DECLARE_WAITQUEUE(wait, current);
11818 +       va_list args;
11819 +       char *tmpbuf;
11820 +       char *buf;
11821 +       int i;
11822 +       unsigned int len;
11823 +
11824 +       if (!gr_learn_attached)
11825 +               return;
11826 +
11827 +       tmpbuf = vmalloc(LEARN_BUFFER_SIZE);
11828 +
11829 +       if (tmpbuf == NULL)
11830 +               return;
11831 +
11832 +       va_start(args, fmt);
11833 +       len = vsnprintf(tmpbuf, LEARN_BUFFER_SIZE, fmt, args);
11834 +       va_end(args);
11835 +
11836 +       if (len < 0)
11837 +               len = LEARN_BUFFER_SIZE - 1;
11838 +
11839 +       buf = vmalloc(len + 1);
11840 +
11841 +       if (buf == NULL) {
11842 +               vfree(tmpbuf);
11843 +               return;
11844 +       }
11845 +
11846 +       memcpy(buf, tmpbuf, len);
11847 +       buf[len] = '\0';
11848 +       vfree(tmpbuf);
11849 +
11850 +       add_wait_queue(&input_wait, &wait);
11851 +
11852 +       atomic_inc(&learn_buffer_count);
11853 +       if (atomic_read(&learn_buffer_count) > ((2 * (LEARN_BUFFER_SLOTS - 1)) + 1)) {
11854 +               /* don't sleep under the BKL */
11855 +//             if (unlikely(current->lock_depth >= 0)) {
11856 +               remove_wait_queue(&input_wait, &wait);
11857 +               atomic_dec(&learn_buffer_count);
11858 +               vfree(buf);
11859 +               return;
11860 +//             }
11861 +//             sleep_on(&input_wait);
11862 +       }
11863 +
11864 +       if (!gr_acl_is_enabled()) {
11865 +               remove_wait_queue(&input_wait, &wait);
11866 +               atomic_dec(&learn_buffer_count);
11867 +               vfree(buf);
11868 +               return;
11869 +       }
11870 +
11871 +       for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11872 +               spin_lock(&learn_buffer_lock[i]);
11873 +
11874 +               if (learn_buffer_len[i]) {
11875 +                       spin_unlock(&learn_buffer_lock[i]);
11876 +                       continue;
11877 +               }
11878 +
11879 +               learn_buffer[i] = buf;
11880 +
11881 +               learn_buffer_len[i] = len + 1;
11882 +
11883 +               atomic_inc(&learn_buffer_count);
11884 +               spin_unlock(&learn_buffer_lock[i]);
11885 +               break;
11886 +       }
11887 +
11888 +       remove_wait_queue(&input_wait, &wait);
11889 +       wake_up_interruptible(&learn_wait);
11890 +
11891 +       return;
11892 +}
11893 +
11894 +static int
11895 +open_learn(struct inode *inode, struct file *file)
11896 +{
11897 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
11898 +               return -EBUSY;
11899 +       else if (file->f_mode & FMODE_READ)
11900 +               gr_learn_attached = 1;
11901 +
11902 +       return 0;
11903 +}
11904 +
11905 +static int
11906 +close_learn(struct inode *inode, struct file *file)
11907 +{
11908 +       if (file->f_mode & FMODE_READ)
11909 +               gr_learn_attached = 0;
11910 +
11911 +       return 0;
11912 +}
11913 +               
11914 +struct file_operations grsec_fops = {
11915 +       read:           read_learn,
11916 +       write:          write_grsec_handler,
11917 +       open:           open_learn,
11918 +       release:        close_learn,
11919 +       poll:           poll_learn,
11920 +};
11921 diff -urN linux-2.4.24.org/grsecurity/gracl_res.c linux-2.4.24/grsecurity/gracl_res.c
11922 --- linux-2.4.24.org/grsecurity/gracl_res.c     1970-01-01 01:00:00.000000000 +0100
11923 +++ linux-2.4.24/grsecurity/gracl_res.c 2004-01-05 18:43:05.265946048 +0100
11924 @@ -0,0 +1,46 @@
11925 +/* resource handling routines (c) Brad Spengler 2002, 2003 */
11926 +
11927 +#include <linux/kernel.h>
11928 +#include <linux/sched.h>
11929 +#include <linux/gracl.h>
11930 +#include <linux/grinternal.h>
11931 +
11932 +static const char *restab_log[11] = {
11933 +       "RLIMIT_CPU",
11934 +       "RLIMIT_FSIZE",
11935 +       "RLIMIT_DATA",
11936 +       "RLIMIT_STACK",
11937 +       "RLIMIT_CORE",
11938 +       "RLIMIT_RSS",
11939 +       "RLIMIT_NPROC",
11940 +       "RLIMIT_NOFILE",
11941 +       "RLIMIT_MEMLOCK",
11942 +       "RLIMIT_AS",
11943 +       "RLIMIT_LOCKS"
11944 +};
11945 +
11946 +__inline__ void
11947 +gr_log_resource(const struct task_struct *task,
11948 +               const int res, const unsigned long wanted, const int gt)
11949 +{
11950 +       if (unlikely(res == RLIMIT_NPROC && 
11951 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
11952 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
11953 +               return;
11954 +
11955 +       if (unlikely(((gt && wanted > task->rlim[res].rlim_cur) ||
11956 +                     (!gt && wanted >= task->rlim[res].rlim_cur)) &&
11957 +                    task->rlim[res].rlim_cur != RLIM_INFINITY))
11958 +               security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
11959 +                              task->rlim[res].rlim_cur,
11960 +                              gr_task_fullpath(task), task->comm,
11961 +                              task->pid, task->uid, task->euid,
11962 +                              task->gid, task->egid,
11963 +                              gr_parent_task_fullpath(task),
11964 +                              task->p_pptr->comm,
11965 +                              task->p_pptr->pid, task->p_pptr->uid, 
11966 +                              task->p_pptr->euid, task->p_pptr->gid,
11967 +                              task->p_pptr->egid);
11968 +
11969 +       return;
11970 +}
11971 diff -urN linux-2.4.24.org/grsecurity/gracl_segv.c linux-2.4.24/grsecurity/gracl_segv.c
11972 --- linux-2.4.24.org/grsecurity/gracl_segv.c    1970-01-01 01:00:00.000000000 +0100
11973 +++ linux-2.4.24/grsecurity/gracl_segv.c        2004-01-05 18:43:05.265946048 +0100
11974 @@ -0,0 +1,327 @@
11975 +/* 
11976 + * grsecurity/gracl_segv.c
11977 + * Copyright Brad Spengler 2002, 2003
11978 + *
11979 + */
11980 +
11981 +#include <linux/kernel.h>
11982 +#include <linux/mm.h>
11983 +#include <asm/uaccess.h>
11984 +#include <asm/errno.h>
11985 +#include <asm/mman.h>
11986 +#include <net/sock.h>
11987 +#include <linux/file.h>
11988 +#include <linux/fs.h>
11989 +#include <linux/net.h>
11990 +#include <linux/in.h>
11991 +#include <linux/smp_lock.h>
11992 +#include <linux/slab.h>
11993 +#include <linux/types.h>
11994 +#include <linux/sched.h>
11995 +#include <linux/timer.h>
11996 +#include <linux/gracl.h>
11997 +#include <linux/grsecurity.h>
11998 +#include <linux/grinternal.h>
11999 +
12000 +static struct crash_uid *uid_set;
12001 +static unsigned short uid_used;
12002 +static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
12003 +extern rwlock_t gr_inode_lock;
12004 +extern __inline__ struct acl_subject_label *lookup_acl_subj_label(const ino_t
12005 +                                                                 inode,
12006 +                                                                 const kdev_t
12007 +                                                                 dev,
12008 +                                                                 struct
12009 +                                                                 acl_role_label
12010 +                                                                 *role);
12011 +
12012 +int
12013 +gr_init_uidset(void)
12014 +{
12015 +       uid_set =
12016 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
12017 +       uid_used = 0;
12018 +
12019 +       return uid_set ? 1 : 0;
12020 +}
12021 +
12022 +void
12023 +gr_free_uidset(void)
12024 +{
12025 +       if (uid_set)
12026 +               kfree(uid_set);
12027 +
12028 +       return;
12029 +}
12030 +
12031 +int
12032 +gr_find_uid(const uid_t uid)
12033 +{
12034 +       struct crash_uid *tmp = uid_set;
12035 +       uid_t buid;
12036 +       int low = 0, high = uid_used - 1, mid;
12037 +
12038 +       while (high >= low) {
12039 +               mid = (low + high) >> 1;
12040 +               buid = tmp[mid].uid;
12041 +               if (buid == uid)
12042 +                       return mid;
12043 +               if (buid > uid)
12044 +                       high = mid - 1;
12045 +               if (buid < uid)
12046 +                       low = mid + 1;
12047 +       }
12048 +
12049 +       return -1;
12050 +}
12051 +
12052 +static __inline__ void
12053 +gr_insertsort(void)
12054 +{
12055 +       unsigned short i, j;
12056 +       struct crash_uid index;
12057 +
12058 +       for (i = 1; i < uid_used; i++) {
12059 +               index = uid_set[i];
12060 +               j = i;
12061 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
12062 +                       uid_set[j] = uid_set[j - 1];
12063 +                       j--;
12064 +               }
12065 +               uid_set[j] = index;
12066 +       }
12067 +
12068 +       return;
12069 +}
12070 +
12071 +static __inline__ void
12072 +gr_insert_uid(const uid_t uid, const unsigned long expires)
12073 +{
12074 +       int loc;
12075 +
12076 +       if (uid_used == GR_UIDTABLE_MAX)
12077 +               return;
12078 +
12079 +       loc = gr_find_uid(uid);
12080 +
12081 +       if (loc >= 0) {
12082 +               uid_set[loc].expires = expires;
12083 +               return;
12084 +       }
12085 +
12086 +       uid_set[uid_used].uid = uid;
12087 +       uid_set[uid_used].expires = expires;
12088 +       uid_used++;
12089 +
12090 +       gr_insertsort();
12091 +
12092 +       return;
12093 +}
12094 +
12095 +void
12096 +gr_remove_uid(const unsigned short loc)
12097 +{
12098 +       unsigned short i;
12099 +
12100 +       for (i = loc + 1; i < uid_used; i++)
12101 +               uid_set[i - i] = uid_set[i];
12102 +
12103 +       uid_used--;
12104 +
12105 +       return;
12106 +}
12107 +
12108 +int
12109 +gr_check_crash_uid(const uid_t uid)
12110 +{
12111 +       int loc;
12112 +
12113 +       if (unlikely(!gr_acl_is_enabled()))
12114 +               return 0;
12115 +
12116 +       read_lock(&gr_uid_lock);
12117 +       loc = gr_find_uid(uid);
12118 +       read_unlock(&gr_uid_lock);
12119 +
12120 +       if (loc < 0)
12121 +               return 0;
12122 +
12123 +       write_lock(&gr_uid_lock);
12124 +       if (time_before_eq(uid_set[loc].expires, jiffies))
12125 +               gr_remove_uid(loc);
12126 +       else {
12127 +               write_unlock(&gr_uid_lock);
12128 +               return 1;
12129 +       }
12130 +
12131 +       write_unlock(&gr_uid_lock);
12132 +       return 0;
12133 +}
12134 +
12135 +static __inline__ int
12136 +proc_is_setxid(const struct task_struct *task)
12137 +{
12138 +       if (task->uid != task->euid || task->uid != task->suid ||
12139 +           task->uid != task->fsuid)
12140 +               return 1;
12141 +       if (task->gid != task->egid || task->gid != task->sgid ||
12142 +           task->gid != task->fsgid)
12143 +               return 1;
12144 +
12145 +       return 0;
12146 +}
12147 +static __inline__ int
12148 +gr_fake_force_sig(int sig, struct task_struct *t)
12149 +{
12150 +       unsigned long int flags;
12151 +
12152 +       spin_lock_irqsave(&t->sigmask_lock, flags);
12153 +       if (t->sig == NULL) {
12154 +               spin_unlock_irqrestore(&t->sigmask_lock, flags);
12155 +               return -ESRCH;
12156 +       }
12157 +
12158 +       if (t->sig->action[sig - 1].sa.sa_handler == SIG_IGN)
12159 +               t->sig->action[sig - 1].sa.sa_handler = SIG_DFL;
12160 +       sigdelset(&t->blocked, sig);
12161 +       recalc_sigpending(t);
12162 +       spin_unlock_irqrestore(&t->sigmask_lock, flags);
12163 +
12164 +       return send_sig_info(sig, (void *) 1L, t);
12165 +}
12166 +
12167 +void
12168 +gr_handle_crash(struct task_struct *task, const int sig)
12169 +{
12170 +       struct acl_subject_label *curr;
12171 +       struct acl_subject_label *curr2;
12172 +       struct task_struct *tsk;
12173 +
12174 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
12175 +               return;
12176 +
12177 +       if (unlikely(!gr_acl_is_enabled()))
12178 +               return;
12179 +
12180 +       curr = task->acl;
12181 +
12182 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
12183 +               return;
12184 +
12185 +       if (time_before_eq(curr->expires, jiffies)) {
12186 +               curr->expires = 0;
12187 +               curr->crashes = 0;
12188 +       }
12189 +
12190 +       curr->crashes++;
12191 +
12192 +       if (!curr->expires)
12193 +               curr->expires = jiffies + curr->res[GR_CRASH_RES].rlim_max;
12194 +
12195 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
12196 +           time_after(curr->expires, jiffies)) {
12197 +               if (task->uid && proc_is_setxid(task)) {
12198 +                       security_alert(GR_SEGVSTART_ACL_MSG,
12199 +                                      gr_task_fullpath(task), task->comm,
12200 +                                      task->pid, task->uid, task->euid,
12201 +                                      task->gid, task->egid,
12202 +                                      gr_parent_task_fullpath(task),
12203 +                                      task->p_pptr->comm, task->p_pptr->pid,
12204 +                                      task->p_pptr->uid, task->p_pptr->euid,
12205 +                                      task->p_pptr->gid, task->p_pptr->egid,
12206 +                                      task->uid,
12207 +                                      curr->res[GR_CRASH_RES].rlim_max / HZ);
12208 +                       write_lock(&gr_uid_lock);
12209 +                       gr_insert_uid(task->uid, curr->expires);
12210 +                       write_unlock(&gr_uid_lock);
12211 +                       curr->expires = 0;
12212 +                       curr->crashes = 0;
12213 +                       read_lock(&tasklist_lock);
12214 +                       for_each_task(tsk) {
12215 +                               if (tsk != task && tsk->uid == task->uid)
12216 +                                       gr_fake_force_sig(SIGKILL, tsk);
12217 +                       }
12218 +                       read_unlock(&tasklist_lock);
12219 +               } else {
12220 +                       security_alert(GR_SEGVNOSUID_ACL_MSG,
12221 +                                      gr_task_fullpath(task), task->comm,
12222 +                                      task->pid, task->uid, task->euid,
12223 +                                      task->gid, task->egid,
12224 +                                      gr_parent_task_fullpath(task),
12225 +                                      task->p_pptr->comm, task->p_pptr->pid,
12226 +                                      task->p_pptr->uid, task->p_pptr->euid,
12227 +                                      task->p_pptr->gid, task->p_pptr->egid,
12228 +                                      kdevname(curr->device), curr->inode,
12229 +                                      curr->res[GR_CRASH_RES].rlim_max / HZ);
12230 +                       read_lock(&tasklist_lock);
12231 +                       for_each_task(tsk) {
12232 +                               if (likely(tsk != task)) {
12233 +                                       curr2 = tsk->acl;
12234 +
12235 +                                       if (curr2->device == curr->device &&
12236 +                                           curr2->inode == curr->inode)
12237 +                                               gr_fake_force_sig(SIGKILL, tsk);
12238 +                               }
12239 +                       }
12240 +                       read_unlock(&tasklist_lock);
12241 +               }
12242 +       }
12243 +
12244 +       return;
12245 +}
12246 +
12247 +int
12248 +gr_check_crash_exec(const struct file *filp)
12249 +{
12250 +       struct acl_subject_label *curr;
12251 +
12252 +       if (unlikely(!gr_acl_is_enabled()))
12253 +               return 0;
12254 +
12255 +       read_lock(&gr_inode_lock);
12256 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
12257 +                                    filp->f_dentry->d_inode->i_dev,
12258 +                                    current->role);
12259 +       read_unlock(&gr_inode_lock);
12260 +
12261 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
12262 +           (!curr->crashes && !curr->expires))
12263 +               return 0;
12264 +
12265 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
12266 +           time_after(curr->expires, jiffies))
12267 +               return 1;
12268 +       else if (time_before_eq(curr->expires, jiffies)) {
12269 +               curr->crashes = 0;
12270 +               curr->expires = 0;
12271 +       }
12272 +
12273 +       return 0;
12274 +}
12275 +
12276 +void
12277 +gr_handle_alertkill(void)
12278 +{
12279 +       struct acl_subject_label *curracl;
12280 +       __u32 curr_ip;
12281 +       struct task_struct *task;
12282 +
12283 +       if (unlikely(!gr_acl_is_enabled()))
12284 +               return;
12285 +
12286 +       curracl = current->acl;
12287 +       curr_ip = current->curr_ip;
12288 +
12289 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
12290 +           (curr_ip != 0xffffffff)) {
12291 +               read_lock(&tasklist_lock);
12292 +               for_each_task(task) {
12293 +                       if (task->curr_ip == curr_ip)
12294 +                               gr_fake_force_sig(SIGKILL, task);
12295 +               }
12296 +               read_unlock(&tasklist_lock);
12297 +       } else if (curracl->mode & GR_KILLPROC)
12298 +               gr_fake_force_sig(SIGKILL, current);
12299 +
12300 +       return;
12301 +}
12302 diff -urN linux-2.4.24.org/grsecurity/gracl_shm.c linux-2.4.24/grsecurity/gracl_shm.c
12303 --- linux-2.4.24.org/grsecurity/gracl_shm.c     1970-01-01 01:00:00.000000000 +0100
12304 +++ linux-2.4.24/grsecurity/gracl_shm.c 2004-01-05 18:43:05.266945896 +0100
12305 @@ -0,0 +1,36 @@
12306 +/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
12307 +
12308 +#include <linux/kernel.h>
12309 +#include <linux/mm.h>
12310 +#include <linux/sched.h>
12311 +#include <linux/file.h>
12312 +#include <linux/ipc.h>
12313 +#include <linux/gracl.h>
12314 +#include <linux/grsecurity.h>
12315 +#include <linux/grinternal.h>
12316 +
12317 +int
12318 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12319 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
12320 +{
12321 +       struct task_struct *task;
12322 +
12323 +       if (!gr_acl_is_enabled())
12324 +               return 1;
12325 +
12326 +       task = find_task_by_pid(shm_cprid);
12327 +
12328 +       if (unlikely(!task))
12329 +               task = find_task_by_pid(shm_lapid);
12330 +
12331 +       if (unlikely(task && ((task->start_time < shm_createtime) ||
12332 +                             (task->pid == shm_lapid)) &&
12333 +                    (task->acl->mode & GR_PROTSHM) &&
12334 +                    (task->acl != current->acl))) {
12335 +               security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
12336 +                              DEFAULTSECARGS);
12337 +               return 0;
12338 +       }
12339 +
12340 +       return 1;
12341 +}
12342 diff -urN linux-2.4.24.org/grsecurity/grsec_chdir.c linux-2.4.24/grsecurity/grsec_chdir.c
12343 --- linux-2.4.24.org/grsecurity/grsec_chdir.c   1970-01-01 01:00:00.000000000 +0100
12344 +++ linux-2.4.24/grsecurity/grsec_chdir.c       2004-01-05 18:43:05.266945896 +0100
12345 @@ -0,0 +1,20 @@
12346 +#include <linux/kernel.h>
12347 +#include <linux/sched.h>
12348 +#include <linux/fs.h>
12349 +#include <linux/file.h>
12350 +#include <linux/grsecurity.h>
12351 +#include <linux/grinternal.h>
12352 +
12353 +void
12354 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
12355 +{
12356 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
12357 +       if ((grsec_enable_chdir && grsec_enable_group &&
12358 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
12359 +                                             !grsec_enable_group)) {
12360 +               security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
12361 +                              DEFAULTSECARGS);
12362 +       }
12363 +#endif
12364 +       return;
12365 +}
12366 diff -urN linux-2.4.24.org/grsecurity/grsec_chroot.c linux-2.4.24/grsecurity/grsec_chroot.c
12367 --- linux-2.4.24.org/grsecurity/grsec_chroot.c  1970-01-01 01:00:00.000000000 +0100
12368 +++ linux-2.4.24/grsecurity/grsec_chroot.c      2004-01-05 18:43:05.267945744 +0100
12369 @@ -0,0 +1,333 @@
12370 +#include <linux/kernel.h>
12371 +#include <linux/sched.h>
12372 +#include <linux/file.h>
12373 +#include <linux/fs.h>
12374 +#include <linux/types.h>
12375 +#include <linux/grinternal.h>
12376 +
12377 +int
12378 +gr_handle_chroot_unix(const pid_t pid)
12379 +{
12380 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12381 +       struct task_struct *p, **htable;
12382 +
12383 +       if (unlikely(!grsec_enable_chroot_unix))
12384 +               return 1;
12385 +
12386 +       if (likely(!proc_is_chrooted(current)))
12387 +               return 1;
12388 +
12389 +       read_lock(&tasklist_lock);
12390 +
12391 +       htable = &pidhash[pid_hashfn(pid)];
12392 +
12393 +       for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ;
12394 +
12395 +       if (unlikely(p && !have_same_root(current, p))) {
12396 +               read_unlock(&tasklist_lock);
12397 +               security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
12398 +               return 0;
12399 +       }
12400 +       read_unlock(&tasklist_lock);
12401 +#endif
12402 +       return 1;
12403 +}
12404 +
12405 +int
12406 +gr_handle_chroot_nice(void)
12407 +{
12408 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12409 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
12410 +               security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
12411 +               return -EPERM;
12412 +       }
12413 +#endif
12414 +       return 0;
12415 +}
12416 +
12417 +int
12418 +gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval)
12419 +{
12420 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12421 +       if (grsec_enable_chroot_nice && (!have_same_root(p, current)
12422 +                                        || (have_same_root(p, current)
12423 +                                            && (niceval < task_nice(p))
12424 +                                            && proc_is_chrooted(current)))) {
12425 +               security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
12426 +                              DEFAULTSECARGS);
12427 +               return -ESRCH;
12428 +       }
12429 +#endif
12430 +       return 0;
12431 +}
12432 +
12433 +int
12434 +gr_handle_chroot_capset(const struct task_struct *target)
12435 +{
12436 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12437 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
12438 +           !have_same_root(current, target)) {
12439 +               security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
12440 +                              DEFAULTSECARGS);
12441 +               return 1;
12442 +       }
12443 +#endif
12444 +       return 0;
12445 +}
12446 +
12447 +int
12448 +gr_handle_chroot_rawio(const struct inode *inode)
12449 +{
12450 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12451 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
12452 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
12453 +               return 1;
12454 +#endif
12455 +       return 0;
12456 +}
12457 +
12458 +int
12459 +gr_pid_is_chrooted(const struct task_struct *p)
12460 +{
12461 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
12462 +       if (!grsec_enable_chroot_findtask || (current->pid <= 1))
12463 +               return 0;
12464 +
12465 +       if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
12466 +           child_reaper && child_reaper->fs && child_reaper->fs->root &&
12467 +           child_reaper->fs->root->d_inode && current && current->fs &&
12468 +           current->fs->root && current->fs->root->d_inode) {
12469 +               if (proc_is_chrooted(current) && !have_same_root(current, p))
12470 +                       return 1;
12471 +       }
12472 +#endif
12473 +       return 0;
12474 +}
12475 +
12476 +int
12477 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
12478 +{
12479 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
12480 +       if (!grsec_enable_chroot_fchdir)
12481 +               return 1;
12482 +
12483 +       if (!proc_is_chrooted(current))
12484 +               return 1;
12485 +       else {
12486 +               struct dentry *dentry = u_dentry;
12487 +               struct vfsmount *mnt = u_mnt;
12488 +               struct dentry *realroot;
12489 +               struct vfsmount *realrootmnt;
12490 +               struct dentry *currentroot;
12491 +               struct vfsmount *currentmnt;
12492 +
12493 +               read_lock(&child_reaper->fs->lock);
12494 +               realrootmnt = mntget(child_reaper->fs->rootmnt);
12495 +               realroot = dget(child_reaper->fs->root);
12496 +               read_unlock(&child_reaper->fs->lock);
12497 +
12498 +               read_lock(&current->fs->lock);
12499 +               currentmnt = mntget(current->fs->rootmnt);
12500 +               currentroot = dget(current->fs->root);
12501 +               read_unlock(&current->fs->lock);
12502 +
12503 +               spin_lock(&dcache_lock);
12504 +               for (;;) {
12505 +                       if (unlikely
12506 +                           ((dentry == realroot && mnt == realrootmnt)
12507 +                            || (dentry == currentroot && mnt == currentmnt)))
12508 +                               break;
12509 +                       if (unlikely
12510 +                           (dentry == mnt->mnt_root || IS_ROOT(dentry))) {
12511 +                               if (mnt->mnt_parent == mnt)
12512 +                                       break;
12513 +                               dentry = mnt->mnt_mountpoint;
12514 +                               mnt = mnt->mnt_parent;
12515 +                               continue;
12516 +                       }
12517 +                       dentry = dentry->d_parent;
12518 +               }
12519 +               spin_unlock(&dcache_lock);
12520 +
12521 +               dput(currentroot);
12522 +               mntput(currentmnt);
12523 +
12524 +               if (dentry == realroot && mnt == realrootmnt) {
12525 +                       /* ok, they're definitely trying to fchdir outside of the
12526 +                          chroot. */
12527 +                       dput(realroot);
12528 +                       mntput(realrootmnt);
12529 +                       security_alert(GR_CHROOT_FCHDIR_MSG,
12530 +                                      gr_to_filename(u_dentry, u_mnt),
12531 +                                      DEFAULTSECARGS);
12532 +                       return 0;
12533 +               } else {
12534 +                       dput(realroot);
12535 +                       mntput(realrootmnt);
12536 +                       return 1;
12537 +               }
12538 +       }
12539 +#endif
12540 +       return 1;
12541 +}
12542 +
12543 +int
12544 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12545 +               const time_t shm_createtime)
12546 +{
12547 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12548 +       struct task_struct *p, **htable;
12549 +
12550 +       if (unlikely(!grsec_enable_chroot_shmat))
12551 +               return 1;
12552 +
12553 +       if (likely(!proc_is_chrooted(current)))
12554 +               return 1;
12555 +
12556 +       read_lock(&tasklist_lock);
12557 +
12558 +       htable = &pidhash[pid_hashfn(shm_cprid)];
12559 +
12560 +       for (p = *htable; p && p->pid != shm_cprid; p = p->pidhash_next) ;
12561 +
12562 +       if (unlikely(p && !have_same_root(current, p) &&
12563 +                    (p->start_time < shm_createtime))) {
12564 +               read_unlock(&tasklist_lock);
12565 +               security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12566 +               return 0;
12567 +       }
12568 +
12569 +       if (unlikely(!p)) {
12570 +               htable = &pidhash[pid_hashfn(shm_lapid)];
12571 +               for (p = *htable; p && p->pid != shm_lapid;
12572 +                    p = p->pidhash_next) ;
12573 +
12574 +               if (unlikely(p && !have_same_root(current, p))) {
12575 +                       read_unlock(&tasklist_lock);
12576 +                       security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12577 +                       return 0;
12578 +               }
12579 +       }
12580 +
12581 +       read_unlock(&tasklist_lock);
12582 +#endif
12583 +       return 1;
12584 +}
12585 +
12586 +void
12587 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12588 +{
12589 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12590 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
12591 +               security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
12592 +                              DEFAULTSECARGS);
12593 +#endif
12594 +       return;
12595 +}
12596 +
12597 +int
12598 +gr_handle_chroot_mknod(const struct dentry *dentry,
12599 +                      const struct vfsmount *mnt, const int mode)
12600 +{
12601 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12602 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) &&
12603 +           proc_is_chrooted(current)) {
12604 +               security_alert(GR_MKNOD_CHROOT_MSG,
12605 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12606 +               return -EPERM;
12607 +       }
12608 +#endif
12609 +       return 0;
12610 +}
12611 +
12612 +int
12613 +gr_handle_chroot_mount(const struct dentry *dentry,
12614 +                      const struct vfsmount *mnt, const char *dev_name)
12615 +{
12616 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12617 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
12618 +               security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
12619 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12620 +               return -EPERM;
12621 +       }
12622 +#endif
12623 +       return 0;
12624 +}
12625 +
12626 +int
12627 +gr_handle_chroot_pivot(void)
12628 +{
12629 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12630 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
12631 +               security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
12632 +               return -EPERM;
12633 +       }
12634 +#endif
12635 +       return 0;
12636 +}
12637 +
12638 +int
12639 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
12640 +{
12641 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12642 +       if (grsec_enable_chroot_double && proc_is_chrooted(current)) {
12643 +               security_alert(GR_CHROOT_CHROOT_MSG,
12644 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12645 +               return -EPERM;
12646 +       }
12647 +#endif
12648 +       return 0;
12649 +}
12650 +
12651 +void
12652 +gr_handle_chroot_caps(struct task_struct *task)
12653 +{
12654 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12655 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
12656 +               task->cap_permitted =
12657 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
12658 +               task->cap_inheritable =
12659 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
12660 +               task->cap_effective =
12661 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
12662 +       }
12663 +#endif
12664 +       return;
12665 +}
12666 +
12667 +int
12668 +gr_handle_chroot_sysctl(const int op)
12669 +{
12670 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12671 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
12672 +           && (op & 002))
12673 +               return -EACCES;
12674 +#endif
12675 +       return 0;
12676 +}
12677 +
12678 +void
12679 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
12680 +{
12681 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12682 +       if (grsec_enable_chroot_chdir)
12683 +               set_fs_pwd(current->fs, mnt, dentry);
12684 +#endif
12685 +       return;
12686 +}
12687 +
12688 +int
12689 +gr_handle_chroot_chmod(const struct dentry *dentry,
12690 +                      const struct vfsmount *mnt, const int mode)
12691 +{
12692 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12693 +       if (grsec_enable_chroot_chmod &&
12694 +           ((mode & S_ISUID) || (mode & S_ISGID)) &&
12695 +           proc_is_chrooted(current)) {
12696 +               security_alert(GR_CHMOD_CHROOT_MSG,
12697 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12698 +               return -EPERM;
12699 +       }
12700 +#endif
12701 +       return 0;
12702 +}
12703 diff -urN linux-2.4.24.org/grsecurity/grsec_disabled.c linux-2.4.24/grsecurity/grsec_disabled.c
12704 --- linux-2.4.24.org/grsecurity/grsec_disabled.c        1970-01-01 01:00:00.000000000 +0100
12705 +++ linux-2.4.24/grsecurity/grsec_disabled.c    2004-01-05 18:43:05.268945592 +0100
12706 @@ -0,0 +1,380 @@
12707 +/* 
12708 + * when grsecurity is disabled, compile all external functions into nothing
12709 + */
12710 +
12711 +#include <linux/kernel.h>
12712 +#include <linux/config.h>
12713 +#include <linux/sched.h>
12714 +#include <linux/file.h>
12715 +#include <linux/fs.h>
12716 +#include <linux/kdev_t.h>
12717 +#include <linux/net.h>
12718 +#include <linux/in.h>
12719 +#include <linux/ip.h>
12720 +#include <linux/skbuff.h>
12721 +#include <linux/sysctl.h>
12722 +
12723 +#ifdef CONFIG_SYSCTL
12724 +__u32
12725 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
12726 +{
12727 +       return mode;
12728 +}
12729 +#endif
12730 +
12731 +int
12732 +gr_acl_is_enabled(void)
12733 +{
12734 +       return 0;
12735 +}
12736 +
12737 +int
12738 +gr_handle_rawio(const struct inode *inode)
12739 +{
12740 +       return 0;
12741 +}
12742 +
12743 +void
12744 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12745 +{
12746 +       return;
12747 +}
12748 +
12749 +int
12750 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12751 +{
12752 +       return 0;
12753 +}
12754 +
12755 +int
12756 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
12757 +{
12758 +       return 0;
12759 +}
12760 +
12761 +int
12762 +gr_handle_ptrace(struct task_struct *task, const long request)
12763 +{
12764 +       return 0;
12765 +}
12766 +
12767 +void
12768 +gr_learn_resource(const struct task_struct *task,
12769 +                 const int res, const unsigned long wanted, const int gt)
12770 +{
12771 +       return;
12772 +}
12773 +
12774 +int
12775 +gr_set_acls(const int type)
12776 +{
12777 +       return 0;
12778 +}
12779 +
12780 +int
12781 +gr_check_hidden_task(const struct task_struct *tsk)
12782 +{
12783 +       return 0;
12784 +}
12785 +
12786 +int
12787 +gr_check_protected_task(const struct task_struct *task)
12788 +{
12789 +       return 0;
12790 +}
12791 +
12792 +__inline__ void
12793 +gr_copy_label(struct task_struct *tsk)
12794 +{
12795 +       return;
12796 +}
12797 +
12798 +void
12799 +gr_set_pax_flags(struct task_struct *task)
12800 +{
12801 +       return;
12802 +}
12803 +
12804 +void
12805 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
12806 +{
12807 +       return;
12808 +}
12809 +
12810 +void
12811 +gr_handle_delete(const ino_t ino, const kdev_t dev)
12812 +{
12813 +       return;
12814 +}
12815 +
12816 +void
12817 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
12818 +{
12819 +       return;
12820 +}
12821 +
12822 +void
12823 +gr_handle_crash(struct task_struct *task, const int sig)
12824 +{
12825 +       return;
12826 +}
12827 +
12828 +int
12829 +gr_check_crash_exec(const struct file *filp)
12830 +{
12831 +       return 0;
12832 +}
12833 +
12834 +int
12835 +gr_check_crash_uid(const uid_t uid)
12836 +{
12837 +       return 0;
12838 +}
12839 +
12840 +int
12841 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
12842 +                struct dentry *old_dentry,
12843 +                struct dentry *new_dentry,
12844 +                struct vfsmount *mnt, const __u8 replace)
12845 +{
12846 +       return 0;
12847 +}
12848 +
12849 +int
12850 +gr_search_socket(const int family, const int type, const int protocol)
12851 +{
12852 +       return 1;
12853 +}
12854 +
12855 +int
12856 +gr_search_connectbind(const int mode, const struct socket *sock,
12857 +                     const struct sockaddr_in *addr)
12858 +{
12859 +       return 1;
12860 +}
12861 +
12862 +int
12863 +gr_is_capable(const int cap)
12864 +{
12865 +       return 1;
12866 +}
12867 +
12868 +void
12869 +gr_handle_alertkill(void)
12870 +{
12871 +       return;
12872 +}
12873 +
12874 +__u32
12875 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
12876 +{
12877 +       return 1;
12878 +}
12879 +
12880 +__u32
12881 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12882 +                         const struct vfsmount * mnt)
12883 +{
12884 +       return 1;
12885 +}
12886 +
12887 +__u32
12888 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12889 +                  const int fmode)
12890 +{
12891 +       return 1;
12892 +}
12893 +
12894 +__u32
12895 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12896 +{
12897 +       return 1;
12898 +}
12899 +
12900 +__u32
12901 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
12902 +{
12903 +       return 1;
12904 +}
12905 +
12906 +int
12907 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
12908 +                  unsigned int *vm_flags)
12909 +{
12910 +       return 1;
12911 +}
12912 +
12913 +__u32
12914 +gr_acl_handle_truncate(const struct dentry * dentry,
12915 +                      const struct vfsmount * mnt)
12916 +{
12917 +       return 1;
12918 +}
12919 +
12920 +__u32
12921 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
12922 +{
12923 +       return 1;
12924 +}
12925 +
12926 +__u32
12927 +gr_acl_handle_access(const struct dentry * dentry,
12928 +                    const struct vfsmount * mnt, const int fmode)
12929 +{
12930 +       return 1;
12931 +}
12932 +
12933 +__u32
12934 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
12935 +                    mode_t mode)
12936 +{
12937 +       return 1;
12938 +}
12939 +
12940 +__u32
12941 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
12942 +                   mode_t mode)
12943 +{
12944 +       return 1;
12945 +}
12946 +
12947 +__u32
12948 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
12949 +{
12950 +       return 1;
12951 +}
12952 +
12953 +void
12954 +grsecurity_init(void)
12955 +{
12956 +       return;
12957 +}
12958 +
12959 +__u32
12960 +gr_acl_handle_mknod(const struct dentry * new_dentry,
12961 +                   const struct dentry * parent_dentry,
12962 +                   const struct vfsmount * parent_mnt,
12963 +                   const int mode)
12964 +{
12965 +       return 1;
12966 +}
12967 +
12968 +__u32
12969 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
12970 +                   const struct dentry * parent_dentry,
12971 +                   const struct vfsmount * parent_mnt)
12972 +{
12973 +       return 1;
12974 +}
12975 +
12976 +__u32
12977 +gr_acl_handle_symlink(const struct dentry * new_dentry,
12978 +                     const struct dentry * parent_dentry,
12979 +                     const struct vfsmount * parent_mnt, const char *from)
12980 +{
12981 +       return 1;
12982 +}
12983 +
12984 +__u32
12985 +gr_acl_handle_link(const struct dentry * new_dentry,
12986 +                  const struct dentry * parent_dentry,
12987 +                  const struct vfsmount * parent_mnt,
12988 +                  const struct dentry * old_dentry,
12989 +                  const struct vfsmount * old_mnt, const char *to)
12990 +{
12991 +       return 1;
12992 +}
12993 +
12994 +int
12995 +gr_acl_handle_rename(const struct dentry *new_dentry,
12996 +                    const struct dentry *parent_dentry,
12997 +                    const struct vfsmount *parent_mnt,
12998 +                    const struct dentry *old_dentry,
12999 +                    const struct inode *old_parent_inode,
13000 +                    const struct vfsmount *old_mnt, const char *newname)
13001 +{
13002 +       return 1;
13003 +}
13004 +
13005 +__u32
13006 +gr_acl_handle_filldir(const struct dentry * dentry,
13007 +                     const struct vfsmount * mnt, const ino_t ino)
13008 +{
13009 +       return 1;
13010 +}
13011 +
13012 +int
13013 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
13014 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
13015 +{
13016 +       return 1;
13017 +}
13018 +
13019 +int
13020 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
13021 +{
13022 +       return 1;
13023 +}
13024 +
13025 +int
13026 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
13027 +{
13028 +       return 1;
13029 +}
13030 +
13031 +__u32
13032 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
13033 +{
13034 +       return 1;
13035 +}
13036 +
13037 +__u32
13038 +gr_acl_handle_creat(const struct dentry * dentry,
13039 +                   const struct dentry * p_dentry,
13040 +                   const struct vfsmount * p_mnt, const int fmode,
13041 +                   const int imode)
13042 +{
13043 +       return 1;
13044 +}
13045 +
13046 +void
13047 +gr_acl_handle_exit(void)
13048 +{
13049 +       return;
13050 +}
13051 +
13052 +int
13053 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
13054 +{
13055 +       return 1;
13056 +}
13057 +
13058 +void
13059 +gr_set_role_label(const uid_t uid, const gid_t gid)
13060 +{
13061 +       return;
13062 +}
13063 +
13064 +int
13065 +gr_acl_handle_procpidmem(const struct task_struct *task)
13066 +{
13067 +       return 0;
13068 +}
13069 +
13070 +int
13071 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
13072 +{
13073 +       return 1;
13074 +}
13075 +
13076 +int
13077 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
13078 +{
13079 +       return 1;
13080 +}
13081 +
13082 +void
13083 +gr_set_kernel_label(struct task_struct *task)
13084 +{
13085 +       return;
13086 +}
13087 diff -urN linux-2.4.24.org/grsecurity/grsec_exec.c linux-2.4.24/grsecurity/grsec_exec.c
13088 --- linux-2.4.24.org/grsecurity/grsec_exec.c    1970-01-01 01:00:00.000000000 +0100
13089 +++ linux-2.4.24/grsecurity/grsec_exec.c        2004-01-05 18:43:05.268945592 +0100
13090 @@ -0,0 +1,70 @@
13091 +#include <linux/kernel.h>
13092 +#include <linux/sched.h>
13093 +#include <linux/file.h>
13094 +#include <linux/fs.h>
13095 +#include <linux/types.h>
13096 +#include <linux/grdefs.h>
13097 +#include <linux/grinternal.h>
13098 +#include <linux/capability.h>
13099 +
13100 +#include <asm/uaccess.h>
13101 +
13102 +int
13103 +gr_handle_nproc(void)
13104 +{
13105 +#ifdef CONFIG_GRKERNSEC_EXECVE
13106 +       if (grsec_enable_execve && current->user &&
13107 +           (atomic_read(&current->user->processes) >
13108 +            current->rlim[RLIMIT_NPROC].rlim_cur) &&
13109 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
13110 +               security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
13111 +               return -EAGAIN;
13112 +       }
13113 +#endif
13114 +       return 0;
13115 +}
13116 +
13117 +void
13118 +gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
13119 +{
13120 +#ifdef CONFIG_GRKERNSEC_EXECLOG
13121 +       char grarg[64] = { 0 };
13122 +       __u8 execlen = 0;
13123 +       unsigned int i;
13124 +
13125 +       if (!((grsec_enable_execlog && grsec_enable_group &&
13126 +              in_group_p(grsec_audit_gid))
13127 +             || (grsec_enable_execlog && !grsec_enable_group)))
13128 +               return;
13129 +
13130 +       if (unlikely(!argv))
13131 +               goto log;
13132 +
13133 +       for (i = 0; i < bprm->argc && execlen < 62; i++) {
13134 +               char *p;
13135 +               __u8 len;
13136 +
13137 +               if (get_user(p, argv + i))
13138 +                       goto log;
13139 +               if (!p)
13140 +                       goto log;
13141 +               len = strnlen_user(p, 62 - execlen);
13142 +               if (len > 62 - execlen)
13143 +                       len = 62 - execlen;
13144 +               else if (len > 0)
13145 +                       len--;
13146 +               if (copy_from_user(grarg + execlen, p, len))
13147 +                       goto log;
13148 +               execlen += len;
13149 +               *(grarg + execlen) = ' ';
13150 +               *(grarg + execlen + 1) = '\0';
13151 +               execlen++;
13152 +       }
13153 +
13154 +      log:
13155 +       security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
13156 +                                                        bprm->file->f_vfsmnt),
13157 +                      grarg, DEFAULTSECARGS);
13158 +#endif
13159 +       return;
13160 +}
13161 diff -urN linux-2.4.24.org/grsecurity/grsec_fifo.c linux-2.4.24/grsecurity/grsec_fifo.c
13162 --- linux-2.4.24.org/grsecurity/grsec_fifo.c    1970-01-01 01:00:00.000000000 +0100
13163 +++ linux-2.4.24/grsecurity/grsec_fifo.c        2004-01-05 18:43:05.269945440 +0100
13164 @@ -0,0 +1,24 @@
13165 +#include <linux/kernel.h>
13166 +#include <linux/sched.h>
13167 +#include <linux/fs.h>
13168 +#include <linux/file.h>
13169 +#include <linux/grinternal.h>
13170 +
13171 +int
13172 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
13173 +              const struct dentry *dir, const int flag, const int acc_mode)
13174 +{
13175 +#ifdef CONFIG_GRKERNSEC_FIFO
13176 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
13177 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
13178 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
13179 +           (current->fsuid != dentry->d_inode->i_uid)) {
13180 +               if (!permission(dentry->d_inode, acc_mode))
13181 +                       security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
13182 +                                      dentry->d_inode->i_uid,
13183 +                                      dentry->d_inode->i_gid, DEFAULTSECARGS);
13184 +               return -EACCES;
13185 +       }
13186 +#endif
13187 +       return 0;
13188 +}
13189 diff -urN linux-2.4.24.org/grsecurity/grsec_fork.c linux-2.4.24/grsecurity/grsec_fork.c
13190 --- linux-2.4.24.org/grsecurity/grsec_fork.c    1970-01-01 01:00:00.000000000 +0100
13191 +++ linux-2.4.24/grsecurity/grsec_fork.c        2004-01-05 18:43:05.269945440 +0100
13192 @@ -0,0 +1,14 @@
13193 +#include <linux/kernel.h>
13194 +#include <linux/sched.h>
13195 +#include <linux/grsecurity.h>
13196 +#include <linux/grinternal.h>
13197 +
13198 +void
13199 +gr_log_forkfail(const int retval)
13200 +{
13201 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
13202 +       if (grsec_enable_forkfail)
13203 +               security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
13204 +#endif
13205 +       return;
13206 +}
13207 diff -urN linux-2.4.24.org/grsecurity/grsec_init.c linux-2.4.24/grsecurity/grsec_init.c
13208 --- linux-2.4.24.org/grsecurity/grsec_init.c    1970-01-01 01:00:00.000000000 +0100
13209 +++ linux-2.4.24/grsecurity/grsec_init.c        2004-01-05 18:43:05.270945288 +0100
13210 @@ -0,0 +1,222 @@
13211 +#include <linux/kernel.h>
13212 +#include <linux/sched.h>
13213 +#include <linux/mm.h>
13214 +#include <linux/smp_lock.h>
13215 +#include <linux/gracl.h>
13216 +#include <linux/slab.h>
13217 +#include <linux/vmalloc.h>
13218 +
13219 +int grsec_enable_link;
13220 +int grsec_enable_dmesg;
13221 +int grsec_enable_fifo;
13222 +int grsec_enable_execve;
13223 +int grsec_enable_execlog;
13224 +int grsec_enable_signal;
13225 +int grsec_enable_forkfail;
13226 +int grsec_enable_time;
13227 +int grsec_enable_group;
13228 +int grsec_audit_gid;
13229 +int grsec_enable_chdir;
13230 +int grsec_enable_audit_ipc;
13231 +int grsec_enable_mount;
13232 +int grsec_enable_chroot_findtask;
13233 +int grsec_enable_chroot_mount;
13234 +int grsec_enable_chroot_shmat;
13235 +int grsec_enable_chroot_fchdir;
13236 +int grsec_enable_chroot_double;
13237 +int grsec_enable_chroot_pivot;
13238 +int grsec_enable_chroot_chdir;
13239 +int grsec_enable_chroot_chmod;
13240 +int grsec_enable_chroot_mknod;
13241 +int grsec_enable_chroot_nice;
13242 +int grsec_enable_chroot_execlog;
13243 +int grsec_enable_chroot_caps;
13244 +int grsec_enable_chroot_sysctl;
13245 +int grsec_enable_chroot_unix;
13246 +int grsec_enable_tpe;
13247 +int grsec_tpe_gid;
13248 +int grsec_enable_tpe_all;
13249 +int grsec_enable_randpid;
13250 +int grsec_enable_randid;
13251 +int grsec_enable_randisn;
13252 +int grsec_enable_randsrc;
13253 +int grsec_enable_randrpc;
13254 +int grsec_enable_socket_all;
13255 +int grsec_socket_all_gid;
13256 +int grsec_enable_socket_client;
13257 +int grsec_socket_client_gid;
13258 +int grsec_enable_socket_server;
13259 +int grsec_socket_server_gid;
13260 +int grsec_lock;
13261 +
13262 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
13263 +unsigned long grsec_alert_wtime = 0;
13264 +unsigned long grsec_alert_fyet = 0;
13265 +
13266 +spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
13267 +unsigned long grsec_alertgood_wtime = 0;
13268 +unsigned long grsec_alertgood_fyet = 0;
13269 +
13270 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
13271 +
13272 +char *gr_shared_page[4][NR_CPUS];
13273 +extern struct gr_arg *gr_usermode;
13274 +extern unsigned char *gr_system_salt;
13275 +extern unsigned char *gr_system_sum;
13276 +extern struct task_struct **gr_conn_table;
13277 +extern const unsigned int gr_conn_table_size;
13278 +
13279 +void
13280 +grsecurity_init(void)
13281 +{
13282 +       int i, j;
13283 +       /* create the per-cpu shared pages */
13284 +
13285 +       for (j = 0; j < 4; j++) {
13286 +               for (i = 0; i < NR_CPUS; i++) {
13287 +                       gr_shared_page[j][i] = (char *) get_zeroed_page(GFP_KERNEL);
13288 +                       if (!gr_shared_page[j][i]) {
13289 +                               panic("Unable to allocate grsecurity shared page");
13290 +                               return;
13291 +                       }
13292 +               }
13293 +       }
13294 +
13295 +       /* create hash tables for ip tagging */
13296 +
13297 +       gr_conn_table = (struct task_struct **) vmalloc(gr_conn_table_size * sizeof(struct task_struct *));
13298 +       if (gr_conn_table == NULL) {
13299 +               panic("Unable to allocate grsecurity IP tagging table");
13300 +               return;
13301 +       }
13302 +       memset(gr_conn_table, 0, gr_conn_table_size * sizeof(struct task_struct *));
13303 +
13304 +       /* allocate memory for authentication structure */
13305 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
13306 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
13307 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
13308 +
13309 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
13310 +               panic("Unable to allocate grsecurity authentication structure");
13311 +               return;
13312 +       }
13313 +
13314 +#ifndef CONFIG_GRKERNSEC_SYSCTL
13315 +       grsec_lock = 1;
13316 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
13317 +       grsec_enable_group = 1;
13318 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
13319 +#endif
13320 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
13321 +       grsec_enable_chdir = 1;
13322 +#endif
13323 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13324 +       grsec_enable_audit_ipc = 1;
13325 +#endif
13326 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13327 +       grsec_enable_mount = 1;
13328 +#endif
13329 +#ifdef CONFIG_GRKERNSEC_LINK
13330 +       grsec_enable_link = 1;
13331 +#endif
13332 +#ifdef CONFIG_GRKERNSEC_DMESG
13333 +       grsec_enable_dmesg = 1;
13334 +#endif
13335 +#ifdef CONFIG_GRKERNSEC_FIFO
13336 +       grsec_enable_fifo = 1;
13337 +#endif
13338 +#ifdef CONFIG_GRKERNSEC_EXECVE
13339 +       grsec_enable_execve = 1;
13340 +#endif
13341 +#ifdef CONFIG_GRKERNSEC_EXECLOG
13342 +       grsec_enable_execlog = 1;
13343 +#endif
13344 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13345 +       grsec_enable_signal = 1;
13346 +#endif
13347 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
13348 +       grsec_enable_forkfail = 1;
13349 +#endif
13350 +#ifdef CONFIG_GRKERNSEC_TIME
13351 +       grsec_enable_time = 1;
13352 +#endif
13353 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
13354 +       grsec_enable_chroot_findtask = 1;
13355 +#endif
13356 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
13357 +       grsec_enable_chroot_unix = 1;
13358 +#endif
13359 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
13360 +       grsec_enable_chroot_mount = 1;
13361 +#endif
13362 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
13363 +       grsec_enable_chroot_fchdir = 1;
13364 +#endif
13365 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
13366 +       grsec_enable_chroot_shmat = 1;
13367 +#endif
13368 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
13369 +       grsec_enable_chroot_double = 1;
13370 +#endif
13371 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
13372 +       grsec_enable_chroot_pivot = 1;
13373 +#endif
13374 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
13375 +       grsec_enable_chroot_chdir = 1;
13376 +#endif
13377 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
13378 +       grsec_enable_chroot_chmod = 1;
13379 +#endif
13380 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
13381 +       grsec_enable_chroot_mknod = 1;
13382 +#endif
13383 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
13384 +       grsec_enable_chroot_nice = 1;
13385 +#endif
13386 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
13387 +       grsec_enable_chroot_execlog = 1;
13388 +#endif
13389 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
13390 +       grsec_enable_chroot_caps = 1;
13391 +#endif
13392 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
13393 +       grsec_enable_chroot_sysctl = 1;
13394 +#endif
13395 +#ifdef CONFIG_GRKERNSEC_TPE
13396 +       grsec_enable_tpe = 1;
13397 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
13398 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
13399 +       grsec_enable_tpe_all = 1;
13400 +#endif
13401 +#endif
13402 +#ifdef CONFIG_GRKERNSEC_RANDPID
13403 +       grsec_enable_randpid = 1;
13404 +#endif
13405 +#ifdef CONFIG_GRKERNSEC_RANDID
13406 +       grsec_enable_randid = 1;
13407 +#endif
13408 +#ifdef CONFIG_GRKERNSEC_RANDISN
13409 +       grsec_enable_randisn = 1;
13410 +#endif
13411 +#ifdef CONFIG_GRKERNSEC_RANDSRC
13412 +       grsec_enable_randsrc = 1;
13413 +#endif
13414 +#ifdef CONFIG_GRKERNSEC_RANDRPC
13415 +       grsec_enable_randrpc = 1;
13416 +#endif
13417 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13418 +       grsec_enable_socket_all = 1;
13419 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
13420 +#endif
13421 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13422 +       grsec_enable_socket_client = 1;
13423 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
13424 +#endif
13425 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13426 +       grsec_enable_socket_server = 1;
13427 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
13428 +#endif
13429 +#endif
13430 +
13431 +       return;
13432 +}
13433 diff -urN linux-2.4.24.org/grsecurity/grsec_ipc.c linux-2.4.24/grsecurity/grsec_ipc.c
13434 --- linux-2.4.24.org/grsecurity/grsec_ipc.c     1970-01-01 01:00:00.000000000 +0100
13435 +++ linux-2.4.24/grsecurity/grsec_ipc.c 2004-01-05 18:43:05.270945288 +0100
13436 @@ -0,0 +1,81 @@
13437 +#include <linux/kernel.h>
13438 +#include <linux/sched.h>
13439 +#include <linux/types.h>
13440 +#include <linux/ipc.h>
13441 +#include <linux/grsecurity.h>
13442 +#include <linux/grinternal.h>
13443 +
13444 +void
13445 +gr_log_msgget(const int ret, const int msgflg)
13446 +{
13447 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13448 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13449 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13450 +                                         !grsec_enable_group)) && (ret >= 0)
13451 +           && (msgflg & IPC_CREAT))
13452 +               security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
13453 +#endif
13454 +       return;
13455 +}
13456 +
13457 +void
13458 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
13459 +{
13460 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13461 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13462 +            grsec_enable_audit_ipc) ||
13463 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13464 +               security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13465 +#endif
13466 +       return;
13467 +}
13468 +
13469 +void
13470 +gr_log_semget(const int err, const int semflg)
13471 +{
13472 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13473 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13474 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13475 +                                         !grsec_enable_group)) && (err >= 0)
13476 +           && (semflg & IPC_CREAT))
13477 +               security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
13478 +#endif
13479 +       return;
13480 +}
13481 +
13482 +void
13483 +gr_log_semrm(const uid_t uid, const uid_t cuid)
13484 +{
13485 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13486 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13487 +            grsec_enable_audit_ipc) ||
13488 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13489 +               security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13490 +#endif
13491 +       return;
13492 +}
13493 +
13494 +void
13495 +gr_log_shmget(const int err, const int shmflg, const size_t size)
13496 +{
13497 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13498 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13499 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13500 +                                         !grsec_enable_group)) && (err >= 0)
13501 +           && (shmflg & IPC_CREAT))
13502 +               security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
13503 +#endif
13504 +       return;
13505 +}
13506 +
13507 +void
13508 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
13509 +{
13510 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13511 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13512 +            grsec_enable_audit_ipc) ||
13513 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13514 +               security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13515 +#endif
13516 +       return;
13517 +}
13518 diff -urN linux-2.4.24.org/grsecurity/grsec_link.c linux-2.4.24/grsecurity/grsec_link.c
13519 --- linux-2.4.24.org/grsecurity/grsec_link.c    1970-01-01 01:00:00.000000000 +0100
13520 +++ linux-2.4.24/grsecurity/grsec_link.c        2004-01-05 18:43:05.271945136 +0100
13521 @@ -0,0 +1,41 @@
13522 +#include <linux/kernel.h>
13523 +#include <linux/sched.h>
13524 +#include <linux/fs.h>
13525 +#include <linux/file.h>
13526 +#include <linux/grinternal.h>
13527 +
13528 +int
13529 +gr_handle_follow_link(const struct inode *parent,
13530 +                     const struct inode *inode,
13531 +                     const struct dentry *dentry, const struct vfsmount *mnt)
13532 +{
13533 +#ifdef CONFIG_GRKERNSEC_LINK
13534 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
13535 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
13536 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
13537 +               security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
13538 +                              inode->i_uid, inode->i_gid, DEFAULTSECARGS);
13539 +               return -EACCES;
13540 +       }
13541 +#endif
13542 +       return 0;
13543 +}
13544 +
13545 +int
13546 +gr_handle_hardlink(const struct dentry *dentry,
13547 +                  const struct vfsmount *mnt,
13548 +                  struct inode *inode, const int mode, const char *to)
13549 +{
13550 +#ifdef CONFIG_GRKERNSEC_LINK
13551 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
13552 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
13553 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
13554 +            (permission(inode, MAY_READ | MAY_WRITE))) &&
13555 +           !capable(CAP_FOWNER) && current->uid) {
13556 +               security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
13557 +                              inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
13558 +               return -EPERM;
13559 +       }
13560 +#endif
13561 +       return 0;
13562 +}
13563 diff -urN linux-2.4.24.org/grsecurity/grsec_mem.c linux-2.4.24/grsecurity/grsec_mem.c
13564 --- linux-2.4.24.org/grsecurity/grsec_mem.c     1970-01-01 01:00:00.000000000 +0100
13565 +++ linux-2.4.24/grsecurity/grsec_mem.c 2004-01-05 18:43:05.271945136 +0100
13566 @@ -0,0 +1,54 @@
13567 +#include <linux/kernel.h>
13568 +#include <linux/sched.h>
13569 +#include <linux/mm.h>
13570 +#include <linux/grinternal.h>
13571 +
13572 +void
13573 +gr_handle_ioperm(void)
13574 +{
13575 +       security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
13576 +       return;
13577 +}
13578 +
13579 +void
13580 +gr_handle_iopl(void)
13581 +{
13582 +       security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
13583 +       return;
13584 +}
13585 +
13586 +void
13587 +gr_handle_mem_write(void)
13588 +{
13589 +       security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
13590 +       return;
13591 +}
13592 +
13593 +void
13594 +gr_handle_kmem_write(void)
13595 +{
13596 +       security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
13597 +       return;
13598 +}
13599 +
13600 +void
13601 +gr_handle_open_port(void)
13602 +{
13603 +       security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
13604 +       return;
13605 +}
13606 +
13607 +int
13608 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
13609 +{
13610 +       if (offset < __pa(high_memory) &&
13611 +           (pgprot_val(vma->vm_page_prot) & PROT_WRITE) &&
13612 +           !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
13613 +           !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
13614 +               security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
13615 +               return -EPERM;
13616 +       } else if (offset < __pa(high_memory))
13617 +               vma->vm_flags &= ~VM_MAYWRITE;
13618 +
13619 +       return 0;
13620 +}
13621 diff -urN linux-2.4.24.org/grsecurity/grsec_mount.c linux-2.4.24/grsecurity/grsec_mount.c
13622 --- linux-2.4.24.org/grsecurity/grsec_mount.c   1970-01-01 01:00:00.000000000 +0100
13623 +++ linux-2.4.24/grsecurity/grsec_mount.c       2004-01-05 18:43:05.271945136 +0100
13624 @@ -0,0 +1,34 @@
13625 +#include <linux/kernel.h>
13626 +#include <linux/sched.h>
13627 +#include <linux/grsecurity.h>
13628 +#include <linux/grinternal.h>
13629 +
13630 +void
13631 +gr_log_remount(const char *devname, const int retval)
13632 +{
13633 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13634 +       if (grsec_enable_mount && (retval >= 0))
13635 +               security_audit(GR_REMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13636 +#endif
13637 +       return;
13638 +}
13639 +
13640 +void
13641 +gr_log_unmount(const char *devname, const int retval)
13642 +{
13643 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13644 +       if (grsec_enable_mount && (retval >= 0))
13645 +               security_audit(GR_UNMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13646 +#endif
13647 +       return;
13648 +}
13649 +
13650 +void
13651 +gr_log_mount(const char *from, const char *to, const int retval)
13652 +{
13653 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13654 +       if (grsec_enable_mount && (retval >= 0))
13655 +               security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
13656 +#endif
13657 +       return;
13658 +}
13659 diff -urN linux-2.4.24.org/grsecurity/grsec_rand.c linux-2.4.24/grsecurity/grsec_rand.c
13660 --- linux-2.4.24.org/grsecurity/grsec_rand.c    1970-01-01 01:00:00.000000000 +0100
13661 +++ linux-2.4.24/grsecurity/grsec_rand.c        2004-01-05 18:43:05.272944984 +0100
13662 @@ -0,0 +1,36 @@
13663 +#include <linux/kernel.h>
13664 +#include <linux/sched.h>
13665 +#include <linux/smp_lock.h>
13666 +#include <linux/grsecurity.h>
13667 +#include <linux/grinternal.h>
13668 +
13669 +extern int last_pid;
13670 +
13671 +int
13672 +gr_random_pid(spinlock_t * pid_lock)
13673 +{
13674 +#ifdef CONFIG_GRKERNSEC_RANDPID
13675 +       struct task_struct *p;
13676 +       int pid;
13677 +
13678 +       if (grsec_enable_randpid && current->fs->root) {
13679 +               read_lock(&tasklist_lock);
13680 +               spin_lock(pid_lock);
13681 +
13682 +             repeater:
13683 +
13684 +               pid = 1 + (get_random_long() % PID_MAX);
13685 +
13686 +               for_each_task(p) {
13687 +                       if (p->pid == pid || p->pgrp == pid ||
13688 +                           p->tgid == pid || p->session == pid)
13689 +                               goto repeater;
13690 +               }
13691 +               last_pid = pid;
13692 +               spin_unlock(pid_lock);
13693 +               read_unlock(&tasklist_lock);
13694 +               return pid;
13695 +       }
13696 +#endif
13697 +       return 0;
13698 +}
13699 diff -urN linux-2.4.24.org/grsecurity/grsec_sig.c linux-2.4.24/grsecurity/grsec_sig.c
13700 --- linux-2.4.24.org/grsecurity/grsec_sig.c     1970-01-01 01:00:00.000000000 +0100
13701 +++ linux-2.4.24/grsecurity/grsec_sig.c 2004-01-05 18:43:05.272944984 +0100
13702 @@ -0,0 +1,47 @@
13703 +#include <linux/kernel.h>
13704 +#include <linux/sched.h>
13705 +#include <linux/grinternal.h>
13706 +
13707 +void
13708 +gr_log_signal(const int sig, const struct task_struct *t)
13709 +{
13710 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13711 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
13712 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
13713 +               if (t->pid == current->pid) {
13714 +                       security_alert_good(GR_UNISIGLOG_MSG, sig,
13715 +                                           DEFAULTSECARGS);
13716 +               } else {
13717 +                       security_alert_good(GR_DUALSIGLOG_MSG, sig,
13718 +                                           gr_task_fullpath0(t), t->comm,
13719 +                                           t->pid, t->uid, t->euid, t->gid,
13720 +                                           t->egid, gr_parent_task_fullpath0(t),
13721 +                                           t->p_pptr->comm,
13722 +                                           t->p_pptr->pid, t->p_pptr->uid,
13723 +                                           t->p_pptr->euid, t->p_pptr->gid,
13724 +                                           t->p_pptr->egid, DEFAULTSECARGS);
13725 +               }
13726 +       }
13727 +#endif
13728 +       return;
13729 +}
13730 +
13731 +int
13732 +gr_handle_signal(const struct task_struct *p, const int sig)
13733 +{
13734 +#ifdef CONFIG_GRKERNSEC
13735 +       if (current->pid > 1 && gr_check_protected_task(p)) {
13736 +               security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p),
13737 +                              p->comm, p->pid, p->uid,
13738 +                              p->euid, p->gid, p->egid,
13739 +                              gr_parent_task_fullpath0(p), p->p_pptr->comm,
13740 +                              p->p_pptr->pid, p->p_pptr->uid,
13741 +                              p->p_pptr->euid, p->p_pptr->gid,
13742 +                              p->p_pptr->egid, DEFAULTSECARGS);
13743 +               return -EPERM;
13744 +       } else if (gr_pid_is_chrooted(p)) {
13745 +               return -EPERM;
13746 +       }
13747 +#endif
13748 +       return 0;
13749 +}
13750 diff -urN linux-2.4.24.org/grsecurity/grsec_sock.c linux-2.4.24/grsecurity/grsec_sock.c
13751 --- linux-2.4.24.org/grsecurity/grsec_sock.c    1970-01-01 01:00:00.000000000 +0100
13752 +++ linux-2.4.24/grsecurity/grsec_sock.c        2004-01-05 18:43:05.273944832 +0100
13753 @@ -0,0 +1,205 @@
13754 +#include <linux/kernel.h>
13755 +#include <linux/sched.h>
13756 +#include <linux/file.h>
13757 +#include <linux/net.h>
13758 +#include <net/sock.h>
13759 +#include <linux/grsecurity.h>
13760 +#include <linux/grinternal.h>
13761 +#include <linux/gracl.h>
13762 +
13763 +#ifdef CONFIG_GRKERNSEC
13764 +struct task_struct **gr_conn_table;
13765 +const unsigned int gr_conn_table_size = 65521;
13766 +struct task_struct *deleted_conn = (struct task_struct *)~0;
13767 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
13768 +
13769 +extern __inline__ const char * gr_socktype_to_name(unsigned char type);
13770 +extern __inline__ const char * gr_proto_to_name(unsigned char proto);
13771 +
13772 +static __inline__ int 
13773 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
13774 +{
13775 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
13776 +}
13777 +
13778 +static __inline__ int
13779 +conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr, 
13780 +          __u16 sport, __u16 dport)
13781 +{
13782 +       if (unlikely(task != deleted_conn && task->gr_saddr == saddr && 
13783 +                    task->gr_daddr == daddr && task->gr_sport == sport &&
13784 +                    task->gr_dport == dport))
13785 +               return 1;
13786 +       else
13787 +               return 0;
13788 +}
13789 +
13790 +void gr_add_to_task_ip_table(struct task_struct *task)
13791 +{
13792 +       unsigned int index;
13793 +
13794 +       if (unlikely(gr_conn_table == NULL))
13795 +               return;
13796 +
13797 +       index = conn_hash(task->gr_saddr, task->gr_daddr,
13798 +                         task->gr_sport, task->gr_dport, 
13799 +                         gr_conn_table_size);
13800 +
13801 +       spin_lock(&gr_conn_table_lock);
13802 +
13803 +       while (gr_conn_table[index] && gr_conn_table[index] != deleted_conn) {
13804 +               index = (index + 1) % gr_conn_table_size;
13805 +       }
13806 +
13807 +       gr_conn_table[index] = task;
13808 +
13809 +       spin_unlock(&gr_conn_table_lock);
13810 +
13811 +       return;
13812 +}
13813 +
13814 +void gr_del_task_from_ip_table_nolock(struct task_struct *task)
13815 +{
13816 +       unsigned int index;
13817 +
13818 +       if (unlikely(gr_conn_table == NULL))
13819 +               return;
13820 +
13821 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
13822 +                         task->gr_sport, task->gr_dport, 
13823 +                         gr_conn_table_size);
13824 +
13825 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
13826 +               task->gr_saddr, task->gr_daddr, task->gr_sport, 
13827 +               task->gr_dport)) {
13828 +               index = (index + 1) % gr_conn_table_size;
13829 +       }
13830 +
13831 +       if (gr_conn_table[index] && conn_match(gr_conn_table[index],
13832 +               task->gr_saddr, task->gr_daddr, task->gr_sport, 
13833 +               task->gr_dport)) {
13834 +               if (gr_conn_table[(index + 1) % gr_conn_table_size])
13835 +                       gr_conn_table[index] = deleted_conn;
13836 +               else
13837 +                       gr_conn_table[index] = NULL;
13838 +       }
13839 +
13840 +       return;
13841 +}
13842 +
13843 +struct task_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
13844 +                                            __u16 sport, __u16 dport)
13845 +{
13846 +       unsigned int index;
13847 +
13848 +       if (unlikely(gr_conn_table == NULL))
13849 +               return NULL;
13850 +
13851 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
13852 +
13853 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
13854 +               saddr, daddr, sport, dport)) {
13855 +               index = (index + 1) % gr_conn_table_size;
13856 +       }
13857 +
13858 +       if (unlikely(gr_conn_table[index] && conn_match(gr_conn_table[index],
13859 +                    saddr, daddr, sport, dport)))
13860 +               return gr_conn_table[index];
13861 +       else
13862 +               return NULL;
13863 +}
13864 +
13865 +#endif
13866 +
13867 +void gr_del_task_from_ip_table(struct task_struct *task)
13868 +{
13869 +#ifdef CONFIG_GRKERNSEC
13870 +       spin_lock(&gr_conn_table_lock);
13871 +       gr_del_task_from_ip_table_nolock(task);
13872 +       spin_unlock(&gr_conn_table_lock);
13873 +#endif
13874 +       return;
13875 +}
13876 +
13877 +void
13878 +gr_attach_curr_ip(const struct sock *sk)
13879 +{
13880 +#ifdef CONFIG_GRKERNSEC
13881 +       struct task_struct *p;
13882 +
13883 +       if (unlikely(sk->protocol != IPPROTO_TCP))
13884 +               return;
13885 +
13886 +       spin_lock(&gr_conn_table_lock);
13887 +       p = gr_lookup_task_ip_table(sk->daddr, sk->rcv_saddr,
13888 +                                   sk->dport, sk->sport);
13889 +       if (unlikely(p != NULL)) {
13890 +               current->curr_ip = p->curr_ip;
13891 +               current->used_accept = 1;
13892 +               gr_del_task_from_ip_table_nolock(p);
13893 +               spin_unlock(&gr_conn_table_lock);
13894 +               return;
13895 +       }
13896 +       spin_unlock(&gr_conn_table_lock);
13897 +
13898 +       current->curr_ip = sk->daddr;
13899 +       current->used_accept = 1;
13900 +#endif
13901 +       return;
13902 +}
13903 +
13904 +int
13905 +gr_handle_sock_all(const int family, const int type, const int protocol)
13906 +{
13907 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13908 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
13909 +           (family != AF_UNIX) && (family != AF_LOCAL) && (type < SOCK_MAX)) {
13910 +               security_alert(GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol),
13911 +                              DEFAULTSECARGS);
13912 +               return -EACCES;
13913 +       }
13914 +#endif
13915 +       return 0;
13916 +}
13917 +
13918 +int
13919 +gr_handle_sock_server(const struct sockaddr *sck)
13920 +{
13921 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13922 +       if (grsec_enable_socket_server &&
13923 +           in_group_p(grsec_socket_server_gid) &&
13924 +           sck && (sck->sa_family != AF_UNIX) &&
13925 +           (sck->sa_family != AF_LOCAL)) {
13926 +               security_alert(GR_BIND_MSG, DEFAULTSECARGS);
13927 +               return -EACCES;
13928 +       }
13929 +#endif
13930 +       return 0;
13931 +}
13932 +
13933 +int
13934 +gr_handle_sock_client(const struct sockaddr *sck)
13935 +{
13936 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13937 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
13938 +           sck && (sck->sa_family != AF_UNIX) &&
13939 +           (sck->sa_family != AF_LOCAL)) {
13940 +               security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
13941 +               return -EACCES;
13942 +       }
13943 +#endif
13944 +       return 0;
13945 +}
13946 +
13947 +__u32
13948 +gr_cap_rtnetlink(void)
13949 +{
13950 +#ifdef CONFIG_GRKERNSEC
13951 +       if (!gr_acl_is_enabled())
13952 +               return current->cap_effective;
13953 +       else
13954 +               return (current->cap_effective & ~(current->acl->cap_lower));
13955 +#else
13956 +       return current->cap_effective;
13957 +#endif
13958 +}
13959 diff -urN linux-2.4.24.org/grsecurity/grsec_sysctl.c linux-2.4.24/grsecurity/grsec_sysctl.c
13960 --- linux-2.4.24.org/grsecurity/grsec_sysctl.c  1970-01-01 01:00:00.000000000 +0100
13961 +++ linux-2.4.24/grsecurity/grsec_sysctl.c      2004-01-05 18:43:05.274944680 +0100
13962 @@ -0,0 +1,16 @@
13963 +#include <linux/kernel.h>
13964 +#include <linux/sched.h>
13965 +#include <linux/sysctl.h>
13966 +#include <linux/grinternal.h>
13967 +
13968 +int
13969 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
13970 +{
13971 +#ifdef CONFIG_GRKERNSEC_SYSCTL
13972 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
13973 +               security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
13974 +               return -EACCES;
13975 +       }
13976 +#endif
13977 +       return 0;
13978 +}
13979 diff -urN linux-2.4.24.org/grsecurity/grsec_time.c linux-2.4.24/grsecurity/grsec_time.c
13980 --- linux-2.4.24.org/grsecurity/grsec_time.c    1970-01-01 01:00:00.000000000 +0100
13981 +++ linux-2.4.24/grsecurity/grsec_time.c        2004-01-05 18:43:05.274944680 +0100
13982 @@ -0,0 +1,13 @@
13983 +#include <linux/kernel.h>
13984 +#include <linux/sched.h>
13985 +#include <linux/grinternal.h>
13986 +
13987 +void
13988 +gr_log_timechange(void)
13989 +{
13990 +#ifdef CONFIG_GRKERNSEC_TIME
13991 +       if (grsec_enable_time)
13992 +               security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
13993 +#endif
13994 +       return;
13995 +}
13996 diff -urN linux-2.4.24.org/grsecurity/grsec_tpe.c linux-2.4.24/grsecurity/grsec_tpe.c
13997 --- linux-2.4.24.org/grsecurity/grsec_tpe.c     1970-01-01 01:00:00.000000000 +0100
13998 +++ linux-2.4.24/grsecurity/grsec_tpe.c 2004-01-05 18:43:05.274944680 +0100
13999 @@ -0,0 +1,35 @@
14000 +#include <linux/kernel.h>
14001 +#include <linux/sched.h>
14002 +#include <linux/file.h>
14003 +#include <linux/fs.h>
14004 +#include <linux/grinternal.h>
14005 +
14006 +extern int gr_acl_tpe_check(void);
14007 +
14008 +int
14009 +gr_tpe_allow(const struct file *file)
14010 +{
14011 +#ifdef CONFIG_GRKERNSEC
14012 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
14013 +
14014 +       if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
14015 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
14016 +                                               (inode->i_mode & S_IWOTH))))) {
14017 +               security_alert(GR_EXEC_TPE_MSG,
14018 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
14019 +                              DEFAULTSECARGS);
14020 +               return 0;
14021 +       }
14022 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
14023 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
14024 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
14025 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
14026 +               security_alert(GR_EXEC_TPE_MSG,
14027 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
14028 +                              DEFAULTSECARGS);
14029 +               return 0;
14030 +       }
14031 +#endif
14032 +#endif
14033 +       return 1;
14034 +}
14035 diff -urN linux-2.4.24.org/grsecurity/grsum.c linux-2.4.24/grsecurity/grsum.c
14036 --- linux-2.4.24.org/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100
14037 +++ linux-2.4.24/grsecurity/grsum.c     2004-01-05 18:43:05.275944528 +0100
14038 @@ -0,0 +1,59 @@
14039 +#include <linux/kernel.h>
14040 +#include <linux/sched.h>
14041 +#include <linux/mm.h>
14042 +#include <asm/scatterlist.h>
14043 +#include <linux/crypto.h>
14044 +#include <linux/gracl.h>
14045 +
14046 +
14047 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
14048 +#error "crypto and sha256 must be built into the kernel"
14049 +#endif
14050 +
14051 +int
14052 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
14053 +{
14054 +       char *p;
14055 +       struct crypto_tfm *tfm;
14056 +       unsigned char temp_sum[GR_SHA_LEN];
14057 +       struct scatterlist sg[2];
14058 +       volatile int retval = 0;
14059 +       volatile int dummy = 0;
14060 +       unsigned int i;
14061 +
14062 +       tfm = crypto_alloc_tfm("sha256", 0);
14063 +       if (tfm == NULL) {
14064 +               /* should never happen, since sha256 should be built in */
14065 +               return 1;
14066 +       }
14067 +
14068 +       crypto_digest_init(tfm);
14069 +
14070 +       p = salt;
14071 +       sg[0].page = virt_to_page(p);
14072 +       sg[0].offset = ((long) p & ~PAGE_MASK);
14073 +       sg[0].length = GR_SALT_LEN;
14074 +       
14075 +       crypto_digest_update(tfm, sg, 1);
14076 +
14077 +       p = entry->pw;
14078 +       sg[0].page = virt_to_page(p);
14079 +       sg[0].offset = ((long) p & ~PAGE_MASK);
14080 +       sg[0].length = strlen(entry->pw);
14081 +
14082 +       crypto_digest_update(tfm, sg, 1);
14083 +
14084 +       crypto_digest_final(tfm, temp_sum);
14085 +
14086 +       memset(entry->pw, 0, GR_PW_LEN);
14087 +
14088 +       for (i = 0; i < GR_SHA_LEN; i++)
14089 +               if (sum[i] != temp_sum[i])
14090 +                       retval = 1;
14091 +               else
14092 +                       dummy = 1;      // waste a cycle
14093 +
14094 +       crypto_free_tfm(tfm);
14095 +
14096 +       return retval;
14097 +}
14098 diff -urN linux-2.4.24.org/grsecurity/Makefile linux-2.4.24/grsecurity/Makefile
14099 --- linux-2.4.24.org/grsecurity/Makefile        1970-01-01 01:00:00.000000000 +0100
14100 +++ linux-2.4.24/grsecurity/Makefile    2004-01-05 18:43:05.254947720 +0100
14101 @@ -0,0 +1,24 @@
14102 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
14103 +# during 2001, 2002, and 2003 it has been completely redesigned by
14104 +# Brad Spengler
14105 +#
14106 +# All code in this directory and various hooks inserted throughout the kernel
14107 +# are copyright Brad Spengler, and released under the GPL, unless otherwise
14108 +# noted (as in obsd_rand.c)
14109 +
14110 +O_TARGET := grsec.o
14111 +
14112 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
14113 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
14114 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o
14115 +
14116 +ifeq ($(CONFIG_GRKERNSEC),y)
14117 +obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
14118 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
14119 +       gracl_learn.o
14120 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
14121 +else
14122 +obj-y += grsec_disabled.o
14123 +endif
14124 +
14125 +include $(TOPDIR)/Rules.make
14126 diff -urN linux-2.4.24.org/grsecurity/obsd_rand.c linux-2.4.24/grsecurity/obsd_rand.c
14127 --- linux-2.4.24.org/grsecurity/obsd_rand.c     1970-01-01 01:00:00.000000000 +0100
14128 +++ linux-2.4.24/grsecurity/obsd_rand.c 2004-01-05 18:43:05.275944528 +0100
14129 @@ -0,0 +1,185 @@
14130 +
14131 +/*
14132 + * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
14133 + * 
14134 + * Version 1.89, last modified 19-Sep-99
14135 + *    
14136 + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
14137 + * All rights reserved.
14138 + *
14139 + * Copyright 1998 Niels Provos <provos@citi.umich.edu>
14140 + * All rights reserved.
14141 + * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
14142 + * such a mathematical system to generate more random (yet non-repeating)
14143 + * ids to solve the resolver/named problem.  But Niels designed the
14144 + * actual system based on the constraints.
14145 + *
14146 + * Redistribution and use in source and binary forms, with or without
14147 + * modification, are permitted provided that the following conditions
14148 + * are met:
14149 + * 1. Redistributions of source code must retain the above copyright
14150 + *    notice, this list of conditions and the following disclaimer,
14151 + * 2. Redistributions in binary form must reproduce the above copyright
14152 + *    notice, this list of conditions and the following disclaimer in the
14153 + *    documentation and/or other materials provided with the distribution.
14154 + *
14155 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14156 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14157 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14158 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14159 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14160 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
14161 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
14162 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14163 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
14164 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14165 + */
14166 +
14167 +#include <linux/kernel.h>
14168 +#include <linux/sched.h>
14169 +#include <linux/timer.h>
14170 +#include <linux/smp_lock.h>
14171 +#include <linux/random.h>
14172 +#include <linux/grsecurity.h>
14173 +
14174 +#define RU_OUT 180
14175 +#define RU_MAX 30000
14176 +#define RU_GEN 2
14177 +#define RU_N 32749
14178 +#define RU_AGEN 7
14179 +#define RU_M 31104
14180 +#define PFAC_N 3
14181 +const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
14182 +
14183 +static __u16 ru_x;
14184 +static __u16 ru_seed, ru_seed2;
14185 +static __u16 ru_a, ru_b;
14186 +static __u16 ru_g;
14187 +static __u16 ru_counter = 0;
14188 +static __u16 ru_msb = 0;
14189 +static unsigned long ru_reseed = 0;
14190 +static __u32 tmp;
14191 +
14192 +#define TCP_RNDISS_ROUNDS      15
14193 +#define TCP_RNDISS_OUT         7200
14194 +#define TCP_RNDISS_MAX         30000
14195 +
14196 +static __u8 tcp_rndiss_sbox[128];
14197 +static __u16 tcp_rndiss_msb;
14198 +static __u16 tcp_rndiss_cnt;
14199 +static unsigned long tcp_rndiss_reseed;
14200 +
14201 +static __u16 pmod(__u16, __u16, __u16);
14202 +static void ip_initid(void);
14203 +__u16 ip_randomid(void);
14204 +
14205 +static __u16
14206 +pmod(__u16 gen, __u16 exp, __u16 mod)
14207 +{
14208 +       __u16 s, t, u;
14209 +
14210 +       s = 1;
14211 +       t = gen;
14212 +       u = exp;
14213 +
14214 +       while (u) {
14215 +               if (u & 1)
14216 +                       s = (s * t) % mod;
14217 +               u >>= 1;
14218 +               t = (t * t) % mod;
14219 +       }
14220 +       return (s);
14221 +}
14222 +
14223 +static void
14224 +ip_initid(void)
14225 +{
14226 +       __u16 j, i;
14227 +       int noprime = 1;
14228 +
14229 +       ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
14230 +
14231 +       ru_seed = (tmp >> 16) & 0x7FFF;
14232 +       ru_seed2 = get_random_long() & 0x7FFF;
14233 +
14234 +       ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
14235 +       ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
14236 +       while (ru_b % 3 == 0)
14237 +               ru_b += 2;
14238 +
14239 +       j = (tmp = get_random_long()) % RU_N;
14240 +       tmp = tmp >> 16;
14241 +
14242 +       while (noprime) {
14243 +               for (i = 0; i < PFAC_N; i++)
14244 +                       if (j % pfacts[i] == 0)
14245 +                               break;
14246 +
14247 +               if (i >= PFAC_N)
14248 +                       noprime = 0;
14249 +               else
14250 +                       j = (j + 1) % RU_N;
14251 +       }
14252 +
14253 +       ru_g = pmod(RU_GEN, j, RU_N);
14254 +       ru_counter = 0;
14255 +
14256 +       ru_reseed = xtime.tv_sec + RU_OUT;
14257 +       ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
14258 +}
14259 +
14260 +__u16
14261 +ip_randomid(void)
14262 +{
14263 +       int i, n;
14264 +
14265 +       if (ru_counter >= RU_MAX || time_after(xtime.tv_sec, ru_reseed))
14266 +               ip_initid();
14267 +
14268 +       if (!tmp)
14269 +               tmp = get_random_long();
14270 +
14271 +       n = tmp & 0x3;
14272 +       tmp = tmp >> 2;
14273 +       if (ru_counter + n >= RU_MAX)
14274 +               ip_initid();
14275 +       for (i = 0; i <= n; i++)
14276 +               ru_x = (ru_a * ru_x + ru_b) % RU_M;
14277 +       ru_counter += i;
14278 +
14279 +       return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
14280 +}
14281 +
14282 +__u16
14283 +tcp_rndiss_encrypt(__u16 val)
14284 +{
14285 +       __u16 sum = 0, i;
14286 +
14287 +       for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
14288 +               sum += 0x79b9;
14289 +               val ^= ((__u16) tcp_rndiss_sbox[(val ^ sum) & 0x7f]) << 7;
14290 +               val = ((val & 0xff) << 7) | (val >> 8);
14291 +       }
14292 +
14293 +       return val;
14294 +}
14295 +
14296 +static void
14297 +tcp_rndiss_init(void)
14298 +{
14299 +       get_random_bytes(tcp_rndiss_sbox, sizeof (tcp_rndiss_sbox));
14300 +       tcp_rndiss_reseed = xtime.tv_sec + TCP_RNDISS_OUT;
14301 +       tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
14302 +       tcp_rndiss_cnt = 0;
14303 +}
14304 +
14305 +__u32
14306 +ip_randomisn(void)
14307 +{
14308 +       if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
14309 +           time_after(xtime.tv_sec, tcp_rndiss_reseed))
14310 +               tcp_rndiss_init();
14311 +
14312 +       return (((tcp_rndiss_encrypt(tcp_rndiss_cnt++) |
14313 +                 tcp_rndiss_msb) << 16) | (get_random_long() & 0x7fff));
14314 +}
14315 diff -urN linux-2.4.24.org/include/asm-alpha/a.out.h linux-2.4.24/include/asm-alpha/a.out.h
14316 --- linux-2.4.24.org/include/asm-alpha/a.out.h  2004-01-05 18:39:37.000000000 +0100
14317 +++ linux-2.4.24/include/asm-alpha/a.out.h      2004-01-05 18:43:05.290942248 +0100
14318 @@ -98,7 +98,7 @@
14319         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
14320                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
14321  
14322 -#define STACK_TOP \
14323 +#define __STACK_TOP \
14324    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
14325  
14326  #endif
14327 diff -urN linux-2.4.24.org/include/asm-alpha/elf.h linux-2.4.24/include/asm-alpha/elf.h
14328 --- linux-2.4.24.org/include/asm-alpha/elf.h    2004-01-05 18:39:37.000000000 +0100
14329 +++ linux-2.4.24/include/asm-alpha/elf.h        2004-01-05 18:43:05.294941640 +0100
14330 @@ -41,6 +41,18 @@
14331  
14332  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
14333  
14334 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14335 +#define PAX_ELF_ET_DYN_BASE(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
14336 +
14337 +#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
14338 +#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
14339 +#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
14340 +#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
14341 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14342 +#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
14343 +#endif
14344 +
14345 +
14346  /* $0 is set by ld.so to a pointer to a function which might be 
14347     registered using atexit.  This provides a mean for the dynamic
14348     linker to call DT_FINI functions for shared libraries that have
14349 diff -urN linux-2.4.24.org/include/asm-alpha/mman.h linux-2.4.24/include/asm-alpha/mman.h
14350 --- linux-2.4.24.org/include/asm-alpha/mman.h   2004-01-05 18:39:37.000000000 +0100
14351 +++ linux-2.4.24/include/asm-alpha/mman.h       2004-01-05 18:43:05.310939208 +0100
14352 @@ -24,6 +24,10 @@
14353  #define MAP_LOCKED     0x8000          /* lock the mapping */
14354  #define MAP_NORESERVE  0x10000         /* don't check for reservations */
14355  
14356 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14357 +#define MAP_MIRROR     0x20000
14358 +#endif
14359 +
14360  #define MS_ASYNC       1               /* sync memory asynchronously */
14361  #define MS_SYNC                2               /* synchronous memory sync */
14362  #define MS_INVALIDATE  4               /* invalidate the caches */
14363 diff -urN linux-2.4.24.org/include/asm-alpha/pgtable.h linux-2.4.24/include/asm-alpha/pgtable.h
14364 --- linux-2.4.24.org/include/asm-alpha/pgtable.h        2004-01-05 18:39:37.000000000 +0100
14365 +++ linux-2.4.24/include/asm-alpha/pgtable.h    2004-01-05 18:43:05.328936472 +0100
14366 @@ -96,6 +96,17 @@
14367  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
14368  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
14369  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
14370 +
14371 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14372 +#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
14373 +#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
14374 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
14375 +#else
14376 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14377 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14378 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14379 +#endif
14380 +
14381  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
14382  
14383  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
14384 diff -urN linux-2.4.24.org/include/asm-i386/a.out.h linux-2.4.24/include/asm-i386/a.out.h
14385 --- linux-2.4.24.org/include/asm-i386/a.out.h   2004-01-05 18:39:17.000000000 +0100
14386 +++ linux-2.4.24/include/asm-i386/a.out.h       2004-01-05 18:43:05.360931608 +0100
14387 @@ -19,7 +19,11 @@
14388  
14389  #ifdef __KERNEL__
14390  
14391 -#define STACK_TOP      TASK_SIZE
14392 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14393 +#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
14394 +#else
14395 +#define __STACK_TOP    TASK_SIZE
14396 +#endif
14397  
14398  #endif
14399  
14400 diff -urN linux-2.4.24.org/include/asm-i386/desc.h linux-2.4.24/include/asm-i386/desc.h
14401 --- linux-2.4.24.org/include/asm-i386/desc.h    2004-01-05 18:39:18.000000000 +0100
14402 +++ linux-2.4.24/include/asm-i386/desc.h        2004-01-05 18:43:05.392926744 +0100
14403 @@ -46,7 +46,8 @@
14404  };
14405  
14406  extern struct desc_struct gdt_table[];
14407 -extern struct desc_struct *idt, *gdt;
14408 +extern struct desc_struct gdt_table2[];
14409 +extern struct desc_struct *idt, *gdt, *gdt2;
14410  
14411  struct Xgt_desc_struct {
14412         unsigned short size;
14413 @@ -55,6 +56,7 @@
14414  
14415  #define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
14416  #define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
14417 +#define gdt_descr2 (*(struct Xgt_desc_struct *)((char *)&gdt2 - 2))
14418  
14419  #define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3))
14420  
14421 @@ -64,10 +66,11 @@
14422   * This is the ldt that every process will get unless we need
14423   * something other than this.
14424   */
14425 -extern struct desc_struct default_ldt[];
14426 +extern const struct desc_struct default_ldt[];
14427  extern void set_intr_gate(unsigned int irq, void * addr);
14428 -extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
14429 -extern void set_tss_desc(unsigned int n, void *addr);
14430 +extern void set_ldt_desc(unsigned int n, const void *addr, unsigned int size);
14431 +extern void __set_ldt_desc(unsigned int n, const void *addr, unsigned int size);
14432 +extern void set_tss_desc(unsigned int n, const void *addr);
14433  
14434  static inline void clear_LDT(void)
14435  {
14436 @@ -82,7 +85,7 @@
14437  static inline void load_LDT (struct mm_struct *mm)
14438  {
14439         int cpu = smp_processor_id();
14440 -       void *segments = mm->context.segments;
14441 +       const void *segments = mm->context.segments;
14442         int count = LDT_ENTRIES;
14443  
14444         if (!segments) {
14445 @@ -94,6 +97,21 @@
14446         __load_LDT(cpu);
14447  }
14448  
14449 +static inline void _load_LDT (struct mm_struct *mm)
14450 +{
14451 +       int cpu = smp_processor_id();
14452 +       const void *segments = mm->context.segments;
14453 +       int count = LDT_ENTRIES;
14454 +
14455 +       if (!segments) {
14456 +               segments = &default_ldt[0];
14457 +               count = 5;
14458 +       }
14459 +               
14460 +       __set_ldt_desc(cpu, segments, count);
14461 +       __load_LDT(cpu);
14462 +}
14463 +
14464  #endif /* !__ASSEMBLY__ */
14465  
14466  #endif
14467 diff -urN linux-2.4.24.org/include/asm-i386/elf.h linux-2.4.24/include/asm-i386/elf.h
14468 --- linux-2.4.24.org/include/asm-i386/elf.h     2004-01-05 18:39:18.000000000 +0100
14469 +++ linux-2.4.24/include/asm-i386/elf.h 2004-01-05 18:43:05.398925832 +0100
14470 @@ -55,7 +55,22 @@
14471     the loader.  We need to make sure that it is out of the way of the program
14472     that it will "exec", and that there is sufficient room for the brk.  */
14473  
14474 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14475 +#define ELF_ET_DYN_BASE                ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2)
14476 +#else
14477  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
14478 +#endif
14479 +
14480 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14481 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
14482 +
14483 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14484 +#define PAX_DELTA_MMAP_LEN(tsk)                16
14485 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14486 +#define PAX_DELTA_EXEC_LEN(tsk)                16
14487 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT  
14488 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
14489 +#endif
14490  
14491  /* Wow, the "main" arch needs arch dependent functions too.. :) */
14492  
14493 diff -urN linux-2.4.24.org/include/asm-i386/hw_irq.h linux-2.4.24/include/asm-i386/hw_irq.h
14494 --- linux-2.4.24.org/include/asm-i386/hw_irq.h  2004-01-05 18:39:18.000000000 +0100
14495 +++ linux-2.4.24/include/asm-i386/hw_irq.h      2004-01-05 18:43:05.420922488 +0100
14496 @@ -128,6 +128,7 @@
14497  asmlinkage void x(void); \
14498  asmlinkage void call_##x(void); \
14499  __asm__( \
14500 +"\n .text" \
14501  "\n"__ALIGN_STR"\n" \
14502  SYMBOL_NAME_STR(x) ":\n\t" \
14503         "pushl $"#v"-256\n\t" \
14504 @@ -141,6 +142,7 @@
14505  asmlinkage void x(struct pt_regs * regs); \
14506  asmlinkage void call_##x(void); \
14507  __asm__( \
14508 +"\n .text" \
14509  "\n"__ALIGN_STR"\n" \
14510  SYMBOL_NAME_STR(x) ":\n\t" \
14511         "pushl $"#v"-256\n\t" \
14512 @@ -155,6 +157,7 @@
14513  #define BUILD_COMMON_IRQ() \
14514  asmlinkage void call_do_IRQ(void); \
14515  __asm__( \
14516 +       "\n .text" \
14517         "\n" __ALIGN_STR"\n" \
14518         "common_interrupt:\n\t" \
14519         SAVE_ALL \
14520 @@ -175,6 +178,7 @@
14521  #define BUILD_IRQ(nr) \
14522  asmlinkage void IRQ_NAME(nr); \
14523  __asm__( \
14524 +"\n .text" \
14525  "\n"__ALIGN_STR"\n" \
14526  SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
14527         "pushl $"#nr"-256\n\t" \
14528 diff -urN linux-2.4.24.org/include/asm-i386/mman.h linux-2.4.24/include/asm-i386/mman.h
14529 --- linux-2.4.24.org/include/asm-i386/mman.h    2004-01-05 18:39:18.000000000 +0100
14530 +++ linux-2.4.24/include/asm-i386/mman.h        2004-01-05 18:43:05.420922488 +0100
14531 @@ -18,6 +18,10 @@
14532  #define MAP_LOCKED     0x2000          /* pages are locked */
14533  #define MAP_NORESERVE  0x4000          /* don't check for reservations */
14534  
14535 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
14536 +#define MAP_MIRROR     0x8000
14537 +#endif
14538 +
14539  #define MS_ASYNC       1               /* sync memory asynchronously */
14540  #define MS_INVALIDATE  2               /* invalidate the caches */
14541  #define MS_SYNC                4               /* synchronous memory sync */
14542 diff -urN linux-2.4.24.org/include/asm-i386/page.h linux-2.4.24/include/asm-i386/page.h
14543 --- linux-2.4.24.org/include/asm-i386/page.h    2004-01-05 18:39:18.000000000 +0100
14544 +++ linux-2.4.24/include/asm-i386/page.h        2004-01-05 18:43:05.495911088 +0100
14545 @@ -78,7 +78,7 @@
14546   * and CONFIG_HIGHMEM64G options in the kernel configuration.
14547   */
14548  
14549 -#define __PAGE_OFFSET          (0xC0000000)
14550 +#include <asm/page_offset.h>
14551  
14552  /*
14553   * This much address space is reserved for vmalloc() and iomap()
14554 diff -urN linux-2.4.24.org/include/asm-i386/page_offset.h linux-2.4.24/include/asm-i386/page_offset.h
14555 --- linux-2.4.24.org/include/asm-i386/page_offset.h     1970-01-01 01:00:00.000000000 +0100
14556 +++ linux-2.4.24/include/asm-i386/page_offset.h 2004-01-05 18:43:05.496910936 +0100
14557 @@ -0,0 +1,2 @@
14558 +#define __KERNEL_TEXT_OFFSET   (0xC0400000)
14559 +#define __PAGE_OFFSET          (0xC0000000)
14560 diff -urN linux-2.4.24.org/include/asm-i386/pgtable.h linux-2.4.24/include/asm-i386/pgtable.h
14561 --- linux-2.4.24.org/include/asm-i386/pgtable.h 2004-01-05 18:39:18.000000000 +0100
14562 +++ linux-2.4.24/include/asm-i386/pgtable.h     2004-01-05 18:43:05.502910024 +0100
14563 @@ -205,6 +205,16 @@
14564  #define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
14565  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
14566  
14567 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14568 +#define PAGE_SHARED_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
14569 +#define PAGE_COPY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
14570 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) 
14571 +#else
14572 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14573 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14574 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14575 +#endif
14576 +
14577  #define __PAGE_KERNEL \
14578         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
14579  #define __PAGE_KERNEL_NOCACHE \
14580 @@ -237,18 +247,18 @@
14581   * This is the closest we can get..
14582   */
14583  #define __P000 PAGE_NONE
14584 -#define __P001 PAGE_READONLY
14585 -#define __P010 PAGE_COPY
14586 -#define __P011 PAGE_COPY
14587 +#define __P001  PAGE_READONLY_NOEXEC
14588 +#define __P010  PAGE_COPY_NOEXEC
14589 +#define __P011  PAGE_COPY_NOEXEC
14590  #define __P100 PAGE_READONLY
14591  #define __P101 PAGE_READONLY
14592  #define __P110 PAGE_COPY
14593  #define __P111 PAGE_COPY
14594  
14595  #define __S000 PAGE_NONE
14596 -#define __S001 PAGE_READONLY
14597 -#define __S010 PAGE_SHARED
14598 -#define __S011 PAGE_SHARED
14599 +#define __S001  PAGE_READONLY_NOEXEC
14600 +#define __S010  PAGE_SHARED_NOEXEC
14601 +#define __S011  PAGE_SHARED_NOEXEC
14602  #define __S100 PAGE_READONLY
14603  #define __S101 PAGE_READONLY
14604  #define __S110 PAGE_SHARED
14605 @@ -324,7 +334,7 @@
14606  ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
14607  
14608  /* to find an entry in a page-table-directory. */
14609 -#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14610 +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14611  
14612  #define __pgd_offset(address) pgd_index(address)
14613  
14614 diff -urN linux-2.4.24.org/include/asm-i386/processor.h linux-2.4.24/include/asm-i386/processor.h
14615 --- linux-2.4.24.org/include/asm-i386/processor.h       2004-01-05 18:39:17.000000000 +0100
14616 +++ linux-2.4.24/include/asm-i386/processor.h   2004-01-05 18:43:05.529905920 +0100
14617 @@ -261,10 +261,19 @@
14618   */
14619  #define TASK_SIZE      (PAGE_OFFSET)
14620  
14621 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14622 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
14623 +#endif
14624 +
14625  /* This decides where the kernel will search for a free chunk of vm
14626   * space during mmap's.
14627   */
14628 +
14629 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14630 +#define TASK_UNMAPPED_BASE     ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3)
14631 +#else
14632  #define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
14633 +#endif
14634  
14635  /*
14636   * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
14637 diff -urN linux-2.4.24.org/include/asm-i386/system.h linux-2.4.24/include/asm-i386/system.h
14638 --- linux-2.4.24.org/include/asm-i386/system.h  2004-01-05 18:39:17.000000000 +0100
14639 +++ linux-2.4.24/include/asm-i386/system.h      2004-01-05 18:57:18.809187752 +0100
14640 @@ -11,6 +11,7 @@
14641  
14642  struct task_struct;    /* one of the stranger aspects of C forward declarations.. */
14643  extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
14644 +void pax_switch_segments(struct task_struct *);
14645  
14646  #define switch_to(prev,next,last) do {                                 \
14647         asm volatile("pushl %%esi\n\t"                                  \
14648 diff -urN linux-2.4.24.org/include/asm-parisc/a.out.h linux-2.4.24/include/asm-parisc/a.out.h
14649 --- linux-2.4.24.org/include/asm-parisc/a.out.h 2004-01-05 18:39:19.000000000 +0100
14650 +++ linux-2.4.24/include/asm-parisc/a.out.h     2004-01-05 18:43:05.566900296 +0100
14651 @@ -22,7 +22,7 @@
14652  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
14653   * prumpf */
14654  
14655 -#define STACK_TOP      TASK_SIZE
14656 +#define __STACK_TOP    TASK_SIZE
14657  
14658  #endif
14659  
14660 diff -urN linux-2.4.24.org/include/asm-parisc/elf.h linux-2.4.24/include/asm-parisc/elf.h
14661 --- linux-2.4.24.org/include/asm-parisc/elf.h   2004-01-05 18:39:19.000000000 +0100
14662 +++ linux-2.4.24/include/asm-parisc/elf.h       2004-01-05 18:43:05.583897712 +0100
14663 @@ -135,6 +135,17 @@
14664  
14665  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
14666  
14667 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14668 +#define PAX_ELF_ET_DYN_BASE(tsk)        0x10000UL
14669 +
14670 +#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
14671 +#define PAX_DELTA_MMAP_LEN(tsk)         16
14672 +#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
14673 +#define PAX_DELTA_EXEC_LEN(tsk)         16
14674 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14675 +#define PAX_DELTA_STACK_LEN(tsk)        16
14676 +#endif
14677 +
14678  /* This yields a mask that user programs can use to figure out what
14679     instruction set this CPU supports.  This could be done in user space,
14680     but it's not easy, and we've already done it here.  */
14681 diff -urN linux-2.4.24.org/include/asm-parisc/mman.h linux-2.4.24/include/asm-parisc/mman.h
14682 --- linux-2.4.24.org/include/asm-parisc/mman.h  2004-01-05 18:39:19.000000000 +0100
14683 +++ linux-2.4.24/include/asm-parisc/mman.h      2004-01-05 18:43:05.585897408 +0100
14684 @@ -18,6 +18,10 @@
14685  #define MAP_NORESERVE  0x4000          /* don't check for reservations */
14686  #define MAP_GROWSDOWN  0x8000          /* stack-like segment */
14687  
14688 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14689 +#define MAP_MIRROR     0x0400
14690 +#endif
14691 +
14692  #define MS_SYNC                1               /* synchronous memory sync */
14693  #define MS_ASYNC       2               /* sync memory asynchronously */
14694  #define MS_INVALIDATE  4               /* invalidate the caches */
14695 diff -urN linux-2.4.24.org/include/asm-parisc/pgtable.h linux-2.4.24/include/asm-parisc/pgtable.h
14696 --- linux-2.4.24.org/include/asm-parisc/pgtable.h       2004-01-05 18:39:19.000000000 +0100
14697 +++ linux-2.4.24/include/asm-parisc/pgtable.h   2004-01-05 18:43:05.589896800 +0100
14698 @@ -167,6 +167,17 @@
14699  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
14700  #define PAGE_COPY       PAGE_EXECREAD
14701  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
14702 +
14703 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14704 +#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
14705 +#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14706 +#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14707 +#else
14708 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14709 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14710 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14711 +#endif
14712 +
14713  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
14714  #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
14715  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
14716 diff -urN linux-2.4.24.org/include/asm-ppc/a.out.h linux-2.4.24/include/asm-ppc/a.out.h
14717 --- linux-2.4.24.org/include/asm-ppc/a.out.h    2004-01-05 18:39:37.000000000 +0100
14718 +++ linux-2.4.24/include/asm-ppc/a.out.h        2004-01-05 18:43:05.607894064 +0100
14719 @@ -2,7 +2,7 @@
14720  #define __PPC_A_OUT_H__
14721  
14722  /* grabbed from the intel stuff  */
14723 -#define STACK_TOP TASK_SIZE
14724 +#define __STACK_TOP TASK_SIZE
14725  
14726  
14727  struct exec
14728 diff -urN linux-2.4.24.org/include/asm-ppc/elf.h linux-2.4.24/include/asm-ppc/elf.h
14729 --- linux-2.4.24.org/include/asm-ppc/elf.h      2004-01-05 18:39:38.000000000 +0100
14730 +++ linux-2.4.24/include/asm-ppc/elf.h  2004-01-05 18:43:05.638889352 +0100
14731 @@ -46,6 +46,17 @@
14732  
14733  #define ELF_ET_DYN_BASE         (0x08000000)
14734  
14735 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14736 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
14737 +
14738 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14739 +#define PAX_DELTA_MMAP_LEN(tsk)                15
14740 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14741 +#define PAX_DELTA_EXEC_LEN(tsk)                15
14742 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
14743 +#define PAX_DELTA_STACK_LEN(tsk)       15
14744 +#endif
14745 +
14746  #define USE_ELF_CORE_DUMP
14747  #define ELF_EXEC_PAGESIZE      4096
14748  
14749 diff -urN linux-2.4.24.org/include/asm-ppc/mman.h linux-2.4.24/include/asm-ppc/mman.h
14750 --- linux-2.4.24.org/include/asm-ppc/mman.h     2004-01-05 18:39:38.000000000 +0100
14751 +++ linux-2.4.24/include/asm-ppc/mman.h 2004-01-05 18:43:05.639889200 +0100
14752 @@ -19,6 +19,10 @@
14753  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14754  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14755  
14756 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14757 +#define MAP_MIRROR     0x0200
14758 +#endif
14759 +
14760  #define MS_ASYNC       1               /* sync memory asynchronously */
14761  #define MS_INVALIDATE  2               /* invalidate the caches */
14762  #define MS_SYNC                4               /* synchronous memory sync */
14763 diff -urN linux-2.4.24.org/include/asm-ppc/pgtable.h linux-2.4.24/include/asm-ppc/pgtable.h
14764 --- linux-2.4.24.org/include/asm-ppc/pgtable.h  2004-01-05 18:39:38.000000000 +0100
14765 +++ linux-2.4.24/include/asm-ppc/pgtable.h      2004-01-05 18:43:05.659886160 +0100
14766 @@ -386,6 +386,16 @@
14767  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
14768  #define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
14769  
14770 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14771 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
14772 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14773 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14774 +#else
14775 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
14776 +# define PAGE_COPY_NOEXEC      PAGE_COPY
14777 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
14778 +#endif
14779 +
14780  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
14781  #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_SHARED)
14782  #define PAGE_KERNEL_CI __pgprot(_PAGE_IO)
14783 @@ -397,21 +407,21 @@
14784   * This is the closest we can get..
14785   */
14786  #define __P000 PAGE_NONE
14787 -#define __P001 PAGE_READONLY_X
14788 -#define __P010 PAGE_COPY
14789 -#define __P011 PAGE_COPY_X
14790 -#define __P100 PAGE_READONLY
14791 +#define __P001 PAGE_READONLY_NOEXEC
14792 +#define __P010 PAGE_COPY_NOEXEC
14793 +#define __P011 PAGE_COPY_NOEXEC
14794 +#define __P100 PAGE_READONLY_X
14795  #define __P101 PAGE_READONLY_X
14796 -#define __P110 PAGE_COPY
14797 +#define __P110 PAGE_COPY_X
14798  #define __P111 PAGE_COPY_X
14799  
14800  #define __S000 PAGE_NONE
14801 -#define __S001 PAGE_READONLY_X
14802 -#define __S010 PAGE_SHARED
14803 -#define __S011 PAGE_SHARED_X
14804 -#define __S100 PAGE_READONLY
14805 +#define __S001 PAGE_READONLY_NOEXEC
14806 +#define __S010 PAGE_SHARED_NOEXEC
14807 +#define __S011 PAGE_SHARED_NOEXEC
14808 +#define __S100 PAGE_READONLY_X
14809  #define __S101 PAGE_READONLY_X
14810 -#define __S110 PAGE_SHARED
14811 +#define __S110 PAGE_SHARED_X
14812  #define __S111 PAGE_SHARED_X
14813  
14814  #ifndef __ASSEMBLY__
14815 diff -urN linux-2.4.24.org/include/asm-sparc/a.out.h linux-2.4.24/include/asm-sparc/a.out.h
14816 --- linux-2.4.24.org/include/asm-sparc/a.out.h  2004-01-05 18:39:46.000000000 +0100
14817 +++ linux-2.4.24/include/asm-sparc/a.out.h      2004-01-05 18:43:05.670884488 +0100
14818 @@ -91,7 +91,7 @@
14819  
14820  #include <asm/page.h>
14821  
14822 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
14823 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
14824  
14825  #endif /* __KERNEL__ */
14826  
14827 diff -urN linux-2.4.24.org/include/asm-sparc/elf.h linux-2.4.24/include/asm-sparc/elf.h
14828 --- linux-2.4.24.org/include/asm-sparc/elf.h    2004-01-05 18:39:47.000000000 +0100
14829 +++ linux-2.4.24/include/asm-sparc/elf.h        2004-01-05 18:43:05.674883880 +0100
14830 @@ -83,6 +83,18 @@
14831  
14832  #define ELF_ET_DYN_BASE         (0x08000000)
14833  
14834 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14835 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
14836 +
14837 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
14838 +#define PAX_DELTA_MMAP_LEN(tsk)                16
14839 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
14840 +#define PAX_DELTA_EXEC_LEN(tsk)                16
14841 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
14842 +#define PAX_DELTA_STACK_LEN(tsk)       16
14843 +#endif
14844 +
14845 +
14846  /* This yields a mask that user programs can use to figure out what
14847     instruction set this cpu supports.  This can NOT be done in userspace
14848     on Sparc.  */
14849 diff -urN linux-2.4.24.org/include/asm-sparc/mman.h linux-2.4.24/include/asm-sparc/mman.h
14850 --- linux-2.4.24.org/include/asm-sparc/mman.h   2004-01-05 18:39:47.000000000 +0100
14851 +++ linux-2.4.24/include/asm-sparc/mman.h       2004-01-05 18:43:05.687881904 +0100
14852 @@ -24,6 +24,10 @@
14853  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14854  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14855  
14856 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14857 +#define MAP_MIRROR     0x0400
14858 +#endif
14859 +
14860  #define MS_ASYNC       1               /* sync memory asynchronously */
14861  #define MS_INVALIDATE  2               /* invalidate the caches */
14862  #define MS_SYNC                4               /* synchronous memory sync */
14863 diff -urN linux-2.4.24.org/include/asm-sparc/pgtable.h linux-2.4.24/include/asm-sparc/pgtable.h
14864 --- linux-2.4.24.org/include/asm-sparc/pgtable.h        2004-01-05 18:39:47.000000000 +0100
14865 +++ linux-2.4.24/include/asm-sparc/pgtable.h    2004-01-05 18:43:05.689881600 +0100
14866 @@ -97,6 +97,13 @@
14867  BTFIXUPDEF_INT(page_shared)
14868  BTFIXUPDEF_INT(page_copy)
14869  BTFIXUPDEF_INT(page_readonly)
14870 +
14871 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14872 +BTFIXUPDEF_INT(page_shared_noexec)
14873 +BTFIXUPDEF_INT(page_copy_noexec)
14874 +BTFIXUPDEF_INT(page_readonly_noexec)
14875 +#endif
14876 +
14877  BTFIXUPDEF_INT(page_kernel)
14878  
14879  #define PMD_SHIFT              BTFIXUP_SIMM13(pmd_shift)
14880 @@ -118,6 +125,16 @@
14881  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
14882  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
14883  
14884 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14885 +#define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
14886 +#define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
14887 +#define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
14888 +#else
14889 +#define PAGE_SHARED_NOEXEC    PAGE_SHARED
14890 +#define PAGE_COPY_NOEXEC      PAGE_COPY
14891 +#define PAGE_READONLY_NOEXEC  PAGE_READONLY
14892 +#endif
14893 +
14894  extern unsigned long page_kernel;
14895  
14896  #ifdef MODULE
14897 diff -urN linux-2.4.24.org/include/asm-sparc/pgtsrmmu.h linux-2.4.24/include/asm-sparc/pgtsrmmu.h
14898 --- linux-2.4.24.org/include/asm-sparc/pgtsrmmu.h       2004-01-05 18:39:47.000000000 +0100
14899 +++ linux-2.4.24/include/asm-sparc/pgtsrmmu.h   2004-01-05 18:43:05.695880688 +0100
14900 @@ -76,6 +76,15 @@
14901                                     SRMMU_EXEC | SRMMU_REF)
14902  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14903                                     SRMMU_EXEC | SRMMU_REF)
14904 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14905 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14906 +                                          SRMMU_WRITE | SRMMU_REF)
14907 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14908 +                                          SRMMU_REF)
14909 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14910 +                                          SRMMU_REF)
14911 +#endif
14912 +
14913  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
14914                                     SRMMU_DIRTY | SRMMU_REF)
14915  
14916 diff -urN linux-2.4.24.org/include/asm-sparc/uaccess.h linux-2.4.24/include/asm-sparc/uaccess.h
14917 --- linux-2.4.24.org/include/asm-sparc/uaccess.h        2004-01-05 18:39:47.000000000 +0100
14918 +++ linux-2.4.24/include/asm-sparc/uaccess.h    2004-01-05 18:43:05.696880536 +0100
14919 @@ -39,7 +39,7 @@
14920   * No one can read/write anything from userland in the kernel space by setting
14921   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
14922   */
14923 -#define __user_ok(addr,size) ((addr) < STACK_TOP)
14924 +#define __user_ok(addr,size) ((addr) < __STACK_TOP)
14925  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
14926  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
14927  #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
14928 diff -urN linux-2.4.24.org/include/asm-sparc64/a.out.h linux-2.4.24/include/asm-sparc64/a.out.h
14929 --- linux-2.4.24.org/include/asm-sparc64/a.out.h        2004-01-05 18:39:41.000000000 +0100
14930 +++ linux-2.4.24/include/asm-sparc64/a.out.h    2004-01-05 18:43:05.709878560 +0100
14931 @@ -95,7 +95,7 @@
14932  
14933  #ifdef __KERNEL__
14934  
14935 -#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14936 +#define __STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14937  
14938  #endif
14939  
14940 diff -urN linux-2.4.24.org/include/asm-sparc64/elf.h linux-2.4.24/include/asm-sparc64/elf.h
14941 --- linux-2.4.24.org/include/asm-sparc64/elf.h  2004-01-05 18:39:41.000000000 +0100
14942 +++ linux-2.4.24/include/asm-sparc64/elf.h      2004-01-05 18:43:05.716877496 +0100
14943 @@ -82,6 +82,17 @@
14944  #define ELF_ET_DYN_BASE         0x0000010000000000UL
14945  #endif
14946  
14947 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14948 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 0x10000UL : 0x100000UL)
14949 +
14950 +#define PAX_DELTA_MMAP_LSB(tsk)         (PAGE_SHIFT + 1)
14951 +#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14952 +#define PAX_DELTA_EXEC_LSB(tsk)         (PAGE_SHIFT + 1)
14953 +#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14954 +#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
14955 +#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 15 : 29 )
14956 +#endif
14957 +
14958  
14959  /* This yields a mask that user programs can use to figure out what
14960     instruction set this cpu supports.  */
14961 diff -urN linux-2.4.24.org/include/asm-sparc64/mman.h linux-2.4.24/include/asm-sparc64/mman.h
14962 --- linux-2.4.24.org/include/asm-sparc64/mman.h 2004-01-05 18:39:41.000000000 +0100
14963 +++ linux-2.4.24/include/asm-sparc64/mman.h     2004-01-05 18:43:05.717877344 +0100
14964 @@ -24,6 +24,10 @@
14965  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
14966  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
14967  
14968 +#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14969 +#define MAP_MIRROR     0x0400
14970 +#endif
14971 +
14972  #define MS_ASYNC       1               /* sync memory asynchronously */
14973  #define MS_INVALIDATE  2               /* invalidate the caches */
14974  #define MS_SYNC                4               /* synchronous memory sync */
14975 diff -urN linux-2.4.24.org/include/asm-sparc64/pgtable.h linux-2.4.24/include/asm-sparc64/pgtable.h
14976 --- linux-2.4.24.org/include/asm-sparc64/pgtable.h      2004-01-05 18:39:41.000000000 +0100
14977 +++ linux-2.4.24/include/asm-sparc64/pgtable.h  2004-01-05 18:43:05.718877192 +0100
14978 @@ -122,7 +122,8 @@
14979  #define _PAGE_G                0x0000000000000001      /* Global                             */
14980  
14981  /* Here are the SpitFire software bits we use in the TTE's. */
14982 -#define _PAGE_MODIFIED 0x0000000000000800      /* Modified Page (ie. dirty)          */
14983 +#define _PAGE_MODIFIED 0x0000000000001000      /* Modified Page (ie. dirty)          */
14984 +#define _PAGE_EXEC     0x0000000000000800      /* Executable SW bit                  */
14985  #define _PAGE_ACCESSED 0x0000000000000400      /* Accessed Page (ie. referenced)     */
14986  #define _PAGE_READ     0x0000000000000200      /* Readable SW Bit                    */
14987  #define _PAGE_WRITE    0x0000000000000100      /* Writable SW Bit                    */
14988 @@ -150,16 +151,30 @@
14989  
14990  /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
14991  #define PAGE_SHARED    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14992 -                                 __ACCESS_BITS | _PAGE_WRITE)
14993 +                                 __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
14994  
14995  #define PAGE_COPY      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14996 -                                 __ACCESS_BITS)
14997 +                                 __ACCESS_BITS | _PAGE_EXEC)
14998  
14999  #define PAGE_READONLY  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15000 -                                 __ACCESS_BITS)
15001 +                                 __ACCESS_BITS | _PAGE_EXEC)
15002  
15003  #define PAGE_KERNEL    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15004 -                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
15005 +                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \
15006 +                                 _PAGE_EXEC)
15007 +
15008 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
15009 +#define PAGE_SHARED_NOEXEC    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15010 +                                       __ACCESS_BITS | _PAGE_WRITE)
15011 +#define PAGE_COPY_NOEXEC      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15012 +                                       __ACCESS_BITS)
15013 +#define PAGE_READONLY_NOEXEC  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
15014 +                                       __ACCESS_BITS)
15015 +#else
15016 +#define PAGE_SHARED_NOEXEC     PAGE_SHARED
15017 +#define PAGE_COPY_NOEXEC       PAGE_COPY
15018 +#define PAGE_READONLY_NOEXEC   PAGE_READONLY
15019 +#endif
15020  
15021  #define PAGE_INVALID   __pgprot (0)
15022  
15023 @@ -170,18 +185,18 @@
15024  #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
15025  
15026  #define __P000 PAGE_NONE
15027 -#define __P001 PAGE_READONLY
15028 -#define __P010 PAGE_COPY
15029 -#define __P011 PAGE_COPY
15030 +#define __P001 PAGE_READONLY_NOEXEC
15031 +#define __P010 PAGE_COPY_NOEXEC
15032 +#define __P011 PAGE_COPY_NOEXEC
15033  #define __P100 PAGE_READONLY
15034  #define __P101 PAGE_READONLY
15035  #define __P110 PAGE_COPY
15036  #define __P111 PAGE_COPY
15037  
15038  #define __S000 PAGE_NONE
15039 -#define __S001 PAGE_READONLY
15040 -#define __S010 PAGE_SHARED
15041 -#define __S011 PAGE_SHARED
15042 +#define __S001 PAGE_READONLY_NOEXEC
15043 +#define __S010 PAGE_SHARED_NOEXEC
15044 +#define __S011 PAGE_SHARED_NOEXEC
15045  #define __S100 PAGE_READONLY
15046  #define __S101 PAGE_READONLY
15047  #define __S110 PAGE_SHARED
15048 diff -urN linux-2.4.24.org/include/linux/a.out.h linux-2.4.24/include/linux/a.out.h
15049 --- linux-2.4.24.org/include/linux/a.out.h      2004-01-05 18:39:25.000000000 +0100
15050 +++ linux-2.4.24/include/linux/a.out.h  2004-01-05 18:43:05.728875672 +0100
15051 @@ -7,6 +7,16 @@
15052  
15053  #include <asm/a.out.h>
15054  
15055 +#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
15056 +#define __DELTA_STACK (current->mm->delta_stack)
15057 +#else
15058 +#define __DELTA_STACK 0UL
15059 +#endif
15060 +
15061 +#ifndef STACK_TOP
15062 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
15063 +#endif
15064 +
15065  #endif /* __STRUCT_EXEC_OVERRIDE__ */
15066  
15067  /* these go in the N_MACHTYPE field */
15068 @@ -37,6 +47,14 @@
15069    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
15070  };
15071  
15072 +/* Constants for the N_FLAGS field */
15073 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
15074 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
15075 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
15076 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */   
15077 +#define F_PAX_RANDEXEC 16      /* Randomize ET_EXEC base */
15078 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
15079 +
15080  #if !defined (N_MAGIC)
15081  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
15082  #endif
15083 diff -urN linux-2.4.24.org/include/linux/binfmts.h linux-2.4.24/include/linux/binfmts.h
15084 --- linux-2.4.24.org/include/linux/binfmts.h    2004-01-05 18:39:25.000000000 +0100
15085 +++ linux-2.4.24/include/linux/binfmts.h        2004-01-05 18:43:05.751872176 +0100
15086 @@ -61,6 +61,8 @@
15087  extern int do_coredump(long signr, struct pt_regs * regs);
15088  extern void set_binfmt(struct linux_binfmt *new);
15089  
15090 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
15091 +void pax_report_insns(void *pc);
15092  
15093  #if 0
15094  /* this went away now */
15095 diff -urN linux-2.4.24.org/include/linux/elf.h linux-2.4.24/include/linux/elf.h
15096 --- linux-2.4.24.org/include/linux/elf.h        2004-01-05 18:39:30.000000000 +0100
15097 +++ linux-2.4.24/include/linux/elf.h    2004-01-05 18:43:05.772868984 +0100
15098 @@ -33,6 +33,10 @@
15099  #define PT_HIPROC  0x7fffffff
15100  #define PT_MIPS_REGINFO                0x70000000
15101  
15102 +#define PT_LOOS                        0x60000000
15103 +#define PT_GNU_STACK           (PT_LOOS + 0x474e551)
15104 +#define PT_GNU_HEAP            (PT_LOOS + 0x474e552)
15105 +
15106  /* Flags in the e_flags field of the header */
15107  #define EF_MIPS_NOREORDER 0x00000001
15108  #define EF_MIPS_PIC       0x00000002
15109 @@ -117,6 +121,8 @@
15110  #define DT_DEBUG       21
15111  #define DT_TEXTREL     22
15112  #define DT_JMPREL      23
15113 +#define DT_FLAGS       30
15114 +#define DF_TEXTREL     0x00000004
15115  #define DT_LOPROC      0x70000000
15116  #define DT_HIPROC      0x7fffffff
15117  #define DT_MIPS_RLD_VERSION    0x70000001
15118 @@ -255,6 +261,13 @@
15119  #define R_MIPS_LOVENDOR                100
15120  #define R_MIPS_HIVENDOR                127
15121  
15122 +/* Constants for the e_flags field */
15123 +#define EF_PAX_PAGEEXEC               1       /* Paging based non-executable pages */
15124 +#define EF_PAX_EMUTRAMP               2       /* Emulate trampolines */
15125 +#define EF_PAX_MPROTECT               4       /* Restrict mprotect() */
15126 +#define EF_PAX_RANDMMAP               8       /* Randomize mmap() base */ 
15127 +#define EF_PAX_RANDEXEC                      16      /* Randomize ET_EXEC base */
15128 +#define EF_PAX_SEGMEXEC                      32      /* Segmentation based non-executable pages */
15129  
15130  /*
15131   * Sparc ELF relocation types
15132 @@ -550,6 +563,8 @@
15133  #define        EI_VERSION      6
15134  #define        EI_PAD          7
15135  
15136 +#define EI_PAX         14
15137 +
15138  #define        ELFMAG0         0x7f            /* EI_MAG */
15139  #define        ELFMAG1         'E'
15140  #define        ELFMAG2         'L'
15141 @@ -597,6 +612,7 @@
15142  #define elfhdr         elf32_hdr
15143  #define elf_phdr       elf32_phdr
15144  #define elf_note       elf32_note
15145 +#define elf_dyn                Elf32_Dyn
15146  
15147  #else
15148  
15149 @@ -604,6 +620,7 @@
15150  #define elfhdr         elf64_hdr
15151  #define elf_phdr       elf64_phdr
15152  #define elf_note       elf64_note
15153 +#define elf_dyn                Elf64_Dyn
15154  
15155  #endif
15156  
15157 diff -urN linux-2.4.24.org/include/linux/fs.h linux-2.4.24/include/linux/fs.h
15158 --- linux-2.4.24.org/include/linux/fs.h 2004-01-05 18:39:26.000000000 +0100
15159 +++ linux-2.4.24/include/linux/fs.h     2004-01-05 18:43:05.802864424 +0100
15160 @@ -1167,7 +1167,7 @@
15161  
15162  asmlinkage long sys_open(const char *, int, int);
15163  asmlinkage long sys_close(unsigned int);       /* yes, it's really unsigned */
15164 -extern int do_truncate(struct dentry *, loff_t start);
15165 +extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
15166  
15167  extern struct file *filp_open(const char *, int, int);
15168  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
15169 diff -urN linux-2.4.24.org/include/linux/gracl.h linux-2.4.24/include/linux/gracl.h
15170 --- linux-2.4.24.org/include/linux/gracl.h      1970-01-01 01:00:00.000000000 +0100
15171 +++ linux-2.4.24/include/linux/gracl.h  2004-01-05 18:43:05.821861536 +0100
15172 @@ -0,0 +1,212 @@
15173 +#ifndef GR_ACL_H
15174 +#define GR_ACL_H
15175 +#endif
15176 +#include <linux/grdefs.h>
15177 +#include <linux/resource.h>
15178 +
15179 +#include <asm/resource.h>
15180 +
15181 +/* * * * * * * * * * * * * * * * * * * * *
15182 + * grsecurity ACL System
15183 + * Main header file
15184 + * Purpose: define most gracl data structures 
15185 + * * * * * * * * * * * * * * * * * * * * */
15186 +
15187 +/* Major status information */
15188 +
15189 +#define GR_VERSION  "grsecurity 2.0-rc4"
15190 +
15191 +enum {
15192 +
15193 +       SHUTDOWN = 0,
15194 +       ENABLE = 1,
15195 +       SPROLE = 2,
15196 +       RELOAD = 3,
15197 +       SEGVMOD = 4,
15198 +       STATUS = 5,
15199 +       UNSPROLE = 6
15200 +};
15201 +
15202 +/* Password setup definitions
15203 + * kernel/grhash.c */
15204 +enum {
15205 +       GR_PW_LEN = 128,
15206 +       GR_SALT_LEN = 16,
15207 +       GR_SHA_LEN = 32,
15208 +};
15209 +
15210 +enum {
15211 +       GR_SPROLE_LEN = 64,
15212 +};
15213 +
15214 +/* Begin Data Structures */
15215 +
15216 +struct sprole_pw {
15217 +       unsigned char *rolename;
15218 +       unsigned char salt[GR_SALT_LEN];
15219 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
15220 +};
15221 +
15222 +struct name_entry {
15223 +       ino_t inode;
15224 +       kdev_t device;
15225 +       char *name;
15226 +       __u16 len;
15227 +};
15228 +
15229 +struct acl_role_db {
15230 +       struct acl_role_label **r_hash;
15231 +       __u32 r_size;
15232 +};
15233 +
15234 +struct name_db {
15235 +       struct name_entry **n_hash;
15236 +       __u32 n_size;
15237 +};
15238 +
15239 +struct crash_uid {
15240 +       uid_t uid;
15241 +       unsigned long expires;
15242 +};
15243 +
15244 +/* Userspace Grsecurity ACL data structures */
15245 +struct acl_subject_label {
15246 +       char *filename;
15247 +       ino_t inode;
15248 +       kdev_t device;
15249 +       __u32 mode;
15250 +       __u32 cap_raise;
15251 +       __u32 cap_lower;
15252 +
15253 +       struct rlimit res[RLIM_NLIMITS + 1];
15254 +       __u16 resmask;
15255 +
15256 +       __u32 ip_proto[8];
15257 +       __u32 ip_type;
15258 +       struct acl_ip_label **ips;
15259 +       __u32 ip_num;
15260 +
15261 +       __u32 crashes;
15262 +       unsigned long expires;
15263 +
15264 +       struct acl_subject_label *parent_subject;
15265 +       struct acl_object_label *proc_object;
15266 +       struct acl_ip_label *ip_object;
15267 +       struct acl_subject_label *prev;
15268 +       struct acl_subject_label *next;
15269 +
15270 +       struct acl_object_label **obj_hash;
15271 +       __u32 obj_hash_size;
15272 +};
15273 +
15274 +struct role_allowed_ip {
15275 +       __u32 addr;
15276 +       __u32 netmask;
15277 +
15278 +       struct role_allowed_ip *prev;
15279 +       struct role_allowed_ip *next;
15280 +};
15281 +
15282 +struct role_transition {
15283 +       char *rolename;
15284 +
15285 +       struct role_transition *prev;
15286 +       struct role_transition *next;
15287 +};
15288 +
15289 +struct acl_role_label {
15290 +       char *rolename;
15291 +       uid_t uidgid;
15292 +       __u16 roletype;
15293 +
15294 +       __u16 auth_attempts;
15295 +       unsigned long expires;
15296 +
15297 +       struct acl_subject_label *root_label;
15298 +       struct acl_subject_label *proc_subject;
15299 +
15300 +       struct acl_role_label *prev;
15301 +       struct acl_role_label *next;
15302 +
15303 +       struct role_transition *transitions;
15304 +       struct role_allowed_ip *allowed_ips;
15305 +       struct acl_subject_label **subj_hash;
15306 +       __u32 subj_hash_size;
15307 +};
15308 +
15309 +struct user_acl_role_db {
15310 +       struct acl_role_label **r_table;
15311 +       __u32 r_entries;        /* number of entries in table */
15312 +       __u32 s_entries;        /* total number of subject acls */
15313 +       __u32 i_entries;        /* total number of ip acls */
15314 +       __u32 o_entries;        /* Total number of object acls */
15315 +       __u32 a_entries;        /* total number of allowed ips */
15316 +       __u32 t_entries;        /* total number of transitions */
15317 +};
15318 +
15319 +struct acl_object_label {
15320 +       char *filename;
15321 +       ino_t inode;
15322 +       kdev_t device;
15323 +       __u32 mode;
15324 +
15325 +       struct acl_subject_label *nested;
15326 +
15327 +       /* next two structures not used */
15328 +
15329 +       struct acl_object_label *prev;
15330 +       struct acl_object_label *next;
15331 +};
15332 +
15333 +struct acl_ip_label {
15334 +       __u32 addr;
15335 +       __u32 netmask;
15336 +       __u16 low, high;
15337 +       __u8 mode;
15338 +       __u32 type;
15339 +       __u32 proto[8];
15340 +
15341 +       /* next two structures not used */
15342 +
15343 +       struct acl_ip_label *prev;
15344 +       struct acl_ip_label *next;
15345 +};
15346 +
15347 +struct gr_arg {
15348 +       struct user_acl_role_db role_db;
15349 +       unsigned char pw[GR_PW_LEN];
15350 +       unsigned char salt[GR_SALT_LEN];
15351 +       unsigned char sum[GR_SHA_LEN];
15352 +       unsigned char sp_role[GR_SPROLE_LEN];
15353 +       struct sprole_pw *sprole_pws;
15354 +       __u16 num_sprole_pws;
15355 +       kdev_t segv_device;
15356 +       ino_t segv_inode;
15357 +       uid_t segv_uid;
15358 +       __u16 mode;
15359 +};
15360 +
15361 +/* End Data Structures Section */
15362 +
15363 +/* Hash functions generated by empirical testing by Brad Spengler
15364 +   Makes good use of the low bits of the inode.  Generally 0-1 times
15365 +   in loop for successful match.  0-3 for unsuccessful match.
15366 +   Shift/add algorithm with modulus of table size and an XOR*/
15367 +
15368 +static __inline__ unsigned long
15369 +rhash(const uid_t uid, const __u16 type, const unsigned long sz)
15370 +{
15371 +       return (((uid << type) + (uid ^ type)) % sz);
15372 +}
15373 +
15374 +static __inline__ unsigned long
15375 +fhash(const ino_t ino, const kdev_t dev, const unsigned long sz)
15376 +{
15377 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
15378 +}
15379 +
15380 +static __inline__ unsigned long
15381 +nhash(const char *name, const __u16 len, const unsigned long sz)
15382 +{
15383 +       return full_name_hash(name, len) % sz;
15384 +}
15385 diff -urN linux-2.4.24.org/include/linux/gralloc.h linux-2.4.24/include/linux/gralloc.h
15386 --- linux-2.4.24.org/include/linux/gralloc.h    1970-01-01 01:00:00.000000000 +0100
15387 +++ linux-2.4.24/include/linux/gralloc.h        2004-01-05 18:43:05.821861536 +0100
15388 @@ -0,0 +1,8 @@
15389 +#ifndef __GRALLOC_H
15390 +#define __GRALLOC_H
15391 +
15392 +void acl_free_all(void);
15393 +int acl_alloc_stack_init(unsigned long size);
15394 +void *acl_alloc(unsigned long len);
15395 +
15396 +#endif
15397 diff -urN linux-2.4.24.org/include/linux/grdefs.h linux-2.4.24/include/linux/grdefs.h
15398 --- linux-2.4.24.org/include/linux/grdefs.h     1970-01-01 01:00:00.000000000 +0100
15399 +++ linux-2.4.24/include/linux/grdefs.h 2004-01-05 18:43:05.822861384 +0100
15400 @@ -0,0 +1,103 @@
15401 +#ifndef GRDEFS_H
15402 +#define GRDEFS_H
15403 +
15404 +/* Begin grsecurity status declarations */
15405 +
15406 +enum {
15407 +       GR_READY = 0x01,
15408 +       GR_STATUS_INIT = 0x00   // disabled state
15409 +};
15410 +
15411 +/* Begin  ACL declarations */
15412 +
15413 +/* Role flags */
15414 +
15415 +enum {
15416 +       GR_ROLE_USER = 0x0001,
15417 +       GR_ROLE_GROUP = 0x0002,
15418 +       GR_ROLE_DEFAULT = 0x0004,
15419 +       GR_ROLE_SPECIAL = 0x0008,
15420 +       GR_ROLE_AUTH = 0x0010,
15421 +       GR_ROLE_NOPW = 0x0020,
15422 +       GR_ROLE_GOD = 0x0040,
15423 +       GR_ROLE_LEARN = 0x0080,
15424 +       GR_ROLE_TPE = 0x0100
15425 +};
15426 +
15427 +/* ACL Subject and Object mode flags */
15428 +enum {
15429 +       GR_DELETED = 0x00000080
15430 +};
15431 +
15432 +/* ACL Object-only mode flags */
15433 +enum {
15434 +       GR_READ         = 0x00000001,
15435 +       GR_APPEND       = 0x00000002,
15436 +       GR_WRITE        = 0x00000004,
15437 +       GR_EXEC         = 0x00000008,
15438 +       GR_FIND         = 0x00000010,
15439 +       GR_INHERIT      = 0x00000040,
15440 +       GR_PTRACERD     = 0x00000100,
15441 +       GR_SETID        = 0x00000200,
15442 +       GR_CREATE       = 0x00000400,
15443 +       GR_DELETE       = 0x00000800,
15444 +       GR_AUDIT_READ   = 0x00001000,
15445 +       GR_AUDIT_APPEND = 0x00002000,
15446 +       GR_AUDIT_WRITE  = 0x00004000,
15447 +       GR_AUDIT_EXEC   = 0x00008000,
15448 +       GR_AUDIT_FIND   = 0x00010000,
15449 +       GR_AUDIT_INHERIT= 0x00020000,
15450 +       GR_AUDIT_SETID  = 0x00040000,
15451 +       GR_AUDIT_CREATE = 0x00080000,
15452 +       GR_AUDIT_DELETE = 0x00100000,
15453 +       GR_SUPPRESS     = 0x00200000,
15454 +       GR_NOLEARN      = 0x00400000
15455 +};
15456 +
15457 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
15458 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
15459 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE)
15460 +
15461 +/* ACL subject-only mode flags */
15462 +enum {
15463 +       GR_KILL         = 0x00000001,
15464 +       GR_VIEW         = 0x00000002,
15465 +       GR_PROTECTED    = 0x00000100,
15466 +       GR_LEARN        = 0x00000200,
15467 +       GR_OVERRIDE     = 0x00000400,
15468 +       /* just a placeholder, this mode is only used in userspace */
15469 +       GR_DUMMY        = 0x00000800,
15470 +       GR_PAXPAGE      = 0x00001000,
15471 +       GR_PAXSEGM      = 0x00002000,
15472 +       GR_PAXGCC       = 0x00004000,
15473 +       GR_PAXRANDMMAP  = 0x00008000,
15474 +       GR_PAXRANDEXEC  = 0x00010000,
15475 +       GR_PAXMPROTECT  = 0x00020000,
15476 +       GR_PROTSHM      = 0x00040000,
15477 +       GR_KILLPROC     = 0x00080000,
15478 +       GR_KILLIPPROC   = 0x00100000,
15479 +       /* just a placeholder, this mode is only used in userspace */
15480 +       GR_NOTROJAN     = 0x00200000,
15481 +       GR_PROTPROCFD   = 0x00400000,
15482 +       GR_PROCACCT     = 0x00800000
15483 +};
15484 +
15485 +#define GR_CRASH_RES   11
15486 +#define GR_UIDTABLE_MAX 500
15487 +
15488 +/* begin resource learning section */
15489 +enum {
15490 +       GR_RLIM_CPU_BUMP = 60,
15491 +       GR_RLIM_FSIZE_BUMP = 50000,
15492 +       GR_RLIM_DATA_BUMP = 10000,
15493 +       GR_RLIM_STACK_BUMP = 1000,
15494 +       GR_RLIM_CORE_BUMP = 10000,
15495 +       GR_RLIM_RSS_BUMP = 500000,
15496 +       GR_RLIM_NPROC_BUMP = 1,
15497 +       GR_RLIM_NOFILE_BUMP = 5,
15498 +       GR_RLIM_MEMLOCK_BUMP = 50000,
15499 +       GR_RLIM_AS_BUMP = 500000,
15500 +       GR_RLIM_LOCKS_BUMP = 2
15501 +};
15502 +
15503 +#endif
15504 diff -urN linux-2.4.24.org/include/linux/grinternal.h linux-2.4.24/include/linux/grinternal.h
15505 --- linux-2.4.24.org/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100
15506 +++ linux-2.4.24/include/linux/grinternal.h     2004-01-05 18:43:05.823861232 +0100
15507 @@ -0,0 +1,200 @@
15508 +#ifndef __GRINTERNAL_H
15509 +#define __GRINTERNAL_H
15510 +
15511 +#ifdef CONFIG_GRKERNSEC
15512 +
15513 +#include <linux/grdefs.h>
15514 +#include <linux/grmsg.h>
15515 +
15516 +extern void gr_add_learn_entry(const char *fmt, ...);
15517 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
15518 +                           const struct vfsmount *mnt);
15519 +extern __u32 gr_check_create(const struct dentry *new_dentry,
15520 +                            const struct dentry *parent,
15521 +                            const struct vfsmount *mnt, const __u32 mode);
15522 +extern int gr_check_protected_task(const struct task_struct *task);
15523 +extern __inline__ __u32 to_gr_audit(const __u32 reqmode);
15524 +extern int gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
15525 +                           struct dentry *old_dentry,
15526 +                           struct dentry *new_dentry,
15527 +                           struct vfsmount *mnt, const __u8 replace);
15528 +extern int gr_set_acls(const int type);
15529 +
15530 +extern void gr_handle_alertkill(void);
15531 +extern char *gr_to_filename(const struct dentry *dentry,
15532 +                           const struct vfsmount *mnt);
15533 +extern char *gr_to_filename1(const struct dentry *dentry,
15534 +                           const struct vfsmount *mnt);
15535 +extern char *gr_to_filename2(const struct dentry *dentry,
15536 +                           const struct vfsmount *mnt);
15537 +extern char *gr_to_filename3(const struct dentry *dentry,
15538 +                           const struct vfsmount *mnt);
15539 +
15540 +extern int grsec_enable_link;
15541 +extern int grsec_enable_fifo;
15542 +extern int grsec_enable_execve;
15543 +extern int grsec_enable_forkbomb;
15544 +extern int grsec_forkbomb_gid;
15545 +extern int grsec_forkbomb_sec;
15546 +extern int grsec_forkbomb_max;
15547 +extern int grsec_enable_execlog;
15548 +extern int grsec_enable_signal;
15549 +extern int grsec_enable_forkfail;
15550 +extern int grsec_enable_time;
15551 +extern int grsec_enable_chroot_shmat;
15552 +extern int grsec_enable_chroot_findtask;
15553 +extern int grsec_enable_chroot_mount;
15554 +extern int grsec_enable_chroot_double;
15555 +extern int grsec_enable_chroot_pivot;
15556 +extern int grsec_enable_chroot_chdir;
15557 +extern int grsec_enable_chroot_chmod;
15558 +extern int grsec_enable_chroot_mknod;
15559 +extern int grsec_enable_chroot_fchdir;
15560 +extern int grsec_enable_chroot_nice;
15561 +extern int grsec_enable_chroot_execlog;
15562 +extern int grsec_enable_chroot_caps;
15563 +extern int grsec_enable_chroot_sysctl;
15564 +extern int grsec_enable_chroot_unix;
15565 +extern int grsec_enable_tpe;
15566 +extern int grsec_tpe_gid;
15567 +extern int grsec_enable_tpe_all;
15568 +extern int grsec_enable_randpid;
15569 +extern int grsec_enable_socket_all;
15570 +extern int grsec_socket_all_gid;
15571 +extern int grsec_enable_socket_client;
15572 +extern int grsec_socket_client_gid;
15573 +extern int grsec_enable_socket_server;
15574 +extern int grsec_socket_server_gid;
15575 +extern int grsec_audit_gid;
15576 +extern int grsec_enable_group;
15577 +extern int grsec_enable_audit_ipc;
15578 +extern int grsec_enable_mount;
15579 +extern int grsec_enable_chdir;
15580 +extern int grsec_lock;
15581 +
15582 +extern struct task_struct *child_reaper;
15583 +
15584 +extern spinlock_t grsec_alert_lock;
15585 +extern unsigned long grsec_alert_wtime;
15586 +extern unsigned long grsec_alert_fyet;
15587 +
15588 +extern spinlock_t grsec_alertgood_lock;
15589 +extern unsigned long grsec_alertgood_wtime;
15590 +extern unsigned long grsec_alertgood_fyet;
15591 +
15592 +extern spinlock_t grsec_audit_lock;
15593 +
15594 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
15595 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
15596 +                       tsk->exec_file->f_vfsmnt) : "/")
15597 +
15598 +#define gr_parent_task_fullpath(tsk) (tsk->p_pptr->exec_file ? \
15599 +                       gr_to_filename3(tsk->p_pptr->exec_file->f_dentry, \
15600 +                       tsk->p_pptr->exec_file->f_vfsmnt) : "/")
15601 +
15602 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
15603 +                       gr_to_filename(tsk->exec_file->f_dentry, \
15604 +                       tsk->exec_file->f_vfsmnt) : "/")
15605 +
15606 +#define gr_parent_task_fullpath0(tsk) (tsk->p_pptr->exec_file ? \
15607 +                       gr_to_filename1(tsk->p_pptr->exec_file->f_dentry, \
15608 +                       tsk->p_pptr->exec_file->f_vfsmnt) : "/")
15609 +
15610 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && \
15611 +                         ((tsk_a->fs->root->d_inode->i_dev != \
15612 +                         child_reaper->fs->root->d_inode->i_dev) || \
15613 +                         (tsk_a->fs->root->d_inode->i_ino != \
15614 +                         child_reaper->fs->root->d_inode->i_ino)))
15615 +
15616 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_dev == \
15617 +                         tsk_b->fs->root->d_inode->i_dev) && \
15618 +                         (tsk_a->fs->root->d_inode->i_ino == \
15619 +                         tsk_b->fs->root->d_inode->i_ino))
15620 +
15621 +#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
15622 +                      current->pid, current->uid, \
15623 +                      current->euid, current->gid, current->egid, \
15624 +                      gr_parent_task_fullpath(current), \
15625 +                      current->p_pptr->comm, current->p_pptr->pid, \
15626 +                      current->p_pptr->uid, current->p_pptr->euid, \
15627 +                      current->p_pptr->gid, current->p_pptr->egid
15628 +
15629 +#define GR_CHROOT_CAPS ( \
15630 +       CAP_TO_MASK(CAP_FOWNER) | \
15631 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
15632 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
15633 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
15634 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
15635 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
15636 +       CAP_TO_MASK(CAP_IPC_OWNER))
15637 +
15638 +#define security_alert_good(normal_msg,args...) \
15639 +({ \
15640 +       spin_lock(&grsec_alertgood_lock); \
15641 +       \
15642 +       if (!grsec_alertgood_wtime || jiffies - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15643 +           grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet = 0; \
15644 +           if (current->curr_ip) \
15645 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15646 +           else \
15647 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15648 +       } else if((jiffies - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15649 +           grsec_alertgood_fyet++; \
15650 +           if (current->curr_ip) \
15651 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15652 +           else \
15653 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15654 +       } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15655 +           grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet++; \
15656 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15657 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15658 +       } \
15659 +       \
15660 +       spin_unlock(&grsec_alertgood_lock); \
15661 +})
15662 +
15663 +#define security_alert(normal_msg,args...) \
15664 +({ \
15665 +       spin_lock(&grsec_alert_lock); \
15666 +       \
15667 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15668 +           grsec_alert_wtime = jiffies; grsec_alert_fyet = 0; \
15669 +           if (current->curr_ip) \
15670 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15671 +           else \
15672 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15673 +       } else if((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15674 +           grsec_alert_fyet++; \
15675 +           if (current->curr_ip) \
15676 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15677 +           else \
15678 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15679 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15680 +           grsec_alert_wtime = jiffies; grsec_alert_fyet++; \
15681 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15682 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15683 +       } \
15684 +       \
15685 +       gr_handle_alertkill(); \
15686 +       spin_unlock(&grsec_alert_lock); \
15687 +})
15688 +
15689 +#define security_audit(normal_msg,args...) \
15690 +({ \
15691 +       spin_lock(&grsec_audit_lock); \
15692 +       if (current->curr_ip) \
15693 +               printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
15694 +                      NIPQUAD(current->curr_ip) , ## args); \
15695 +       else \
15696 +               printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
15697 +       spin_unlock(&grsec_audit_lock); \
15698 +})
15699 +
15700 +#define security_learn(normal_msg,args...) \
15701 +({ \
15702 +       gr_add_learn_entry(normal_msg "\n", ## args); \
15703 +})
15704 +
15705 +#endif
15706 +
15707 +#endif
15708 diff -urN linux-2.4.24.org/include/linux/grmsg.h linux-2.4.24/include/linux/grmsg.h
15709 --- linux-2.4.24.org/include/linux/grmsg.h      1970-01-01 01:00:00.000000000 +0100
15710 +++ linux-2.4.24/include/linux/grmsg.h  2004-01-05 18:43:05.824861080 +0100
15711 @@ -0,0 +1,105 @@
15712 +#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"
15713 +#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"
15714 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
15715 +#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
15716 +#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
15717 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
15718 +#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
15719 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
15720 +#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
15721 +#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
15722 +#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
15723 +#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
15724 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
15725 +#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"
15726 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
15727 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
15728 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
15729 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
15730 +#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
15731 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
15732 +#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
15733 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
15734 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
15735 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
15736 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
15737 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
15738 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
15739 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
15740 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
15741 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
15742 +#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
15743 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
15744 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
15745 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
15746 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution of [%.16s:%lu] for %lu seconds"
15747 +#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
15748 +#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
15749 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
15750 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
15751 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
15752 +#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
15753 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
15754 +#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
15755 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
15756 +#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
15757 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
15758 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
15759 +#define GR_INITF_ACL_MSG "init_variables() failed %s"
15760 +#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"
15761 +#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
15762 +#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
15763 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
15764 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
15765 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
15766 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
15767 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
15768 +#define GR_ENABLE_ACL_MSG "Loaded %s"
15769 +#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
15770 +#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
15771 +#define GR_RELOAD_ACL_MSG "Reloaded %s"
15772 +#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
15773 +#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
15774 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
15775 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
15776 +#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
15777 +#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
15778 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
15779 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
15780 +#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
15781 +#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
15782 +#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
15783 +#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
15784 +#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
15785 +#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
15786 +#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
15787 +#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
15788 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
15789 +#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
15790 +#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
15791 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
15792 +#define GR_TIME_MSG "time set by " DEFAULTSECMSG
15793 +#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
15794 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
15795 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
15796 +#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG
15797 +#define GR_SOCK2_MSG "attempted socket(%d,%.16s,%.16s) by " DEFAULTSECMSG
15798 +#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
15799 +#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
15800 +#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15801 +#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15802 +#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"
15803 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
15804 +#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
15805 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
15806 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
15807 +#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
15808 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
15809 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
15810 +#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
15811 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
15812 +#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
15813 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
15814 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
15815 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
15816 +#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
15817 diff -urN linux-2.4.24.org/include/linux/grsecurity.h linux-2.4.24/include/linux/grsecurity.h
15818 --- linux-2.4.24.org/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100
15819 +++ linux-2.4.24/include/linux/grsecurity.h     2004-01-05 18:43:05.824861080 +0100
15820 @@ -0,0 +1,177 @@
15821 +#ifndef GR_SECURITY_H
15822 +#define GR_SECURITY_H
15823 +
15824 +extern void gr_add_to_task_ip_table(struct task_struct *p);
15825 +extern void gr_del_task_from_ip_table(struct task_struct *p);
15826 +
15827 +extern int gr_pid_is_chrooted(const struct task_struct *p);
15828 +extern int gr_handle_chroot_nice(void);
15829 +extern int gr_handle_chroot_sysctl(const int op);
15830 +extern int gr_handle_chroot_capset(const struct task_struct *target);
15831 +extern int gr_handle_chroot_setpriority(const struct task_struct *p,
15832 +                                       const int niceval);
15833 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
15834 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
15835 +                                  const struct vfsmount *mnt);
15836 +extern void gr_handle_chroot_caps(struct task_struct *task);
15837 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
15838 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
15839 +                                 const struct vfsmount *mnt, const int mode);
15840 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
15841 +                                 const struct vfsmount *mnt, const int mode);
15842 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
15843 +                                 const struct vfsmount *mnt,
15844 +                                 const char *dev_name);
15845 +extern int gr_handle_chroot_pivot(void);
15846 +extern int gr_handle_chroot_unix(const pid_t pid);
15847 +
15848 +extern int gr_handle_rawio(const struct inode *inode);
15849 +extern int gr_handle_nproc(void);
15850 +
15851 +extern void gr_handle_ioperm(void);
15852 +extern void gr_handle_iopl(void);
15853 +
15854 +extern int gr_tpe_allow(const struct file *file);
15855 +
15856 +extern int gr_random_pid(spinlock_t * pid_lock);
15857 +
15858 +extern void gr_log_forkfail(const int retval);
15859 +extern void gr_log_timechange(void);
15860 +extern void gr_log_signal(const int sig, const struct task_struct *t);
15861 +extern void gr_log_chdir(const struct dentry *dentry,
15862 +                        const struct vfsmount *mnt);
15863 +extern void gr_log_chroot_exec(const struct dentry *dentry,
15864 +                              const struct vfsmount *mnt);
15865 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
15866 +extern void gr_log_remount(const char *devname, const int retval);
15867 +extern void gr_log_unmount(const char *devname, const int retval);
15868 +extern void gr_log_mount(const char *from, const char *to, const int retval);
15869 +extern void gr_log_msgget(const int ret, const int msgflg);
15870 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
15871 +extern void gr_log_semget(const int err, const int semflg);
15872 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
15873 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
15874 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
15875 +
15876 +extern int gr_handle_follow_link(const struct inode *parent,
15877 +                                const struct inode *inode,
15878 +                                const struct dentry *dentry,
15879 +                                const struct vfsmount *mnt);
15880 +extern int gr_handle_fifo(const struct dentry *dentry,
15881 +                         const struct vfsmount *mnt,
15882 +                         const struct dentry *dir, const int flag,
15883 +                         const int acc_mode);
15884 +extern int gr_handle_hardlink(const struct dentry *dentry,
15885 +                             const struct vfsmount *mnt,
15886 +                             struct inode *inode,
15887 +                             const int mode, const char *to);
15888 +
15889 +extern int gr_is_capable(const int cap);
15890 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
15891 +                             const unsigned long wanted, const int gt);
15892 +extern void gr_copy_label(struct task_struct *tsk);
15893 +extern void gr_handle_crash(struct task_struct *task, const int sig);
15894 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
15895 +extern int gr_check_crash_uid(const uid_t uid);
15896 +extern int gr_check_protected_task(const struct task_struct *task);
15897 +extern int gr_acl_handle_mmap(const struct file *file,
15898 +                             const unsigned long prot);
15899 +extern int gr_acl_handle_mprotect(const struct file *file,
15900 +                                 const unsigned long prot);
15901 +extern int gr_check_hidden_task(const struct task_struct *tsk);
15902 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
15903 +                                   const struct vfsmount *mnt);
15904 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
15905 +                                const struct vfsmount *mnt);
15906 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
15907 +                                 const struct vfsmount *mnt, const int fmode);
15908 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
15909 +                                 const struct vfsmount *mnt, mode_t mode);
15910 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
15911 +                                const struct vfsmount *mnt, mode_t mode);
15912 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
15913 +                                const struct vfsmount *mnt);
15914 +extern int gr_handle_ptrace_exec(const struct dentry *dentry,
15915 +                                const struct vfsmount *mnt);
15916 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
15917 +extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
15918 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
15919 +                                 const struct vfsmount *mnt);
15920 +extern int gr_check_crash_exec(const struct file *filp);
15921 +extern int gr_acl_is_enabled(void);
15922 +extern void gr_set_kernel_label(struct task_struct *task);
15923 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
15924 +                             const gid_t gid);
15925 +extern void gr_set_proc_label(const struct dentry *dentry,
15926 +                             const struct vfsmount *mnt);
15927 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
15928 +                                      const struct vfsmount *mnt);
15929 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
15930 +                               const struct vfsmount *mnt, const int fmode);
15931 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
15932 +                                const struct dentry *p_dentry,
15933 +                                const struct vfsmount *p_mnt, const int fmode,
15934 +                                const int imode);
15935 +extern void gr_handle_create(const struct dentry *dentry,
15936 +                            const struct vfsmount *mnt);
15937 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
15938 +                                const struct dentry *parent_dentry,
15939 +                                const struct vfsmount *parent_mnt,
15940 +                                const int mode);
15941 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
15942 +                                const struct dentry *parent_dentry,
15943 +                                const struct vfsmount *parent_mnt);
15944 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
15945 +                                const struct vfsmount *mnt);
15946 +extern void gr_handle_delete(const ino_t ino, const kdev_t dev);
15947 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
15948 +                                 const struct vfsmount *mnt);
15949 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
15950 +                                  const struct dentry *parent_dentry,
15951 +                                  const struct vfsmount *parent_mnt,
15952 +                                  const char *from);
15953 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
15954 +                               const struct dentry *parent_dentry,
15955 +                               const struct vfsmount *parent_mnt,
15956 +                               const struct dentry *old_dentry,
15957 +                               const struct vfsmount *old_mnt, const char *to);
15958 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
15959 +                               struct dentry *parent_dentry,
15960 +                               const struct vfsmount *parent_mnt,
15961 +                               struct dentry *old_dentry,
15962 +                               struct inode *old_parent_inode,
15963 +                               struct vfsmount *old_mnt, const char *newname);
15964 +extern __u32 gr_check_link(const struct dentry *new_dentry,
15965 +                          const struct dentry *parent_dentry,
15966 +                          const struct vfsmount *parent_mnt,
15967 +                          const struct dentry *old_dentry,
15968 +                          const struct vfsmount *old_mnt);
15969 +extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
15970 +                                  const struct vfsmount *mnt, const ino_t ino);
15971 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
15972 +                               const struct vfsmount *mnt);
15973 +extern void gr_set_pax_flags(struct task_struct *task);
15974 +extern void gr_acl_handle_exit(void);
15975 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
15976 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
15977 +extern __u32 gr_cap_rtnetlink(void);
15978 +
15979 +#ifdef CONFIG_GRKERNSEC
15980 +extern void gr_handle_mem_write(void);
15981 +extern void gr_handle_kmem_write(void);
15982 +extern void gr_handle_open_port(void);
15983 +extern int gr_handle_mem_mmap(const unsigned long offset,
15984 +                             struct vm_area_struct *vma);
15985 +
15986 +extern __u16 ip_randomid(void);
15987 +extern __u32 ip_randomisn(void);
15988 +extern unsigned long get_random_long(void);
15989 +
15990 +extern int grsec_enable_dmesg;
15991 +extern int grsec_enable_randid;
15992 +extern int grsec_enable_randisn;
15993 +extern int grsec_enable_randsrc;
15994 +extern int grsec_enable_randrpc;
15995 +#endif
15996 +
15997 +#endif
15998 diff -urN linux-2.4.24.org/include/linux/kernel.h linux-2.4.24/include/linux/kernel.h
15999 --- linux-2.4.24.org/include/linux/kernel.h     2004-01-05 18:39:28.000000000 +0100
16000 +++ linux-2.4.24/include/linux/kernel.h 2004-01-05 18:43:05.833859712 +0100
16001 @@ -71,14 +71,17 @@
16002  extern long long simple_strtoll(const char *,char **,unsigned int);
16003  extern int sprintf(char * buf, const char * fmt, ...)
16004         __attribute__ ((format (printf, 2, 3)));
16005 -extern int vsprintf(char *buf, const char *, va_list);
16006 +extern int vsprintf(char *buf, const char *, va_list)
16007 +       __attribute__ ((format (printf, 2, 0)));
16008  extern int snprintf(char * buf, size_t size, const char * fmt, ...)
16009         __attribute__ ((format (printf, 3, 4)));
16010 -extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
16011 +extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
16012 +       __attribute__ ((format (printf, 3, 0)));
16013  
16014  extern int sscanf(const char *, const char *, ...)
16015         __attribute__ ((format (scanf,2,3)));
16016 -extern int vsscanf(const char *, const char *, va_list);
16017 +extern int vsscanf(const char *, const char *, va_list)
16018 +       __attribute__ ((format (scanf, 2, 0)));
16019  
16020  extern void qsort(void *, size_t, size_t, int (*)(const void *,const void *));
16021  
16022 diff -urN linux-2.4.24.org/include/linux/mm.h linux-2.4.24/include/linux/mm.h
16023 --- linux-2.4.24.org/include/linux/mm.h 2004-01-05 18:39:33.000000000 +0100
16024 +++ linux-2.4.24/include/linux/mm.h     2004-01-05 19:03:58.537419824 +0100
16025 @@ -22,9 +22,13 @@
16026  extern struct list_head active_list;
16027  extern struct list_head inactive_list;
16028  
16029 +extern void gr_learn_resource(const struct task_struct * task, const int limit,
16030 +                             const unsigned long wanted, const int gt);
16031 +
16032  #include <asm/page.h>
16033  #include <asm/pgtable.h>
16034  #include <asm/atomic.h>
16035 +#include <asm/mman.h>
16036  
16037  /*
16038   * Linux kernel virtual memory manager primitives.
16039 @@ -104,6 +108,33 @@
16040  #define VM_DONTEXPAND  0x00040000      /* Cannot expand with mremap() */
16041  #define VM_RESERVED    0x00080000      /* Don't unmap it from swap_out */
16042  
16043 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16044 +#define VM_MIRROR      0x00100000      /* vma is mirroring another */
16045 +#endif
16046 +
16047 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
16048 +#define VM_MAYNOTWRITE 0x00200000      /* vma cannot be granted VM_WRITE any more */
16049 +#endif
16050 +
16051 +#ifdef ARCH_STACK_GROWSUP
16052 +#define __VM_STACK_FLAGS       0x00000233
16053 +#else
16054 +#define __VM_STACK_FLAGS       0x00000133
16055 +#endif
16056 +
16057 +#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
16058 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
16059 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | \
16060 +                       ((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16061 +                       ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
16062 +#else
16063 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_MAYEXEC | \
16064 +                       ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
16065 +#endif
16066 +#else
16067 +#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_EXEC | VM_MAYEXEC)
16068 +#endif
16069 +
16070  #ifndef VM_STACK_FLAGS
16071  #define VM_STACK_FLAGS 0x00000177
16072  #endif
16073 @@ -575,11 +606,38 @@
16074         unsigned long flag, unsigned long offset)
16075  {
16076         unsigned long ret = -EINVAL;
16077 +
16078 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
16079 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
16080 +                       (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
16081 +               goto out;
16082 +#endif
16083 +           
16084         if ((offset + PAGE_ALIGN(len)) < offset)
16085                 goto out;
16086         if (!(offset & ~PAGE_MASK))
16087                 ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
16088                                     offset >> PAGE_SHIFT);
16089 +
16090 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
16091 +#define BAD_ADDR(x)   ((unsigned long)(x) > TASK_SIZE)
16092 +       if ((current->flags & PF_PAX_SEGMEXEC) && !BAD_ADDR(ret) &&
16093 +               (prot & PROT_EXEC) && ((flag & MAP_TYPE) == MAP_PRIVATE)
16094 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
16095 +               && (!(current->flags & PF_PAX_MPROTECT) || (file && !(prot & PROT_WRITE)))
16096 +#endif
16097 +               )
16098 +       {
16099 +               unsigned long ret_m;
16100 +               ret_m = do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flag | MAP_MIRROR | MAP_FIXED, ret);
16101 +               if (BAD_ADDR(ret_m)) {
16102 +                       do_munmap(current->mm, ret, len);
16103 +                       ret = ret_m;
16104 +               }
16105 +       }
16106 +#undef BAD_ADDR
16107 +#endif
16108 +
16109  out:
16110         return ret;
16111  }
16112 @@ -598,6 +656,12 @@
16113  
16114  static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
16115  {
16116 +
16117 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16118 +       if ((vma->vm_flags | vm_flags) & VM_MIRROR)
16119 +               return 0;
16120 +#endif
16121 +
16122         if (!vma->vm_file && vma->vm_flags == vm_flags)
16123                 return 1;
16124         else
16125 @@ -651,7 +715,12 @@
16126  
16127         return gfp_mask;
16128  }
16129 -       
16130 +
16131 +/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
16132 +extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
16133 +extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
16134 +                                            struct vm_area_struct **pprev);
16135 +
16136  /* vma is the first one with  address < vma->vm_end,
16137   * and even  address < vma->vm_start. Have to extend vma. */
16138  static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
16139 @@ -666,11 +735,51 @@
16140         address &= PAGE_MASK;
16141         spin_lock(&vma->vm_mm->page_table_lock);
16142         grow = (vma->vm_start - address) >> PAGE_SHIFT;
16143 +
16144 +       gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address, 1);
16145 +       gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
16146 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
16147 +
16148 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16149 +       if (vma->vm_flags & VM_MIRROR) {
16150 +               struct vm_area_struct * vma_m;
16151 +               unsigned long address_m;
16152 +
16153 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16154 +               vma_m = find_vma(vma->vm_mm, address_m);
16155 +               if (!vma_m || vma_m->vm_start != address_m || !(vma_m->vm_flags & VM_MIRROR) ||
16156 +                   vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start) {
16157 +                       spin_unlock(&vma->vm_mm->page_table_lock);
16158 +                       printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
16159 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
16160 +                       return -ENOMEM;
16161 +               }
16162 +
16163 +               address_m = address + (unsigned long)vma->vm_private_data;
16164 +               if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
16165 +                   ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
16166 +                   ((vma_m->vm_flags & VM_LOCKED) && ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
16167 +                    current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
16168 +                       spin_unlock(&vma->vm_mm->page_table_lock);
16169 +                       return -ENOMEM;
16170 +               }
16171 +
16172 +               vma_m->vm_start = address_m;
16173 +               vma_m->vm_pgoff -= grow;
16174 +               vma_m->vm_mm->total_vm += grow;
16175 +               if (vma_m->vm_flags & VM_LOCKED)
16176 +                       vma_m->vm_mm->locked_vm += grow;
16177 +       } else
16178 +#endif
16179 +
16180         if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
16181 -           ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
16182 +           ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
16183 +           ((vma->vm_flags & VM_LOCKED) && ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
16184 +            current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
16185                 spin_unlock(&vma->vm_mm->page_table_lock);
16186                 return -ENOMEM;
16187         }
16188 +
16189         vma->vm_start = address;
16190         vma->vm_pgoff -= grow;
16191         vma->vm_mm->total_vm += grow;
16192 @@ -680,11 +789,6 @@
16193         return 0;
16194  }
16195  
16196 -/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
16197 -extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
16198 -extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
16199 -                                            struct vm_area_struct **pprev);
16200 -
16201  /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
16202     NULL if none.  Assume start_addr < end_addr. */
16203  static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
16204 diff -urN linux-2.4.24.org/include/linux/proc_fs.h linux-2.4.24/include/linux/proc_fs.h
16205 --- linux-2.4.24.org/include/linux/proc_fs.h    2004-01-05 18:39:31.000000000 +0100
16206 +++ linux-2.4.24/include/linux/proc_fs.h        2004-01-05 18:43:05.857856064 +0100
16207 @@ -143,6 +143,9 @@
16208  extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
16209                 struct proc_dir_entry *,kdev_t);
16210  extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
16211 +#ifdef CONFIG_GRKERNSEC_PROC
16212 +extern struct proc_dir_entry *proc_priv_mkdir(const char *, struct proc_dir_entry *);
16213 +#endif
16214  
16215  static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
16216         mode_t mode, struct proc_dir_entry *base, 
16217 diff -urN linux-2.4.24.org/include/linux/sched.h linux-2.4.24/include/linux/sched.h
16218 --- linux-2.4.24.org/include/linux/sched.h      2004-01-05 18:39:31.000000000 +0100
16219 +++ linux-2.4.24/include/linux/sched.h  2004-01-05 19:04:31.417421304 +0100
16220 @@ -28,6 +28,9 @@
16221  #include <linux/securebits.h>
16222  #include <linux/fs_struct.h>
16223  
16224 +extern int gr_is_capable(const int cap);
16225 +extern int gr_pid_is_chrooted(const struct task_struct *p);
16226 +
16227  struct exec_domain;
16228  
16229  /*
16230 @@ -250,6 +253,20 @@
16231         unsigned long cpu_vm_mask;
16232         unsigned long swap_address;
16233  
16234 +#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
16235 +       unsigned long call_dl_resolve;
16236 +#endif
16237 +
16238 +#if defined(CONFIG_PPC32) && defined(CONFIG_GRKERNSEC_PAX_EMUSIGRT)
16239 +       unsigned long call_syscall;
16240 +#endif
16241 +
16242 +#ifdef CONFIG_GRKERNSEC_PAX_ASLR
16243 +       unsigned long delta_mmap;               /* PaX: randomized offset */
16244 +       unsigned long delta_exec;               /* PaX: randomized offset */
16245 +       unsigned long delta_stack;              /* PaX: randomized offset */
16246 +#endif
16247
16248         unsigned dumpable:1;
16249  
16250         /* Architecture-specific MM context */
16251 @@ -422,7 +439,7 @@
16252         int (*notifier)(void *priv);
16253         void *notifier_data;
16254         sigset_t *notifier_mask;
16255 -       
16256 +
16257  /* Thread group tracking */
16258         u32 parent_exec_id;
16259         u32 self_exec_id;
16260 @@ -433,6 +450,22 @@
16261  
16262  /* journalling filesystem info */
16263         void *journal_info;
16264 +
16265 +#ifdef CONFIG_GRKERNSEC
16266 +/* added by grsecurity's ACL system */ 
16267 +       struct acl_subject_label *acl;
16268 +       struct acl_role_label *role;
16269 +       struct file *exec_file;
16270 +       u32 curr_ip;
16271 +       u32 gr_saddr;
16272 +       u32 gr_daddr;
16273 +       u16 gr_sport;
16274 +       u16 gr_dport;
16275 +       u16 acl_role_id;        
16276 +       u8 acl_sp_role:1;       
16277 +       u8 used_accept:1;       
16278 +       u8 is_writable:1;
16279 +#endif
16280  };
16281  
16282  /*
16283 @@ -453,6 +486,21 @@
16284  
16285  #define PF_USEDFPU     0x00100000      /* task used FPU this quantum (SMP) */
16286  
16287 +#define PF_PAX_PAGEEXEC       0x01000000      /* Paging based non-executable pages */
16288 +#define PF_PAX_EMUTRAMP       0x02000000      /* Emulate trampolines */
16289 +#define PF_PAX_MPROTECT       0x04000000      /* Restrict mprotect() */
16290 +#define PF_PAX_RANDMMAP       0x08000000      /* Randomize mmap() base */
16291 +#define PF_PAX_RANDEXEC              0x10000000      /* Randomize ET_EXEC base */
16292 +#define PF_PAX_SEGMEXEC              0x20000000      /* Segmentation based non-executable pages */
16293 +
16294 +extern int pax_check_flags(unsigned long *);
16295 +        
16296 +#ifdef CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS
16297 +extern void pax_set_flags(struct linux_binprm * bprm);
16298 +#elif defined(CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS)
16299 +extern void (*pax_set_flags_func)(struct linux_binprm * bprm);
16300 +#endif
16301 +
16302  /*
16303   * Ptrace flags
16304   */
16305 @@ -573,6 +621,8 @@
16306         *p->pidhash_pprev = p->pidhash_next;
16307  }
16308  
16309 +#include <asm/current.h>
16310 +
16311  static inline task_t *find_task_by_pid(int pid)
16312  {
16313         task_t *p, **htable = &pidhash[pid_hashfn(pid)];
16314 @@ -580,6 +630,8 @@
16315         for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
16316                 ;
16317  
16318 +       if(gr_pid_is_chrooted(p)) p = NULL;
16319 +
16320         return p;
16321  }
16322  
16323 @@ -588,8 +640,6 @@
16324  extern void free_uid(struct user_struct *);
16325  extern void switch_uid(struct user_struct *);
16326  
16327 -#include <asm/current.h>
16328 -
16329  extern unsigned long volatile jiffies;
16330  extern unsigned long itimer_ticks;
16331  extern unsigned long itimer_next;
16332 @@ -756,7 +806,7 @@
16333  static inline int capable(int cap)
16334  {
16335  #if 1 /* ok now */
16336 -       if (cap_raised(current->cap_effective, cap))
16337 +       if (cap_raised(current->cap_effective, cap) && gr_is_capable(cap))
16338  #else
16339         if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
16340  #endif
16341 diff -urN linux-2.4.24.org/include/linux/sysctl.h linux-2.4.24/include/linux/sysctl.h
16342 --- linux-2.4.24.org/include/linux/sysctl.h     2004-01-05 18:39:36.000000000 +0100
16343 +++ linux-2.4.24/include/linux/sysctl.h 2004-01-05 18:43:05.878852872 +0100
16344 @@ -128,6 +128,7 @@
16345         KERN_PPC_L3CR=57,       /* l3cr register on PPC */
16346         KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
16347         KERN_CORE_SETUID=59,    /* int: set to allow core dumps of setuid apps */
16348 +       KERN_GRSECURITY=68      /* grsecurity */
16349  };
16350  
16351  
16352 diff -urN linux-2.4.24.org/include/net/inetpeer.h linux-2.4.24/include/net/inetpeer.h
16353 --- linux-2.4.24.org/include/net/inetpeer.h     2004-01-05 18:39:21.000000000 +0100
16354 +++ linux-2.4.24/include/net/inetpeer.h 2004-01-05 18:43:05.904848920 +0100
16355 @@ -13,6 +13,7 @@
16356  #include <linux/init.h>
16357  #include <linux/sched.h>
16358  #include <linux/spinlock.h>
16359 +
16360  #include <asm/atomic.h>
16361  
16362  struct inet_peer
16363 @@ -34,6 +35,11 @@
16364  /* can be called with or without local BH being disabled */
16365  struct inet_peer       *inet_getpeer(__u32 daddr, int create);
16366  
16367 +#ifdef CONFIG_GRKERNSEC_RANDID
16368 +extern int grsec_enable_randid;
16369 +extern __u16 ip_randomid(void);
16370 +#endif
16371 +
16372  extern spinlock_t inet_peer_unused_lock;
16373  extern struct inet_peer *inet_peer_unused_head;
16374  extern struct inet_peer **inet_peer_unused_tailp;
16375 @@ -58,7 +64,14 @@
16376         __u16 id;
16377  
16378         spin_lock_bh(&inet_peer_idlock);
16379 -       id = p->ip_id_count++;
16380 +
16381 +#ifdef CONFIG_GRKERNSEC_RANDID
16382 +       if(grsec_enable_randid)
16383 +               id = htons(ip_randomid());
16384 +       else
16385 +#endif
16386 +               id = p->ip_id_count++;
16387 +
16388         spin_unlock_bh(&inet_peer_idlock);
16389         return id;
16390  }
16391 diff -urN linux-2.4.24.org/include/net/ip.h linux-2.4.24/include/net/ip.h
16392 --- linux-2.4.24.org/include/net/ip.h   2004-01-05 18:39:21.000000000 +0100
16393 +++ linux-2.4.24/include/net/ip.h       2004-01-05 18:43:05.951841776 +0100
16394 @@ -64,6 +64,11 @@
16395         void                    (*destructor)(struct sock *);
16396  };
16397  
16398 +#ifdef CONFIG_GRKERNSEC_RANDID
16399 +extern int grsec_enable_randid;
16400 +extern __u16 ip_randomid(void);
16401 +#endif
16402 +
16403  extern struct ip_ra_chain *ip_ra_chain;
16404  extern rwlock_t ip_ra_lock;
16405  
16406 @@ -197,7 +202,13 @@
16407                  * does not change, they drop every other packet in
16408                  * a TCP stream using header compression.
16409                  */
16410 -               iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
16411 +
16412 +#ifdef CONFIG_GRKERNSEC_RANDID
16413 +               if(grsec_enable_randid)
16414 +                       iph->id = htons(ip_randomid());
16415 +               else
16416 +#endif
16417 +                       iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
16418         } else
16419                 __ip_select_ident(iph, dst);
16420  }
16421 diff -urN linux-2.4.24.org/init/main.c linux-2.4.24/init/main.c
16422 --- linux-2.4.24.org/init/main.c        2004-01-05 18:41:00.660888896 +0100
16423 +++ linux-2.4.24/init/main.c    2004-01-05 18:43:05.952841624 +0100
16424 @@ -28,6 +28,7 @@
16425  #include <linux/bootmem.h>
16426  #include <linux/file.h>
16427  #include <linux/tty.h>
16428 +#include <linux/grsecurity.h>
16429  
16430  #include <asm/io.h>
16431  #include <asm/bugs.h>
16432 @@ -113,6 +114,8 @@
16433  extern void ipc_init(void);
16434  #endif
16435  
16436 +extern void grsecurity_init(void);
16437 +
16438  /*
16439   * Boot command-line arguments
16440   */
16441 @@ -568,6 +571,7 @@
16442         do_basic_setup();
16443  
16444         prepare_namespace();
16445 +       grsecurity_init();
16446  
16447         /*
16448          * Ok, we have completed the initial bootup, and
16449 diff -urN linux-2.4.24.org/ipc/msg.c linux-2.4.24/ipc/msg.c
16450 --- linux-2.4.24.org/ipc/msg.c  2004-01-05 18:41:09.346568472 +0100
16451 +++ linux-2.4.24/ipc/msg.c      2004-01-05 18:43:05.953841472 +0100
16452 @@ -22,6 +22,7 @@
16453  #include <linux/init.h>
16454  #include <linux/proc_fs.h>
16455  #include <linux/list.h>
16456 +#include <linux/grsecurity.h>
16457  #include <asm/uaccess.h>
16458  #include "util.h"
16459  
16460 @@ -326,6 +327,9 @@
16461                 msg_unlock(id);
16462         }
16463         up(&msg_ids.sem);
16464 +
16465 +       gr_log_msgget(ret, msgflg);
16466 +
16467         return ret;
16468  }
16469  
16470 @@ -560,6 +564,8 @@
16471                 break;
16472         }
16473         case IPC_RMID:
16474 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
16475 +
16476                 freeque (msqid); 
16477                 break;
16478         }
16479 diff -urN linux-2.4.24.org/ipc/sem.c linux-2.4.24/ipc/sem.c
16480 --- linux-2.4.24.org/ipc/sem.c  2004-01-05 18:41:09.344568776 +0100
16481 +++ linux-2.4.24/ipc/sem.c      2004-01-05 18:43:05.954841320 +0100
16482 @@ -63,6 +63,7 @@
16483  #include <linux/init.h>
16484  #include <linux/proc_fs.h>
16485  #include <linux/time.h>
16486 +#include <linux/grsecurity.h>
16487  #include <asm/uaccess.h>
16488  #include "util.h"
16489  
16490 @@ -182,6 +183,9 @@
16491         }
16492  
16493         up(&sem_ids.sem);
16494 +
16495 +       gr_log_semget(err, semflg);
16496 +
16497         return err;
16498  }
16499  
16500 @@ -724,6 +728,8 @@
16501  
16502         switch(cmd){
16503         case IPC_RMID:
16504 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
16505 +
16506                 freeary(semid);
16507                 err = 0;
16508                 break;
16509 diff -urN linux-2.4.24.org/ipc/shm.c linux-2.4.24/ipc/shm.c
16510 --- linux-2.4.24.org/ipc/shm.c  2004-01-05 18:41:09.345568624 +0100
16511 +++ linux-2.4.24/ipc/shm.c      2004-01-05 18:43:05.955841168 +0100
16512 @@ -23,6 +23,7 @@
16513  #include <linux/mman.h>
16514  #include <linux/proc_fs.h>
16515  #include <asm/uaccess.h>
16516 +#include <linux/grsecurity.h>
16517  
16518  #include "util.h"
16519  
16520 @@ -38,8 +39,21 @@
16521         time_t                  shm_ctim;
16522         pid_t                   shm_cprid;
16523         pid_t                   shm_lprid;
16524 +
16525 +#ifdef CONFIG_GRKERNSEC
16526 +       time_t                  shm_createtime;
16527 +       pid_t                   shm_lapid;
16528 +#endif
16529  };
16530  
16531 +#ifdef CONFIG_GRKERNSEC
16532 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16533 +                           const time_t shm_createtime, const uid_t cuid,
16534 +                           const int shmid);
16535 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16536 +                    const time_t shm_createtime);
16537 +#endif
16538 +
16539  #define shm_flags      shm_perm.mode
16540  
16541  static struct file_operations shm_file_operations;
16542 @@ -209,6 +223,9 @@
16543         shp->shm_lprid = 0;
16544         shp->shm_atim = shp->shm_dtim = 0;
16545         shp->shm_ctim = CURRENT_TIME;
16546 +#ifdef CONFIG_GRKERNSEC
16547 +       shp->shm_createtime = CURRENT_TIME;
16548 +#endif
16549         shp->shm_segsz = size;
16550         shp->shm_nattch = 0;
16551         shp->id = shm_buildid(id,shp->shm_perm.seq);
16552 @@ -254,6 +271,9 @@
16553                 shm_unlock(id);
16554         }
16555         up(&shm_ids.sem);
16556 +
16557 +       gr_log_shmget(err, shmflg, size);
16558 +
16559         return err;
16560  }
16561  
16562 @@ -509,6 +529,9 @@
16563                         err=-EPERM;
16564                         goto out_unlock_up;
16565                 }
16566 +
16567 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
16568 +
16569                 if (shp->shm_nattch){
16570                         shp->shm_flags |= SHM_DEST;
16571                         /* Do not find it any more */
16572 @@ -622,9 +645,28 @@
16573                 shm_unlock(shmid);
16574                 return -EACCES;
16575         }
16576 +
16577 +#ifdef CONFIG_GRKERNSEC
16578 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
16579 +                            shp->shm_perm.cuid, shmid)) {
16580 +               shm_unlock(shmid);
16581 +               return -EACCES;
16582 +       }
16583 +
16584 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
16585 +               shm_unlock(shmid);
16586 +               return -EACCES;
16587 +       }
16588 +#endif
16589 +
16590         file = shp->shm_file;
16591         size = file->f_dentry->d_inode->i_size;
16592         shp->shm_nattch++;
16593 +
16594 +#ifdef CONFIG_GRKERNSEC
16595 +       shp->shm_lapid = current->pid;
16596 +#endif
16597 +
16598         shm_unlock(shmid);
16599  
16600         down_write(&current->mm->mmap_sem);
16601 diff -urN linux-2.4.24.org/kernel/capability.c linux-2.4.24/kernel/capability.c
16602 --- linux-2.4.24.org/kernel/capability.c        2004-01-05 18:41:08.688668488 +0100
16603 +++ linux-2.4.24/kernel/capability.c    2004-01-05 18:43:05.955841168 +0100
16604 @@ -7,6 +7,7 @@
16605  
16606  #include <linux/mm.h>
16607  #include <asm/uaccess.h>
16608 +#include <linux/grsecurity.h>
16609  
16610  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
16611  
16612 @@ -170,6 +171,10 @@
16613               target = current;
16614       }
16615  
16616 +     if (gr_handle_chroot_capset(target)) {
16617 +            error = -ESRCH;
16618 +            goto out;
16619 +     }
16620  
16621       /* verify restrictions on target's new Inheritable set */
16622       if (!cap_issubset(inheritable,
16623 diff -urN linux-2.4.24.org/kernel/exit.c linux-2.4.24/kernel/exit.c
16624 --- linux-2.4.24.org/kernel/exit.c      2004-01-05 18:41:08.643675328 +0100
16625 +++ linux-2.4.24/kernel/exit.c  2004-01-05 19:09:06.667576920 +0100
16626 @@ -13,9 +13,11 @@
16627  #include <linux/personality.h>
16628  #include <linux/tty.h>
16629  #include <linux/namespace.h>
16630 +#include <linux/file.h>
16631  #ifdef CONFIG_BSD_PROCESS_ACCT
16632  #include <linux/acct.h>
16633  #endif
16634 +#include <linux/grsecurity.h>
16635  
16636  #include <asm/uaccess.h>
16637  #include <asm/pgtable.h>
16638 @@ -139,12 +141,21 @@
16639  {
16640         write_lock_irq(&tasklist_lock);
16641  
16642 +#ifdef CONFIG_GRKERNSEC
16643 +       if (current->exec_file) {
16644 +               fput(current->exec_file);
16645 +               current->exec_file = NULL;
16646 +       }
16647 +#endif
16648 +               
16649         /* Reparent to init */
16650         REMOVE_LINKS(current);
16651         current->p_pptr = child_reaper;
16652         current->p_opptr = child_reaper;
16653         SET_LINKS(current);
16654  
16655 +       gr_set_kernel_label(current);
16656 +
16657         /* Set the exit signal to SIGCHLD so we signal init on exit */
16658         current->exit_signal = SIGCHLD;
16659  
16660 @@ -173,7 +184,14 @@
16661  {
16662         struct fs_struct *fs;
16663  
16664 -
16665 +#ifdef CONFIG_GRKERNSEC
16666 +       if (current->exec_file) {
16667 +               fput(current->exec_file);
16668 +               current->exec_file = NULL;
16669 +       }
16670 +#endif
16671 +       gr_set_kernel_label(current);
16672 +       
16673         /*
16674          * If we were started as result of loading a module, close all of the
16675          * user space pages.  We don't need them, and if we didn't close them
16676 @@ -485,6 +503,11 @@
16677  #ifdef CONFIG_BSD_PROCESS_ACCT
16678         acct_process(code);
16679  #endif
16680 +
16681 +       gr_acl_handle_psacct(tsk, code);
16682 +       gr_acl_handle_exit();
16683 +       gr_del_task_from_ip_table(tsk);
16684 +
16685         __exit_mm(tsk);
16686  
16687         lock_kernel();
16688 diff -urN linux-2.4.24.org/kernel/fork.c linux-2.4.24/kernel/fork.c
16689 --- linux-2.4.24.org/kernel/fork.c      2004-01-05 18:41:08.496697672 +0100
16690 +++ linux-2.4.24/kernel/fork.c  2004-01-05 18:43:05.957840864 +0100
16691 @@ -22,6 +22,7 @@
16692  #include <linux/namespace.h>
16693  #include <linux/personality.h>
16694  #include <linux/compiler.h>
16695 +#include <linux/grsecurity.h>
16696  
16697  #include <asm/pgtable.h>
16698  #include <asm/pgalloc.h>
16699 @@ -94,6 +95,10 @@
16700         if (flags & CLONE_PID)
16701                 return current->pid;
16702  
16703 +       pid = gr_random_pid(&lastpid_lock);
16704 +       if (pid)
16705 +               return pid;
16706 +
16707         spin_lock(&lastpid_lock);
16708         beginpid = last_pid;
16709         if((++last_pid) & 0xffff8000) {
16710 @@ -672,6 +677,9 @@
16711          * friends to set the per-user process limit to something lower
16712          * than the amount of processes root is running. -- Rik
16713          */
16714 +
16715 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
16716 +
16717         if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
16718                       && p->user != &root_user
16719                       && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
16720 @@ -756,6 +764,7 @@
16721         retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
16722         if (retval)
16723                 goto bad_fork_cleanup_namespace;
16724 +       gr_copy_label(p);
16725         p->semundo = NULL;
16726         
16727         /* Our parent execution domain becomes current domain
16728 @@ -858,6 +867,9 @@
16729         free_uid(p->user);
16730  bad_fork_free:
16731         free_task_struct(p);
16732 +
16733 +       gr_log_forkfail(retval);
16734 +
16735         goto fork_out;
16736  }
16737  
16738 diff -urN linux-2.4.24.org/kernel/ksyms.c linux-2.4.24/kernel/ksyms.c
16739 --- linux-2.4.24.org/kernel/ksyms.c     2004-01-05 18:41:09.122602520 +0100
16740 +++ linux-2.4.24/kernel/ksyms.c 2004-01-05 18:43:05.958840712 +0100
16741 @@ -51,6 +51,7 @@
16742  #include <linux/dnotify.h>
16743  #include <linux/crc32.h>
16744  #include <linux/firmware.h>
16745 +#include <linux/grsecurity.h>
16746  #include <asm/checksum.h>
16747  
16748  #if defined(CONFIG_PROC_FS)
16749 @@ -636,3 +637,9 @@
16750  /* To match ksyms with System.map */
16751  extern const char _end[];
16752  EXPORT_SYMBOL(_end);
16753 +
16754 +/* grsecurity */
16755 +EXPORT_SYMBOL(gr_is_capable);
16756 +EXPORT_SYMBOL(gr_pid_is_chrooted);
16757 +EXPORT_SYMBOL(gr_learn_resource);
16758 +EXPORT_SYMBOL(gr_set_kernel_label);
16759 diff -urN linux-2.4.24.org/kernel/module.c linux-2.4.24/kernel/module.c
16760 --- linux-2.4.24.org/kernel/module.c    2004-01-05 18:41:08.388714088 +0100
16761 +++ linux-2.4.24/kernel/module.c        2004-01-05 18:43:05.959840560 +0100
16762 @@ -900,6 +900,11 @@
16763         struct module *mod;
16764         int err;
16765  
16766 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16767 +       if (!capable(CAP_SYS_MODULE))
16768 +               return -EPERM;
16769 +#endif
16770 +
16771         lock_kernel();
16772         if (name_user == NULL)
16773                 mod = &kernel_module;
16774 @@ -969,6 +974,11 @@
16775         int i;
16776         struct kernel_sym ksym;
16777  
16778 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16779 +       if (!capable(CAP_SYS_MODULE))
16780 +               return 0;
16781 +#endif
16782 +
16783         lock_kernel();
16784         for (mod = module_list, i = 0; mod; mod = mod->next) {
16785                 /* include the count for the module name! */
16786 diff -urN linux-2.4.24.org/kernel/printk.c linux-2.4.24/kernel/printk.c
16787 --- linux-2.4.24.org/kernel/printk.c    2004-01-05 18:41:08.480700104 +0100
16788 +++ linux-2.4.24/kernel/printk.c        2004-01-05 19:05:01.186895656 +0100
16789 @@ -27,6 +27,7 @@
16790  #include <linux/interrupt.h>                   /* For in_interrupt() */
16791  #include <linux/config.h>
16792  #include <linux/delay.h>
16793 +#include <linux/grsecurity.h>
16794  
16795  #include <asm/uaccess.h>
16796  
16797 @@ -299,6 +300,11 @@
16798  
16799  asmlinkage long sys_syslog(int type, char * buf, int len)
16800  {
16801 +#ifdef CONFIG_GRKERNSEC_DMESG
16802 +       if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
16803 +               return -EPERM;
16804 +       else
16805 +#endif
16806         if ((type != 3) && !capable(CAP_SYS_ADMIN))
16807                 return -EPERM;
16808         return do_syslog(type, buf, len);
16809 diff -urN linux-2.4.24.org/kernel/sched.c linux-2.4.24/kernel/sched.c
16810 --- linux-2.4.24.org/kernel/sched.c     2004-01-05 18:41:08.752658760 +0100
16811 +++ linux-2.4.24/kernel/sched.c 2004-01-05 19:06:22.215577424 +0100
16812 @@ -20,11 +20,13 @@
16813  #include <linux/nmi.h>
16814  #include <linux/interrupt.h>
16815  #include <linux/init.h>
16816 +#include <linux/file.h>
16817  #include <asm/uaccess.h>
16818  #include <linux/smp_lock.h>
16819  #include <asm/mmu_context.h>
16820  #include <linux/kernel_stat.h>
16821  #include <linux/completion.h>
16822 +#include <linux/grsecurity.h>
16823  
16824  /*
16825   * Convert user-nice values [ -20 ... 0 ... 19 ]
16826 @@ -1192,6 +1194,9 @@
16827                         return -EPERM;
16828                 if (increment < -40)
16829                         increment = -40;
16830 +
16831 +               if (gr_handle_chroot_nice())
16832 +                       return -EPERM;
16833         }
16834         if (increment > 40)
16835                 increment = 40;
16836 diff -urN linux-2.4.24.org/kernel/signal.c linux-2.4.24/kernel/signal.c
16837 --- linux-2.4.24.org/kernel/signal.c    2004-01-05 18:41:08.737661040 +0100
16838 +++ linux-2.4.24/kernel/signal.c        2004-01-05 18:43:05.967839344 +0100
16839 @@ -13,6 +13,8 @@
16840  #include <linux/smp_lock.h>
16841  #include <linux/init.h>
16842  #include <linux/sched.h>
16843 +#include <linux/fs.h>
16844 +#include <linux/grsecurity.h>
16845  
16846  #include <asm/uaccess.h>
16847  
16848 @@ -553,6 +555,8 @@
16849         if (!sig || !t->sig)
16850                 goto out_nolock;
16851  
16852 +       gr_log_signal(sig, t);
16853 +
16854         spin_lock_irqsave(&t->sigmask_lock, flags);
16855         handle_stop_signal(sig, t);
16856  
16857 @@ -602,6 +606,8 @@
16858         recalc_sigpending(t);
16859         spin_unlock_irqrestore(&t->sigmask_lock, flags);
16860  
16861 +       gr_handle_crash(t, sig);
16862 +
16863         return send_sig_info(sig, info, t);
16864  }
16865  
16866 @@ -621,9 +627,13 @@
16867                 read_lock(&tasklist_lock);
16868                 for_each_task(p) {
16869                         if (p->pgrp == pgrp && thread_group_leader(p)) {
16870 -                               int err = send_sig_info(sig, info, p);
16871 -                               if (retval)
16872 -                                       retval = err;
16873 +                               if (gr_handle_signal(p, sig))
16874 +                                       retval = -EPERM;
16875 +                               else {
16876 +                                       int err = send_sig_info(sig, info, p);
16877 +                                       if (retval)
16878 +                                               retval = err;
16879 +                               }
16880                         }
16881                 }
16882                 read_unlock(&tasklist_lock);
16883 @@ -674,7 +684,10 @@
16884                         if (tg)
16885                                 p = tg;
16886                  }
16887 -               error = send_sig_info(sig, info, p);
16888 +               if (gr_handle_signal(p, sig))
16889 +                       error = -EPERM;
16890 +               else
16891 +                       error = send_sig_info(sig, info, p);
16892         }
16893         read_unlock(&tasklist_lock);
16894         return error;
16895 @@ -699,10 +712,14 @@
16896                 read_lock(&tasklist_lock);
16897                 for_each_task(p) {
16898                         if (p->pid > 1 && p != current && thread_group_leader(p)) {
16899 -                               int err = send_sig_info(sig, info, p);
16900 -                               ++count;
16901 -                               if (err != -EPERM)
16902 -                                       retval = err;
16903 +                               if (gr_handle_signal(p, sig))
16904 +                                       retval = -EPERM;
16905 +                               else {
16906 +                                       int err = send_sig_info(sig, info, p);
16907 +                                       ++count;
16908 +                                       if (err != -EPERM)
16909 +                                               retval = err;
16910 +                               }
16911                         }
16912                 }
16913                 read_unlock(&tasklist_lock);
16914 diff -urN linux-2.4.24.org/kernel/sys.c linux-2.4.24/kernel/sys.c
16915 --- linux-2.4.24.org/kernel/sys.c       2004-01-05 18:41:09.099606016 +0100
16916 +++ linux-2.4.24/kernel/sys.c   2004-01-05 18:43:05.969839040 +0100
16917 @@ -4,6 +4,7 @@
16918   *  Copyright (C) 1991, 1992  Linus Torvalds
16919   */
16920  
16921 +#include <linux/config.h>
16922  #include <linux/module.h>
16923  #include <linux/mm.h>
16924  #include <linux/utsname.h>
16925 @@ -14,6 +15,7 @@
16926  #include <linux/prctl.h>
16927  #include <linux/init.h>
16928  #include <linux/highuid.h>
16929 +#include <linux/grsecurity.h>
16930  
16931  #include <asm/uaccess.h>
16932  #include <asm/io.h>
16933 @@ -239,6 +241,12 @@
16934                 }
16935                 if (error == -ESRCH)
16936                         error = 0;
16937 +
16938 +               if (gr_handle_chroot_setpriority(p, niceval)) {
16939 +                       read_unlock(&tasklist_lock);
16940 +                       return -ESRCH;
16941 +               }
16942 +
16943                 if (niceval < task_nice(p) && !capable(CAP_SYS_NICE))
16944                         error = -EACCES;
16945                 else
16946 @@ -425,6 +433,9 @@
16947         if (rgid != (gid_t) -1 ||
16948             (egid != (gid_t) -1 && egid != old_rgid))
16949                 current->sgid = new_egid;
16950 +
16951 +       gr_set_role_label(current, current->uid, new_rgid);
16952 +
16953         current->fsgid = new_egid;
16954         current->egid = new_egid;
16955         current->gid = new_rgid;
16956 @@ -447,6 +458,9 @@
16957                         current->mm->dumpable=0;
16958                         wmb();
16959                 }
16960 +
16961 +               gr_set_role_label(current, current->uid, gid);
16962 +
16963                 current->gid = current->egid = current->sgid = current->fsgid = gid;
16964         }
16965         else if ((gid == current->gid) || (gid == current->sgid))
16966 @@ -523,6 +537,9 @@
16967                 current->mm->dumpable = 0;
16968                 wmb();
16969         }
16970 +
16971 +       gr_set_role_label(current, new_ruid, current->gid);
16972 +
16973         current->uid = new_ruid;
16974         return 0;
16975  }
16976 @@ -617,6 +634,9 @@
16977         } else if ((uid != current->uid) && (uid != new_suid))
16978                 return -EPERM;
16979  
16980 +       if (gr_check_crash_uid(uid))
16981 +               return -EPERM;
16982 +
16983         if (old_euid != uid)
16984         {
16985                 current->mm->dumpable = 0;
16986 @@ -713,8 +733,10 @@
16987                 current->egid = egid;
16988         }
16989         current->fsgid = current->egid;
16990 -       if (rgid != (gid_t) -1)
16991 +       if (rgid != (gid_t) -1) {
16992 +               gr_set_role_label(current, current->uid, rgid);
16993                 current->gid = rgid;
16994 +       }
16995         if (sgid != (gid_t) -1)
16996                 current->sgid = sgid;
16997         return 0;
16998 @@ -1137,6 +1159,10 @@
16999         if (new_rlim.rlim_cur > new_rlim.rlim_max)
17000                 return -EINVAL;
17001         old_rlim = current->rlim + resource;
17002 +
17003 +       if (old_rlim->rlim_max < old_rlim->rlim_cur)
17004 +               return -EINVAL;
17005 +
17006         if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
17007              (new_rlim.rlim_max > old_rlim->rlim_max)) &&
17008             !capable(CAP_SYS_RESOURCE))
17009 diff -urN linux-2.4.24.org/kernel/sysctl.c linux-2.4.24/kernel/sysctl.c
17010 --- linux-2.4.24.org/kernel/sysctl.c    2004-01-05 18:41:09.278578808 +0100
17011 +++ linux-2.4.24/kernel/sysctl.c        2004-01-05 18:43:05.971838736 +0100
17012 @@ -39,6 +39,13 @@
17013  #endif
17014  
17015  #if defined(CONFIG_SYSCTL)
17016 +#include <linux/grsecurity.h>
17017 +#include <linux/grinternal.h>
17018 +
17019 +extern __u32 gr_handle_sysctl(const ctl_table * table, const void *oldval,
17020 +                             const void *newval);
17021 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op);
17022 +extern int gr_handle_chroot_sysctl(const int op);
17023  
17024  /* External variables not in a header file. */
17025  extern int panic_timeout;
17026 @@ -131,6 +138,8 @@
17027  static ctl_table debug_table[];
17028  extern ctl_table random_table[];
17029  
17030 +static ctl_table grsecurity_table[];
17031 +
17032  /* /proc declarations: */
17033  
17034  #ifdef CONFIG_PROC_FS
17035 @@ -277,8 +286,191 @@
17036         {KERN_EXCEPTION_TRACE,"exception-trace",
17037          &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
17038  #endif 
17039 +#ifdef CONFIG_GRKERNSEC_SYSCTL
17040 +       {KERN_GRSECURITY, "grsecurity", NULL, 0, 0500, grsecurity_table},
17041 +#endif
17042 +       {0}
17043 +};
17044 +
17045 +#ifdef CONFIG_GRKERNSEC_SYSCTL
17046 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL, 
17047 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
17048 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
17049 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS, 
17050 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL,
17051 +GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
17052 +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
17053 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
17054 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
17055 +GS_FINDTASK, GS_LOCK};
17056 +
17057 +static ctl_table grsecurity_table[] = {
17058 +#ifdef CONFIG_GRKERNSEC_LINK
17059 +       {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int),
17060 +        0600, NULL, &proc_dointvec}, 
17061 +#endif
17062 +#ifdef CONFIG_GRKERNSEC_FIFO
17063 +       {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int),
17064 +        0600, NULL, &proc_dointvec},
17065 +#endif
17066 +#ifdef CONFIG_GRKERNSEC_EXECVE
17067 +       {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int),
17068 +        0600, NULL, &proc_dointvec},
17069 +#endif
17070 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17071 +       {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int),
17072 +        0600, NULL, &proc_dointvec},
17073 +#endif
17074 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17075 +       {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int),
17076 +        0600, NULL, &proc_dointvec},
17077 +#endif
17078 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
17079 +       {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int),
17080 +        0600, NULL, &proc_dointvec},
17081 +#endif
17082 +#ifdef CONFIG_GRKERNSEC_TIME
17083 +       {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int),
17084 +        0600, NULL, &proc_dointvec},
17085 +#endif
17086 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17087 +       {GS_CHROOT_SHMAT, "chroot_deny_shmat", &grsec_enable_chroot_shmat, sizeof (int),
17088 +        0600, NULL, &proc_dointvec},
17089 +#endif
17090 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17091 +       {GS_CHROOT_UNIX, "chroot_deny_unix", &grsec_enable_chroot_unix, sizeof(int),
17092 +        0600, NULL, &proc_dointvec},
17093 +#endif
17094 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17095 +       {GS_CHROOT_MNT, "chroot_deny_mount", &grsec_enable_chroot_mount, sizeof (int),
17096 +        0600, NULL, &proc_dointvec},
17097 +#endif
17098 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17099 +       {GS_CHROOT_FCHDIR, "chroot_deny_fchdir", &grsec_enable_chroot_fchdir, sizeof (int),
17100 +        0600, NULL, &proc_dointvec},
17101 +#endif
17102 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17103 +       {GS_CHROOT_DBL, "chroot_deny_chroot", &grsec_enable_chroot_double, sizeof (int),
17104 +        0600, NULL, &proc_dointvec},
17105 +#endif
17106 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17107 +       {GS_CHROOT_PVT, "chroot_deny_pivot", &grsec_enable_chroot_pivot, sizeof (int),
17108 +        0600, NULL, &proc_dointvec},
17109 +#endif
17110 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17111 +       {GS_CHROOT_CD, "chroot_enforce_chdir", &grsec_enable_chroot_chdir, sizeof (int),
17112 +        0600, NULL, &proc_dointvec},
17113 +#endif
17114 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17115 +       {GS_CHROOT_CM, "chroot_deny_chmod", &grsec_enable_chroot_chmod, sizeof (int),
17116 +        0600, NULL, &proc_dointvec},
17117 +#endif
17118 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17119 +       {GS_CHROOT_MK, "chroot_deny_mknod", &grsec_enable_chroot_mknod, sizeof (int),
17120 +        0600, NULL, &proc_dointvec},
17121 +#endif
17122 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17123 +       {GS_CHROOT_NI, "chroot_restrict_nice", &grsec_enable_chroot_nice, sizeof (int),
17124 +        0600, NULL, &proc_dointvec},
17125 +#endif
17126 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17127 +       {GS_CHROOT_EXECLOG, "chroot_execlog",
17128 +        &grsec_enable_chroot_execlog, sizeof (int),
17129 +         0600, NULL, &proc_dointvec},
17130 +#endif
17131 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17132 +       {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int),
17133 +        0600, NULL, &proc_dointvec},
17134 +#endif
17135 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17136 +       {GS_CHROOT_SYSCTL, "chroot_deny_sysctl", &grsec_enable_chroot_sysctl, sizeof (int),
17137 +        0600, NULL, &proc_dointvec},
17138 +#endif
17139 +#ifdef CONFIG_GRKERNSEC_TPE
17140 +       {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int),
17141 +        0600, NULL, &proc_dointvec},
17142 +       {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int),
17143 +        0600, NULL, &proc_dointvec},
17144 +#endif
17145 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
17146 +       {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int),
17147 +        0600, NULL, &proc_dointvec},
17148 +#endif
17149 +#ifdef CONFIG_GRKERNSEC_RANDPID
17150 +       {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int),
17151 +        0600, NULL, &proc_dointvec},
17152 +#endif
17153 +#ifdef CONFIG_GRKERNSEC_RANDID
17154 +       {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int),
17155 +        0600, NULL, &proc_dointvec},
17156 +#endif
17157 +#ifdef CONFIG_GRKERNSEC_RANDSRC
17158 +       {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int),
17159 +        0600, NULL, &proc_dointvec},
17160 +#endif
17161 +#ifdef CONFIG_GRKERNSEC_RANDISN
17162 +       {GS_RANDISN, "rand_isns", &grsec_enable_randisn, sizeof (int),
17163 +        0600, NULL, &proc_dointvec},
17164 +#endif
17165 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
17166 +       {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int),
17167 +        0600, NULL, &proc_dointvec},
17168 +       {GS_SOCKET_ALL_GID, "socket_all_gid",
17169 +        &grsec_socket_all_gid, sizeof (int),
17170 +        0600, NULL, &proc_dointvec},
17171 +#endif
17172 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
17173 +       {GS_SOCKET_CLIENT, "socket_client", 
17174 +        &grsec_enable_socket_client, sizeof (int),
17175 +        0600, NULL, &proc_dointvec},
17176 +       {GS_SOCKET_CLIENT_GID, "socket_client_gid", 
17177 +        &grsec_socket_client_gid, sizeof (int),
17178 +        0600, NULL, &proc_dointvec},
17179 +#endif
17180 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17181 +       {GS_SOCKET_SERVER, "socket_server", 
17182 +        &grsec_enable_socket_server, sizeof (int),
17183 +        0600, NULL, &proc_dointvec},
17184 +       {GS_SOCKET_SERVER_GID, "socket_server_gid",
17185 +        &grsec_socket_server_gid, sizeof (int),
17186 +        0600, NULL, &proc_dointvec},
17187 +#endif
17188 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
17189 +       {GS_GROUP, "audit_group", &grsec_enable_group, sizeof (int),
17190 +        0600, NULL, &proc_dointvec},
17191 +       {GS_GID, "audit_gid",
17192 +        &grsec_audit_gid, sizeof (int),
17193 +        0600, NULL, &proc_dointvec},
17194 +#endif
17195 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17196 +       {GS_ACHDIR, "audit_chdir", &grsec_enable_chdir, sizeof (int),
17197 +        0600, NULL, &proc_dointvec},
17198 +#endif
17199 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17200 +       {GS_AMOUNT, "audit_mount", &grsec_enable_mount, sizeof (int),
17201 +        0600, NULL, &proc_dointvec},
17202 +#endif
17203 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17204 +       {GS_AIPC, "audit_ipc", &grsec_enable_audit_ipc, sizeof (int),
17205 +        0600, NULL, &proc_dointvec},
17206 +#endif
17207 +#ifdef CONFIG_GRKERNSEC_DMESG
17208 +       {GS_DMSG, "dmesg", &grsec_enable_dmesg, sizeof (int),
17209 +        0600, NULL, &proc_dointvec},
17210 +#endif
17211 +#ifdef CONFIG_GRKERNSEC_RANDRPC
17212 +       {GS_RANDRPC, "rand_rpc", &grsec_enable_randrpc, sizeof (int),
17213 +        0600, NULL, &proc_dointvec},
17214 +#endif
17215 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17216 +       {GS_FINDTASK, "chroot_findtask", &grsec_enable_chroot_findtask, 
17217 +        sizeof (int), 0600, NULL, &proc_dointvec},
17218 +#endif
17219 +       {GS_LOCK, "grsec_lock", &grsec_lock, sizeof (int), 0600, NULL,
17220 +        &proc_dointvec},
17221         {0}
17222  };
17223 +#endif
17224  
17225  static ctl_table vm_table[] = {
17226         {VM_GFP_DEBUG, "vm_gfp_debug", 
17227 @@ -427,6 +619,11 @@
17228  
17229  static inline int ctl_perm(ctl_table *table, int op)
17230  {
17231 +       if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
17232 +               return -EACCES;
17233 +       if (gr_handle_chroot_sysctl(op))
17234 +               return -EACCES;
17235 +
17236         return test_perm(table->mode, op);
17237  }
17238  
17239 @@ -460,6 +657,10 @@
17240                                 table = table->child;
17241                                 goto repeat;
17242                         }
17243 +
17244 +                       if (!gr_handle_sysctl(table, oldval, newval))
17245 +                               return -EACCES;
17246 +
17247                         error = do_sysctl_strategy(table, name, nlen,
17248                                                    oldval, oldlenp,
17249                                                    newval, newlen, context);
17250 diff -urN linux-2.4.24.org/kernel/time.c linux-2.4.24/kernel/time.c
17251 --- linux-2.4.24.org/kernel/time.c      2004-01-05 18:41:08.665671984 +0100
17252 +++ linux-2.4.24/kernel/time.c  2004-01-05 18:43:05.972838584 +0100
17253 @@ -27,6 +27,7 @@
17254  #include <linux/mm.h>
17255  #include <linux/timex.h>
17256  #include <linux/smp_lock.h>
17257 +#include <linux/grsecurity.h>
17258  
17259  #include <asm/uaccess.h>
17260  
17261 @@ -89,6 +90,9 @@
17262         time_maxerror = NTP_PHASE_LIMIT;
17263         time_esterror = NTP_PHASE_LIMIT;
17264         write_unlock_irq(&xtime_lock);
17265 +
17266 +       gr_log_timechange();
17267 +
17268         return 0;
17269  }
17270  
17271 @@ -167,6 +171,8 @@
17272                  * globally block out interrupts when it runs.
17273                  */
17274                 do_settimeofday(tv);
17275 +
17276 +               gr_log_timechange();
17277         }
17278         return 0;
17279  }
17280 diff -urN linux-2.4.24.org/kernel/timer.c linux-2.4.24/kernel/timer.c
17281 --- linux-2.4.24.org/kernel/timer.c     2004-01-05 18:41:08.735661344 +0100
17282 +++ linux-2.4.24/kernel/timer.c 2004-01-05 18:43:05.975838128 +0100
17283 @@ -565,6 +565,9 @@
17284  
17285         psecs = (p->times.tms_utime += user);
17286         psecs += (p->times.tms_stime += system);
17287 +
17288 +       gr_learn_resource(p, RLIMIT_CPU, psecs / HZ, 1);
17289 +
17290         if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
17291                 /* Send SIGXCPU every second.. */
17292                 if (!(psecs % HZ))
17293 diff -urN linux-2.4.24.org/Makefile linux-2.4.24/Makefile
17294 --- linux-2.4.24.org/Makefile   2004-01-05 18:41:08.305726704 +0100
17295 +++ linux-2.4.24/Makefile       2004-01-05 18:43:03.257251416 +0100
17296 @@ -134,9 +134,10 @@
17297  
17298  CORE_FILES     =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
17299  NETWORKS       =net/network.o
17300 +GRSECURITY     =grsecurity/grsec.o
17301  
17302  LIBS           =$(TOPDIR)/lib/lib.a
17303 -SUBDIRS                =kernel drivers mm fs net ipc lib crypto
17304 +SUBDIRS                =kernel drivers mm fs net ipc lib crypto grsecurity
17305  
17306  DRIVERS-n :=
17307  DRIVERS-y :=
17308 @@ -280,7 +281,7 @@
17309  
17310  export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
17311  
17312 -export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
17313 +export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS GRSECURITY
17314  
17315  .S.s:
17316         $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
17317 @@ -299,6 +300,7 @@
17318                 $(CORE_FILES) \
17319                 $(DRIVERS) \
17320                 $(NETWORKS) \
17321 +               $(GRSECURITY) \
17322                 $(LIBS) \
17323                 --end-group \
17324                 -o vmlinux
17325 diff -urN linux-2.4.24.org/mm/filemap.c linux-2.4.24/mm/filemap.c
17326 --- linux-2.4.24.org/mm/filemap.c       2004-01-05 18:40:39.047174680 +0100
17327 +++ linux-2.4.24/mm/filemap.c   2004-01-05 18:43:06.004833720 +0100
17328 @@ -2320,6 +2320,12 @@
17329         }
17330         if (!mapping->a_ops->readpage)
17331                 return -ENOEXEC;
17332 +
17333 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17334 +       if (current->flags & PF_PAX_PAGEEXEC)
17335 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
17336 +#endif
17337 +
17338         UPDATE_ATIME(inode);
17339         vma->vm_ops = &generic_file_vm_ops;
17340         return 0;
17341 @@ -2549,8 +2555,42 @@
17342   * We can potentially split a vm area into separate
17343   * areas, each area with its own behavior.
17344   */
17345 +
17346 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17347 +static long __madvise_behavior(struct vm_area_struct * vma,
17348 +       unsigned long start, unsigned long end, int behavior);
17349 +
17350 +static long madvise_behavior(struct vm_area_struct * vma,
17351 +       unsigned long start, unsigned long end, int behavior)
17352 +{
17353 +       if (vma->vm_flags & VM_MIRROR) {
17354 +               struct vm_area_struct * vma_m, * prev_m;
17355 +               unsigned long start_m, end_m;
17356 +               int error;
17357 +
17358 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17359 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
17360 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
17361 +                       start_m = start + (unsigned long)vma->vm_private_data;
17362 +                       end_m = end + (unsigned long)vma->vm_private_data;
17363 +                       error = __madvise_behavior(vma_m, start_m, end_m, behavior);
17364 +                       if (error)
17365 +                               return error;
17366 +               } else {
17367 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
17368 +                       return -ENOMEM;
17369 +               }
17370 +       }
17371 +
17372 +       return __madvise_behavior(vma, start, end, behavior);
17373 +}
17374 +
17375 +static long __madvise_behavior(struct vm_area_struct * vma,
17376 +       unsigned long start, unsigned long end, int behavior)
17377 +#else
17378  static long madvise_behavior(struct vm_area_struct * vma,
17379         unsigned long start, unsigned long end, int behavior)
17380 +#endif
17381  {
17382         int error = 0;
17383  
17384 @@ -2604,6 +2644,7 @@
17385         error = -EIO;
17386         rlim_rss = current->rlim ?  current->rlim[RLIMIT_RSS].rlim_cur :
17387                                 LONG_MAX; /* default: see resource.h */
17388 +       gr_learn_resource(current, RLIMIT_RSS, vma->vm_mm->rss + (end - start), 1);
17389         if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
17390                 return error;
17391  
17392 @@ -3087,6 +3128,7 @@
17393         err = -EFBIG;
17394         
17395         if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
17396 +               gr_learn_resource(current, RLIMIT_FSIZE, pos, 0);
17397                 if (pos >= limit) {
17398                         send_sig(SIGXFSZ, current, 0);
17399                         goto out;
17400 @@ -3122,6 +3164,7 @@
17401          */
17402          
17403         if (!S_ISBLK(inode->i_mode)) {
17404 +               gr_learn_resource(current, RLIMIT_FSIZE, *count + (u32)pos, 0);
17405                 if (pos >= inode->i_sb->s_maxbytes)
17406                 {
17407                         if (*count || pos > inode->i_sb->s_maxbytes) {
17408 diff -urN linux-2.4.24.org/mm/memory.c linux-2.4.24/mm/memory.c
17409 --- linux-2.4.24.org/mm/memory.c        2004-01-05 18:40:38.877200520 +0100
17410 +++ linux-2.4.24/mm/memory.c    2004-01-05 18:43:06.034829160 +0100
17411 @@ -925,6 +925,65 @@
17412         establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
17413  }
17414  
17415 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17416 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
17417 + *
17418 + * mm->page_table_lock is held on entry and is not released on exit or inside
17419 + * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
17420 + */
17421 +static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
17422 +       unsigned long address, pte_t *pte)
17423 +{
17424 +       unsigned long address_m;
17425 +       struct vm_area_struct * vma_m = NULL;
17426 +       pte_t * pte_m, entry_m;
17427 +       struct page * page_m;
17428 +
17429 +       if (!(vma->vm_flags & VM_MIRROR))
17430 +               return;
17431 +
17432 +       address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17433 +       vma_m = find_vma(mm, address_m);
17434 +       if (!vma_m || vma_m->vm_start != address_m)
17435 +               return;
17436 +
17437 +       address_m = address + (unsigned long)vma->vm_private_data;
17438 +
17439 +       {
17440 +               pgd_t *pgd_m;
17441 +               pmd_t *pmd_m;
17442 +
17443 +               pgd_m = pgd_offset(mm, address_m);
17444 +               pmd_m = pmd_offset(pgd_m, address_m);
17445 +               pte_m = pte_offset(pmd_m, address_m);
17446 +       }
17447 +
17448 +       if (pte_present(*pte_m)) {
17449 +               flush_cache_page(vma_m, address_m);
17450 +               flush_icache_page(vma_m, pte_page(*pte_m));
17451 +       }
17452 +       entry_m = ptep_get_and_clear(pte_m);
17453 +       if (pte_present(entry_m))
17454 +               flush_tlb_page(vma_m, address_m);  
17455 +
17456 +       if (pte_none(entry_m)) {
17457 +               ++mm->rss;
17458 +       } else if (pte_present(entry_m)) {
17459 +               page_cache_release(pte_page(entry_m));
17460 +       } else {
17461 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
17462 +               ++mm->rss;
17463 +       }
17464 +
17465 +       page_m = pte_page(*pte);
17466 +       page_cache_get(page_m);
17467 +       entry_m = mk_pte(page_m, vma_m->vm_page_prot);
17468 +       if (pte_write(*pte))
17469 +               entry_m = pte_mkdirty(pte_mkwrite(entry_m));
17470 +       establish_pte(vma_m, address_m, pte_m, entry_m);  
17471 +}                      
17472 +#endif
17473 +
17474  /*
17475   * This routine handles present pages, when users try to write
17476   * to a shared page. It is done by copying the page to a new address
17477 @@ -988,6 +1047,11 @@
17478  
17479                 /* Free the old page.. */
17480                 new_page = old_page;
17481 +
17482 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17483 +               pax_mirror_fault(mm, vma, address, page_table);
17484 +#endif
17485 +
17486         }
17487         spin_unlock(&mm->page_table_lock);
17488         page_cache_release(new_page);
17489 @@ -1065,6 +1129,7 @@
17490  
17491  do_expand:
17492         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
17493 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
17494         if (limit != RLIM_INFINITY && offset > limit)
17495                 goto out_sig;
17496         if (offset > inode->i_sb->s_maxbytes)
17497 @@ -1178,6 +1243,11 @@
17498  
17499         /* No need to invalidate - it was non-present before */
17500         update_mmu_cache(vma, address, pte);
17501 +
17502 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17503 +       pax_mirror_fault(mm, vma, address, page_table);
17504 +#endif
17505 +
17506         spin_unlock(&mm->page_table_lock);
17507         return ret;
17508  }
17509 @@ -1223,6 +1293,11 @@
17510  
17511         /* No need to invalidate - it was non-present before */
17512         update_mmu_cache(vma, addr, entry);
17513 +
17514 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17515 +       pax_mirror_fault(mm, vma, addr, page_table);
17516 +#endif
17517 +
17518         spin_unlock(&mm->page_table_lock);
17519         return 1;       /* Minor fault */
17520  
17521 @@ -1304,6 +1379,11 @@
17522  
17523         /* no need to invalidate: a not-present page shouldn't be cached */
17524         update_mmu_cache(vma, address, entry);
17525 +
17526 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17527 +       pax_mirror_fault(mm, vma, address, page_table);
17528 +#endif
17529 +
17530         spin_unlock(&mm->page_table_lock);
17531         return 2;       /* Major fault */
17532  }
17533 @@ -1368,6 +1448,11 @@
17534         pgd_t *pgd;
17535         pmd_t *pmd;
17536  
17537 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17538 +       unsigned long address_m = 0UL;
17539 +       struct vm_area_struct * vma_m = NULL;
17540 +#endif
17541 +
17542         current->state = TASK_RUNNING;
17543         pgd = pgd_offset(mm, address);
17544  
17545 @@ -1376,6 +1461,47 @@
17546          * and the SMP-safe atomic PTE updates.
17547          */
17548         spin_lock(&mm->page_table_lock);
17549 +
17550 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17551 +       if (vma->vm_flags & VM_MIRROR) {
17552 +               pgd_t *pgd_m;
17553 +               pmd_t *pmd_m;
17554 +               pte_t *pte_m;
17555 +
17556 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17557 +               vma_m = find_vma(mm, address_m);
17558 +
17559 +               /* PaX: sanity checks */
17560 +               if (!vma_m) {
17561 +                       spin_unlock(&mm->page_table_lock);
17562 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
17563 +                              address, vma, address_m, vma_m);
17564 +                       return 0;
17565 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
17566 +                          vma_m->vm_start != address_m ||
17567 +                          vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
17568 +               {
17569 +                       spin_unlock(&mm->page_table_lock);
17570 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
17571 +                               address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
17572 +                       return 0;
17573 +               }
17574 +
17575 +               address_m = address + (unsigned long)vma->vm_private_data;
17576 +               pgd_m = pgd_offset(mm, address_m);
17577 +               pmd_m = pmd_alloc(mm, pgd_m, address_m);
17578 +               if (!pmd_m) {
17579 +                       spin_unlock(&mm->page_table_lock);
17580 +                       return -1;
17581 +               }
17582 +               pte_m = pte_alloc(mm, pmd_m, address_m);
17583 +               if (!pte_m) {
17584 +                       spin_unlock(&mm->page_table_lock);
17585 +                       return -1;
17586 +               }
17587 +       }                       
17588 +#endif
17589 +
17590         pmd = pmd_alloc(mm, pgd, address);
17591  
17592         if (pmd) {
17593 diff -urN linux-2.4.24.org/mm/mlock.c linux-2.4.24/mm/mlock.c
17594 --- linux-2.4.24.org/mm/mlock.c 2004-01-05 18:40:38.983184408 +0100
17595 +++ linux-2.4.24/mm/mlock.c     2004-01-05 18:43:06.043827792 +0100
17596 @@ -114,9 +114,40 @@
17597         return 0;
17598  }
17599  
17600 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17601 +static int __mlock_fixup(struct vm_area_struct * vma,
17602 +       unsigned long start, unsigned long end, unsigned int newflags);
17603  static int mlock_fixup(struct vm_area_struct * vma, 
17604         unsigned long start, unsigned long end, unsigned int newflags)
17605  {
17606 +       if (vma->vm_flags & VM_MIRROR) {
17607 +               struct vm_area_struct * vma_m;
17608 +               unsigned long start_m, end_m;
17609 +               int error;
17610 +
17611 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17612 +               vma_m = find_vma(vma->vm_mm, start_m);
17613 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
17614 +                       start_m = start + (unsigned long)vma->vm_private_data;
17615 +                       end_m = end + (unsigned long)vma->vm_private_data;
17616 +                       error = __mlock_fixup(vma_m, start_m, end_m, newflags);
17617 +                       if (error)
17618 +                               return error;
17619 +               } else {
17620 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
17621 +                       return -ENOMEM;
17622 +               }
17623 +       }
17624 +       return __mlock_fixup(vma, start, end, newflags);
17625 +}
17626 +
17627 +static int __mlock_fixup(struct vm_area_struct * vma,
17628 +       unsigned long start, unsigned long end, unsigned int newflags)
17629 +#else
17630 +static int mlock_fixup(struct vm_area_struct * vma,
17631 +       unsigned long start, unsigned long end, unsigned int newflags)
17632 +#endif
17633 +{
17634         int pages, retval;
17635  
17636         if (newflags == vma->vm_flags)
17637 @@ -159,6 +190,17 @@
17638                 return -EINVAL;
17639         if (end == start)
17640                 return 0;
17641 +
17642 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17643 +       if (current->flags & PF_PAX_SEGMEXEC) {
17644 +               if (end > SEGMEXEC_TASK_SIZE)
17645 +                       return -EINVAL;
17646 +       } else
17647 +#endif
17648 +
17649 +       if (end > TASK_SIZE)
17650 +               return -EINVAL;
17651 +
17652         vma = find_vma(current->mm, start);
17653         if (!vma || vma->vm_start > start)
17654                 return -ENOMEM;
17655 @@ -209,6 +251,7 @@
17656         lock_limit >>= PAGE_SHIFT;
17657  
17658         /* check against resource limits */
17659 +       gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
17660         if (locked > lock_limit)
17661                 goto out;
17662  
17663 @@ -253,6 +296,16 @@
17664         for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
17665                 unsigned int newflags;
17666  
17667 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17668 +               if (current->flags & PF_PAX_SEGMEXEC) {
17669 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
17670 +                               break;
17671 +               } else
17672 +#endif
17673 +
17674 +               if (vma->vm_end > TASK_SIZE)
17675 +                       break;
17676 +
17677                 newflags = vma->vm_flags | VM_LOCKED;
17678                 if (!(flags & MCL_CURRENT))
17679                         newflags &= ~VM_LOCKED;
17680 @@ -276,6 +329,7 @@
17681         lock_limit >>= PAGE_SHIFT;
17682  
17683         ret = -ENOMEM;
17684 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
17685         if (current->mm->total_vm > lock_limit)
17686                 goto out;
17687  
17688 diff -urN linux-2.4.24.org/mm/mmap.c linux-2.4.24/mm/mmap.c
17689 --- linux-2.4.24.org/mm/mmap.c  2004-01-05 18:40:38.911195352 +0100
17690 +++ linux-2.4.24/mm/mmap.c      2004-01-05 18:43:06.068823992 +0100
17691 @@ -14,6 +14,8 @@
17692  #include <linux/file.h>
17693  #include <linux/fs.h>
17694  #include <linux/personality.h>
17695 +#include <linux/random.h>
17696 +#include <linux/grsecurity.h>
17697  
17698  #include <asm/uaccess.h>
17699  #include <asm/pgalloc.h>
17700 @@ -168,6 +170,7 @@
17701  
17702         /* Check against rlimit.. */
17703         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
17704 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
17705         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
17706                 goto out;
17707  
17708 @@ -205,6 +208,11 @@
17709                 _trans(prot, PROT_WRITE, VM_WRITE) |
17710                 _trans(prot, PROT_EXEC, VM_EXEC);
17711         flag_bits =
17712 +
17713 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17714 +               _trans(flags, MAP_MIRROR, VM_MIRROR) |
17715 +#endif
17716 +
17717                 _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
17718                 _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
17719                 _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
17720 @@ -401,6 +409,28 @@
17721         int error;
17722         rb_node_t ** rb_link, * rb_parent;
17723  
17724 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17725 +       struct vm_area_struct * vma_m = NULL;
17726 +       
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 (file && (!file->f_op || !file->f_op->mmap))
17747                 return -ENODEV;
17748  
17749 @@ -433,10 +463,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 @@ -481,6 +533,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 @@ -491,10 +546,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 @@ -518,6 +579,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 @@ -546,6 +614,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 @@ -581,6 +657,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 @@ -617,20 +696,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 @@ -792,6 +900,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 @@ -917,6 +1028,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 @@ -926,6 +1114,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 @@ -958,60 +1150,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 +       extra = unmap_vma_list(mm, addr, len, free, extra, prev);
18066  
18067 -               st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
18068 -               end = addr+len;
18069 -               end = end > mpnt->vm_end ? mpnt->vm_end : end;
18070 -               size = end - st;
18071 -
18072 -               if (mpnt->vm_flags & VM_DENYWRITE &&
18073 -                   (st != mpnt->vm_start || end != mpnt->vm_end) &&
18074 -                   (file = mpnt->vm_file) != NULL) {
18075 -                       atomic_dec(&file->f_dentry->d_inode->i_writecount);
18076 -               }
18077 -               remove_shared_vm_struct(mpnt);
18078 -               mm->map_count--;
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 @@ -1020,8 +1221,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 @@ -1051,6 +1259,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 @@ -1067,6 +1276,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 @@ -1079,6 +1289,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 @@ -1094,6 +1315,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 diff -urN linux-2.4.24.org/mm/mprotect.c linux-2.4.24/mm/mprotect.c
18172 --- linux-2.4.24.org/mm/mprotect.c      2004-01-05 18:40:38.898197328 +0100
18173 +++ linux-2.4.24/mm/mprotect.c  2004-01-05 19:13:05.192315648 +0100
18174 @@ -7,6 +7,12 @@
18175  #include <linux/smp_lock.h>
18176  #include <linux/shm.h>
18177  #include <linux/mman.h>
18178 +#include <linux/grsecurity.h>
18179 +
18180 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18181 +#include <linux/elf.h>
18182 +#include <linux/fs.h>
18183 +#endif
18184  
18185  #include <asm/uaccess.h>
18186  #include <asm/pgalloc.h>
18187 @@ -236,9 +242,45 @@
18188         return 0;
18189  }
18190  
18191 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18192 +static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18193 +       unsigned long start, unsigned long end, unsigned int newflags);
18194 +
18195  static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18196         unsigned long start, unsigned long end, unsigned int newflags)
18197  {
18198 +       if (vma->vm_flags & VM_MIRROR) {
18199 +               struct vm_area_struct * vma_m, * prev_m;
18200 +               unsigned long start_m, end_m;
18201 +               int error;
18202 +
18203 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
18204 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
18205 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
18206 +                       start_m = start + (unsigned long)vma->vm_private_data;
18207 +                       end_m = end + (unsigned long)vma->vm_private_data;
18208 +                       if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
18209 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
18210 +                       else
18211 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
18212 +                       if (error)
18213 +                               return error;
18214 +               } else {
18215 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
18216 +                       return -ENOMEM;
18217 +               }
18218 +       }
18219 +
18220 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
18221 +}
18222 +
18223 +static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18224 +       unsigned long start, unsigned long end, unsigned int newflags)
18225 +#else
18226 +static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
18227 +       unsigned long start, unsigned long end, unsigned int newflags)
18228 +#endif
18229 +{
18230         pgprot_t newprot;
18231         int error;
18232  
18233 @@ -246,6 +288,12 @@
18234                 *pprev = vma;
18235                 return 0;
18236         }
18237 +
18238 +#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
18239 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
18240 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
18241 +       else
18242 +#endif
18243         newprot = protection_map[newflags & 0xf];
18244         if (start == vma->vm_start) {
18245                 if (end == vma->vm_end)
18246 @@ -277,6 +325,14 @@
18247         end = start + len;
18248         if (end < start)
18249                 return -ENOMEM;
18250 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
18251 +       if (current->flags & PF_PAX_SEGMEXEC) {
18252 +               if (end > SEGMEXEC_TASK_SIZE)
18253 +                       return -EINVAL;
18254 +       } else
18255 +#endif
18256 +       if (end > TASK_SIZE)
18257 +               return -EINVAL;
18258         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
18259                 return -EINVAL;
18260         if (end == start)
18261 @@ -288,7 +344,15 @@
18262         error = -ENOMEM;
18263         if (!vma || vma->vm_start > start)
18264                 goto out;
18265 -
18266 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
18267 +               error = -EACCES;
18268 +               goto out;
18269 +       }
18270 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18271 +       if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
18272 +               pax_handle_maywrite(vma, start);
18273 +#endif
18274 +       
18275         for (nstart = start ; ; ) {
18276                 unsigned int newflags;
18277                 int last = 0;
18278 @@ -306,6 +370,12 @@
18279                         if (error < 0)
18280                                 goto out;
18281                 }
18282 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18283 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
18284 +               if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
18285 +                       newflags &= ~VM_MAYWRITE;
18286 +#endif
18287 +    
18288                 if (vma->vm_end > end) {
18289                         error = mprotect_fixup(vma, &prev, nstart, end, newflags);
18290                         goto out;
18291 @@ -342,6 +412,68 @@
18292         return error;
18293  }
18294  
18295 +#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
18296 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
18297 + * therefore we'll grant them VM_MAYWRITE once during their life.
18298 + *
18299 + * The checks favor ld-linux.so behaviour which operates on a per ELF segment
18300 + * basis because we want to allow the common case and not the special ones.
18301 + */
18302 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
18303 +{
18304 +       struct elfhdr elf_h;
18305 +       struct elf_phdr elf_p, p_dyn;
18306 +       elf_dyn dyn;
18307 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
18308 +
18309 +#ifndef CONFIG_GRKERNSEC_PAX_NOELFRELOCS
18310 +       if ((vma->vm_start != start) ||
18311 +           !vma->vm_file ||
18312 +           !(vma->vm_flags & VM_MAYEXEC) ||
18313 +           (vma->vm_flags & VM_MAYNOTWRITE))
18314 +#endif
18315 +
18316 +               return;
18317 +
18318 +       if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
18319 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
18320 +
18321 +#ifdef CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
18322 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
18323 +#else
18324 +           elf_h.e_type != ET_DYN ||
18325 +#endif
18326 +
18327 +           !elf_check_arch(&elf_h) ||
18328 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
18329 +           elf_h.e_phnum > j)
18330 +               return;
18331 +
18332 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
18333 +               if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
18334 +                       return;
18335 +               if (elf_p.p_type == PT_DYNAMIC) {
18336 +                       p_dyn = elf_p;
18337 +                       j = i;
18338 +               }
18339 +       }
18340 +       if (elf_h.e_phnum <= j)
18341 +               return;
18342 +
18343 +       i = 0UL;
18344 +       do {
18345 +               if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
18346 +                       return;
18347 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
18348 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
18349 +                       return;
18350 +               }
18351 +               i++;
18352 +       } while (dyn.d_tag != DT_NULL);
18353 +       return;
18354 +}
18355 +#endif
18356 +
18357  asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
18358  {
18359          return(do_mprotect(current->mm, start, len, prot));
18360 diff -urN linux-2.4.24.org/mm/mremap.c linux-2.4.24/mm/mremap.c
18361 --- linux-2.4.24.org/mm/mremap.c        2004-01-05 18:40:39.134161456 +0100
18362 +++ linux-2.4.24/mm/mremap.c    2004-01-05 18:43:06.104818520 +0100
18363 @@ -193,7 +193,9 @@
18364                 }
18365  
18366                 do_munmap(current->mm, addr, old_len);
18367 -
18368 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18369 +               if (!(new_vma->vm_flags & VM_MIRROR))
18370 +#endif
18371                 current->mm->total_vm += new_len >> PAGE_SHIFT;
18372                 if (vm_locked) {
18373                         current->mm->locked_vm += new_len >> PAGE_SHIFT;
18374 @@ -232,6 +234,18 @@
18375         old_len = PAGE_ALIGN(old_len);
18376         new_len = PAGE_ALIGN(new_len);
18377  
18378 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
18379 +       if (current->flags & PF_PAX_SEGMEXEC) {
18380 +               if (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
18381 +                   old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)
18382 +                       goto out;
18383 +       } else
18384 +#endif
18385 +
18386 +       if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
18387 +           old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
18388 +               goto out;
18389 +
18390         /* new_addr is only valid if MREMAP_FIXED is specified */
18391         if (flags & MREMAP_FIXED) {
18392                 if (new_addr & ~PAGE_MASK)
18393 @@ -249,6 +263,16 @@
18394                 if (unlikely(!new_len && new_addr != addr))
18395                         goto out;
18396  
18397 +#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
18398 +               if (current->flags & PF_PAX_SEGMEXEC) {
18399 +                       if (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)
18400 +                       goto out;
18401 +               } else
18402 +#endif
18403 +
18404 +               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
18405 +                       goto out;
18406 +
18407                 /* Check if the location we're moving into overlaps the
18408                  * old location at all, and fail if it does.
18409                  */
18410 @@ -279,6 +303,16 @@
18411         vma = find_vma(current->mm, addr);
18412         if (!vma || vma->vm_start > addr)
18413                 goto out;
18414 +
18415 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18416 +       if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
18417 +           (vma->vm_flags & VM_MIRROR))
18418 +       {
18419 +               ret = -EINVAL;
18420 +               goto out;
18421 +       }
18422 +#endif
18423 +
18424         /* We can't remap across vm area boundaries */
18425         if (old_len > vma->vm_end - addr)
18426                 goto out;
18427 @@ -290,13 +324,22 @@
18428                 unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
18429                 locked += new_len - old_len;
18430                 ret = -EAGAIN;
18431 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
18432                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
18433                         goto out;
18434         }
18435         ret = -ENOMEM;
18436 +
18437 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18438 +       if (!(vma->vm_flags & VM_MIRROR)) {
18439 +#endif   
18440 +       gr_learn_resource(current, RLIMIT_AS, (current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len), 1);
18441         if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
18442             > current->rlim[RLIMIT_AS].rlim_cur)
18443                 goto out;
18444 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18445 +       }
18446 +#endif
18447         /* Private writable mapping? Check memory availability.. */
18448         if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
18449             !(flags & MAP_NORESERVE)                             &&
18450 @@ -318,6 +361,9 @@
18451                         spin_lock(&vma->vm_mm->page_table_lock);
18452                         vma->vm_end = addr + new_len;
18453                         spin_unlock(&vma->vm_mm->page_table_lock);
18454 +#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
18455 +                       if (!(vma->vm_flags & VM_MIRROR))
18456 +#endif   
18457                         current->mm->total_vm += pages;
18458                         if (vma->vm_flags & VM_LOCKED) {
18459                                 current->mm->locked_vm += pages;
18460 diff -urN linux-2.4.24.org/net/ipv4/af_inet.c linux-2.4.24/net/ipv4/af_inet.c
18461 --- linux-2.4.24.org/net/ipv4/af_inet.c 2004-01-05 18:39:54.000000000 +0100
18462 +++ linux-2.4.24/net/ipv4/af_inet.c     2004-01-05 18:43:06.130814568 +0100
18463 @@ -83,6 +83,7 @@
18464  #include <linux/init.h>
18465  #include <linux/poll.h>
18466  #include <linux/netfilter_ipv4.h>
18467 +#include <linux/grsecurity.h>
18468  
18469  #include <asm/uaccess.h>
18470  #include <asm/system.h>
18471 @@ -374,7 +375,12 @@
18472         else
18473                 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
18474  
18475 -       sk->protinfo.af_inet.id = 0;
18476 +#ifdef CONFIG_GRKERNSEC_RANDID
18477 +       if(grsec_enable_randid)
18478 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18479 +       else
18480 +#endif
18481 +               sk->protinfo.af_inet.id = 0;
18482  
18483         sock_init_data(sock,sk);
18484  
18485 diff -urN linux-2.4.24.org/net/ipv4/ip_output.c linux-2.4.24/net/ipv4/ip_output.c
18486 --- linux-2.4.24.org/net/ipv4/ip_output.c       2004-01-05 18:39:53.000000000 +0100
18487 +++ linux-2.4.24/net/ipv4/ip_output.c   2004-01-05 18:43:06.150811528 +0100
18488 @@ -77,6 +77,7 @@
18489  #include <linux/netfilter_ipv4.h>
18490  #include <linux/mroute.h>
18491  #include <linux/netlink.h>
18492 +#include <linux/grsecurity.h>
18493  
18494  /*
18495   *      Shall we try to damage output packets if routing dev changes?
18496 @@ -514,7 +515,13 @@
18497          *      Begin outputting the bytes.
18498          */
18499  
18500 -       id = sk->protinfo.af_inet.id++;
18501 +#ifdef CONFIG_GRKERNSEC_RANDID
18502 +       if(grsec_enable_randid) { 
18503 +               id = htons(ip_randomid());      
18504 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18505 +       } else
18506 +#endif
18507 +               id = sk->protinfo.af_inet.id++;
18508  
18509         do {
18510                 char *data;
18511 diff -urN linux-2.4.24.org/net/ipv4/netfilter/Config.in linux-2.4.24/net/ipv4/netfilter/Config.in
18512 --- linux-2.4.24.org/net/ipv4/netfilter/Config.in       2004-01-05 18:39:55.000000000 +0100
18513 +++ linux-2.4.24/net/ipv4/netfilter/Config.in   2004-01-05 19:13:37.038474296 +0100
18514 @@ -73,6 +73,7 @@
18515    dep_tristate '  address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES
18516    dep_tristate '  tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES
18517    dep_tristate '  realm match support' CONFIG_IP_NF_MATCH_REALM $CONFIG_IP_NF_IPTABLES
18518 +  dep_tristate '  stealth match support' CONFIG_IP_NF_MATCH_STEALTH $CONFIG_IP_NF_IPTABLES
18519    if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
18520      dep_tristate '  Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES
18521    fi
18522 diff -urN linux-2.4.24.org/net/ipv4/netfilter/ipt_stealth.c linux-2.4.24/net/ipv4/netfilter/ipt_stealth.c
18523 --- linux-2.4.24.org/net/ipv4/netfilter/ipt_stealth.c   1970-01-01 01:00:00.000000000 +0100
18524 +++ linux-2.4.24/net/ipv4/netfilter/ipt_stealth.c       2004-01-05 18:43:06.171808336 +0100
18525 @@ -0,0 +1,109 @@
18526 +/* Kernel module to add stealth support.
18527 + *
18528 + * Copyright (C) 2002 Brad Spengler  <spender@grsecurity.net>
18529 + *
18530 + */
18531 +
18532 +#include <linux/kernel.h>
18533 +#include <linux/module.h>
18534 +#include <linux/skbuff.h>
18535 +#include <linux/net.h>
18536 +#include <linux/sched.h>
18537 +#include <linux/inet.h>
18538 +#include <linux/stddef.h>
18539 +
18540 +#include <net/ip.h>
18541 +#include <net/sock.h>
18542 +#include <net/tcp.h>
18543 +#include <net/udp.h>
18544 +#include <net/route.h>
18545 +#include <net/inet_common.h>
18546 +
18547 +#include <linux/netfilter_ipv4/ip_tables.h>
18548 +
18549 +MODULE_LICENSE("GPL");
18550 +
18551 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
18552 +
18553 +static int
18554 +match(const struct sk_buff *skb,
18555 +      const struct net_device *in,
18556 +      const struct net_device *out,
18557 +      const void *matchinfo,
18558 +      int offset,
18559 +      const void *hdr,
18560 +      u_int16_t datalen,
18561 +      int *hotdrop)
18562 +{
18563 +       struct iphdr *ip = skb->nh.iph;
18564 +       struct tcphdr *th = (struct tcphdr *) hdr;
18565 +       struct udphdr *uh = (struct udphdr *) hdr;
18566 +       struct sock *sk = NULL;
18567 +
18568 +       if (!ip || !hdr || offset) return 0;
18569 +
18570 +       switch(ip->protocol) {
18571 +       case IPPROTO_TCP:
18572 +               if (datalen < sizeof(struct tcphdr)) {
18573 +                       *hotdrop = 1;
18574 +                       return 0;
18575 +               }
18576 +               if (!(th->syn && !th->ack)) return 0;
18577 +               sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th->dest), ((struct rtable*)skb->dst)->rt_iif);    
18578 +               break;
18579 +       case IPPROTO_UDP:
18580 +               if (datalen < sizeof(struct udphdr)) {
18581 +                       *hotdrop = 1;
18582 +                       return 0;
18583 +               }
18584 +               sk = udp_v4_lookup(ip->saddr, uh->source, ip->daddr, uh->dest, skb->dev->ifindex);
18585 +               break;
18586 +       default:
18587 +               return 0;
18588 +       }
18589 +
18590 +       if(!sk) // port is being listened on, match this
18591 +               return 1;
18592 +       else {
18593 +               sock_put(sk);
18594 +               return 0;
18595 +       }
18596 +}
18597 +
18598 +/* Called when user tries to insert an entry of this type. */
18599 +static int
18600 +checkentry(const char *tablename,
18601 +           const struct ipt_ip *ip,
18602 +           void *matchinfo,
18603 +           unsigned int matchsize,
18604 +           unsigned int hook_mask)
18605 +{
18606 +        if (matchsize != IPT_ALIGN(0))
18607 +                return 0;
18608 +
18609 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
18610 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
18611 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
18612 +                       return 1;
18613 +
18614 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
18615 +
18616 +        return 0;
18617 +}
18618 +
18619 +
18620 +static struct ipt_match stealth_match
18621 += { { NULL, NULL }, "stealth", &match, &checkentry, NULL, THIS_MODULE };
18622 +
18623 +static int __init init(void)
18624 +{
18625 +       return ipt_register_match(&stealth_match);
18626 +}
18627 +
18628 +static void __exit fini(void)
18629 +{
18630 +       ipt_unregister_match(&stealth_match);
18631 +}
18632 +
18633 +module_init(init);
18634 +module_exit(fini);
18635 diff -urN linux-2.4.24.org/net/ipv4/netfilter/Makefile linux-2.4.24/net/ipv4/netfilter/Makefile
18636 --- linux-2.4.24.org/net/ipv4/netfilter/Makefile        2004-01-05 18:39:57.000000000 +0100
18637 +++ linux-2.4.24/net/ipv4/netfilter/Makefile    2004-01-05 19:13:55.207712152 +0100
18638 @@ -173,6 +173,7 @@
18639  obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
18640  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
18641  obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
18642 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
18643  
18644  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
18645  
18646 diff -urN linux-2.4.24.org/net/ipv4/tcp_ipv4.c linux-2.4.24/net/ipv4/tcp_ipv4.c
18647 --- linux-2.4.24.org/net/ipv4/tcp_ipv4.c        2004-01-05 18:39:54.000000000 +0100
18648 +++ linux-2.4.24/net/ipv4/tcp_ipv4.c    2004-01-05 18:43:06.189805600 +0100
18649 @@ -67,6 +67,7 @@
18650  #include <linux/inet.h>
18651  #include <linux/stddef.h>
18652  #include <linux/ipsec.h>
18653 +#include <linux/grsecurity.h>
18654  
18655  extern int sysctl_ip_dynaddr;
18656  extern int sysctl_ip_default_ttl;
18657 @@ -223,9 +224,18 @@
18658  
18659                 spin_lock(&tcp_portalloc_lock);
18660                 rover = tcp_port_rover;
18661 -               do {    rover++;
18662 -                       if ((rover < low) || (rover > high))
18663 -                               rover = low;
18664 +                do {
18665 +#ifdef CONFIG_GRKERNSEC_RANDSRC
18666 +                       if (grsec_enable_randsrc && (high > low)) {
18667 +                               rover = low + (get_random_long() % (high - low));
18668 +                       } else
18669 +#endif
18670 +                       {
18671 +                               rover++;
18672 +                               if ((rover < low) || (rover > high))
18673 +                                       rover = low;
18674 +                       }
18675 +
18676                         head = &tcp_bhash[tcp_bhashfn(rover)];
18677                         spin_lock(&head->lock);
18678                         for (tb = head->chain; tb; tb = tb->next)
18679 @@ -548,6 +558,11 @@
18680  
18681  static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
18682  {
18683 +#ifdef CONFIG_GRKERNSEC_RANDISN
18684 +       if (likely(grsec_enable_randisn))
18685 +               return ip_randomisn();
18686 +       else
18687 +#endif
18688         return secure_tcp_sequence_number(skb->nh.iph->daddr,
18689                                           skb->nh.iph->saddr,
18690                                           skb->h.th->dest,
18691 @@ -683,9 +698,16 @@
18692                 rover = tcp_port_rover;
18693  
18694                 do {
18695 -                       rover++;
18696 -                       if ((rover < low) || (rover > high))
18697 -                               rover = low;
18698 +#ifdef CONFIG_GRKERNSEC_RANDSRC
18699 +                       if(grsec_enable_randsrc && (high > low)) {
18700 +                               rover = low + (get_random_long() % (high - low));
18701 +                       } else
18702 +#endif
18703 +                       {
18704 +                               rover++;
18705 +                               if ((rover < low) || (rover > high))
18706 +                                       rover = low;
18707 +                       }
18708                         head = &tcp_bhash[tcp_bhashfn(rover)];
18709                         spin_lock(&head->lock);         
18710  
18711 @@ -734,6 +756,15 @@
18712                 }
18713                 spin_unlock(&head->lock);
18714  
18715 +#ifdef CONFIG_GRKERNSEC
18716 +               gr_del_task_from_ip_table(current);
18717 +               current->gr_saddr = sk->rcv_saddr;
18718 +               current->gr_daddr = sk->daddr;
18719 +               current->gr_sport = sk->sport;
18720 +               current->gr_dport = sk->dport;
18721 +               gr_add_to_task_ip_table(current);
18722 +#endif
18723 +
18724                 if (tw) {
18725                         tcp_tw_deschedule(tw);
18726                         tcp_timewait_kill(tw);
18727 @@ -846,11 +877,22 @@
18728         if (err)
18729                 goto failure;
18730  
18731 -       if (!tp->write_seq)
18732 +       if (!tp->write_seq) {
18733 +#ifdef CONFIG_GRKERNSEC_RANDISN
18734 +               if (likely(grsec_enable_randisn))
18735 +                       tp->write_seq = ip_randomisn();
18736 +               else
18737 +#endif
18738                 tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
18739                                                            sk->sport, usin->sin_port);
18740 +       }
18741  
18742 -       sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18743 +#ifdef CONFIG_GRKERNSEC_RANDID
18744 +       if(grsec_enable_randid)
18745 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18746 +       else
18747 +#endif
18748 +               sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18749  
18750         err = tcp_connect(sk);
18751         if (err)
18752 @@ -1572,7 +1614,13 @@
18753         newtp->ext_header_len = 0;
18754         if (newsk->protinfo.af_inet.opt)
18755                 newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen;
18756 -       newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18757 +
18758 +#ifdef CONFIG_GRKERNSEC_RANDID
18759 +       if(grsec_enable_randid)
18760 +               newsk->protinfo.af_inet.id = htons(ip_randomid());
18761 +       else
18762 +#endif
18763 +               newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18764  
18765         tcp_sync_mss(newsk, dst->pmtu);
18766         newtp->advmss = dst->advmss;
18767 diff -urN linux-2.4.24.org/net/ipv4/udp.c linux-2.4.24/net/ipv4/udp.c
18768 --- linux-2.4.24.org/net/ipv4/udp.c     2004-01-05 18:39:53.000000000 +0100
18769 +++ linux-2.4.24/net/ipv4/udp.c 2004-01-05 18:43:06.196804536 +0100
18770 @@ -91,6 +91,7 @@
18771  #include <net/ipv6.h>
18772  #include <net/protocol.h>
18773  #include <linux/skbuff.h>
18774 +#include <linux/grsecurity.h>
18775  #include <net/sock.h>
18776  #include <net/udp.h>
18777  #include <net/icmp.h>
18778 @@ -98,6 +99,11 @@
18779  #include <net/inet_common.h>
18780  #include <net/checksum.h>
18781  
18782 +extern int gr_search_udp_recvmsg(const struct sock *sk,
18783 +                                       const struct sk_buff *skb);
18784 +extern int gr_search_udp_sendmsg(const struct sock *sk,
18785 +                                       const struct sockaddr_in *addr);
18786 +
18787  /*
18788   *     Snmp MIB for the UDP layer
18789   */
18790 @@ -480,9 +486,16 @@
18791                 ufh.uh.dest = usin->sin_port;
18792                 if (ufh.uh.dest == 0)
18793                         return -EINVAL;
18794 +
18795 +               if (!gr_search_udp_sendmsg(sk, usin))
18796 +                       return -EPERM;
18797         } else {
18798                 if (sk->state != TCP_ESTABLISHED)
18799                         return -EDESTADDRREQ;
18800 +
18801 +               if (!gr_search_udp_sendmsg(sk, NULL))
18802 +                       return -EPERM;
18803 +
18804                 ufh.daddr = sk->daddr;
18805                 ufh.uh.dest = sk->dport;
18806                 /* Open fast path for connected socket.
18807 @@ -490,6 +503,7 @@
18808                  */
18809                 connected = 1;
18810         }
18811 +
18812         ipc.addr = sk->saddr;
18813         ufh.uh.source = sk->sport;
18814  
18815 @@ -661,6 +675,11 @@
18816         if (!skb)
18817                 goto out;
18818    
18819 +       if (!gr_search_udp_recvmsg(sk, skb)) {
18820 +               err = -EPERM;
18821 +               goto out_free;
18822 +       }
18823 +
18824         copied = skb->len - sizeof(struct udphdr);
18825         if (copied > len) {
18826                 copied = len;
18827 @@ -765,7 +784,13 @@
18828         sk->daddr = rt->rt_dst;
18829         sk->dport = usin->sin_port;
18830         sk->state = TCP_ESTABLISHED;
18831 -       sk->protinfo.af_inet.id = jiffies;
18832 +
18833 +#ifdef CONFIG_GRKERNSEC_RANDID
18834 +       if(grsec_enable_randid)
18835 +               sk->protinfo.af_inet.id = htons(ip_randomid());
18836 +       else
18837 +#endif
18838 +               sk->protinfo.af_inet.id = jiffies;
18839  
18840         sk_dst_set(sk, &rt->u.dst);
18841         return(0);
18842 diff -urN linux-2.4.24.org/net/netlink/af_netlink.c linux-2.4.24/net/netlink/af_netlink.c
18843 --- linux-2.4.24.org/net/netlink/af_netlink.c   2004-01-05 18:39:53.000000000 +0100
18844 +++ linux-2.4.24/net/netlink/af_netlink.c       2004-01-05 18:43:06.214801800 +0100
18845 @@ -40,6 +40,7 @@
18846  #include <linux/proc_fs.h>
18847  #include <linux/smp_lock.h>
18848  #include <linux/notifier.h>
18849 +#include <linux/grsecurity.h>
18850  #include <net/sock.h>
18851  #include <net/scm.h>
18852  
18853 @@ -625,7 +626,8 @@
18854            check them, when this message will be delivered
18855            to corresponding kernel module.   --ANK (980802)
18856          */
18857 -       NETLINK_CB(skb).eff_cap = current->cap_effective;
18858 +
18859 +       NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
18860  
18861         err = -EFAULT;
18862         if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
18863 diff -urN linux-2.4.24.org/net/netsyms.c linux-2.4.24/net/netsyms.c
18864 --- linux-2.4.24.org/net/netsyms.c      2004-01-05 18:39:57.000000000 +0100
18865 +++ linux-2.4.24/net/netsyms.c  2004-01-05 18:43:06.238798152 +0100
18866 @@ -25,6 +25,7 @@
18867  #include <net/checksum.h>
18868  #include <linux/etherdevice.h>
18869  #include <net/route.h>
18870 +#include <linux/grsecurity.h>
18871  #ifdef CONFIG_HIPPI
18872  #include <linux/hippidevice.h>
18873  #endif
18874 @@ -609,6 +610,49 @@
18875  
18876  EXPORT_SYMBOL(softnet_data);
18877  
18878 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
18879 +#if !defined (CONFIG_IPV6_MODULE) && !defined (CONFIG_KHTTPD) && !defined (CONFIG_KHTTPD_MODULE)
18880 +EXPORT_SYMBOL(tcp_v4_lookup_listener);
18881 +#endif
18882 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
18883 +EXPORT_SYMBOL(udp_v4_lookup);
18884 +#endif
18885 +
18886 +#if defined(CONFIG_GRKERNSEC_RANDID)
18887 +EXPORT_SYMBOL(ip_randomid);
18888 +#endif
18889 +#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
18890 +EXPORT_SYMBOL(get_random_long);
18891 +#endif
18892 +#ifdef CONFIG_GRKERNSEC_RANDISN
18893 +EXPORT_SYMBOL(ip_randomisn);
18894 +EXPORT_SYMBOL(grsec_enable_randisn);
18895 +#endif
18896 +#ifdef CONFIG_GRKERNSEC_RANDID
18897 +EXPORT_SYMBOL(grsec_enable_randid);
18898 +#endif
18899 +#ifdef CONFIG_GRKERNSEC_RANDSRC
18900 +EXPORT_SYMBOL(grsec_enable_randsrc);
18901 +#endif
18902 +#ifdef CONFIG_GRKERNSEC_RANDRPC
18903 +EXPORT_SYMBOL(grsec_enable_randrpc);
18904 +#endif
18905 +
18906 +EXPORT_SYMBOL(gr_cap_rtnetlink);
18907 +
18908 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
18909 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
18910 +
18911 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
18912 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
18913 +
18914 +#ifdef CONFIG_UNIX_MODULE
18915 +EXPORT_SYMBOL(gr_acl_handle_unix);
18916 +EXPORT_SYMBOL(gr_acl_handle_mknod);
18917 +EXPORT_SYMBOL(gr_handle_chroot_unix);
18918 +EXPORT_SYMBOL(gr_handle_create);
18919 +#endif
18920 +
18921  #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
18922  #include <net/iw_handler.h>
18923  EXPORT_SYMBOL(wireless_send_event);
18924 diff -urN linux-2.4.24.org/net/socket.c linux-2.4.24/net/socket.c
18925 --- linux-2.4.24.org/net/socket.c       2004-01-05 18:39:59.000000000 +0100
18926 +++ linux-2.4.24/net/socket.c   2004-01-05 18:43:06.254795720 +0100
18927 @@ -85,6 +85,18 @@
18928  #include <net/scm.h>
18929  #include <linux/netfilter.h>
18930  
18931 +extern void gr_attach_curr_ip(const struct sock *sk);
18932 +extern int gr_handle_sock_all(const int family, const int type,
18933 +                             const int protocol);
18934 +extern int gr_handle_sock_server(const struct sockaddr *sck);  
18935 +extern int gr_handle_sock_client(const struct sockaddr *sck);
18936 +extern int gr_search_connect(const struct socket * sock,
18937 +                            const struct sockaddr_in * addr);  
18938 +extern int gr_search_bind(const struct socket * sock,
18939 +                         const struct sockaddr_in * addr);
18940 +extern int gr_search_socket(const int domain, const int type,
18941 +                           const int protocol);
18942 +
18943  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
18944  static ssize_t sock_read(struct file *file, char *buf,
18945                          size_t size, loff_t *ppos);
18946 @@ -711,6 +723,7 @@
18947         }
18948         sock_fasync(-1, filp, 0);
18949         sock_release(socki_lookup(inode));
18950 +
18951         return 0;
18952  }
18953  
18954 @@ -903,6 +916,16 @@
18955         int retval;
18956         struct socket *sock;
18957  
18958 +       if(!gr_search_socket(family, type, protocol)) {
18959 +               retval = -EACCES;
18960 +               goto out;
18961 +       }
18962 +
18963 +       if (gr_handle_sock_all(family, type, protocol)) {
18964 +               retval = -EACCES;
18965 +               goto out;
18966 +       }
18967 +
18968         retval = sock_create(family, type, protocol, &sock);
18969         if (retval < 0)
18970                 goto out;
18971 @@ -998,12 +1021,26 @@
18972  {
18973         struct socket *sock;
18974         char address[MAX_SOCK_ADDR];
18975 +       struct sockaddr * sck;
18976         int err;
18977  
18978         if((sock = sockfd_lookup(fd,&err))!=NULL)
18979         {
18980 -               if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
18981 +               if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
18982 +                       sck = (struct sockaddr *) address;
18983 +
18984 +                       if(!gr_search_bind(sock, (struct sockaddr_in *) sck)) {
18985 +                               sockfd_put(sock);
18986 +                               return -EACCES;
18987 +                       }
18988 +
18989 +                       if (gr_handle_sock_server(sck)) {
18990 +                               sockfd_put(sock);
18991 +                               return -EACCES;
18992 +                       }
18993 +
18994                         err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
18995 +               }
18996                 sockfd_put(sock);
18997         }                       
18998         return err;
18999 @@ -1079,6 +1116,8 @@
19000         if ((err = sock_map_fd(newsock)) < 0)
19001                 goto out_release;
19002  
19003 +       gr_attach_curr_ip(newsock->sk);
19004 +
19005  out_put:
19006         sockfd_put(sock);
19007  out:
19008 @@ -1106,6 +1145,7 @@
19009  {
19010         struct socket *sock;
19011         char address[MAX_SOCK_ADDR];
19012 +       struct sockaddr * sck;
19013         int err;
19014  
19015         sock = sockfd_lookup(fd, &err);
19016 @@ -1114,6 +1154,19 @@
19017         err = move_addr_to_kernel(uservaddr, addrlen, address);
19018         if (err < 0)
19019                 goto out_put;
19020 +
19021 +       sck = (struct sockaddr *) address;
19022 +
19023 +       if (!gr_search_connect(sock, (struct sockaddr_in *) sck)) {
19024 +               err = -EACCES;
19025 +               goto out_put;
19026 +       }
19027 +
19028 +       if (gr_handle_sock_client(sck)) {
19029 +               err = -EACCES;
19030 +               goto out_put;
19031 +       }
19032 +
19033         err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
19034                                  sock->file->f_flags);
19035  out_put:
19036 @@ -1333,6 +1386,7 @@
19037                 err=sock->ops->shutdown(sock, how);
19038                 sockfd_put(sock);
19039         }
19040 +
19041         return err;
19042  }
19043  
19044 diff -urN linux-2.4.24.org/net/sunrpc/xprt.c linux-2.4.24/net/sunrpc/xprt.c
19045 --- linux-2.4.24.org/net/sunrpc/xprt.c  2004-01-05 18:39:57.000000000 +0100
19046 +++ linux-2.4.24/net/sunrpc/xprt.c      2004-01-05 18:43:06.267793744 +0100
19047 @@ -59,6 +59,7 @@
19048  #include <linux/unistd.h>
19049  #include <linux/sunrpc/clnt.h>
19050  #include <linux/file.h>
19051 +#include <linux/grsecurity.h>
19052  
19053  #include <net/sock.h>
19054  #include <net/checksum.h>
19055 @@ -1297,6 +1298,12 @@
19056         }
19057         ret = xid++;
19058         spin_unlock(&xid_lock);
19059 +
19060 +#ifdef CONFIG_GRKERNSEC_RANDRPC
19061 +       if (grsec_enable_randrpc)
19062 +               ret = (u32) get_random_long();
19063 +#endif
19064 +
19065         return ret;
19066  }
19067  
19068 diff -urN linux-2.4.24.org/net/unix/af_unix.c linux-2.4.24/net/unix/af_unix.c
19069 --- linux-2.4.24.org/net/unix/af_unix.c 2004-01-05 18:39:51.000000000 +0100
19070 +++ linux-2.4.24/net/unix/af_unix.c     2004-01-05 18:43:06.315786448 +0100
19071 @@ -109,6 +109,7 @@
19072  #include <linux/poll.h>
19073  #include <linux/smp_lock.h>
19074  #include <linux/rtnetlink.h>
19075 +#include <linux/grsecurity.h>
19076  
19077  #include <asm/checksum.h>
19078  
19079 @@ -599,6 +600,11 @@
19080                 if (err)
19081                         goto put_fail;
19082  
19083 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
19084 +                       err = -EACCES;
19085 +                       goto put_fail;
19086 +               }
19087 +               
19088                 err = -ECONNREFUSED;
19089                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
19090                         goto put_fail;
19091 @@ -622,6 +628,13 @@
19092                 if (u) {
19093                         struct dentry *dentry;
19094                         dentry = u->protinfo.af_unix.dentry;
19095 +
19096 +                       if (!gr_handle_chroot_unix(u->peercred.pid)) {
19097 +                               err = -EPERM;
19098 +                               sock_put(u);
19099 +                               goto fail;
19100 +                       }
19101 +
19102                         if (dentry)
19103                                 UPDATE_ATIME(dentry->d_inode);
19104                 } else
19105 @@ -720,9 +733,19 @@
19106                  * All right, let's create it.
19107                  */
19108                 mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask);
19109 +       
19110 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
19111 +                       err = -EACCES;
19112 +                       goto out_mknod_dput;
19113 +               }       
19114 +
19115                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
19116 +
19117                 if (err)
19118                         goto out_mknod_dput;
19119 +
19120 +               gr_handle_create(dentry, nd.mnt);
19121 +
19122                 up(&nd.dentry->d_inode->i_sem);
19123                 dput(nd.dentry);
19124                 nd.dentry = dentry;
19125 @@ -740,6 +763,10 @@
19126                         goto out_unlock;
19127                 }
19128  
19129 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
19130 +               sk->peercred.pid = current->pid;
19131 +#endif
19132 +
19133                 list = &unix_socket_table[addr->hash];
19134         } else {
19135                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
19136 @@ -866,6 +893,9 @@
19137         int st;
19138         int err;
19139         long timeo;
19140 +#ifdef CONFIG_GRKERNSEC
19141 +       struct task_struct *p, **htable;
19142 +#endif
19143  
19144         err = unix_mkname(sunaddr, addr_len, &hash);
19145         if (err < 0)
19146 @@ -989,6 +1019,17 @@
19147         /* Set credentials */
19148         sk->peercred = other->peercred;
19149  
19150 +#ifdef CONFIG_GRKERNSEC
19151 +       read_lock(&tasklist_lock);
19152 +       htable = &pidhash[pid_hashfn(other->peercred.pid)];
19153 +       for (p = *htable; p && p->pid != other->peercred.pid; p = p->pidhash_next);
19154 +       if (p) {
19155 +               p->curr_ip = current->curr_ip;
19156 +               p->used_accept = 1;
19157 +       }
19158 +       read_unlock(&tasklist_lock);
19159 +#endif
19160 +
19161         sock_hold(newsk);
19162         unix_peer(sk)=newsk;
19163         sock->state=SS_CONNECTED;
This page took 1.439014 seconds and 3 git commands to generate.