]> git.pld-linux.org Git - packages/kernel.git/blame - grsecurity-2.0-rc3-2.4.22-O1.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / grsecurity-2.0-rc3-2.4.22-O1.patch
CommitLineData
474a6d91
AM
1diff -urN linux-2.4.22.org/arch/alpha/config.in linux-2.4.22/arch/alpha/config.in
2--- linux-2.4.22.org/arch/alpha/config.in 2003-11-22 22:11:56.000000000 +0100
3+++ linux-2.4.22/arch/alpha/config.in 2003-11-22 22:14:06.000000000 +0100
4@@ -469,3 +469,12 @@
8be839c4 5
474a6d91
AM
6 source crypto/Config.in
7 source lib/Config.in
8be839c4 8+
474a6d91
AM
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
8be839c4 16+
474a6d91
AM
17diff -urN linux-2.4.22.org/arch/alpha/kernel/osf_sys.c linux-2.4.22/arch/alpha/kernel/osf_sys.c
18--- linux-2.4.22.org/arch/alpha/kernel/osf_sys.c 2003-11-22 22:11:56.000000000 +0100
19+++ linux-2.4.22/arch/alpha/kernel/osf_sys.c 2003-11-22 22:14:06.000000000 +0100
20@@ -33,6 +33,7 @@
21 #include <linux/file.h>
22 #include <linux/types.h>
23 #include <linux/ipc.h>
24+#include <linux/grsecurity.h>
8be839c4 25
474a6d91
AM
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;
8be839c4 31
474a6d91
AM
32+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
33+ if (flags & MAP_MIRROR)
34+ return -EINVAL;
35+#endif
8be839c4 36+
474a6d91
AM
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 }
8be839c4 44+
474a6d91
AM
45+ if(gr_handle_mmap(file, prot)) {
46+ fput(file);
47+ ret = -EACCES;
48+ goto out;
49+ }
8be839c4 50+
474a6d91
AM
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
8be839c4 61+
474a6d91
AM
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);
8be839c4 71+
474a6d91 72+ addr = TASK_UNMAPPED_BASE;
8be839c4 73+
474a6d91
AM
74+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
75+ if (current->flags & PF_PAX_RANDMMAP)
76+ addr += current->mm->delta_mmap;
77+#endif
8be839c4 78+
474a6d91
AM
79+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
80 if (addr != -ENOMEM)
81 return addr;
82
83diff -urN linux-2.4.22.org/arch/alpha/kernel/ptrace.c linux-2.4.22/arch/alpha/kernel/ptrace.c
84--- linux-2.4.22.org/arch/alpha/kernel/ptrace.c 2003-11-22 22:11:56.000000000 +0100
85+++ linux-2.4.22/arch/alpha/kernel/ptrace.c 2003-11-22 22:14:06.000000000 +0100
86@@ -13,6 +13,7 @@
87 #include <linux/ptrace.h>
88 #include <linux/user.h>
89 #include <linux/slab.h>
90+#include <linux/grsecurity.h>
91
92 #include <asm/uaccess.h>
93 #include <asm/pgtable.h>
94@@ -275,6 +276,10 @@
95 read_unlock(&tasklist_lock);
96 if (!child)
97 goto out_notsk;
8be839c4 98+
474a6d91
AM
99+ if(gr_handle_ptrace(child, request))
100+ goto out;
8be839c4 101+
474a6d91
AM
102 if (request == PTRACE_ATTACH) {
103 ret = ptrace_attach(child);
104 goto out;
105diff -urN linux-2.4.22.org/arch/alpha/mm/fault.c linux-2.4.22/arch/alpha/mm/fault.c
106--- linux-2.4.22.org/arch/alpha/mm/fault.c 2003-11-22 22:11:56.000000000 +0100
107+++ linux-2.4.22/arch/alpha/mm/fault.c 2003-11-22 22:14:06.000000000 +0100
108@@ -53,6 +53,139 @@
109 __reload_thread(&current->thread);
110 }
111
112+/*
113+ * PaX: decide what to do with offenders (regs->pc = fault address)
114+ *
115+ * returns 1 when task should be killed
116+ * 2 when patched PLT trampoline was detected
117+ * 3 when unpatched PLT trampoline was detected
118+ * 4 when legitimate ET_EXEC was detected
119+ */
120+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
121+static int pax_handle_fetch_fault(struct pt_regs *regs)
122+{
123+ int err;
8be839c4 124+
474a6d91
AM
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
8be839c4 137+
474a6d91
AM
138+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
139+ do { /* PaX: patched PLT emulation #1 */
140+ unsigned int ldah, ldq, jmp;
8be839c4 141+
474a6d91
AM
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));
8be839c4 145+
474a6d91
AM
146+ if (err)
147+ break;
8be839c4 148+
474a6d91
AM
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;
8be839c4 156+
474a6d91
AM
157+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
158+ err = get_user(r27, (unsigned long*)addr);
159+ if (err)
160+ break;
8be839c4 161+
474a6d91
AM
162+ regs->r27 = r27;
163+ regs->pc = r27;
164+ return 2;
165+ }
166+ } while (0);
8be839c4 167+
474a6d91
AM
168+ do { /* PaX: patched PLT emulation #2 */
169+ unsigned int ldah, lda, br;
8be839c4 170+
474a6d91
AM
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));
8be839c4 174+
474a6d91
AM
175+ if (err)
176+ break;
8be839c4 177+
474a6d91
AM
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;
8be839c4 185+
474a6d91
AM
186+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
187+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
188+ return 2;
189+ }
190+ } while (0);
8be839c4 191+
474a6d91
AM
192+ do { /* PaX: unpatched PLT emulation */
193+ unsigned int br;
8be839c4 194+
474a6d91 195+ err = get_user(br, (unsigned int *)regs->pc);
8be839c4 196+
474a6d91
AM
197+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
198+ unsigned int br2, ldq, nop, jmp;
199+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
8be839c4 200+
474a6d91
AM
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));
8be839c4 207+
474a6d91
AM
208+ if (err)
209+ break;
8be839c4 210+
474a6d91
AM
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
8be839c4 224+
474a6d91
AM
225+ return 1;
226+}
8be839c4 227+
474a6d91
AM
228+void pax_report_insns(void *pc)
229+{
230+ unsigned long i;
8be839c4 231+
474a6d91
AM
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
8be839c4 244+
474a6d91
AM
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)) {
8be839c4 254+
474a6d91
AM
255+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
256+ if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->pc)
257+ goto bad_area;
8be839c4 258+
474a6d91
AM
259+ up_read(&mm->mmap_sem);
260+ switch(pax_handle_fetch_fault(regs)) {
8be839c4 261+
474a6d91
AM
262+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
263+ case 2:
264+ case 3:
265+ return;
266+#endif
8be839c4 267+
474a6d91
AM
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)))
282diff -urN linux-2.4.22.org/arch/arm/config.in linux-2.4.22/arch/arm/config.in
283--- linux-2.4.22.org/arch/arm/config.in 2003-11-22 22:12:20.000000000 +0100
284+++ linux-2.4.22/arch/arm/config.in 2003-11-22 22:14:06.000000000 +0100
285@@ -737,3 +737,11 @@
286
287 source crypto/Config.in
288 source lib/Config.in
8be839c4 289+
474a6d91
AM
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
297diff -urN linux-2.4.22.org/arch/cris/config.in linux-2.4.22/arch/cris/config.in
298--- linux-2.4.22.org/arch/cris/config.in 2003-11-22 22:12:37.000000000 +0100
299+++ linux-2.4.22/arch/cris/config.in 2003-11-22 22:14:06.000000000 +0100
300@@ -277,3 +277,12 @@
301 source crypto/Config.in
302 source lib/Config.in
303 endmenu
8be839c4 304+
474a6d91
AM
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
8be839c4 312+
474a6d91
AM
313diff -urN linux-2.4.22.org/arch/i386/config.in linux-2.4.22/arch/i386/config.in
314--- linux-2.4.22.org/arch/i386/config.in 2003-11-22 22:11:56.000000000 +0100
315+++ linux-2.4.22/arch/i386/config.in 2003-11-22 22:14:06.000000000 +0100
316@@ -503,3 +503,11 @@
317
318 source crypto/Config.in
319 source lib/Config.in
8be839c4 320+
474a6d91
AM
321+mainmenu_option next_comment
322+comment 'Grsecurity'
323+bool 'Grsecurity' CONFIG_GRKERNSEC
324+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
325+ source grsecurity/Config.in
326+fi
327+endmenu
328diff -urN linux-2.4.22.org/arch/i386/kernel/apm.c linux-2.4.22/arch/i386/kernel/apm.c
329--- linux-2.4.22.org/arch/i386/kernel/apm.c 2003-11-22 22:11:55.000000000 +0100
330+++ linux-2.4.22/arch/i386/kernel/apm.c 2003-11-22 22:14:06.000000000 +0100
331@@ -614,7 +614,7 @@
332 __asm__ __volatile__(APM_DO_ZERO_SEGS
333 "pushl %%edi\n\t"
334 "pushl %%ebp\n\t"
335- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
336+ "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
337 "setc %%al\n\t"
338 "popl %%ebp\n\t"
339 "popl %%edi\n\t"
340@@ -666,7 +666,7 @@
341 __asm__ __volatile__(APM_DO_ZERO_SEGS
342 "pushl %%edi\n\t"
343 "pushl %%ebp\n\t"
344- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
345+ "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
346 "setc %%bl\n\t"
347 "popl %%ebp\n\t"
348 "popl %%edi\n\t"
349@@ -1985,6 +1985,12 @@
350 __va((unsigned long)0x40 << 4));
351 _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4));
352
353+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
354+ set_base(gdt2[APM_40 >> 3],
355+ __va((unsigned long)0x40 << 4));
356+ _set_limit((char *)&gdt2[APM_40 >> 3], 4095 - (0x40 << 4));
357+#endif
8be839c4 358+
474a6d91
AM
359 apm_bios_entry.offset = apm_info.bios.offset;
360 apm_bios_entry.segment = APM_CS;
361 set_base(gdt[APM_CS >> 3],
362@@ -1993,6 +1999,16 @@
363 __va((unsigned long)apm_info.bios.cseg_16 << 4));
364 set_base(gdt[APM_DS >> 3],
365 __va((unsigned long)apm_info.bios.dseg << 4));
8be839c4 366+
474a6d91
AM
367+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
368+ set_base(gdt2[APM_CS >> 3],
369+ __va((unsigned long)apm_info.bios.cseg << 4));
370+ set_base(gdt2[APM_CS_16 >> 3],
371+ __va((unsigned long)apm_info.bios.cseg_16 << 4));
372+ set_base(gdt2[APM_DS >> 3],
373+ __va((unsigned long)apm_info.bios.dseg << 4));
374+#endif
8be839c4 375+
474a6d91
AM
376 #ifndef APM_RELAX_SEGMENTS
377 if (apm_info.bios.version == 0x100) {
378 #endif
379@@ -2002,6 +2018,13 @@
380 _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
381 /* For the DEC Hinote Ultra CT475 (and others?) */
382 _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
8be839c4 383+
474a6d91
AM
384+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
385+ _set_limit((char *)&gdt2[APM_CS >> 3], 64 * 1024 - 1);
386+ _set_limit((char *)&gdt2[APM_CS_16 >> 3], 64 * 1024 - 1);
387+ _set_limit((char *)&gdt2[APM_DS >> 3], 64 * 1024 - 1);
388+#endif
8be839c4 389+
474a6d91
AM
390 #ifndef APM_RELAX_SEGMENTS
391 } else {
392 _set_limit((char *)&gdt[APM_CS >> 3],
393@@ -2010,6 +2033,16 @@
394 (apm_info.bios.cseg_16_len - 1) & 0xffff);
395 _set_limit((char *)&gdt[APM_DS >> 3],
396 (apm_info.bios.dseg_len - 1) & 0xffff);
8be839c4 397+
474a6d91
AM
398+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
399+ _set_limit((char *)&gdt2[APM_CS >> 3],
400+ (apm_info.bios.cseg_len - 1) & 0xffff);
401+ _set_limit((char *)&gdt2[APM_CS_16 >> 3],
402+ (apm_info.bios.cseg_16_len - 1) & 0xffff);
403+ _set_limit((char *)&gdt2[APM_DS >> 3],
404+ (apm_info.bios.dseg_len - 1) & 0xffff);
405+#endif
8be839c4 406+
474a6d91
AM
407 }
408 #endif
409
410diff -urN linux-2.4.22.org/arch/i386/kernel/entry.S linux-2.4.22/arch/i386/kernel/entry.S
411--- linux-2.4.22.org/arch/i386/kernel/entry.S 2003-11-22 22:11:55.000000000 +0100
412+++ linux-2.4.22/arch/i386/kernel/entry.S 2003-11-22 22:14:06.000000000 +0100
413@@ -211,6 +211,17 @@
414 jae badsys
415 call *SYMBOL_NAME(sys_call_table)(,%eax,4)
416 movl %eax,EAX(%esp) # save the return value
8be839c4 417+
474a6d91
AM
418+#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
419+ cli # need_resched and signals atomic test
420+ cmpl $0,need_resched(%ebx)
421+ jne reschedule
422+ cmpl $0,sigpending(%ebx)
423+ jne signal_return
424+ call SYMBOL_NAME(pax_randomize_kstack)
425+ jmp restore_all
426+#endif
8be839c4 427+
474a6d91
AM
428 ENTRY(ret_from_sys_call)
429 cli # need_resched and signals atomic test
430 cmpl $0,need_resched(%ebx)
431@@ -391,8 +402,56 @@
432 jmp error_code
433
434 ENTRY(page_fault)
435+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
436+ ALIGN
437+ pushl $ SYMBOL_NAME(pax_do_page_fault)
438+#else
439 pushl $ SYMBOL_NAME(do_page_fault)
440+#endif
8be839c4 441+
474a6d91
AM
442+#ifndef CONFIG_GRKERNSEC_PAX_EMUTRAMP
443 jmp error_code
444+#else
445+ pushl %ds
446+ pushl %eax
447+ xorl %eax,%eax
448+ pushl %ebp
449+ pushl %edi
450+ pushl %esi
451+ pushl %edx
452+ decl %eax # eax = -1
453+ pushl %ecx
454+ pushl %ebx
455+ cld
456+ movl %es,%ecx
457+ movl ORIG_EAX(%esp), %esi # get the error code
458+ movl ES(%esp), %edi # get the function address
459+ movl %eax, ORIG_EAX(%esp)
460+ movl %ecx, ES(%esp)
461+ movl %esp,%edx
462+ pushl %esi # push the error code
463+ pushl %edx # push the pt_regs pointer
464+ movl $(__KERNEL_DS),%edx
465+ movl %edx,%ds
466+ movl %edx,%es
467+ GET_CURRENT(%ebx)
468+ call *%edi
469+ addl $8,%esp
470+ decl %eax
471+ jnz ret_from_exception
8be839c4 472+
474a6d91
AM
473+ popl %ebx
474+ popl %ecx
475+ popl %edx
476+ popl %esi
477+ popl %edi
478+ popl %ebp
479+ popl %eax
480+ popl %ds
481+ popl %es
482+ addl $4,%esp
483+ jmp system_call
484+#endif
485
486 ENTRY(machine_check)
487 pushl $0
488@@ -404,7 +463,7 @@
489 pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
490 jmp error_code
491
492-.data
493+.section .rodata, "a"
494 ENTRY(sys_call_table)
495 .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/
496 .long SYMBOL_NAME(sys_exit)
497diff -urN linux-2.4.22.org/arch/i386/kernel/head.S linux-2.4.22/arch/i386/kernel/head.S
498--- linux-2.4.22.org/arch/i386/kernel/head.S 2003-11-22 22:11:55.000000000 +0100
499+++ linux-2.4.22/arch/i386/kernel/head.S 2003-11-22 22:14:06.000000000 +0100
500@@ -41,6 +41,7 @@
501 *
502 * On entry, %esi points to the real-mode code as a 32-bit pointer.
503 */
504+.global startup_32
505 startup_32:
506 /*
507 * Set segments to known values
508@@ -86,7 +87,7 @@
509 PRESENT+RW+USER */
510 2: stosl
511 add $0x1000,%eax
512- cmp $empty_zero_page-__PAGE_OFFSET,%edi
513+ cmp $0x00c00007,%eax
514 jne 2b
515
516 /*
517@@ -100,9 +101,19 @@
518 movl %eax,%cr0 /* ..and set paging (PG) bit */
519 jmp 1f /* flush the prefetch-queue */
520 1:
8be839c4 521+
474a6d91 522+#if !defined(CONFIG_GRKERNSEC_PAX_KERNEXEC) || defined(CONFIG_SMP)
8be839c4 523+
474a6d91
AM
524+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
525+ orw %bx,%bx
526+ jz 1f
527+#endif
8be839c4 528+
474a6d91
AM
529 movl $1f,%eax
530 jmp *%eax /* make sure eip is relocated */
531 1:
532+#endif
8be839c4 533+
474a6d91
AM
534 /* Set up the stack pointer */
535 lss stack_start,%esp
536
537@@ -121,7 +132,7 @@
538 */
539 xorl %eax,%eax
540 movl $ SYMBOL_NAME(__bss_start),%edi
541- movl $ SYMBOL_NAME(_end),%ecx
542+ movl $ SYMBOL_NAME(__bss_end),%ecx
543 subl %edi,%ecx
544 rep
545 stosb
546@@ -272,8 +283,6 @@
547 jmp L6 # main should never return here, but
548 # just in case, we know what happens.
549
550-ready: .byte 0
551-
552 /*
553 * We depend on ET to be correct. This checks for 287/387.
554 */
555@@ -319,13 +328,6 @@
556 jne rp_sidt
557 ret
558
559-ENTRY(stack_start)
560- .long SYMBOL_NAME(init_task_union)+8192
561- .long __KERNEL_DS
562-
563-/* This is the default interrupt "handler" :-) */
564-int_msg:
565- .asciz "Unknown interrupt\n"
566 ALIGN
567 ignore_int:
568 cld
569@@ -347,6 +349,18 @@
570 popl %eax
571 iret
572
573+.data
574+ready: .byte 0
8be839c4 575+
474a6d91
AM
576+ENTRY(stack_start)
577+ .long SYMBOL_NAME(init_task_union)+8192
578+ .long __KERNEL_DS
8be839c4 579+
474a6d91
AM
580+.section .rodata,"a"
581+/* This is the default interrupt "handler" :-) */
582+int_msg:
583+ .asciz "Unknown interrupt\n"
8be839c4 584+
474a6d91
AM
585 /*
586 * The interrupt descriptor table has room for 256 idt's,
587 * the global descriptor table is dependent on the number
588@@ -372,41 +386,58 @@
589 SYMBOL_NAME(gdt):
590 .long SYMBOL_NAME(gdt_table)
591
592+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
593+.globl SYMBOL_NAME(gdt2)
594+ .word 0
595+gdt_descr2:
596+ .word GDT_ENTRIES*8-1
597+SYMBOL_NAME(gdt2):
598+ .long SYMBOL_NAME(gdt_table2)
599+#endif
8be839c4 600+
474a6d91
AM
601 /*
602 * This is initialized to create an identity-mapping at 0-8M (for bootup
603 * purposes) and another mapping of the 0-8M area at virtual address
604 * PAGE_OFFSET.
605 */
606-.org 0x1000
607+.section .data.swapper_pg_dir,"a"
608 ENTRY(swapper_pg_dir)
609- .long 0x00102007
610- .long 0x00103007
611- .fill BOOT_USER_PGD_PTRS-2,4,0
612+ .long pg0-__PAGE_OFFSET+7
613+ .long pg1-__PAGE_OFFSET+7
614+ .long pg2-__PAGE_OFFSET+7
615+ .fill BOOT_USER_PGD_PTRS-3,4,0
616 /* default: 766 entries */
617- .long 0x00102007
618- .long 0x00103007
619+ .long pg0-__PAGE_OFFSET+7
620+ .long pg1-__PAGE_OFFSET+7
621+ .long pg2-__PAGE_OFFSET+7
622 /* default: 254 entries */
623- .fill BOOT_KERNEL_PGD_PTRS-2,4,0
624+ .fill BOOT_KERNEL_PGD_PTRS-3,4,0
625
626 /*
627 * The page tables are initialized to only 8MB here - the final page
628 * tables are set up later depending on memory size.
629 */
630-.org 0x2000
631+.section .data.pg0,"a"
632 ENTRY(pg0)
633+ .fill 1024,4,0
634
635-.org 0x3000
636+.section .data.pg1,"a"
637 ENTRY(pg1)
638+ .fill 1024,4,0
8be839c4 639+
474a6d91
AM
640+.section .data.pg2,"a"
641+ENTRY(pg2)
642+ .fill 1024,4,0
643
644 /*
645 * empty_zero_page must immediately follow the page tables ! (The
646 * initialization loop counts until empty_zero_page)
647 */
648-
649-.org 0x4000
650+.section .data.empty_zero_page,"a"
651 ENTRY(empty_zero_page)
652+ .fill 1024,4,0
653
654-.org 0x5000
655+.text
656
657 /*
658 * Real beginning of normal "text" segment
659@@ -419,7 +450,7 @@
660 * in the text section because it has alignment requirements
661 * that we cannot fulfill any other way.
662 */
663-.data
664+.section .rodata,"a"
665
666 ALIGN
667 /*
668@@ -430,19 +461,55 @@
669 */
670 ENTRY(gdt_table)
671 .quad 0x0000000000000000 /* NULL descriptor */
672- .quad 0x0000000000000000 /* not used */
673- .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */
674- .quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */
675- .quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */
676- .quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */
8be839c4 677+
474a6d91
AM
678+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
679+ .quad 0x00cf9b000000ffff /* 0x08 kernel 4GB code at 0x00000000 */
680+ .quad 0xc0cf9b400000ffff /* 0x10 kernel 4GB code at 0xc0400000 */
681+#else
682+ .quad 0x0000000000000000 /* not used */
683+ .quad 0x00cf9b000000ffff /* 0x10 kernel 4GB code at 0x00000000 */
684+#endif
8be839c4 685+
474a6d91
AM
686+ .quad 0x00cf93000000ffff /* 0x18 kernel 4GB data at 0x00000000 */
687+ .quad 0x00cffb000000ffff /* 0x23 user 4GB code at 0x00000000 */
688+ .quad 0x00cff3000000ffff /* 0x2b user 4GB data at 0x00000000 */
689+ .quad 0x0000000000000000 /* not used */
690+ .quad 0x0000000000000000 /* not used */
691+ /*
692+ * The APM segments have byte granularity and their bases
693+ * and limits are set at run time.
694+ */
695+ .quad 0x0040930000000000 /* 0x40 APM set up for bad BIOS's */
696+ .quad 0x00409b0000000000 /* 0x48 APM CS code */
697+ .quad 0x00009b0000000000 /* 0x50 APM CS 16 code (16 bit) */
698+ .quad 0x0040930000000000 /* 0x58 APM DS data */
699+ .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */
8be839c4 700+
474a6d91
AM
701+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
702+ENTRY(gdt_table2)
703+ .quad 0x0000000000000000 /* NULL descriptor */
8be839c4 704+
474a6d91
AM
705+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
706+ .quad 0x00cf9b000000ffff /* 0x08 kernel 4GB code at 0x00000000 */
707+ .quad 0xc0cf9b400000ffff /* 0x10 kernel 4GB code at 0xc0400000 */
708+#else
709+ .quad 0x0000000000000000 /* not used */
710+ .quad 0x00cf9b000000ffff /* 0x10 kernel 4GB code at 0x00000000 */
711+#endif
8be839c4 712+
474a6d91
AM
713+ .quad 0x00cf93000000ffff /* 0x18 kernel 4GB data at 0x00000000 */
714+ .quad 0x60c5fb000000ffff /* 0x23 user 1.5GB code at 0x60000000 */
715+ .quad 0x00c5f3000000ffff /* 0x2b user 1.5GB data at 0x00000000 */
8be839c4 716+
474a6d91
AM
717 .quad 0x0000000000000000 /* not used */
718 .quad 0x0000000000000000 /* not used */
719 /*
720 * The APM segments have byte granularity and their bases
721 * and limits are set at run time.
722 */
723- .quad 0x0040920000000000 /* 0x40 APM set up for bad BIOS's */
724- .quad 0x00409a0000000000 /* 0x48 APM CS code */
725- .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */
726- .quad 0x0040920000000000 /* 0x58 APM DS data */
727+ .quad 0x0040930000000000 /* 0x40 APM set up for bad BIOS's */
728+ .quad 0x00409b0000000000 /* 0x48 APM CS code */
729+ .quad 0x00009b0000000000 /* 0x50 APM CS 16 code (16 bit) */
730+ .quad 0x0040930000000000 /* 0x58 APM DS data */
731 .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */
732+#endif
733diff -urN linux-2.4.22.org/arch/i386/kernel/i386_ksyms.c linux-2.4.22/arch/i386/kernel/i386_ksyms.c
734--- linux-2.4.22.org/arch/i386/kernel/i386_ksyms.c 2003-11-22 22:11:55.000000000 +0100
735+++ linux-2.4.22/arch/i386/kernel/i386_ksyms.c 2003-11-22 22:14:06.000000000 +0100
736@@ -74,6 +74,9 @@
737 EXPORT_SYMBOL(get_cmos_time);
738 EXPORT_SYMBOL(apm_info);
739 EXPORT_SYMBOL(gdt);
740+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
741+EXPORT_SYMBOL(gdt2);
742+#endif
743 EXPORT_SYMBOL(empty_zero_page);
8be839c4 744
474a6d91
AM
745 #ifdef CONFIG_DEBUG_IOVIRT
746diff -urN linux-2.4.22.org/arch/i386/kernel/ioport.c linux-2.4.22/arch/i386/kernel/ioport.c
747--- linux-2.4.22.org/arch/i386/kernel/ioport.c 2003-11-22 22:11:55.000000000 +0100
748+++ linux-2.4.22/arch/i386/kernel/ioport.c 2003-11-22 22:14:06.000000000 +0100
749@@ -14,6 +14,7 @@
750 #include <linux/smp.h>
751 #include <linux/smp_lock.h>
752 #include <linux/stddef.h>
753+#include <linux/grsecurity.h>
8be839c4 754
474a6d91
AM
755 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
756 static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
757@@ -59,8 +60,16 @@
8be839c4 758
474a6d91
AM
759 if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
760 return -EINVAL;
761+#ifdef CONFIG_GRKERNSEC_IO
762+ if (turn_on) {
763+ gr_handle_ioperm();
764+#else
765 if (turn_on && !capable(CAP_SYS_RAWIO))
766+#endif
767 return -EPERM;
768+#ifdef CONFIG_GRKERNSEC_IO
769+ }
770+#endif
771 /*
772 * If it's the first ioperm() call in this thread's lifetime, set the
773 * IO bitmap up. ioperm() is much less timing critical than clone(),
774@@ -109,8 +118,13 @@
775 return -EINVAL;
776 /* Trying to gain more privileges? */
777 if (level > old) {
778+#ifdef CONFIG_GRKERNSEC_IO
779+ gr_handle_iopl();
780+ return -EPERM;
781+#else
782 if (!capable(CAP_SYS_RAWIO))
783 return -EPERM;
784+#endif
785 }
786 regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
787 return 0;
788diff -urN linux-2.4.22.org/arch/i386/kernel/ldt.c linux-2.4.22/arch/i386/kernel/ldt.c
789--- linux-2.4.22.org/arch/i386/kernel/ldt.c 2003-11-22 22:11:55.000000000 +0100
790+++ linux-2.4.22/arch/i386/kernel/ldt.c 2003-11-22 22:14:06.000000000 +0100
791@@ -124,6 +124,13 @@
792 }
793 }
8be839c4 794
474a6d91
AM
795+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
796+ if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
797+ error = -EINVAL;
798+ goto out_unlock;
799+ }
800+#endif
801+
802 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
803 (ldt_info.limit & 0x0ffff);
804 entry_2 = (ldt_info.base_addr & 0xff000000) |
805diff -urN linux-2.4.22.org/arch/i386/kernel/pci-pc.c linux-2.4.22/arch/i386/kernel/pci-pc.c
806--- linux-2.4.22.org/arch/i386/kernel/pci-pc.c 2003-11-22 22:11:55.000000000 +0100
807+++ linux-2.4.22/arch/i386/kernel/pci-pc.c 2003-11-22 22:14:06.000000000 +0100
808@@ -17,6 +17,7 @@
809 #include <asm/io.h>
810 #include <asm/smp.h>
811 #include <asm/smpboot.h>
812+#include <asm/desc.h>
8be839c4 813
474a6d91 814 #include "pci-i386.h"
8be839c4 815
474a6d91
AM
816@@ -575,10 +576,16 @@
817 * the array there.
818 */
8be839c4 819
474a6d91
AM
820+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
821+#define __FLAT_KERNEL_CS 0x08
822+#else
823+#define __FLAT_KERNEL_CS __KERNEL_CS
824+#endif
825+
826 static struct {
827 unsigned long address;
828 unsigned short segment;
829-} bios32_indirect = { 0, __KERNEL_CS };
830+} bios32_indirect = { 0, __FLAT_KERNEL_CS };
8be839c4 831
474a6d91
AM
832 /*
833 * Returns the entry point for the given service, NULL on error
834@@ -619,7 +626,9 @@
835 static struct {
836 unsigned long address;
837 unsigned short segment;
838-} pci_indirect = { 0, __KERNEL_CS };
839+} pci_indirect = { 0, __FLAT_KERNEL_CS };
8be839c4 840+
474a6d91
AM
841+#undef __FLAT_KERNEL_CS
842
843 static int pci_bios_present;
844
845@@ -1457,6 +1466,7 @@
846 if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
847 pcibios_sort();
848 #endif
8be839c4 849+
474a6d91 850 }
8be839c4 851
474a6d91
AM
852 char * __devinit pcibios_setup(char *str)
853diff -urN linux-2.4.22.org/arch/i386/kernel/process.c linux-2.4.22/arch/i386/kernel/process.c
854--- linux-2.4.22.org/arch/i386/kernel/process.c 2003-11-22 22:11:55.000000000 +0100
855+++ linux-2.4.22/arch/i386/kernel/process.c 2003-11-22 22:14:06.000000000 +0100
856@@ -600,7 +600,11 @@
857 {
858 struct pt_regs * childregs;
8be839c4 859
474a6d91
AM
860+#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
861+ childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p - sizeof(unsigned long))) - 1;
862+#else
863 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
864+#endif
865 struct_cpy(childregs, regs);
866 childregs->eax = 0;
867 childregs->esp = esp;
868@@ -661,6 +665,16 @@
869 dump->u_fpvalid = dump_fpu (regs, &dump->i387);
870 }
871
872+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
873+void pax_switch_segments(struct task_struct * tsk)
874+{
875+ if (tsk->flags & PF_PAX_SEGMEXEC)
876+ __asm__ __volatile__("lgdt %0": "=m" (gdt_descr2));
877+ else
878+ __asm__ __volatile__("lgdt %0": "=m" (gdt_descr));
879+}
8be839c4
JR
880+#endif
881+
474a6d91
AM
882 /*
883 * This special macro can be used to load a debugging register
884 */
885@@ -700,6 +714,10 @@
8be839c4 886
474a6d91
AM
887 unlazy_fpu(prev_p);
888
889+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
890+ pax_switch_segments(next_p);
8be839c4
JR
891+#endif
892+
474a6d91
AM
893 /*
894 * Reload esp0, LDT and the page table pointer:
895 */
896@@ -842,3 +860,25 @@
897 }
898 #undef last_sched
899 #undef first_sched
8be839c4 900+
474a6d91
AM
901+#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
902+asmlinkage void pax_randomize_kstack(void)
903+{
904+ struct tss_struct *tss = init_tss + smp_processor_id();
905+ unsigned long time;
8be839c4 906+
474a6d91
AM
907+ rdtscl(time);
908+
909+ /* P4 seems to return a 0 LSB, ignore it */
910+#ifdef CONFIG_MPENTIUM4
911+ time &= 0x3EUL;
912+ time <<= 1;
913+#else
914+ time &= 0x1FUL;
915+ time <<= 2;
8be839c4
JR
916+#endif
917+
474a6d91
AM
918+ current->thread.esp0 ^= time;
919+ tss->esp0 = current->thread.esp0;
920+}
921+#endif
922diff -urN linux-2.4.22.org/arch/i386/kernel/ptrace.c linux-2.4.22/arch/i386/kernel/ptrace.c
923--- linux-2.4.22.org/arch/i386/kernel/ptrace.c 2003-11-22 22:11:55.000000000 +0100
924+++ linux-2.4.22/arch/i386/kernel/ptrace.c 2003-11-22 22:14:06.000000000 +0100
8be839c4 925@@ -13,6 +13,7 @@
474a6d91 926 #include <linux/errno.h>
8be839c4
JR
927 #include <linux/ptrace.h>
928 #include <linux/user.h>
8be839c4
JR
929+#include <linux/grsecurity.h>
930
931 #include <asm/uaccess.h>
932 #include <asm/pgtable.h>
474a6d91
AM
933@@ -182,6 +183,9 @@
934 if (pid == 1) /* you may not mess with init */
935 goto out_tsk;
936
8be839c4 937+ if(gr_handle_ptrace(child, request))
474a6d91 938+ goto out_tsk;
8be839c4
JR
939+
940 if (request == PTRACE_ATTACH) {
941 ret = ptrace_attach(child);
474a6d91
AM
942 goto out_tsk;
943@@ -261,6 +265,17 @@
944 if(addr < (long) &dummy->u_debugreg[4] &&
945 ((unsigned long) data) >= TASK_SIZE-3) break;
946
947+#ifdef CONFIG_GRKERNSEC
948+ if(addr >= (long) &dummy->u_debugreg[0] &&
949+ addr <= (long) &dummy->u_debugreg[3]){
950+ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
951+ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
952+ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
953+ if((type & 1) && (data & align))
954+ break;
955+ }
8be839c4
JR
956+#endif
957+
474a6d91
AM
958 if(addr == (long) &dummy->u_debugreg[7]) {
959 data &= ~DR_CONTROL_RESERVED;
960 for(i=0; i<4; i++)
961diff -urN linux-2.4.22.org/arch/i386/kernel/setup.c linux-2.4.22/arch/i386/kernel/setup.c
962--- linux-2.4.22.org/arch/i386/kernel/setup.c 2003-11-22 22:11:55.000000000 +0100
963+++ linux-2.4.22/arch/i386/kernel/setup.c 2003-11-22 22:14:06.000000000 +0100
964@@ -3188,7 +3188,7 @@
965 set_tss_desc(nr,t);
966 gdt_table[__TSS(nr)].b &= 0xfffffdff;
967 load_TR(nr);
968- load_LDT(&init_mm);
969+ _load_LDT(&init_mm);
970
971 /* Clear %fs and %gs. */
972 asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
973diff -urN linux-2.4.22.org/arch/i386/kernel/sys_i386.c linux-2.4.22/arch/i386/kernel/sys_i386.c
974--- linux-2.4.22.org/arch/i386/kernel/sys_i386.c 2003-11-22 22:11:55.000000000 +0100
975+++ linux-2.4.22/arch/i386/kernel/sys_i386.c 2003-11-22 22:14:06.000000000 +0100
976@@ -18,6 +18,7 @@
977 #include <linux/mman.h>
978 #include <linux/file.h>
979 #include <linux/utsname.h>
980+#include <linux/grsecurity.h>
981
982 #include <asm/uaccess.h>
983 #include <asm/ipc.h>
984@@ -48,6 +49,11 @@
985 int error = -EBADF;
986 struct file * file = NULL;
987
988+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
989+ if (flags & MAP_MIRROR)
990+ return -EINVAL;
8be839c4
JR
991+#endif
992+
474a6d91
AM
993 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
994 if (!(flags & MAP_ANONYMOUS)) {
995 file = fget(fd);
996@@ -55,8 +61,14 @@
997 goto out;
998 }
8be839c4 999
474a6d91
AM
1000+ if(gr_handle_mmap(file, prot)) {
1001+ fput(file);
1002+ error = -EACCES;
1003+ goto out;
1004+ }
8be839c4 1005+
474a6d91
AM
1006 down_write(&mm->mmap_sem);
1007- error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
1008+ error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
1009 up_write(&mm->mmap_sem);
1010
1011 if (file)
1012diff -urN linux-2.4.22.org/arch/i386/kernel/trampoline.S linux-2.4.22/arch/i386/kernel/trampoline.S
1013--- linux-2.4.22.org/arch/i386/kernel/trampoline.S 2003-11-22 22:11:55.000000000 +0100
1014+++ linux-2.4.22/arch/i386/kernel/trampoline.S 2003-11-22 22:14:06.000000000 +0100
1015@@ -54,7 +54,7 @@
1016 lmsw %ax # into protected mode
1017 jmp flush_instr
1018 flush_instr:
1019- ljmpl $__KERNEL_CS, $0x00100000
1020+ ljmpl $__KERNEL_CS, $SYMBOL_NAME(startup_32)-__PAGE_OFFSET
1021 # jump to startup_32 in arch/i386/kernel/head.S
1022
1023 idt_48:
1024diff -urN linux-2.4.22.org/arch/i386/kernel/traps.c linux-2.4.22/arch/i386/kernel/traps.c
1025--- linux-2.4.22.org/arch/i386/kernel/traps.c 2003-11-22 22:11:55.000000000 +0100
1026+++ linux-2.4.22/arch/i386/kernel/traps.c 2003-11-22 22:14:06.000000000 +0100
1027@@ -228,14 +228,23 @@
1028 show_stack((unsigned long*)esp);
1029
1030 printk("\nCode: ");
8be839c4 1031+
474a6d91
AM
1032+#ifndef CONFIG_GRKERNSEC_PAX_KERNEXEC
1033 if(regs->eip < PAGE_OFFSET)
1034 goto bad;
8be839c4 1035+#endif
474a6d91
AM
1036
1037 for(i=0;i<20;i++)
1038 {
1039 unsigned char c;
8be839c4 1040+
474a6d91
AM
1041+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1042+ if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) {
8be839c4 1043+#else
474a6d91
AM
1044 if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
1045 bad:
8be839c4 1046+#endif
474a6d91
AM
1047+
1048 printk(" Bad EIP value.");
1049 break;
1050 }
1051@@ -258,8 +267,13 @@
8be839c4 1052
474a6d91
AM
1053 eip = regs->eip;
1054
1055+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1056+ eip += __KERNEL_TEXT_OFFSET;
1057+#else
1058 if (eip < PAGE_OFFSET)
1059 goto no_bug;
1060+#endif
8be839c4 1061+
474a6d91
AM
1062 if (__get_user(ud2, (unsigned short *)eip))
1063 goto no_bug;
1064 if (ud2 != 0x0b0f)
1065@@ -267,7 +281,13 @@
1066 if (__get_user(line, (unsigned short *)(eip + 2)))
1067 goto bug;
1068 if (__get_user(file, (char **)(eip + 4)) ||
8be839c4 1069+
474a6d91
AM
1070+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1071+ __get_user(c, file + __KERNEL_TEXT_OFFSET))
1072+#else
1073 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
1074+#endif
8be839c4 1075+
474a6d91 1076 file = "<bad filename>";
8be839c4 1077
474a6d91
AM
1078 printk("kernel BUG at %s:%d!\n", file, line);
1079@@ -417,6 +437,18 @@
1080 gp_in_kernel:
1081 {
1082 unsigned long fixup;
8be839c4 1083+
474a6d91
AM
1084+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1085+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS) {
1086+ if (current->curr_ip)
1087+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n",
1088+ NIPQUAD(current->curr_ip), current->comm, current->pid, current->uid, current->euid, regs->eip);
1089+ else
1090+ printk(KERN_ERR "PAX: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n",
1091+ current->comm, current->pid, current->uid, current->euid, regs->eip);
1092+ }
1093+#endif
1094+
1095 fixup = search_exception_table(regs->eip);
1096 if (fixup) {
1097 regs->eip = fixup;
1098@@ -527,13 +559,12 @@
1099 {
1100 unsigned int condition;
1101 struct task_struct *tsk = current;
1102- unsigned long eip = regs->eip;
1103 siginfo_t info;
8be839c4 1104
474a6d91 1105 __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
8be839c4 1106
474a6d91
AM
1107 /* If the user set TF, it's simplest to clear it right away. */
1108- if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
1109+ if (!(regs->xcs & 3) && (regs->eflags & TF_MASK) && !(regs->eflags & VM_MASK))
1110 goto clear_TF;
8be839c4 1111
474a6d91
AM
1112 /* Mask out spurious debug traps due to lazy DR7 setting */
1113@@ -855,11 +886,55 @@
1114 void set_tss_desc(unsigned int n, void *addr)
1115 {
1116 _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
8be839c4 1117+
8be839c4 1118+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
474a6d91 1119+ _set_tssldt_desc(gdt_table2+__TSS(n), (int)addr, 235, 0x89);
8be839c4
JR
1120+#endif
1121+
474a6d91
AM
1122+}
1123+
1124+void __set_ldt_desc(unsigned int n, void *addr, unsigned int size)
1125+{
1126+ _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
8be839c4
JR
1127+
1128+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
474a6d91 1129+ _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
8be839c4
JR
1130+#endif
1131+
474a6d91
AM
1132 }
1133
1134 void set_ldt_desc(unsigned int n, void *addr, unsigned int size)
1135 {
8be839c4 1136+
474a6d91
AM
1137+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1138+ unsigned long temp, cr3;
1139+ pgd_t* pgd;
1140+ pmd_t* pmd;
1141+
1142+ asm("movl %%cr3,%0":"=r" (cr3));
1143+ for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
1144+ pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
1145+ pmd = pmd_offset(pgd, temp);
1146+ set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_RW));
1147+ }
1148+ __flush_tlb_all();
8be839c4
JR
1149+#endif
1150+
474a6d91 1151 _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
8be839c4
JR
1152+
1153+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
474a6d91 1154+ _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
8be839c4
JR
1155+#endif
1156+
474a6d91
AM
1157+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1158+ for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
1159+ pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
1160+ pmd = pmd_offset(pgd, temp);
1161+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1162+ }
1163+ flush_tlb_all();
8be839c4
JR
1164+#endif
1165+
474a6d91 1166 }
8be839c4 1167
474a6d91
AM
1168 #ifdef CONFIG_X86_VISWS_APIC
1169diff -urN linux-2.4.22.org/arch/i386/Makefile linux-2.4.22/arch/i386/Makefile
1170--- linux-2.4.22.org/arch/i386/Makefile 2003-11-22 22:11:54.000000000 +0100
1171+++ linux-2.4.22/arch/i386/Makefile 2003-11-22 22:14:06.000000000 +0100
1172@@ -114,6 +114,9 @@
1173
1174 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
1175
1176+arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE
1177+ $(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/linux/config.h -imacros $(HPATH)/asm-i386/segment.h -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds
8be839c4 1178+
474a6d91 1179 vmlinux: arch/i386/vmlinux.lds
8be839c4 1180
474a6d91
AM
1181 FORCE: ;
1182@@ -150,6 +153,7 @@
1183 @$(MAKEBOOT) clean
8be839c4 1184
474a6d91
AM
1185 archmrproper:
1186+ rm -f arch/i386/vmlinux.lds
1187
1188 archdep:
1189 @$(MAKEBOOT) dep
1190diff -urN linux-2.4.22.org/arch/i386/mm/fault.c linux-2.4.22/arch/i386/mm/fault.c
1191--- linux-2.4.22.org/arch/i386/mm/fault.c 2003-11-22 22:11:54.000000000 +0100
1192+++ linux-2.4.22/arch/i386/mm/fault.c 2003-11-22 22:14:06.000000000 +0100
1193@@ -4,6 +4,7 @@
1194 * Copyright (C) 1995 Linus Torvalds
8be839c4 1195 */
8be839c4 1196
474a6d91
AM
1197+#include <linux/config.h>
1198 #include <linux/signal.h>
1199 #include <linux/sched.h>
1200 #include <linux/kernel.h>
1201@@ -19,6 +20,8 @@
1202 #include <linux/init.h>
1203 #include <linux/tty.h>
1204 #include <linux/vt_kern.h> /* For unblank_screen() */
1205+#include <linux/unistd.h>
1206+#include <linux/compiler.h>
1207
1208 #include <asm/system.h>
1209 #include <asm/uaccess.h>
1210@@ -123,6 +126,10 @@
1211 asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
1212 extern unsigned long idt;
1213
1214+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
1215+static int pax_handle_fetch_fault(struct pt_regs *regs);
8be839c4
JR
1216+#endif
1217+
474a6d91
AM
1218 /*
1219 * This routine handles page faults. It determines the address,
1220 * and the problem, and then passes it off to one of the appropriate
1221@@ -133,23 +140,31 @@
1222 * bit 1 == 0 means read, 1 means write
1223 * bit 2 == 0 means kernel, 1 means user-mode
1224 */
1225-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
1226+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1227+static int do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
1228+#else
1229+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long error_code)
8be839c4 1230+#endif
474a6d91
AM
1231 {
1232 struct task_struct *tsk;
1233 struct mm_struct *mm;
1234 struct vm_area_struct * vma;
1235+#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1236 unsigned long address;
1237+#endif
1238 unsigned long page;
1239 unsigned long fixup;
1240 int write;
1241 siginfo_t info;
8be839c4 1242
474a6d91
AM
1243+#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1244 /* get the address */
1245 __asm__("movl %%cr2,%0":"=r" (address));
8be839c4 1246
474a6d91
AM
1247 /* It's safe to allow irq's after cr2 has been saved */
1248 if (regs->eflags & X86_EFLAGS_IF)
1249 local_irq_enable();
1250+#endif
8be839c4 1251
474a6d91
AM
1252 tsk = current;
1253
1254@@ -256,7 +271,7 @@
1255 }
1256 up_read(&mm->mmap_sem);
1257 tsk->in_page_fault = 0;
1258- return;
1259+ return 0;
8be839c4 1260
8be839c4 1261 /*
474a6d91
AM
1262 * Something tried to access memory that isn't in our memory map..
1263@@ -268,6 +283,39 @@
8be839c4 1264
474a6d91
AM
1265 /* User mode accesses just cause a SIGSEGV */
1266 if (error_code & 4) {
8be839c4 1267+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
474a6d91
AM
1268+ if (current->flags & PF_PAX_SEGMEXEC) {
1269+
1270+#if defined(CONFIG_GRKERNSEC_PAX_EMUTRAMP) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
1271+ if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
1272+ switch (pax_handle_fetch_fault(regs)) {
1273+
1274+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1275+ case 5:
1276+ return 0;
8be839c4
JR
1277+#endif
1278+
474a6d91
AM
1279+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1280+ case 4:
1281+ return 0;
1282+ case 3:
1283+ case 2:
1284+ return 1;
1285+#endif
8be839c4 1286+
474a6d91
AM
1287+ case 1:
1288+ default:
1289+ }
1290+ }
1291+#endif
1292+
1293+ if (address >= SEGMEXEC_TASK_SIZE) {
1294+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1295+ do_exit(SIGKILL);
1296+ }
1297+ }
1298+#endif
1299+
1300 tsk->thread.cr2 = address;
1301 tsk->thread.error_code = error_code;
1302 tsk->thread.trap_no = 14;
1303@@ -276,7 +324,7 @@
1304 /* info.si_code has been set above */
1305 info.si_addr = (void *)address;
1306 force_sig_info(SIGSEGV, &info, tsk);
1307- return;
1308+ return 0;
1309 }
8be839c4 1310
474a6d91
AM
1311 /*
1312@@ -289,7 +337,7 @@
8be839c4 1313
474a6d91
AM
1314 if (nr == 6) {
1315 do_invalid_op(regs, 0);
1316- return;
1317+ return 0;
1318 }
1319 }
8be839c4 1320
474a6d91
AM
1321@@ -297,7 +345,7 @@
1322 /* Are we prepared to handle this kernel fault? */
1323 if ((fixup = search_exception_table(regs->eip)) != 0) {
1324 regs->eip = fixup;
1325- return;
1326+ return 0;
1327 }
8be839c4 1328
8be839c4 1329 /*
474a6d91
AM
1330@@ -310,6 +358,18 @@
1331
1332 if (address < PAGE_SIZE)
1333 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
8be839c4
JR
1334+
1335+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
474a6d91
AM
1336+ else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET) {
1337+ if (tsk->curr_ip)
1338+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1339+ NIPQUAD(tsk->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1340+ else
1341+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1342+ tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1343+ }
1344+#endif
1345+
1346 else
1347 printk(KERN_ALERT "Unable to handle kernel paging request");
1348 printk(" at virtual address %08lx\n",address);
1349@@ -364,7 +424,7 @@
1350 /* Kernel mode? Handle exceptions or die */
1351 if (!(error_code & 4))
1352 goto no_context;
1353- return;
1354+ return 0;
1355
1356 vmalloc_fault:
1357 {
1358@@ -397,6 +457,337 @@
1359 pte_k = pte_offset(pmd_k, address);
1360 if (!pte_present(*pte_k))
1361 goto no_context;
1362- return;
1363+ return 0;
1364+ }
1365+}
1366+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1367+/* PaX: called with the page_table_lock spinlock held */
1368+static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
1369+{
1370+ pgd_t *pgd;
1371+ pmd_t *pmd;
1372+
1373+ pgd = pgd_offset(mm, address);
1374+ if (!pgd || !pgd_present(*pgd))
1375+ return 0;
1376+ pmd = pmd_offset(pgd, address);
1377+ if (!pmd || !pmd_present(*pmd))
1378+ return 0;
1379+ return pte_offset(pmd, address);
1380+}
1381+#endif
1382+
1383+/*
1384+ * PaX: decide what to do with offenders (regs->eip = fault address)
1385+ *
1386+ * returns 1 when task should be killed
1387+ * 2 when sigreturn trampoline was detected
1388+ * 3 when rt_sigreturn trampoline was detected
1389+ * 4 when gcc trampoline was detected
1390+ * 5 when legitimate ET_EXEC was detected
1391+ */
1392+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
1393+static int pax_handle_fetch_fault(struct pt_regs *regs)
1394+{
1395+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1396+ static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
1397+#endif
1398+ int err;
1399+
1400+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1401+ if (current->flags & PF_PAX_RANDEXEC) {
1402+ unsigned long esp_4;
1403+ if (regs->eip >= current->mm->start_code &&
1404+ regs->eip < current->mm->end_code)
1405+ {
1406+ err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
1407+ if (err || esp_4 == regs->eip)
1408+ return 1;
1409+ regs->eip += current->mm->delta_exec;
1410+ return 5;
1411+ }
1412+ }
1413+#endif
1414+
1415+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1416+
1417+#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1418+ if (!(current->flags & PF_PAX_EMUTRAMP))
1419+ return 1;
1420+#endif
1421+
1422+ do { /* PaX: sigreturn emulation */
1423+ unsigned char pop, mov;
1424+ unsigned short sys;
1425+ unsigned long nr;
1426+
1427+ err = get_user(pop, (unsigned char *)(regs->eip));
1428+ err |= get_user(mov, (unsigned char *)(regs->eip + 1));
1429+ err |= get_user(nr, (unsigned long *)(regs->eip + 2));
1430+ err |= get_user(sys, (unsigned short *)(regs->eip + 6));
1431+
1432+ if (err)
1433+ break;
1434+
1435+ if (pop == 0x58 &&
1436+ mov == 0xb8 &&
1437+ nr == __NR_sigreturn &&
1438+ sys == 0x80cd)
1439+ {
1440+
1441+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1442+ int sig;
1443+ struct k_sigaction *ka;
1444+ __sighandler_t handler;
1445+
1446+ if (get_user(sig, (int *)regs->esp))
1447+ return 1;
1448+ if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
1449+ return 1;
1450+ ka = &current->sig->action[sig-1];
1451+ handler = ka->sa.sa_handler;
1452+ if (handler == SIG_DFL || handler == SIG_IGN) {
1453+ if (!(current->flags & PF_PAX_EMUTRAMP))
1454+ return 1;
1455+ } else if (!(ka->sa.sa_flags & SA_SIGINFO))
1456+ return 1;
8be839c4
JR
1457+#endif
1458+
474a6d91
AM
1459+ regs->esp += 4;
1460+ regs->eax = nr;
1461+ regs->eip += 8;
1462+ return 2;
1463+ }
1464+ } while (0);
8be839c4 1465+
474a6d91
AM
1466+ do { /* PaX: rt_sigreturn emulation */
1467+ unsigned char mov;
1468+ unsigned short sys;
1469+ unsigned long nr;
8be839c4 1470+
474a6d91
AM
1471+ err = get_user(mov, (unsigned char *)(regs->eip));
1472+ err |= get_user(nr, (unsigned long *)(regs->eip + 1));
1473+ err |= get_user(sys, (unsigned short *)(regs->eip + 5));
8be839c4 1474+
474a6d91
AM
1475+ if (err)
1476+ break;
8be839c4 1477+
474a6d91
AM
1478+ if (mov == 0xb8 &&
1479+ nr == __NR_rt_sigreturn &&
1480+ sys == 0x80cd)
1481+ {
1482+
1483+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1484+ int sig;
1485+ struct k_sigaction *ka;
1486+ __sighandler_t handler;
1487+
1488+ if (get_user(sig, (int *)regs->esp))
1489+ return 1;
1490+ if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
1491+ return 1;
1492+ ka = &current->sig->action[sig-1];
1493+ handler = ka->sa.sa_handler;
1494+ if (handler == SIG_DFL || handler == SIG_IGN) {
1495+ if (!(current->flags & PF_PAX_EMUTRAMP))
1496+ return 1;
1497+ } else if (ka->sa.sa_flags & SA_SIGINFO)
1498+ return 1;
8be839c4
JR
1499+#endif
1500+
474a6d91
AM
1501+ regs->eax = nr;
1502+ regs->eip += 7;
1503+ return 3;
1504+ }
1505+ } while (0);
1506+
1507+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
1508+ if (!(current->flags & PF_PAX_EMUTRAMP))
1509+ return 1;
8be839c4
JR
1510+#endif
1511+
474a6d91
AM
1512+ do { /* PaX: gcc trampoline emulation #1 */
1513+ unsigned char mov1, mov2;
1514+ unsigned short jmp;
1515+ unsigned long addr1, addr2, ret;
1516+ unsigned short call;
1517+
1518+ err = get_user(mov1, (unsigned char *)regs->eip);
1519+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1520+ err |= get_user(mov2, (unsigned char *)(regs->eip + 5));
1521+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1522+ err |= get_user(jmp, (unsigned short *)(regs->eip + 10));
1523+ err |= get_user(ret, (unsigned long *)regs->esp);
1524+
1525+ if (err)
1526+ break;
1527+
1528+ err = get_user(call, (unsigned short *)(ret-2));
1529+ if (err)
1530+ break;
1531+
1532+ if ((mov1 & 0xF8) == 0xB8 &&
1533+ (mov2 & 0xF8) == 0xB8 &&
1534+ (mov1 & 0x07) != (mov2 & 0x07) &&
1535+ (jmp & 0xF8FF) == 0xE0FF &&
1536+ (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
1537+ (call & 0xF8FF) == 0xD0FF &&
1538+ regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1539+ {
1540+ ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
1541+ ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
1542+ regs->eip = addr2;
1543+ return 4;
1544+ }
1545+ } while (0);
1546+
1547+ do { /* PaX: gcc trampoline emulation #2 */
1548+ unsigned char mov, jmp;
1549+ unsigned long addr1, addr2, ret;
1550+ unsigned short call;
1551+
1552+ err = get_user(mov, (unsigned char *)regs->eip);
1553+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1554+ err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1555+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1556+ err |= get_user(ret, (unsigned long *)regs->esp);
1557+
1558+ if (err)
1559+ break;
1560+
1561+ err = get_user(call, (unsigned short *)(ret-2));
1562+ if (err)
1563+ break;
1564+
1565+ if ((mov & 0xF8) == 0xB8 &&
1566+ jmp == 0xE9 &&
1567+ (call & 0xF8FF) == 0xD0FF &&
1568+ regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1569+ {
1570+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1571+ regs->eip += addr2 + 10;
1572+ return 4;
1573+ }
1574+ } while (0);
1575+#endif
8be839c4 1576+
474a6d91
AM
1577+ return 1; /* PaX in action */
1578+}
8be839c4 1579+
474a6d91 1580+void pax_report_insns(void *pc)
8be839c4 1581+{
474a6d91
AM
1582+ unsigned long i;
1583+
1584+ printk(KERN_ERR "PAX: bytes at PC: ");
1585+ for (i = 0; i < 20; i++) {
1586+ unsigned char c;
1587+ if (get_user(c, (unsigned char*)pc+i)) {
1588+ printk("<invalid address>.");
1589+ break;
1590+ }
1591+ printk("%02x ", c);
1592+ }
1593+ printk("\n");
8be839c4
JR
1594+}
1595+#endif
1596+
474a6d91
AM
1597+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
1598+/*
1599+ * PaX: handle the extra page faults or pass it down to the original handler
1600+ *
1601+ * returns 0 when nothing special was detected
1602+ * 1 when sigreturn trampoline (syscall) has to be emulated
1603+ */
1604+asmlinkage int pax_do_page_fault(struct pt_regs *regs, unsigned long error_code)
1605+{
1606+ struct mm_struct *mm = current->mm;
1607+ unsigned long address;
1608+ pte_t *pte;
1609+ unsigned char pte_mask;
1610+ int ret;
8be839c4 1611+
474a6d91 1612+ __asm__("movl %%cr2,%0":"=r" (address));
8be839c4 1613+
474a6d91
AM
1614+ /* It's safe to allow irq's after cr2 has been saved */
1615+ if (likely(regs->eflags & X86_EFLAGS_IF))
1616+ local_irq_enable();
8be839c4 1617+
474a6d91
AM
1618+ if (unlikely((error_code & 5) != 5 ||
1619+ address >= TASK_SIZE ||
1620+ !(current->flags & PF_PAX_PAGEEXEC)))
1621+ return do_page_fault(regs, error_code, address);
8be839c4 1622+
474a6d91 1623+ /* PaX: it's our fault, let's handle it if we can */
8be839c4 1624+
474a6d91
AM
1625+ /* PaX: take a look at read faults before acquiring any locks */
1626+ if (unlikely((error_code == 5) && (regs->eip == address))) {
1627+ /* instruction fetch attempt from a protected page in user mode */
1628+ ret = pax_handle_fetch_fault(regs);
1629+ switch (ret) {
1630+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
1631+ case 5:
1632+ return 0;
8be839c4 1633+#endif
8be839c4 1634+
474a6d91
AM
1635+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1636+ case 4:
1637+ return 0;
1638+ case 3:
1639+ case 2:
1640+ return 1;
8be839c4 1641+#endif
474a6d91
AM
1642+ case 1:
1643+ default:
1644+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1645+ do_exit(SIGKILL);
1646+ }
1647+ }
8be839c4 1648+
474a6d91 1649+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
8be839c4 1650+
474a6d91
AM
1651+ spin_lock(&mm->page_table_lock);
1652+ pte = pax_get_pte(mm, address);
1653+ if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
1654+ spin_unlock(&mm->page_table_lock);
1655+ do_page_fault(regs, error_code, address);
1656+ return 0;
8be839c4 1657 }
474a6d91
AM
1658+
1659+ if (unlikely((error_code == 7) && !pte_write(*pte))) {
1660+ /* write attempt to a protected page in user mode */
1661+ spin_unlock(&mm->page_table_lock);
1662+ do_page_fault(regs, error_code, address);
1663+ return 0;
8be839c4
JR
1664+ }
1665+
474a6d91
AM
1666+ /*
1667+ * PaX: fill DTLB with user rights and retry
1668+ */
1669+ __asm__ __volatile__ (
1670+ "orb %2,%1\n"
1671+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
1672+/*
1673+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
1674+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
1675+ * page fault when examined during a TLB load attempt. this is true not only
1676+ * for PTEs holding a non-present entry but also present entries that will
1677+ * raise a page fault (such as those set up by PaX, or the copy-on-write
1678+ * mechanism). in effect it means that we do *not* need to flush the TLBs
1679+ * for our target pages since their PTEs are simply not in the TLBs at all.
1680+ * the best thing in omitting it is that we gain around 15-20% speed in the
1681+ * fast path of the page fault handler and can get rid of tracing since we
1682+ * can no longer flush unintended entries.
1683+ */
1684+
1685+ "invlpg %0\n"
1686+#endif
1687+
1688+ "testb $0,%0\n"
1689+ "xorb %3,%1\n"
1690+ :
1691+ : "m" (*(char*)address), "m" (*(char*)pte) , "q" (pte_mask) , "i" (_PAGE_USER)
1692+ : "memory", "cc");
1693+ spin_unlock(&mm->page_table_lock);
1694+ return 0;
1695 }
1696+#endif
1697diff -urN linux-2.4.22.org/arch/i386/mm/init.c linux-2.4.22/arch/i386/mm/init.c
1698--- linux-2.4.22.org/arch/i386/mm/init.c 2003-11-22 22:11:54.000000000 +0100
1699+++ linux-2.4.22/arch/i386/mm/init.c 2003-11-22 22:14:06.000000000 +0100
1700@@ -37,6 +37,8 @@
1701 #include <asm/e820.h>
1702 #include <asm/apic.h>
1703 #include <asm/tlb.h>
1704+#include <asm/page_offset.h>
1705+#include <asm/desc.h>
8be839c4 1706
474a6d91
AM
1707 mmu_gather_t mmu_gathers[NR_CPUS];
1708 unsigned long highstart_pfn, highend_pfn;
1709@@ -122,7 +124,7 @@
1710
1711 /* References to section boundaries */
1712
1713-extern char _text, _etext, _edata, __bss_start, _end;
1714+extern char _text, _etext, _data, _edata, __bss_start, _end;
1715 extern char __init_begin, __init_end;
8be839c4 1716
474a6d91
AM
1717 static inline void set_pte_phys (unsigned long vaddr,
1718@@ -514,7 +516,7 @@
1719 reservedpages = free_pages_init();
8be839c4 1720
474a6d91
AM
1721 codesize = (unsigned long) &_etext - (unsigned long) &_text;
1722- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
1723+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
1724 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
8be839c4 1725
474a6d91
AM
1726 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
1727@@ -582,6 +584,42 @@
1728 totalram_pages++;
1729 }
1730 printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
8be839c4
JR
1731+
1732+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
474a6d91
AM
1733+ /* PaX: limit KERNEL_CS to actual size */
1734+ {
1735+ unsigned long limit;
8be839c4 1736+
474a6d91
AM
1737+ limit = (unsigned long)&_etext >> PAGE_SHIFT;
1738+ gdt_table[2].a = (gdt_table[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1739+ gdt_table[2].b = (gdt_table[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1740+
1741+ /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */
1742+ gdt_table[1].a = 0UL;
1743+ gdt_table[1].b = 0UL;
1744+
1745+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
1746+ gdt_table2[2].a = (gdt_table2[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1747+ gdt_table2[2].b = (gdt_table2[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1748+
1749+ /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */
1750+ gdt_table2[1].a = 0UL;
1751+ gdt_table2[1].b = 0UL;
8be839c4
JR
1752+#endif
1753+
474a6d91
AM
1754+ /* PaX: make KERNEL_CS read-only */
1755+ for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
1756+ pgd_t *pgd;
1757+ pmd_t *pmd;
8be839c4 1758+
474a6d91
AM
1759+ pgd = pgd_offset_k(addr);
1760+ pmd = pmd_offset(pgd, addr);
1761+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1762+ }
1763+ flush_tlb_all();
1764+ }
8be839c4
JR
1765+#endif
1766+
474a6d91 1767 }
8be839c4 1768
474a6d91
AM
1769 #ifdef CONFIG_BLK_DEV_INITRD
1770diff -urN linux-2.4.22.org/arch/i386/vmlinux.lds linux-2.4.22/arch/i386/vmlinux.lds
1771--- linux-2.4.22.org/arch/i386/vmlinux.lds 2003-11-22 22:11:55.000000000 +0100
1772+++ linux-2.4.22/arch/i386/vmlinux.lds 1970-01-01 01:00:00.000000000 +0100
1773@@ -1,82 +0,0 @@
1774-/* ld script to make i386 Linux kernel
1775- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1776- */
1777-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1778-OUTPUT_ARCH(i386)
1779-ENTRY(_start)
1780-SECTIONS
1781-{
1782- . = 0xC0000000 + 0x100000;
1783- _text = .; /* Text and read-only data */
1784- .text : {
1785- *(.text)
1786- *(.fixup)
1787- *(.gnu.warning)
1788- } = 0x9090
1789-
1790- _etext = .; /* End of text section */
1791-
1792- .rodata : { *(.rodata) *(.rodata.*) }
1793- .kstrtab : { *(.kstrtab) }
1794-
1795- . = ALIGN(16); /* Exception table */
1796- __start___ex_table = .;
1797- __ex_table : { *(__ex_table) }
1798- __stop___ex_table = .;
1799-
1800- __start___ksymtab = .; /* Kernel symbol table */
1801- __ksymtab : { *(__ksymtab) }
1802- __stop___ksymtab = .;
1803-
1804- .data : { /* Data */
1805- *(.data)
1806- CONSTRUCTORS
1807- }
1808-
1809- _edata = .; /* End of data section */
1810-
1811- . = ALIGN(8192); /* init_task */
1812- .data.init_task : { *(.data.init_task) }
1813-
1814- . = ALIGN(4096); /* Init code and data */
1815- __init_begin = .;
1816- .text.init : { *(.text.init) }
1817- .data.init : { *(.data.init) }
1818- . = ALIGN(16);
1819- __setup_start = .;
1820- .setup.init : { *(.setup.init) }
1821- __setup_end = .;
1822- __initcall_start = .;
1823- .initcall.init : { *(.initcall.init) }
1824- __initcall_end = .;
1825- . = ALIGN(4096);
1826- __init_end = .;
1827-
1828- . = ALIGN(4096);
1829- .data.page_aligned : { *(.data.idt) }
1830-
1831- . = ALIGN(32);
1832- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1833-
1834- __bss_start = .; /* BSS */
1835- .bss : {
1836- *(.bss)
1837- }
1838- _end = . ;
1839-
1840- /* Sections to be discarded */
1841- /DISCARD/ : {
1842- *(.text.exit)
1843- *(.data.exit)
1844- *(.exitcall.exit)
1845- }
1846-
1847- /* Stabs debugging sections. */
1848- .stab 0 : { *(.stab) }
1849- .stabstr 0 : { *(.stabstr) }
1850- .stab.excl 0 : { *(.stab.excl) }
1851- .stab.exclstr 0 : { *(.stab.exclstr) }
1852- .stab.index 0 : { *(.stab.index) }
1853- .stab.indexstr 0 : { *(.stab.indexstr) }
1854- .comment 0 : { *(.comment) }
1855-}
1856diff -urN linux-2.4.22.org/arch/i386/vmlinux.lds.S linux-2.4.22/arch/i386/vmlinux.lds.S
1857--- linux-2.4.22.org/arch/i386/vmlinux.lds.S 1970-01-01 01:00:00.000000000 +0100
1858+++ linux-2.4.22/arch/i386/vmlinux.lds.S 2003-11-22 22:14:06.000000000 +0100
1859@@ -0,0 +1,136 @@
1860+/* ld script to make i386 Linux kernel
1861+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1862+ */
1863+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1864+OUTPUT_ARCH(i386)
1865+ENTRY(_start)
1866+SECTIONS
1867+{
1868+ . = __PAGE_OFFSET + 0x100000;
1869+ .text.startup : {
1870+ BYTE(0xEA) /* jmp far */
8be839c4
JR
1871+
1872+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
474a6d91
AM
1873+ LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
1874+#else
1875+ LONG(startup_32 - __PAGE_OFFSET)
8be839c4
JR
1876+#endif
1877+
474a6d91
AM
1878+ SHORT(__KERNEL_CS)
1879+ }
1880+
1881+ . = ALIGN(32);
1882+ _data = .;
1883+ .data : { /* Data */
1884+ *(.data)
1885+ CONSTRUCTORS
1886+ }
1887+
1888+ . = ALIGN(32);
1889+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1890+
1891+ . = ALIGN(8192);
1892+ .data.init_task : { *(.data.init_task) }
1893+
1894+ . = ALIGN(4096);
1895+ .data.page_aligned : { *(.data.swapper_pg_dir) }
1896+
1897+ _edata = .; /* End of data section */
1898+
1899+ __bss_start = .; /* BSS */
1900+ .bss : {
1901+ *(.bss)
1902+ LONG(0)
1903+ }
1904+ __bss_end = . ;
1905+
1906+ . = ALIGN(4096); /* Init code and data */
1907+ __init_begin = .;
1908+
1909+ .data.init : {
1910+ *(.data.pg0)
1911+ *(.data.pg1)
1912+ *(.data.pg2)
1913+ *(.data.init)
1914+ }
1915+ . = ALIGN(16);
1916+ __setup_start = .;
1917+ .setup.init : { *(.setup.init) }
1918+ __setup_end = .;
1919+ __initcall_start = .;
1920+ .initcall.init : { *(.initcall.init) }
1921+ __initcall_end = .;
8be839c4 1922+
474a6d91
AM
1923+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1924+ __text_init_start = .;
1925+ .text.init (. - __KERNEL_TEXT_OFFSET) : AT (__text_init_start) {
1926+ *(.text.init)
1927+ . = ALIGN(4*1024*1024) - 1;
1928+ BYTE(0)
1929+ }
1930+ __init_end = . + __KERNEL_TEXT_OFFSET;
1931+
1932+/*
1933+ * PaX: this must be kept in synch with the KERNEL_CS base
1934+ * in the GDTs in arch/i386/kernel/head.S
1935+ */
1936+ _text = .; /* Text and read-only data */
1937+ .text : AT (. + __KERNEL_TEXT_OFFSET) {
1938+#else
1939+ .text.init : { *(.text.init) }
1940+ . = ALIGN(4096);
1941+ __init_end = .;
1942+ _text = .; /* Text and read-only data */
1943+ .text : {
8be839c4
JR
1944+#endif
1945+
474a6d91
AM
1946+ *(.text)
1947+ *(.fixup)
1948+ *(.gnu.warning)
1949+ } = 0x9090
8be839c4 1950+
474a6d91
AM
1951+ _etext = .; /* End of text section */
1952+ . = ALIGN(4096);
8be839c4 1953+
474a6d91
AM
1954+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
1955+ . += __KERNEL_TEXT_OFFSET;
8be839c4
JR
1956+#endif
1957+
474a6d91
AM
1958+ .rodata.page_aligned : {
1959+ *(.data.empty_zero_page)
1960+ *(.data.idt)
1961+ }
1962+ .rodata : { *(.rodata) *(.rodata.*) }
1963+ .kstrtab : { *(.kstrtab) }
1964+
1965+ . = ALIGN(16); /* Exception table */
1966+ __start___ex_table = .;
1967+ __ex_table : { *(__ex_table) }
1968+ __stop___ex_table = .;
1969+
1970+ __start___ksymtab = .; /* Kernel symbol table */
1971+ __ksymtab : { *(__ksymtab) }
1972+ __stop___ksymtab = .;
8be839c4
JR
1973+
1974+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
474a6d91
AM
1975+ _end = ALIGN(4*1024*1024);
1976+#else
1977+ _end = .;
1978+#endif
8be839c4 1979+
474a6d91
AM
1980+ /* Sections to be discarded */
1981+ /DISCARD/ : {
1982+ *(.text.exit)
1983+ *(.data.exit)
1984+ *(.exitcall.exit)
8be839c4 1985+ }
8be839c4 1986+
474a6d91
AM
1987+ /* Stabs debugging sections. */
1988+ .stab 0 : { *(.stab) }
1989+ .stabstr 0 : { *(.stabstr) }
1990+ .stab.excl 0 : { *(.stab.excl) }
1991+ .stab.exclstr 0 : { *(.stab.exclstr) }
1992+ .stab.index 0 : { *(.stab.index) }
1993+ .stab.indexstr 0 : { *(.stab.indexstr) }
1994+ .comment 0 : { *(.comment) }
1995+}
1996diff -urN linux-2.4.22.org/arch/ia64/config.in linux-2.4.22/arch/ia64/config.in
1997--- linux-2.4.22.org/arch/ia64/config.in 2003-11-22 22:12:28.000000000 +0100
1998+++ linux-2.4.22/arch/ia64/config.in 2003-11-22 22:14:06.000000000 +0100
1999@@ -296,3 +296,12 @@
2000 int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
2001
2002 endmenu
8be839c4 2003+
474a6d91
AM
2004+mainmenu_option next_comment
2005+comment 'Grsecurity'
2006+bool 'Grsecurity' CONFIG_GRKERNSEC
2007+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2008+ source grsecurity/Config.in
2009+fi
2010+endmenu
8be839c4 2011+
474a6d91
AM
2012diff -urN linux-2.4.22.org/arch/ia64/kernel/ptrace.c linux-2.4.22/arch/ia64/kernel/ptrace.c
2013--- linux-2.4.22.org/arch/ia64/kernel/ptrace.c 2003-11-22 22:12:33.000000000 +0100
2014+++ linux-2.4.22/arch/ia64/kernel/ptrace.c 2003-11-22 22:14:06.000000000 +0100
2015@@ -16,6 +16,7 @@
2016 #include <linux/ptrace.h>
2017 #include <linux/smp_lock.h>
2018 #include <linux/user.h>
2019+#include <linux/grsecurity.h>
2020
2021 #include <asm/pgtable.h>
2022 #include <asm/processor.h>
2023@@ -1273,6 +1274,9 @@
2024 if (pid == 1) /* no messing around with init! */
2025 goto out_tsk;
2026
2027+ if (gr_handle_ptrace(child, request))
2028+ goto out_tsk;
2029+
2030 if (request == PTRACE_ATTACH) {
2031 ret = ptrace_attach(child);
2032 goto out_tsk;
2033diff -urN linux-2.4.22.org/arch/ia64/kernel/sys_ia64.c linux-2.4.22/arch/ia64/kernel/sys_ia64.c
2034--- linux-2.4.22.org/arch/ia64/kernel/sys_ia64.c 2003-11-22 22:12:34.000000000 +0100
2035+++ linux-2.4.22/arch/ia64/kernel/sys_ia64.c 2003-11-22 22:14:06.000000000 +0100
2036@@ -15,6 +15,7 @@
2037 #include <linux/smp.h>
2038 #include <linux/smp_lock.h>
2039 #include <linux/highuid.h>
2040+#include <linux/grsecurity.h>
2041
2042 #include <asm/shmparam.h>
2043 #include <asm/uaccess.h>
2044@@ -206,6 +207,11 @@
2045 goto out;
2046 }
2047
2048+ if (gr_handle_mmap(file, prot)) {
2049+ addr = -EACCES;
2050+ goto out;
8be839c4 2051+ }
8be839c4 2052+
474a6d91
AM
2053 down_write(&current->mm->mmap_sem);
2054 addr = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
2055 up_write(&current->mm->mmap_sem);
2056diff -urN linux-2.4.22.org/arch/m68k/config.in linux-2.4.22/arch/m68k/config.in
2057--- linux-2.4.22.org/arch/m68k/config.in 2003-11-22 22:12:12.000000000 +0100
2058+++ linux-2.4.22/arch/m68k/config.in 2003-11-22 22:14:06.000000000 +0100
2059@@ -562,3 +562,11 @@
8be839c4 2060
474a6d91
AM
2061 source crypto/Config.in
2062 source lib/Config.in
2063+
2064+mainmenu_option next_comment
2065+comment 'Grsecurity'
2066+bool 'Grsecurity' CONFIG_GRKERNSEC
2067+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2068+ source grsecurity/Config.in
2069+fi
2070+endmenu
2071diff -urN linux-2.4.22.org/arch/mips/config.in linux-2.4.22/arch/mips/config.in
2072--- linux-2.4.22.org/arch/mips/config.in 2003-11-22 22:12:02.000000000 +0100
2073+++ linux-2.4.22/arch/mips/config.in 2003-11-22 22:14:06.000000000 +0100
2074@@ -7,3 +7,11 @@
2075 define_bool CONFIG_MIPS64 n
8be839c4 2076
474a6d91
AM
2077 source arch/mips/config-shared.in
2078+
2079+mainmenu_option next_comment
2080+comment 'Grsecurity'
2081+bool 'Grsecurity' CONFIG_GRKERNSEC
2082+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2083+ source grsecurity/Config.in
2084+fi
2085+endmenu
2086diff -urN linux-2.4.22.org/arch/mips64/config.in linux-2.4.22/arch/mips64/config.in
2087--- linux-2.4.22.org/arch/mips64/config.in 2003-11-22 22:12:35.000000000 +0100
2088+++ linux-2.4.22/arch/mips64/config.in 2003-11-22 22:14:06.000000000 +0100
2089@@ -7,3 +7,11 @@
2090 define_bool CONFIG_MIPS64 y
8be839c4 2091
474a6d91
AM
2092 source arch/mips/config-shared.in
2093+
2094+mainmenu_option next_comment
2095+comment 'Grsecurity'
2096+bool 'Grsecurity' CONFIG_GRKERNSEC
2097+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2098+ source grsecurity/Config.in
2099+fi
2100+endmenu
2101diff -urN linux-2.4.22.org/arch/parisc/config.in linux-2.4.22/arch/parisc/config.in
2102--- linux-2.4.22.org/arch/parisc/config.in 2003-11-22 22:12:37.000000000 +0100
2103+++ linux-2.4.22/arch/parisc/config.in 2003-11-22 22:14:06.000000000 +0100
2104@@ -205,3 +205,11 @@
8be839c4 2105
474a6d91
AM
2106 source crypto/Config.in
2107 source lib/Config.in
8be839c4 2108+
474a6d91
AM
2109+mainmenu_option next_comment
2110+comment 'Grsecurity'
2111+bool 'Grsecurity' CONFIG_GRKERNSEC
2112+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2113+ source grsecurity/Config.in
2114+fi
2115+endmenu
2116diff -urN linux-2.4.22.org/arch/parisc/kernel/ioctl32.c linux-2.4.22/arch/parisc/kernel/ioctl32.c
2117--- linux-2.4.22.org/arch/parisc/kernel/ioctl32.c 2003-11-22 22:12:37.000000000 +0100
2118+++ linux-2.4.22/arch/parisc/kernel/ioctl32.c 2003-11-22 22:14:06.000000000 +0100
2119@@ -1435,7 +1435,11 @@
2120 * To have permissions to do most of the vt ioctls, we either have
2121 * to be the owner of the tty, or super-user.
2122 */
2123+#ifdef CONFIG_GRKERNSEC
2124+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
8be839c4 2125+#else
474a6d91 2126 if (current->tty == tty || suser())
8be839c4 2127+#endif
474a6d91
AM
2128 return 1;
2129 return 0;
2130 }
2131diff -urN linux-2.4.22.org/arch/parisc/kernel/ptrace.c linux-2.4.22/arch/parisc/kernel/ptrace.c
2132--- linux-2.4.22.org/arch/parisc/kernel/ptrace.c 2003-11-22 22:12:37.000000000 +0100
2133+++ linux-2.4.22/arch/parisc/kernel/ptrace.c 2003-11-22 22:14:06.000000000 +0100
2134@@ -15,7 +15,7 @@
2135 #include <linux/ptrace.h>
2136 #include <linux/user.h>
2137 #include <linux/personality.h>
2138-
2139+#include <linux/grsecurity.h>
2140 #include <asm/uaccess.h>
2141 #include <asm/pgtable.h>
2142 #include <asm/system.h>
2143@@ -119,6 +119,9 @@
2144 if (pid == 1) /* no messing around with init! */
2145 goto out_tsk;
8be839c4 2146
474a6d91
AM
2147+ if (gr_handle_ptrace(child, request))
2148+ goto out_tsk;
2149+
2150 if (request == PTRACE_ATTACH) {
2151 ret = ptrace_attach(child);
2152 goto out_tsk;
2153diff -urN linux-2.4.22.org/arch/parisc/kernel/sys_parisc32.c linux-2.4.22/arch/parisc/kernel/sys_parisc32.c
2154--- linux-2.4.22.org/arch/parisc/kernel/sys_parisc32.c 2003-11-22 22:12:37.000000000 +0100
2155+++ linux-2.4.22/arch/parisc/kernel/sys_parisc32.c 2003-11-22 22:14:06.000000000 +0100
2156@@ -50,6 +50,7 @@
2157 #include <linux/highmem.h>
2158 #include <linux/highuid.h>
2159 #include <linux/mman.h>
2160+#include <linux/grsecurity.h>
8be839c4 2161
474a6d91
AM
2162 #include <asm/types.h>
2163 #include <asm/uaccess.h>
2164@@ -177,6 +178,11 @@
2165 struct file *file;
2166 int retval;
2167 int i;
2168+#ifdef CONFIG_GRKERNSEC
2169+ struct file *old_exec_file;
2170+ struct acl_subject_label *old_acl;
2171+ struct rlimit old_rlim[RLIM_NLIMITS];
2172+#endif
8be839c4 2173
474a6d91 2174 file = open_exec(filename);
8be839c4 2175
474a6d91
AM
2176@@ -184,7 +190,26 @@
2177 if (IS_ERR(file))
2178 return retval;
8be839c4 2179
474a6d91 2180+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
8be839c4 2181+
474a6d91
AM
2182+ if (gr_handle_nproc()) {
2183+ allow_write_access(file);
2184+ fput(file);
2185+ return -EAGAIN;
2186+ }
8be839c4 2187+
474a6d91
AM
2188+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
2189+ allow_write_access(file);
2190+ fput(file);
2191+ return -EACCES;
2192+ }
8be839c4 2193+
474a6d91 2194 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
8be839c4 2195+
474a6d91
AM
2196+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
2197+ bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
8be839c4
JR
2198+#endif
2199+
474a6d91
AM
2200 memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
2201
2202 DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs));
2203@@ -209,11 +234,24 @@
2204 if (retval < 0)
2205 goto out;
2206
2207+ if (!gr_tpe_allow(file)) {
2208+ retval = -EACCES;
2209+ goto out;
2210+ }
8be839c4 2211+
474a6d91
AM
2212+ if (gr_check_crash_exec(file)) {
2213+ retval = -EACCES;
2214+ goto out;
2215+ }
2216+
2217 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
2218 if (retval < 0)
2219 goto out;
8be839c4 2220
474a6d91
AM
2221 bprm.exec = bprm.p;
2222+
2223+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
2224+
2225 retval = copy_strings32(bprm.envc, envp, &bprm);
2226 if (retval < 0)
2227 goto out;
2228@@ -222,11 +260,32 @@
2229 if (retval < 0)
2230 goto out;
8be839c4 2231
474a6d91
AM
2232+#ifdef CONFIG_GRKERNSEC
2233+ old_acl = current->acl;
2234+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
2235+ old_exec_file = current->exec_file;
2236+ get_file(file);
2237+ current->exec_file = file;
2238+#endif
2239+
2240+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
2241+
2242 retval = search_binary_handler(&bprm,regs);
2243- if (retval >= 0)
2244+ if (retval >= 0) {
2245+#ifdef CONFIG_GRKERNSEC
2246+ if (old_exec_file)
2247+ fput(old_exec_file);
2248+#endif
2249 /* execve success */
2250 return retval;
2251+ }
8be839c4 2252
474a6d91
AM
2253+#ifdef CONFIG_GRKERNSEC
2254+ current->acl = old_acl;
2255+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
2256+ fput(current->exec_file);
2257+ current->exec_file = old_exec_file;
2258+#endif
2259 out:
2260 /* Something went wrong, return the inode and free the argument pages*/
2261 allow_write_access(bprm.file);
2262diff -urN linux-2.4.22.org/arch/parisc/kernel/sys_parisc.c linux-2.4.22/arch/parisc/kernel/sys_parisc.c
2263--- linux-2.4.22.org/arch/parisc/kernel/sys_parisc.c 2003-11-22 22:12:37.000000000 +0100
2264+++ linux-2.4.22/arch/parisc/kernel/sys_parisc.c 2003-11-22 22:14:06.000000000 +0100
2265@@ -12,6 +12,7 @@
2266 #include <linux/mman.h>
2267 #include <linux/shm.h>
2268 #include <linux/smp_lock.h>
2269+#include <linux/grsecurity.h>
8be839c4 2270
474a6d91
AM
2271 int sys_pipe(int *fildes)
2272 {
2273@@ -90,6 +91,11 @@
2274 inode = filp->f_dentry->d_inode;
2275 }
8be839c4 2276
474a6d91
AM
2277+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2278+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
2279+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
2280+#endif
8be839c4 2281+
474a6d91
AM
2282 if (inode && (flags & MAP_SHARED) && (inode->i_mapping->i_mmap_shared)) {
2283 addr = get_shared_area(inode, addr, len, pgoff);
2284 } else {
2285@@ -104,12 +110,23 @@
2286 {
2287 struct file * file = NULL;
2288 unsigned long error = -EBADF;
2289+
2290+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2291+ if (flags & MAP_MIRROR)
2292+ return -EINVAL;
8be839c4
JR
2293+#endif
2294+
474a6d91
AM
2295 if (!(flags & MAP_ANONYMOUS)) {
2296 file = fget(fd);
2297 if (!file)
2298 goto out;
2299 }
8be839c4 2300
474a6d91
AM
2301+ if (gr_handle_mmap(file, prot)) {
2302+ fput(file);
2303+ return -EACCES;
8be839c4 2304+ }
8be839c4 2305+
474a6d91
AM
2306 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2307
2308 down_write(&current->mm->mmap_sem);
2309diff -urN linux-2.4.22.org/arch/parisc/kernel/traps.c linux-2.4.22/arch/parisc/kernel/traps.c
2310--- linux-2.4.22.org/arch/parisc/kernel/traps.c 2003-11-22 22:12:37.000000000 +0100
2311+++ linux-2.4.22/arch/parisc/kernel/traps.c 2003-11-22 22:14:06.000000000 +0100
2312@@ -637,9 +637,7 @@
2313
2314 down_read(&current->mm->mmap_sem);
2315 vma = find_vma(current->mm,regs->iaoq[0]);
2316- if (vma && (regs->iaoq[0] >= vma->vm_start)
2317- && (vma->vm_flags & VM_EXEC)) {
2318-
2319+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
2320 fault_address = regs->iaoq[0];
2321 fault_space = regs->iasq[0];
2322
2323diff -urN linux-2.4.22.org/arch/parisc/mm/fault.c linux-2.4.22/arch/parisc/mm/fault.c
2324--- linux-2.4.22.org/arch/parisc/mm/fault.c 2003-11-22 22:12:37.000000000 +0100
2325+++ linux-2.4.22/arch/parisc/mm/fault.c 2003-11-22 22:14:06.000000000 +0100
2326@@ -15,6 +15,7 @@
2327 #include <linux/ptrace.h>
2328 #include <linux/sched.h>
2329 #include <linux/interrupt.h>
2330+#include <linux/unistd.h>
2331
2332 #include <asm/uaccess.h>
2333 #include <asm/traps.h>
2334@@ -53,7 +54,7 @@
2335 static unsigned long
2336 parisc_acctyp(unsigned long code, unsigned int inst)
2337 {
2338- if (code == 6 || code == 16)
2339+ if (code == 6 || code == 7 || code == 16)
2340 return VM_EXEC;
2341
2342 switch (inst & 0xf0000000) {
2343@@ -139,6 +140,136 @@
2344 }
2345 #endif
2346
8be839c4 2347+/*
474a6d91 2348+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
8be839c4 2349+ *
474a6d91
AM
2350+ * returns 1 when task should be killed
2351+ * 2 when rt_sigreturn trampoline was detected
2352+ * 3 when unpatched PLT trampoline was detected
2353+ * 4 when legitimate ET_EXEC was detected
8be839c4 2354+ */
474a6d91 2355+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
8be839c4
JR
2356+static int pax_handle_fetch_fault(struct pt_regs *regs)
2357+{
8be839c4 2358+ int err;
474a6d91 2359+
8be839c4
JR
2360+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2361+ if (current->flags & PF_PAX_RANDEXEC) {
474a6d91
AM
2362+ if (instruction_pointer(regs) >= current->mm->start_code &&
2363+ instruction_pointer(regs) < current->mm->end_code)
8be839c4 2364+ {
474a6d91
AM
2365+#if 0
2366+ /* PaX: this needs fixing */
2367+ if ((regs->gr[2] & ~3UL) == instruction_pointer(regs))
8be839c4 2368+ return 1;
474a6d91
AM
2369+#endif
2370+ regs->iaoq[0] += current->mm->delta_exec;
2371+ if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code &&
2372+ (regs->iaoq[1] & ~3UL) < current->mm->end_code)
2373+ regs->iaoq[1] += current->mm->delta_exec;
2374+ return 4;
8be839c4
JR
2375+ }
2376+ }
2377+#endif
2378+
474a6d91
AM
2379+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2380+ do { /* PaX: unpatched PLT emulation */
2381+ unsigned int bl, depwi;
8be839c4 2382+
474a6d91
AM
2383+ err = get_user(bl, (unsigned int*)instruction_pointer(regs));
2384+ err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
8be839c4
JR
2385+
2386+ if (err)
2387+ break;
2388+
474a6d91
AM
2389+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
2390+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
8be839c4 2391+
474a6d91
AM
2392+ err = get_user(ldw, (unsigned int*)addr);
2393+ err |= get_user(bv, (unsigned int*)(addr+4));
2394+ err |= get_user(ldw2, (unsigned int*)(addr+8));
8be839c4 2395+
474a6d91
AM
2396+ if (err)
2397+ break;
8be839c4 2398+
474a6d91
AM
2399+ if (ldw == 0x0E801096U &&
2400+ bv == 0xEAC0C000U &&
2401+ ldw2 == 0x0E881095U)
2402+ {
2403+ unsigned int resolver, map;
2404+
2405+ err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
2406+ err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
2407+ if (err)
2408+ break;
2409+
2410+ regs->gr[20] = instruction_pointer(regs)+8;
2411+ regs->gr[21] = map;
2412+ regs->gr[22] = resolver;
2413+ regs->iaoq[0] = resolver | 3UL;
2414+ regs->iaoq[1] = regs->iaoq[0] + 4;
2415+ return 3;
2416+ }
8be839c4
JR
2417+ }
2418+ } while (0);
474a6d91
AM
2419+#endif
2420+
2421+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2422+
2423+#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2424+ if (!(current->flags & PF_PAX_EMUTRAMP))
2425+ return 1;
2426+#endif
8be839c4
JR
2427+
2428+ do { /* PaX: rt_sigreturn emulation */
474a6d91 2429+ unsigned int ldi1, ldi2, bel, nop;
8be839c4 2430+
474a6d91
AM
2431+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
2432+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
2433+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
2434+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
8be839c4
JR
2435+
2436+ if (err)
2437+ break;
2438+
474a6d91
AM
2439+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
2440+ ldi2 == 0x3414015AU &&
2441+ bel == 0xE4008200U &&
2442+ nop == 0x08000240U)
8be839c4 2443+ {
474a6d91
AM
2444+ regs->gr[25] = (ldi1 & 2) >> 1;
2445+ regs->gr[20] = __NR_rt_sigreturn;
2446+ regs->gr[31] = regs->iaoq[1] + 16;
2447+ regs->sr[0] = regs->iasq[1];
2448+ regs->iaoq[0] = 0x100UL;
2449+ regs->iaoq[1] = regs->iaoq[0] + 4;
2450+ regs->iasq[0] = regs->sr[2];
2451+ regs->iasq[1] = regs->sr[2];
2452+ return 2;
8be839c4
JR
2453+ }
2454+ } while (0);
8be839c4
JR
2455+#endif
2456+
474a6d91
AM
2457+ return 1;
2458+}
8be839c4 2459+
474a6d91
AM
2460+void pax_report_insns(void *pc)
2461+{
2462+ unsigned long i;
8be839c4 2463+
474a6d91
AM
2464+ printk(KERN_ERR "PAX: bytes at PC: ");
2465+ for (i = 0; i < 5; i++) {
2466+ unsigned int c;
2467+ if (get_user(c, (unsigned int*)pc+i)) {
2468+ printk("<invalid address>.");
8be839c4 2469+ break;
8be839c4 2470+ }
474a6d91
AM
2471+ printk("%08x ", c);
2472+ }
2473+ printk("\n");
2474+}
2475+#endif
8be839c4 2476+
474a6d91
AM
2477 void do_page_fault(struct pt_regs *regs, unsigned long code,
2478 unsigned long address)
2479 {
2480@@ -164,8 +295,38 @@
2481
2482 acc_type = parisc_acctyp(code,regs->iir);
2483
2484- if ((vma->vm_flags & acc_type) != acc_type)
2485+ if ((vma->vm_flags & acc_type) != acc_type) {
2486+
2487+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2488+ if ((current->flags & PF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
2489+ (address & ~3UL) == instruction_pointer(regs))
2490+ {
2491+ up_read(&mm->mmap_sem);
2492+ switch(pax_handle_fetch_fault(regs)) {
8be839c4 2493+
474a6d91
AM
2494+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2495+ case 4:
2496+ return;
2497+#endif
8be839c4 2498+
474a6d91
AM
2499+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2500+ case 3:
2501+ return;
2502+#endif
8be839c4 2503+
474a6d91
AM
2504+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2505+ case 2:
2506+ return;
2507+#endif
8be839c4 2508+
474a6d91
AM
2509+ }
2510+ pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
2511+ do_exit(SIGKILL);
8be839c4 2512+ }
8be839c4
JR
2513+#endif
2514+
474a6d91
AM
2515 goto bad_area;
2516+ }
2517
2518 /*
2519 * If for any reason at all we couldn't handle the fault, make
2520diff -urN linux-2.4.22.org/arch/ppc/config.in linux-2.4.22/arch/ppc/config.in
2521--- linux-2.4.22.org/arch/ppc/config.in 2003-11-22 22:12:09.000000000 +0100
2522+++ linux-2.4.22/arch/ppc/config.in 2003-11-22 22:14:06.000000000 +0100
2523@@ -610,3 +610,12 @@
2524 int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
2525
2526 endmenu
2527+
2528+mainmenu_option next_comment
2529+comment 'Grsecurity'
2530+bool 'Grsecurity' CONFIG_GRKERNSEC
2531+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
2532+ source grsecurity/Config.in
2533+fi
2534+endmenu
2535+
2536diff -urN linux-2.4.22.org/arch/ppc/kernel/ptrace.c linux-2.4.22/arch/ppc/kernel/ptrace.c
2537--- linux-2.4.22.org/arch/ppc/kernel/ptrace.c 2003-11-22 22:12:10.000000000 +0100
2538+++ linux-2.4.22/arch/ppc/kernel/ptrace.c 2003-11-22 22:14:06.000000000 +0100
2539@@ -24,6 +24,7 @@
2540 #include <linux/errno.h>
2541 #include <linux/ptrace.h>
2542 #include <linux/user.h>
2543+#include <linux/grsecurity.h>
2544
2545 #include <asm/uaccess.h>
2546 #include <asm/page.h>
2547@@ -195,6 +196,9 @@
2548 if (pid == 1) /* you may not mess with init */
2549 goto out_tsk;
2550
2551+ if (gr_handle_ptrace(child, request))
2552+ goto out_tsk;
2553+
2554 if (request == PTRACE_ATTACH) {
2555 ret = ptrace_attach(child);
2556 goto out_tsk;
2557diff -urN linux-2.4.22.org/arch/ppc/kernel/syscalls.c linux-2.4.22/arch/ppc/kernel/syscalls.c
2558--- linux-2.4.22.org/arch/ppc/kernel/syscalls.c 2003-11-22 22:12:11.000000000 +0100
2559+++ linux-2.4.22/arch/ppc/kernel/syscalls.c 2003-11-22 22:19:00.000000000 +0100
2560@@ -35,6 +35,7 @@
2561 #include <linux/ipc.h>
2562 #include <linux/utsname.h>
2563 #include <linux/file.h>
2564+#include <linux/grsecurity.h>
2565
2566 #include <asm/uaccess.h>
2567 #include <asm/ipc.h>
2568@@ -191,6 +192,11 @@
2569 struct file * file = NULL;
2570 int ret = -EBADF;
2571
2572+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2573+ if (flags & MAP_MIRROR)
2574+ return -EINVAL;
2575+#endif
2576+
2577 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2578 if (!(flags & MAP_ANONYMOUS)) {
2579 if (!(file = fget(fd)))
2580@@ -200,9 +206,15 @@
2581 ret = -EINVAL;
2582 if ((! allow_mmap_address(addr)) && (flags & MAP_FIXED))
2583 goto out;
2584+
2585+ if (gr_handle_mmap(file, prot)) {
2586+ fput(file);
2587+ ret = -EACCES;
2588+ goto out;
2589+ }
2590
2591 down_write(&current->mm->mmap_sem);
2592- ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
675b3a60 2593+ ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
474a6d91
AM
2594 up_write(&current->mm->mmap_sem);
2595 if (file)
2596 fput(file);
2597diff -urN linux-2.4.22.org/arch/ppc/mm/fault.c linux-2.4.22/arch/ppc/mm/fault.c
2598--- linux-2.4.22.org/arch/ppc/mm/fault.c 2003-11-22 22:12:10.000000000 +0100
2599+++ linux-2.4.22/arch/ppc/mm/fault.c 2003-11-22 22:14:06.000000000 +0100
2600@@ -26,6 +26,9 @@
2601 #include <linux/mman.h>
2602 #include <linux/mm.h>
2603 #include <linux/interrupt.h>
2604+#include <linux/slab.h>
2605+#include <linux/pagemap.h>
2606+#include <linux/compiler.h>
2607
2608 #include <asm/page.h>
2609 #include <asm/pgtable.h>
2610@@ -52,6 +55,360 @@
2611 void bad_page_fault(struct pt_regs *, unsigned long, int sig);
2612 void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
2613
2614+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2615+void pax_syscall_close(struct vm_area_struct * vma)
2616+{
2617+ vma->vm_mm->call_syscall = 0UL;
8be839c4
JR
2618+}
2619+
474a6d91 2620+static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
8be839c4 2621+{
474a6d91
AM
2622+ struct page* page;
2623+ unsigned int *kaddr;
8be839c4 2624+
474a6d91
AM
2625+ page = alloc_page(GFP_HIGHUSER);
2626+ if (!page)
2627+ return page;
2628+
2629+ kaddr = kmap(page);
2630+ memset(kaddr, 0, PAGE_SIZE);
2631+ kaddr[0] = 0x44000002U; /* sc */
2632+ __flush_dcache_icache(kaddr);
2633+ kunmap(page);
2634+ return page;
2635+}
2636+
2637+static struct vm_operations_struct pax_vm_ops = {
2638+ close: pax_syscall_close,
2639+ nopage: pax_syscall_nopage,
2640+};
2641+
2642+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2643+{
2644+ vma->vm_mm = current->mm;
2645+ vma->vm_start = addr;
2646+ vma->vm_end = addr + PAGE_SIZE;
2647+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2648+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
2649+ vma->vm_ops = &pax_vm_ops;
2650+ vma->vm_pgoff = 0UL;
2651+ vma->vm_file = NULL;
2652+ vma->vm_private_data = NULL;
2653+ insert_vm_struct(current->mm, vma);
2654+ ++current->mm->total_vm;
8be839c4
JR
2655+}
2656+#endif
2657+
2658+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2659+/*
474a6d91 2660+ * PaX: decide what to do with offenders (regs->nip = fault address)
8be839c4 2661+ *
474a6d91
AM
2662+ * returns 1 when task should be killed
2663+ * 2 when patched GOT trampoline was detected
2664+ * 3 when patched PLT trampoline was detected
2665+ * 4 when unpatched PLT trampoline was detected
2666+ * 5 when legitimate ET_EXEC was detected
2667+ * 6 when sigreturn trampoline was detected
2668+ * 7 when rt_sigreturn trampoline was detected
8be839c4 2669+ */
474a6d91 2670+static int pax_handle_fetch_fault(struct pt_regs *regs)
8be839c4 2671+{
474a6d91 2672+ int err;
8be839c4 2673+
8be839c4 2674+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
474a6d91
AM
2675+ if (current->flags & PF_PAX_RANDEXEC) {
2676+ if (regs->nip >= current->mm->start_code &&
2677+ regs->nip < current->mm->end_code)
2678+ {
2679+ if (regs->link == regs->nip)
2680+ return 1;
8be839c4 2681+
474a6d91
AM
2682+ regs->nip += current->mm->delta_exec;
2683+ return 5;
8be839c4
JR
2684+ }
2685+ }
474a6d91 2686+#endif
8be839c4 2687+
474a6d91
AM
2688+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2689+ do { /* PaX: patched GOT emulation */
2690+ unsigned int blrl;
8be839c4 2691+
474a6d91 2692+ err = get_user(blrl, (unsigned int*)regs->nip);
8be839c4 2693+
474a6d91
AM
2694+ if (!err && blrl == 0x4E800021U) {
2695+ unsigned long temp = regs->nip;
8be839c4 2696+
474a6d91
AM
2697+ regs->nip = regs->link & 0xFFFFFFFCUL;
2698+ regs->link = temp + 4UL;
2699+ return 2;
2700+ }
2701+ } while (0);
8be839c4 2702+
474a6d91
AM
2703+ do { /* PaX: patched PLT emulation #1 */
2704+ unsigned int b;
8be839c4 2705+
474a6d91 2706+ err = get_user(b, (unsigned int *)regs->nip);
8be839c4 2707+
474a6d91
AM
2708+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
2709+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
2710+ return 3;
2711+ }
2712+ } while (0);
8be839c4 2713+
474a6d91
AM
2714+ do { /* PaX: unpatched PLT emulation #1 */
2715+ unsigned int li, b;
8be839c4 2716+
474a6d91
AM
2717+ err = get_user(li, (unsigned int *)regs->nip);
2718+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8be839c4 2719+
474a6d91
AM
2720+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2721+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2722+ unsigned long addr = b | 0xFC000000UL;
8be839c4 2723+
474a6d91
AM
2724+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2725+ err = get_user(rlwinm, (unsigned int*)addr);
2726+ err |= get_user(add, (unsigned int*)(addr+4));
2727+ err |= get_user(li2, (unsigned int*)(addr+8));
2728+ err |= get_user(addis2, (unsigned int*)(addr+12));
2729+ err |= get_user(mtctr, (unsigned int*)(addr+16));
2730+ err |= get_user(li3, (unsigned int*)(addr+20));
2731+ err |= get_user(addis3, (unsigned int*)(addr+24));
2732+ err |= get_user(bctr, (unsigned int*)(addr+28));
8be839c4 2733+
474a6d91
AM
2734+ if (err)
2735+ break;
8be839c4 2736+
474a6d91
AM
2737+ if (rlwinm == 0x556C083CU &&
2738+ add == 0x7D6C5A14U &&
2739+ (li2 & 0xFFFF0000U) == 0x39800000U &&
2740+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2741+ mtctr == 0x7D8903A6U &&
2742+ (li3 & 0xFFFF0000U) == 0x39800000U &&
2743+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2744+ bctr == 0x4E800420U)
2745+ {
2746+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2747+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2748+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2749+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2750+ regs->ctr += (addis2 & 0xFFFFU) << 16;
2751+ regs->nip = regs->ctr;
2752+ return 4;
2753+ }
8be839c4 2754+ }
474a6d91 2755+ } while (0);
8be839c4 2756+
474a6d91
AM
2757+#if 0
2758+ do { /* PaX: unpatched PLT emulation #2 */
2759+ unsigned int lis, lwzu, b, bctr;
2760+
2761+ err = get_user(lis, (unsigned int *)regs->nip);
2762+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
2763+ err |= get_user(b, (unsigned int *)(regs->nip+8));
2764+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
2765+
2766+ if (err)
2767+ break;
2768+
2769+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
2770+ (lwzu & 0xU) == 0xU &&
2771+ (b & 0xFC000003U) == 0x48000000U &&
2772+ bctr == 0x4E800420U)
2773+ {
2774+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2775+ unsigned long addr = b | 0xFC000000UL;
2776+
2777+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2778+ err = get_user(addis, (unsigned int*)addr);
2779+ err |= get_user(addi, (unsigned int*)(addr+4));
2780+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
2781+ err |= get_user(add, (unsigned int*)(addr+12));
2782+ err |= get_user(li2, (unsigned int*)(addr+16));
2783+ err |= get_user(addis2, (unsigned int*)(addr+20));
2784+ err |= get_user(mtctr, (unsigned int*)(addr+24));
2785+ err |= get_user(li3, (unsigned int*)(addr+28));
2786+ err |= get_user(addis3, (unsigned int*)(addr+32));
2787+ err |= get_user(bctr, (unsigned int*)(addr+36));
2788+
2789+ if (err)
2790+ break;
2791+
2792+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2793+ (addi & 0xFFFF0000U) == 0x396B0000U &&
2794+ rlwinm == 0x556C083CU &&
2795+ add == 0x7D6C5A14U &&
2796+ (li2 & 0xFFFF0000U) == 0x39800000U &&
2797+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2798+ mtctr == 0x7D8903A6U &&
2799+ (li3 & 0xFFFF0000U) == 0x39800000U &&
2800+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2801+ bctr == 0x4E800420U)
2802+ {
2803+ regs->gpr[PT_R11] =
2804+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2805+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2806+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2807+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2808+ regs->ctr += (addis2 & 0xFFFFU) << 16;
2809+ regs->nip = regs->ctr;
2810+ return 4;
2811+ }
2812+ }
2813+ } while (0);
2814+#endif
8be839c4 2815+
474a6d91
AM
2816+ do { /* PaX: unpatched PLT emulation #3 */
2817+ unsigned int li, b;
2818+
2819+ err = get_user(li, (unsigned int *)regs->nip);
2820+ err |= get_user(b, (unsigned int *)(regs->nip+4));
2821+
2822+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2823+ unsigned int addis, lwz, mtctr, bctr;
2824+ unsigned long addr = b | 0xFC000000UL;
2825+
2826+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2827+ err = get_user(addis, (unsigned int*)addr);
2828+ err |= get_user(lwz, (unsigned int*)(addr+4));
2829+ err |= get_user(mtctr, (unsigned int*)(addr+8));
2830+ err |= get_user(bctr, (unsigned int*)(addr+12));
2831+
2832+ if (err)
2833+ break;
2834+
2835+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2836+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
2837+ mtctr == 0x7D6903A6U &&
2838+ bctr == 0x4E800420U)
2839+ {
2840+ unsigned int r11;
2841+
2842+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2843+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2844+
2845+ err = get_user(r11, (unsigned int*)addr);
2846+ if (err)
2847+ break;
2848+
2849+ regs->gpr[PT_R11] = r11;
2850+ regs->ctr = r11;
2851+ regs->nip = r11;
2852+ return 4;
2853+ }
2854+ }
2855+ } while (0);
8be839c4
JR
2856+#endif
2857+
474a6d91
AM
2858+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
2859+ do { /* PaX: sigreturn emulation */
2860+ unsigned int li, sc;
8be839c4 2861+
474a6d91
AM
2862+ err = get_user(li, (unsigned int *)regs->nip);
2863+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
8be839c4 2864+
474a6d91
AM
2865+ if (!err && li == 0x38007777U && sc == 0x44000002U) {
2866+ struct vm_area_struct *vma;
2867+ unsigned long call_syscall;
8be839c4 2868+
474a6d91
AM
2869+ down_read(&current->mm->mmap_sem);
2870+ call_syscall = current->mm->call_syscall;
2871+ up_read(&current->mm->mmap_sem);
2872+ if (likely(call_syscall))
2873+ goto emulate;
8be839c4 2874+
474a6d91 2875+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8be839c4 2876+
474a6d91
AM
2877+ down_write(&current->mm->mmap_sem);
2878+ if (current->mm->call_syscall) {
2879+ call_syscall = current->mm->call_syscall;
2880+ up_write(&current->mm->mmap_sem);
2881+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2882+ goto emulate;
2883+ }
8be839c4 2884+
474a6d91
AM
2885+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2886+ if (!vma || (call_syscall & ~PAGE_MASK)) {
2887+ up_write(&current->mm->mmap_sem);
2888+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2889+ return 1;
2890+ }
8be839c4 2891+
474a6d91
AM
2892+ pax_insert_vma(vma, call_syscall);
2893+ current->mm->call_syscall = call_syscall;
2894+ up_write(&current->mm->mmap_sem);
8be839c4 2895+
474a6d91
AM
2896+emulate:
2897+ regs->gpr[PT_R0] = 0x7777UL;
2898+ regs->nip = call_syscall;
2899+ return 6;
2900+ }
2901+ } while (0);
8be839c4 2902+
474a6d91
AM
2903+ do { /* PaX: rt_sigreturn emulation */
2904+ unsigned int li, sc;
8be839c4 2905+
474a6d91
AM
2906+ err = get_user(li, (unsigned int *)regs->nip);
2907+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
8be839c4 2908+
474a6d91
AM
2909+ if (!err && li == 0x38006666U && sc == 0x44000002U) {
2910+ struct vm_area_struct *vma;
2911+ unsigned int call_syscall;
8be839c4 2912+
474a6d91
AM
2913+ down_read(&current->mm->mmap_sem);
2914+ call_syscall = current->mm->call_syscall;
2915+ up_read(&current->mm->mmap_sem);
2916+ if (likely(call_syscall))
2917+ goto rt_emulate;
8be839c4 2918+
474a6d91
AM
2919+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
2920+
2921+ down_write(&current->mm->mmap_sem);
2922+ if (current->mm->call_syscall) {
2923+ call_syscall = current->mm->call_syscall;
2924+ up_write(&current->mm->mmap_sem);
2925+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2926+ goto rt_emulate;
2927+ }
2928+
2929+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2930+ if (!vma || (call_syscall & ~PAGE_MASK)) {
2931+ up_write(&current->mm->mmap_sem);
2932+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2933+ return 1;
2934+ }
2935+
2936+ pax_insert_vma(vma, call_syscall);
2937+ current->mm->call_syscall = call_syscall;
2938+ up_write(&current->mm->mmap_sem);
2939+
2940+rt_emulate:
2941+ regs->gpr[PT_R0] = 0x6666UL;
2942+ regs->nip = call_syscall;
2943+ return 7;
2944+ }
2945+ } while (0);
8be839c4
JR
2946+#endif
2947+
474a6d91
AM
2948+ return 1;
2949+}
2950+
2951+void pax_report_insns(void *pc)
2952+{
2953+ unsigned long i;
2954+
2955+ printk(KERN_ERR "PAX: bytes at PC: ");
2956+ for (i = 0; i < 5; i++) {
2957+ unsigned int c;
2958+ if (get_user(c, (unsigned int*)pc+i)) {
2959+ printk("<invalid address>.");
2960+ break;
2961+ }
2962+ printk("%08x ", c);
8be839c4 2963+ }
474a6d91
AM
2964+ printk("\n");
2965+}
2966+#endif
8be839c4 2967+
474a6d91
AM
2968 /*
2969 * Check whether the instruction at regs->nip is a store using
2970 * an update addressing form which will update r1.
2971@@ -112,7 +469,7 @@
2972 * indicate errors in DSISR but can validly be set in SRR1.
2973 */
2974 if (regs->trap == 0x400)
2975- error_code &= 0x48200000;
2976+ error_code &= 0x58200000;
2977 else
2978 is_write = error_code & 0x02000000;
2979 #endif /* CONFIG_4xx || CONFIG_BOOKE */
2980@@ -245,6 +602,38 @@
2981
2982 /* User mode accesses cause a SIGSEGV */
2983 if (user_mode(regs)) {
8be839c4 2984+
474a6d91
AM
2985+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
2986+ if (current->flags & PF_PAX_PAGEEXEC) {
2987+ if ((regs->trap == 0x400) && (regs->nip == address)) {
2988+ switch (pax_handle_fetch_fault(regs)) {
8be839c4 2989+
474a6d91
AM
2990+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
2991+ case 2:
2992+ case 3:
2993+ case 4:
2994+ return;
8be839c4
JR
2995+#endif
2996+
474a6d91
AM
2997+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
2998+ case 5:
2999+ return;
3000+#endif
8be839c4 3001+
474a6d91
AM
3002+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
3003+ case 6:
3004+ case 7:
3005+ return;
3006+#endif
8be839c4 3007+
474a6d91 3008+ }
8be839c4 3009+
474a6d91
AM
3010+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
3011+ do_exit(SIGKILL);
3012+ }
3013+ }
3014+#endif
8be839c4 3015+
474a6d91
AM
3016 info.si_signo = SIGSEGV;
3017 info.si_errno = 0;
3018 info.si_code = code;
3019diff -urN linux-2.4.22.org/arch/ppc64/kernel/ioctl32.c linux-2.4.22/arch/ppc64/kernel/ioctl32.c
3020--- linux-2.4.22.org/arch/ppc64/kernel/ioctl32.c 2003-11-22 22:11:53.000000000 +0100
3021+++ linux-2.4.22/arch/ppc64/kernel/ioctl32.c 2003-11-22 22:14:06.000000000 +0100
3022@@ -1801,7 +1801,11 @@
3023 * To have permissions to do most of the vt ioctls, we either have
3024 * to be the owner of the tty, or super-user.
3025 */
3026+#ifdef CONFIG_GRKERNSEC
3027+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3028+#else
3029 if (current->tty == tty || suser())
3030+#endif
3031 return 1;
3032 return 0;
3033 }
3034diff -urN linux-2.4.22.org/arch/s390/config.in linux-2.4.22/arch/s390/config.in
3035--- linux-2.4.22.org/arch/s390/config.in 2003-11-22 22:12:36.000000000 +0100
3036+++ linux-2.4.22/arch/s390/config.in 2003-11-22 22:14:06.000000000 +0100
3037@@ -87,3 +87,11 @@
8be839c4
JR
3038
3039 source crypto/Config.in
3040 source lib/Config.in
3041+
3042+mainmenu_option next_comment
3043+comment 'Grsecurity'
3044+bool 'Grsecurity' CONFIG_GRKERNSEC
3045+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3046+ source grsecurity/Config.in
3047+fi
3048+endmenu
474a6d91
AM
3049diff -urN linux-2.4.22.org/arch/s390x/config.in linux-2.4.22/arch/s390x/config.in
3050--- linux-2.4.22.org/arch/s390x/config.in 2003-11-22 22:12:38.000000000 +0100
3051+++ linux-2.4.22/arch/s390x/config.in 2003-11-22 22:14:06.000000000 +0100
3052@@ -91,3 +91,11 @@
8be839c4 3053
474a6d91
AM
3054 source crypto/Config.in
3055 source lib/Config.in
8be839c4
JR
3056+
3057+mainmenu_option next_comment
3058+comment 'Grsecurity'
3059+bool 'Grsecurity' CONFIG_GRKERNSEC
3060+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
474a6d91 3061+ source grsecurity/Config.in
8be839c4
JR
3062+fi
3063+endmenu
474a6d91
AM
3064diff -urN linux-2.4.22.org/arch/sh/config.in linux-2.4.22/arch/sh/config.in
3065--- linux-2.4.22.org/arch/sh/config.in 2003-11-22 22:12:27.000000000 +0100
3066+++ linux-2.4.22/arch/sh/config.in 2003-11-22 22:14:06.000000000 +0100
3067@@ -491,3 +491,11 @@
8be839c4 3068
474a6d91
AM
3069 source crypto/Config.in
3070 source lib/Config.in
8be839c4
JR
3071+
3072+mainmenu_option next_comment
3073+comment 'Grsecurity'
3074+bool 'Grsecurity' CONFIG_GRKERNSEC
3075+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
474a6d91 3076+ source grsecurity/Config.in
8be839c4
JR
3077+fi
3078+endmenu
474a6d91
AM
3079diff -urN linux-2.4.22.org/arch/sparc/boot/Makefile linux-2.4.22/arch/sparc/boot/Makefile
3080--- linux-2.4.22.org/arch/sparc/boot/Makefile 2003-11-22 22:11:57.000000000 +0100
3081+++ linux-2.4.22/arch/sparc/boot/Makefile 2003-11-22 22:14:06.000000000 +0100
3082@@ -24,7 +24,7 @@
3083
3084 BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o
3085 BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
3086- $(DRIVERS) $(NETWORKS)
3087+ $(DRIVERS) $(NETWORKS) $(GRSECURITY)
3088
3089 # I wanted to make this depend upon BTOBJS so that a parallel
3090 # build would work, but this fails because $(HEAD) cannot work
3091diff -urN linux-2.4.22.org/arch/sparc/config.in linux-2.4.22/arch/sparc/config.in
3092--- linux-2.4.22.org/arch/sparc/config.in 2003-11-22 22:11:57.000000000 +0100
3093+++ linux-2.4.22/arch/sparc/config.in 2003-11-22 22:14:06.000000000 +0100
3094@@ -283,3 +283,11 @@
8be839c4
JR
3095
3096 source crypto/Config.in
3097 source lib/Config.in
3098+
3099+mainmenu_option next_comment
3100+comment 'Grsecurity'
3101+bool 'Grsecurity' CONFIG_GRKERNSEC
3102+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3103+ source grsecurity/Config.in
3104+fi
3105+endmenu
474a6d91
AM
3106diff -urN linux-2.4.22.org/arch/sparc/kernel/ptrace.c linux-2.4.22/arch/sparc/kernel/ptrace.c
3107--- linux-2.4.22.org/arch/sparc/kernel/ptrace.c 2003-11-22 22:11:59.000000000 +0100
3108+++ linux-2.4.22/arch/sparc/kernel/ptrace.c 2003-11-22 22:14:06.000000000 +0100
3109@@ -17,6 +17,7 @@
8be839c4 3110 #include <linux/user.h>
474a6d91
AM
3111 #include <linux/smp.h>
3112 #include <linux/smp_lock.h>
8be839c4 3113+#include <linux/grsecurity.h>
474a6d91 3114
8be839c4
JR
3115 #include <asm/pgtable.h>
3116 #include <asm/system.h>
474a6d91
AM
3117@@ -310,6 +311,9 @@
3118 goto out;
3119 }
8be839c4 3120
474a6d91 3121+ if(gr_handle_ptrace(child, request))
8be839c4
JR
3122+ goto out_tsk;
3123+
474a6d91
AM
3124 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3125 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3126 if (ptrace_attach(child)) {
3127diff -urN linux-2.4.22.org/arch/sparc/kernel/sys_sparc.c linux-2.4.22/arch/sparc/kernel/sys_sparc.c
3128--- linux-2.4.22.org/arch/sparc/kernel/sys_sparc.c 2003-11-22 22:12:00.000000000 +0100
3129+++ linux-2.4.22/arch/sparc/kernel/sys_sparc.c 2003-11-22 22:14:06.000000000 +0100
3130@@ -20,6 +20,7 @@
3131 #include <linux/utsname.h>
3132 #include <linux/smp.h>
8be839c4
JR
3133 #include <linux/smp_lock.h>
3134+#include <linux/grsecurity.h>
3135
474a6d91
AM
3136 #include <asm/uaccess.h>
3137 #include <asm/ipc.h>
3138@@ -54,6 +55,13 @@
3139 return -ENOMEM;
3140 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
3141 return -ENOMEM;
3142+
8be839c4
JR
3143+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3144+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3145+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
474a6d91 3146+ else
8be839c4
JR
3147+#endif
3148+
474a6d91
AM
3149 if (!addr)
3150 addr = TASK_UNMAPPED_BASE;
3151
3152@@ -225,6 +233,11 @@
3153 struct file * file = NULL;
3154 unsigned long retval = -EBADF;
3155
3156+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3157+ if (flags & MAP_MIRROR)
3158+ return -EINVAL;
3159+#endif
8be839c4 3160+
474a6d91
AM
3161 if (!(flags & MAP_ANONYMOUS)) {
3162 file = fget(fd);
3163 if (!file)
3164@@ -243,6 +256,12 @@
3165 if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
3166 goto out_putf;
3167
3168+ if (gr_handle_mmap(file, prot)) {
3169+ fput(file);
8be839c4
JR
3170+ retval = -EACCES;
3171+ goto out;
3172+ }
3173+
474a6d91 3174 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
8be839c4 3175
474a6d91
AM
3176 down_write(&current->mm->mmap_sem);
3177diff -urN linux-2.4.22.org/arch/sparc/kernel/sys_sunos.c linux-2.4.22/arch/sparc/kernel/sys_sunos.c
3178--- linux-2.4.22.org/arch/sparc/kernel/sys_sunos.c 2003-11-22 22:11:59.000000000 +0100
3179+++ linux-2.4.22/arch/sparc/kernel/sys_sunos.c 2003-11-22 22:14:06.000000000 +0100
3180@@ -68,6 +68,11 @@
3181 struct file * file = NULL;
3182 unsigned long retval, ret_type;
8be839c4 3183
474a6d91
AM
3184+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3185+ if (flags & MAP_MIRROR)
3186+ return -EINVAL;
8be839c4
JR
3187+#endif
3188+
474a6d91
AM
3189 if(flags & MAP_NORESERVE) {
3190 static int cnt;
3191 if (cnt++ < 10)
3192diff -urN linux-2.4.22.org/arch/sparc/mm/fault.c linux-2.4.22/arch/sparc/mm/fault.c
3193--- linux-2.4.22.org/arch/sparc/mm/fault.c 2003-11-22 22:12:00.000000000 +0100
3194+++ linux-2.4.22/arch/sparc/mm/fault.c 2003-11-22 22:14:06.000000000 +0100
3195@@ -19,6 +19,9 @@
3196 #include <linux/smp.h>
3197 #include <linux/smp_lock.h>
8be839c4 3198 #include <linux/interrupt.h>
474a6d91
AM
3199+#include <linux/slab.h>
3200+#include <linux/pagemap.h>
3201+#include <linux/compiler.h>
8be839c4 3202
474a6d91
AM
3203 #include <asm/system.h>
3204 #include <asm/segment.h>
3205@@ -200,6 +203,261 @@
3206 return 0;
3207 }
8be839c4 3208
474a6d91
AM
3209+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3210+void pax_emuplt_close(struct vm_area_struct * vma)
3211+{
3212+ vma->vm_mm->call_dl_resolve = 0UL;
3213+}
3214+
3215+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
3216+{
3217+ struct page* page;
3218+ unsigned int *kaddr;
3219+
3220+ page = alloc_page(GFP_HIGHUSER);
3221+ if (!page)
3222+ return page;
3223+
3224+ kaddr = kmap(page);
3225+ memset(kaddr, 0, PAGE_SIZE);
3226+ kaddr[0] = 0x9DE3BFA8U; /* save */
3227+ flush_dcache_page(page);
3228+ kunmap(page);
3229+ return page;
3230+}
3231+
3232+static struct vm_operations_struct pax_vm_ops = {
3233+ close: pax_emuplt_close,
3234+ nopage: pax_emuplt_nopage,
3235+};
3236+
3237+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3238+{
3239+ vma->vm_mm = current->mm;
3240+ vma->vm_start = addr;
3241+ vma->vm_end = addr + PAGE_SIZE;
3242+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3243+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3244+ vma->vm_ops = &pax_vm_ops;
3245+ vma->vm_pgoff = 0UL;
3246+ vma->vm_file = NULL;
3247+ vma->vm_private_data = NULL;
3248+ insert_vm_struct(current->mm, vma);
3249+ ++current->mm->total_vm;
3250+}
3251+
8be839c4 3252+/*
474a6d91 3253+ * PaX: decide what to do with offenders (regs->pc = fault address)
8be839c4 3254+ *
474a6d91
AM
3255+ * returns 1 when task should be killed
3256+ * 2 when patched PLT trampoline was detected
3257+ * 3 when unpatched PLT trampoline was detected
8be839c4
JR
3258+ * 4 when legitimate ET_EXEC was detected
3259+ */
8be839c4
JR
3260+static int pax_handle_fetch_fault(struct pt_regs *regs)
3261+{
3262+ int err;
3263+
3264+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3265+ if (current->flags & PF_PAX_RANDEXEC) {
474a6d91
AM
3266+ if (regs->pc >= current->mm->start_code &&
3267+ regs->pc < current->mm->end_code)
8be839c4 3268+ {
474a6d91 3269+ if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
8be839c4 3270+ return 1;
474a6d91
AM
3271+
3272+ regs->pc += current->mm->delta_exec;
3273+ if (regs->npc >= current->mm->start_code &&
3274+ regs->npc < current->mm->end_code)
3275+ regs->npc += current->mm->delta_exec;
8be839c4
JR
3276+ return 4;
3277+ }
474a6d91
AM
3278+ if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
3279+ regs->pc < current->mm->end_code + current->mm->delta_exec)
3280+ {
3281+ regs->pc -= current->mm->delta_exec;
3282+ if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
3283+ regs->npc < current->mm->end_code + current->mm->delta_exec)
3284+ regs->npc -= current->mm->delta_exec;
3285+ }
8be839c4
JR
3286+ }
3287+#endif
3288+
3289+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
474a6d91
AM
3290+ do { /* PaX: patched PLT emulation #1 */
3291+ unsigned int sethi1, sethi2, jmpl;
3292+
3293+ err = get_user(sethi1, (unsigned int *)regs->pc);
3294+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
3295+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
3296+
3297+ if (err)
3298+ break;
3299+
3300+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3301+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
3302+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
3303+ {
3304+ unsigned int addr;
3305+
3306+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3307+ addr = regs->u_regs[UREG_G1];
3308+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3309+ regs->pc = addr;
3310+ regs->npc = addr+4;
3311+ return 2;
3312+ }
3313+ } while (0);
3314+
3315+ { /* PaX: patched PLT emulation #2 */
3316+ unsigned int ba;
3317+
3318+ err = get_user(ba, (unsigned int *)regs->pc);
3319+
3320+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3321+ unsigned int addr;
3322+
3323+ addr = regs->pc + 4 + (((ba | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3324+ regs->pc = addr;
3325+ regs->npc = addr+4;
3326+ return 2;
3327+ }
3328+ }
3329+
3330+ do { /* PaX: patched PLT emulation #3 */
3331+ unsigned int sethi, jmpl, nop;
3332+
3333+ err = get_user(sethi, (unsigned int*)regs->pc);
3334+ err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
3335+ err |= get_user(nop, (unsigned int*)(regs->pc+8));
3336+
3337+ if (err)
3338+ break;
3339+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3340+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3341+ nop == 0x01000000U)
3342+ {
3343+ unsigned int addr;
3344+
3345+ addr = (sethi & 0x003FFFFFU) << 10;
3346+ regs->u_regs[UREG_G1] = addr;
3347+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3348+ regs->pc = addr;
3349+ regs->npc = addr+4;
3350+ return 2;
3351+ }
3352+ } while (0);
3353+
3354+ do { /* PaX: unpatched PLT emulation step 1 */
3355+ unsigned int sethi, ba, nop;
8be839c4 3356+
474a6d91
AM
3357+ err = get_user(sethi, (unsigned int *)regs->pc);
3358+ err |= get_user(ba, (unsigned int *)(regs->pc+4));
3359+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
8be839c4
JR
3360+
3361+ if (err)
3362+ break;
474a6d91
AM
3363+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3364+ (ba & 0xFFC00000U) == 0x30800000U &&
3365+ nop == 0x01000000U)
3366+ {
3367+ unsigned int addr, save, call;
8be839c4 3368+
474a6d91 3369+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
8be839c4 3370+
474a6d91
AM
3371+ err = get_user(save, (unsigned int *)addr);
3372+ err |= get_user(call, (unsigned int *)(addr+4));
3373+ err |= get_user(nop, (unsigned int *)(addr+8));
8be839c4
JR
3374+ if (err)
3375+ break;
3376+
474a6d91
AM
3377+ if (save == 0x9DE3BFA8U &&
3378+ (call & 0xC0000000U) == 0x40000000U &&
3379+ nop == 0x01000000U)
8be839c4 3380+ {
474a6d91
AM
3381+ struct vm_area_struct *vma;
3382+ unsigned long call_dl_resolve;
8be839c4 3383+
474a6d91
AM
3384+ down_read(&current->mm->mmap_sem);
3385+ call_dl_resolve = current->mm->call_dl_resolve;
3386+ up_read(&current->mm->mmap_sem);
3387+ if (likely(call_dl_resolve))
3388+ goto emulate;
8be839c4 3389+
474a6d91
AM
3390+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3391+
3392+ down_write(&current->mm->mmap_sem);
3393+ if (current->mm->call_dl_resolve) {
3394+ call_dl_resolve = current->mm->call_dl_resolve;
3395+ up_write(&current->mm->mmap_sem);
3396+ if (vma) kmem_cache_free(vm_area_cachep, vma);
3397+ goto emulate;
3398+ }
3399+
3400+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3401+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3402+ up_write(&current->mm->mmap_sem);
3403+ if (vma) kmem_cache_free(vm_area_cachep, vma);
3404+ return 1;
3405+ }
3406+
3407+ pax_insert_vma(vma, call_dl_resolve);
3408+ current->mm->call_dl_resolve = call_dl_resolve;
3409+ up_write(&current->mm->mmap_sem);
3410+
3411+emulate:
3412+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3413+ regs->pc = call_dl_resolve;
3414+ regs->npc = addr+4;
8be839c4
JR
3415+ return 3;
3416+ }
3417+ }
3418+ } while (0);
474a6d91
AM
3419+
3420+ do { /* PaX: unpatched PLT emulation step 2 */
3421+ unsigned int save, call, nop;
3422+
3423+ err = get_user(save, (unsigned int*)(regs->pc-4));
3424+ err |= get_user(call, (unsigned int*)regs->pc);
3425+ err |= get_user(nop, (unsigned int*)(regs->pc+4));
3426+ if (err)
3427+ break;
3428+
3429+ if (save == 0x9DE3BFA8U &&
3430+ (call & 0xC0000000U) == 0x40000000U &&
3431+ nop == 0x01000000U)
3432+ {
3433+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
3434+
3435+ regs->u_regs[UREG_RETPC] = regs->pc;
3436+ regs->pc = dl_resolve;
3437+ regs->npc = dl_resolve+4;
3438+ return 3;
3439+ }
3440+ } while (0);
3441+
3442+#endif
3443+
3444+ return 1;
3445+}
3446+
3447+void pax_report_insns(void *pc)
3448+{
3449+ unsigned long i;
3450+
3451+ printk(KERN_ERR "PAX: bytes at PC: ");
3452+ for (i = 0; i < 5; i++) {
3453+ unsigned int c;
3454+ if (get_user(c, (unsigned int*)pc+i)) {
3455+ printk("<invalid address>.");
3456+ break;
3457+ }
3458+ printk("%08x ", c);
3459+ }
3460+ printk("\n");
3461+}
3462+#endif
3463+
3464 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
3465 unsigned long address)
3466 {
3467@@ -263,6 +521,29 @@
3468 if(!(vma->vm_flags & VM_WRITE))
3469 goto bad_area;
3470 } else {
3471+
3472+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3473+ if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
3474+ up_read(&mm->mmap_sem);
3475+ switch (pax_handle_fetch_fault(regs)) {
3476+
3477+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3478+ case 2:
3479+ case 3:
3480+ return;
3481+#endif
3482+
3483+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3484+ case 4:
3485+ return;
3486+#endif
3487+
3488+ }
3489+ pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
3490+ do_exit(SIGKILL);
3491+ }
3492+#endif
3493+
3494 /* Allow reads even for write-only mappings */
3495 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
3496 goto bad_area;
3497diff -urN linux-2.4.22.org/arch/sparc/mm/init.c linux-2.4.22/arch/sparc/mm/init.c
3498--- linux-2.4.22.org/arch/sparc/mm/init.c 2003-11-22 22:12:00.000000000 +0100
3499+++ linux-2.4.22/arch/sparc/mm/init.c 2003-11-22 22:14:06.000000000 +0100
3500@@ -350,17 +350,17 @@
3501
3502 /* Initialize the protection map with non-constant, MMU dependent values. */
3503 protection_map[0] = PAGE_NONE;
3504- protection_map[1] = PAGE_READONLY;
3505- protection_map[2] = PAGE_COPY;
3506- protection_map[3] = PAGE_COPY;
3507+ protection_map[1] = PAGE_READONLY_NOEXEC;
3508+ protection_map[2] = PAGE_COPY_NOEXEC;
3509+ protection_map[3] = PAGE_COPY_NOEXEC;
3510 protection_map[4] = PAGE_READONLY;
3511 protection_map[5] = PAGE_READONLY;
3512 protection_map[6] = PAGE_COPY;
3513 protection_map[7] = PAGE_COPY;
3514 protection_map[8] = PAGE_NONE;
3515- protection_map[9] = PAGE_READONLY;
3516- protection_map[10] = PAGE_SHARED;
3517- protection_map[11] = PAGE_SHARED;
3518+ protection_map[9] = PAGE_READONLY_NOEXEC;
3519+ protection_map[10] = PAGE_SHARED_NOEXEC;
3520+ protection_map[11] = PAGE_SHARED_NOEXEC;
3521 protection_map[12] = PAGE_READONLY;
3522 protection_map[13] = PAGE_READONLY;
3523 protection_map[14] = PAGE_SHARED;
3524diff -urN linux-2.4.22.org/arch/sparc/mm/srmmu.c linux-2.4.22/arch/sparc/mm/srmmu.c
3525--- linux-2.4.22.org/arch/sparc/mm/srmmu.c 2003-11-22 22:12:00.000000000 +0100
3526+++ linux-2.4.22/arch/sparc/mm/srmmu.c 2003-11-22 22:14:07.000000000 +0100
3527@@ -2047,6 +2047,13 @@
3528 BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
3529 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
3530 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
3531+
3532+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3533+ BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
3534+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
3535+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
3536+#endif
3537+
3538 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
3539 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
3540 pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
3541diff -urN linux-2.4.22.org/arch/sparc64/config.in linux-2.4.22/arch/sparc64/config.in
3542--- linux-2.4.22.org/arch/sparc64/config.in 2003-11-22 22:12:20.000000000 +0100
3543+++ linux-2.4.22/arch/sparc64/config.in 2003-11-22 22:14:07.000000000 +0100
3544@@ -318,3 +318,11 @@
3545
3546 source crypto/Config.in
3547 source lib/Config.in
3548+
3549+mainmenu_option next_comment
3550+comment 'Grsecurity'
3551+bool 'Grsecurity' CONFIG_GRKERNSEC
3552+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
3553+ source grsecurity/Config.in
3554+fi
3555+endmenu
3556diff -urN linux-2.4.22.org/arch/sparc64/kernel/ioctl32.c linux-2.4.22/arch/sparc64/kernel/ioctl32.c
3557--- linux-2.4.22.org/arch/sparc64/kernel/ioctl32.c 2003-11-22 22:12:18.000000000 +0100
3558+++ linux-2.4.22/arch/sparc64/kernel/ioctl32.c 2003-11-22 22:14:07.000000000 +0100
3559@@ -2047,7 +2047,11 @@
3560 * To have permissions to do most of the vt ioctls, we either have
3561 * to be the owner of the tty, or super-user.
3562 */
3563+#ifdef CONFIG_GRKERNSEC
3564+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
3565+#else
3566 if (current->tty == tty || suser())
3567+#endif
3568 return 1;
3569 return 0;
3570 }
3571diff -urN linux-2.4.22.org/arch/sparc64/kernel/itlb_base.S linux-2.4.22/arch/sparc64/kernel/itlb_base.S
3572--- linux-2.4.22.org/arch/sparc64/kernel/itlb_base.S 2003-11-22 22:12:19.000000000 +0100
3573+++ linux-2.4.22/arch/sparc64/kernel/itlb_base.S 2003-11-22 22:14:07.000000000 +0100
3574@@ -41,7 +41,9 @@
3575 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
3576 ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE
3577 1: brgez,pn %g5, 3f ! Not valid, branch out
3578- nop ! Delay-slot
3579+ and %g5, _PAGE_EXEC, %g4
3580+ brz,pn %g4, 3f ! Not executable, branch out
3581+ nop ! Delay-slot
3582 2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
3583 retry ! Trap return
3584 3: rdpr %pstate, %g4 ! Move into alternate globals
3585@@ -74,8 +76,6 @@
3586 nop
3587 nop
3588 nop
3589- nop
3590- nop
3591 CREATE_VPTE_NOP
3592
3593 #undef CREATE_VPTE_OFFSET1
3594diff -urN linux-2.4.22.org/arch/sparc64/kernel/ptrace.c linux-2.4.22/arch/sparc64/kernel/ptrace.c
3595--- linux-2.4.22.org/arch/sparc64/kernel/ptrace.c 2003-11-22 22:12:19.000000000 +0100
3596+++ linux-2.4.22/arch/sparc64/kernel/ptrace.c 2003-11-22 22:14:07.000000000 +0100
3597@@ -18,6 +18,7 @@
3598 #include <linux/user.h>
3599 #include <linux/smp.h>
3600 #include <linux/smp_lock.h>
3601+#include <linux/grsecurity.h>
3602
3603 #include <asm/asi.h>
3604 #include <asm/pgtable.h>
3605@@ -161,6 +162,11 @@
3606 goto out;
3607 }
3608
3609+ if (gr_handle_ptrace(child, (long)request)) {
3610+ pt_error_return(regs, EPERM);
3611+ goto out;
3612+ }
3613+
3614 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3615 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3616 if (ptrace_attach(child)) {
3617diff -urN linux-2.4.22.org/arch/sparc64/kernel/sys_sparc32.c linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c
3618--- linux-2.4.22.org/arch/sparc64/kernel/sys_sparc32.c 2003-11-22 22:12:19.000000000 +0100
3619+++ linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c 2003-11-22 22:14:07.000000000 +0100
3620@@ -52,6 +52,8 @@
3621 #include <linux/sysctl.h>
3622 #include <linux/dnotify.h>
3623 #include <linux/netfilter_ipv4/ip_tables.h>
3624+#include <linux/random.h>
3625+#include <linux/grsecurity.h>
3626
3627 #include <asm/types.h>
3628 #include <asm/ipc.h>
3629@@ -3235,8 +3237,18 @@
3630 struct file * file;
3631 int retval;
3632 int i;
3633+#ifdef CONFIG_GRKERNSEC
3634+ struct file *old_exec_file;
3635+ struct acl_subject_label *old_acl;
3636+ struct rlimit old_rlim[RLIM_NLIMITS];
8be839c4 3637+#endif
474a6d91
AM
3638
3639 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
8be839c4 3640+
474a6d91
AM
3641+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
3642+ bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
8be839c4
JR
3643+#endif
3644+
474a6d91
AM
3645 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3646
3647 file = open_exec(filename);
3648@@ -3245,6 +3257,20 @@
3649 if (IS_ERR(file))
3650 return retval;
3651
3652+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
8be839c4 3653+
474a6d91
AM
3654+ if (gr_handle_nproc()) {
3655+ allow_write_access(file);
3656+ fput(file);
3657+ return -EAGAIN;
3658+ }
8be839c4 3659+
474a6d91
AM
3660+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
3661+ allow_write_access(file);
3662+ fput(file);
3663+ return -EACCES;
3664+ }
8be839c4 3665+
474a6d91
AM
3666 bprm.file = file;
3667 bprm.filename = filename;
3668 bprm.sh_bang = 0;
3669@@ -3265,11 +3291,24 @@
3670 if (retval < 0)
3671 goto out;
3672
3673+ if(!gr_tpe_allow(file)) {
3674+ retval = -EACCES;
3675+ goto out;
3676+ }
8be839c4 3677+
474a6d91
AM
3678+ if (gr_check_crash_exec(file)) {
3679+ retval = -EACCES;
3680+ goto out;
8be839c4 3681+ }
8be839c4 3682+
474a6d91
AM
3683 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3684 if (retval < 0)
3685 goto out;
8be839c4 3686
474a6d91 3687 bprm.exec = bprm.p;
8be839c4 3688+
474a6d91 3689+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
8be839c4 3690+
474a6d91
AM
3691 retval = copy_strings32(bprm.envc, envp, &bprm);
3692 if (retval < 0)
3693 goto out;
3694@@ -3278,11 +3317,32 @@
3695 if (retval < 0)
3696 goto out;
3697
3698+#ifdef CONFIG_GRKERNSEC
3699+ old_acl = current->acl;
3700+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
3701+ old_exec_file = current->exec_file;
3702+ get_file(file);
3703+ current->exec_file = file;
8be839c4
JR
3704+#endif
3705+
474a6d91 3706+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
8be839c4 3707+
474a6d91
AM
3708 retval = search_binary_handler(&bprm, regs);
3709- if (retval >= 0)
3710+ if (retval >= 0) {
3711+#ifdef CONFIG_GRKERNSEC
3712+ if (old_exec_file)
3713+ fput(old_exec_file);
8be839c4 3714+#endif
474a6d91
AM
3715 /* execve success */
3716 return retval;
8be839c4
JR
3717+ }
3718
474a6d91
AM
3719+#ifdef CONFIG_GRKERNSEC
3720+ current->acl = old_acl;
3721+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
3722+ fput(current->exec_file);
3723+ current->exec_file = old_exec_file;
3724+#endif
3725 out:
3726 /* Something went wrong, return the inode and free the argument pages*/
3727 allow_write_access(bprm.file);
3728diff -urN linux-2.4.22.org/arch/sparc64/kernel/sys_sparc.c linux-2.4.22/arch/sparc64/kernel/sys_sparc.c
3729--- linux-2.4.22.org/arch/sparc64/kernel/sys_sparc.c 2003-11-22 22:12:18.000000000 +0100
3730+++ linux-2.4.22/arch/sparc64/kernel/sys_sparc.c 2003-11-22 22:14:07.000000000 +0100
8be839c4 3731@@ -24,6 +24,7 @@
474a6d91 3732 #include <linux/slab.h>
8be839c4 3733 #include <linux/ipc.h>
474a6d91 3734 #include <linux/personality.h>
8be839c4
JR
3735+#include <linux/grsecurity.h>
3736
3737 #include <asm/uaccess.h>
3738 #include <asm/ipc.h>
474a6d91
AM
3739@@ -63,6 +64,13 @@
3740 task_size = 0xf0000000UL;
3741 if (len > task_size || len > -PAGE_OFFSET)
3742 return -ENOMEM;
3743+
3744+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
3745+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3746+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3747+ else
3748+#endif
3749+
3750 if (!addr)
3751 addr = TASK_UNMAPPED_BASE;
3752
3753@@ -289,11 +297,22 @@
8be839c4 3754 struct file * file = NULL;
474a6d91 3755 unsigned long retval = -EBADF;
8be839c4
JR
3756
3757+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3758+ if (flags & MAP_MIRROR)
3759+ return -EINVAL;
3760+#endif
3761+
8be839c4 3762 if (!(flags & MAP_ANONYMOUS)) {
474a6d91
AM
3763 file = fget(fd);
3764 if (!file)
8be839c4
JR
3765 goto out;
3766 }
474a6d91 3767+
8be839c4 3768+ if (gr_handle_mmap(file, prot)) {
474a6d91
AM
3769+ retval = -EACCES;
3770+ goto out_putf;
8be839c4
JR
3771+ }
3772+
474a6d91
AM
3773 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3774 len = PAGE_ALIGN(len);
3775 retval = -EINVAL;
3776diff -urN linux-2.4.22.org/arch/sparc64/kernel/sys_sunos32.c linux-2.4.22/arch/sparc64/kernel/sys_sunos32.c
3777--- linux-2.4.22.org/arch/sparc64/kernel/sys_sunos32.c 2003-11-22 22:12:19.000000000 +0100
3778+++ linux-2.4.22/arch/sparc64/kernel/sys_sunos32.c 2003-11-22 22:14:07.000000000 +0100
3779@@ -68,6 +68,11 @@
3780 struct file *file = NULL;
3781 unsigned long retval, ret_type;
3782
3783+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3784+ if (flags & MAP_MIRROR)
3785+ return -EINVAL;
3786+#endif
3787+
3788 if(flags & MAP_NORESERVE) {
3789 static int cnt;
3790 if (cnt++ < 10)
3791diff -urN linux-2.4.22.org/arch/sparc64/mm/fault.c linux-2.4.22/arch/sparc64/mm/fault.c
3792--- linux-2.4.22.org/arch/sparc64/mm/fault.c 2003-11-22 22:12:19.000000000 +0100
3793+++ linux-2.4.22/arch/sparc64/mm/fault.c 2003-11-22 22:14:07.000000000 +0100
3794@@ -16,6 +16,9 @@
3795 #include <linux/smp_lock.h>
3796 #include <linux/init.h>
8be839c4
JR
3797 #include <linux/interrupt.h>
3798+#include <linux/slab.h>
3799+#include <linux/pagemap.h>
3800+#include <linux/compiler.h>
3801
3802 #include <asm/page.h>
3803 #include <asm/pgtable.h>
474a6d91
AM
3804@@ -299,6 +302,267 @@
3805 unhandled_fault (address, current, regs);
3806 }
8be839c4 3807
474a6d91
AM
3808+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
3809+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
3810+static void pax_emuplt_close(struct vm_area_struct * vma)
8be839c4 3811+{
474a6d91 3812+ vma->vm_mm->call_dl_resolve = 0UL;
8be839c4
JR
3813+}
3814+
474a6d91 3815+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
8be839c4
JR
3816+{
3817+ struct page* page;
3818+ unsigned int *kaddr;
3819+
3820+ page = alloc_page(GFP_HIGHUSER);
3821+ if (!page)
3822+ return page;
3823+
3824+ kaddr = kmap(page);
3825+ memset(kaddr, 0, PAGE_SIZE);
474a6d91
AM
3826+ kaddr[0] = 0x9DE3BFA8U; /* save */
3827+ flush_dcache_page(page);
8be839c4
JR
3828+ kunmap(page);
3829+ return page;
3830+}
3831+
3832+static struct vm_operations_struct pax_vm_ops = {
474a6d91
AM
3833+ close: pax_emuplt_close,
3834+ nopage: pax_emuplt_nopage,
8be839c4
JR
3835+};
3836+
3837+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3838+{
3839+ vma->vm_mm = current->mm;
3840+ vma->vm_start = addr;
3841+ vma->vm_end = addr + PAGE_SIZE;
3842+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3843+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3844+ vma->vm_ops = &pax_vm_ops;
474a6d91 3845+ vma->vm_pgoff = 0UL;
8be839c4
JR
3846+ vma->vm_file = NULL;
3847+ vma->vm_private_data = NULL;
3848+ insert_vm_struct(current->mm, vma);
3849+ ++current->mm->total_vm;
3850+}
3851+#endif
3852+
8be839c4 3853+/*
474a6d91 3854+ * PaX: decide what to do with offenders (regs->tpc = fault address)
8be839c4
JR
3855+ *
3856+ * returns 1 when task should be killed
474a6d91
AM
3857+ * 2 when patched PLT trampoline was detected
3858+ * 3 when unpatched PLT trampoline was detected
3859+ * 4 when legitimate ET_EXEC was detected
8be839c4
JR
3860+ */
3861+static int pax_handle_fetch_fault(struct pt_regs *regs)
3862+{
3863+ int err;
3864+
3865+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
3866+ if (current->flags & PF_PAX_RANDEXEC) {
474a6d91
AM
3867+ if (regs->tpc >= current->mm->start_code &&
3868+ regs->tpc < current->mm->end_code)
8be839c4 3869+ {
474a6d91 3870+ if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
8be839c4
JR
3871+ return 1;
3872+
474a6d91
AM
3873+ regs->tpc += current->mm->delta_exec;
3874+ if (regs->tnpc >= current->mm->start_code &&
3875+ regs->tnpc < current->mm->end_code)
3876+ regs->tnpc += current->mm->delta_exec;
3877+ return 4;
3878+ }
3879+ if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
3880+ regs->tpc < current->mm->end_code + current->mm->delta_exec)
3881+ {
3882+ regs->tpc -= current->mm->delta_exec;
3883+ if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
3884+ regs->tnpc < current->mm->end_code + current->mm->delta_exec)
3885+ regs->tnpc -= current->mm->delta_exec;
8be839c4
JR
3886+ }
3887+ }
3888+#endif
3889+
3890+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
8be839c4 3891+ do { /* PaX: patched PLT emulation #1 */
474a6d91 3892+ unsigned int sethi1, sethi2, jmpl;
8be839c4 3893+
474a6d91
AM
3894+ err = get_user(sethi1, (unsigned int*)regs->tpc);
3895+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
3896+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
8be839c4
JR
3897+
3898+ if (err)
474a6d91 3899+ break;
8be839c4 3900+
474a6d91
AM
3901+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3902+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
3903+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
3904+ {
3905+ unsigned long addr;
3906+
3907+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3908+ addr = regs->u_regs[UREG_G1];
3909+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3910+ regs->tpc = addr;
3911+ regs->tnpc = addr+4;
3912+ return 2;
8be839c4
JR
3913+ }
3914+ } while (0);
3915+
474a6d91
AM
3916+ { /* PaX: patched PLT emulation #2 */
3917+ unsigned int ba;
8be839c4 3918+
474a6d91 3919+ err = get_user(ba, (unsigned int*)regs->tpc);
8be839c4 3920+
474a6d91
AM
3921+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3922+ unsigned long addr;
8be839c4 3923+
474a6d91
AM
3924+ addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3925+ regs->tpc = addr;
3926+ regs->tnpc = addr+4;
3927+ return 2;
3928+ }
3929+ }
8be839c4 3930+
474a6d91
AM
3931+ do { /* PaX: patched PLT emulation #3 */
3932+ unsigned int sethi, jmpl, nop;
8be839c4 3933+
474a6d91
AM
3934+ err = get_user(sethi, (unsigned int*)regs->tpc);
3935+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
3936+ err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8be839c4 3937+
474a6d91
AM
3938+ if (err)
3939+ break;
8be839c4 3940+
474a6d91
AM
3941+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3942+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3943+ nop == 0x01000000U)
3944+ {
3945+ unsigned long addr;
8be839c4 3946+
474a6d91
AM
3947+ addr = (sethi & 0x003FFFFFU) << 10;
3948+ regs->u_regs[UREG_G1] = addr;
3949+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3950+ regs->tpc = addr;
3951+ regs->tnpc = addr+4;
3952+ return 2;
8be839c4
JR
3953+ }
3954+ } while (0);
8be839c4 3955+
474a6d91
AM
3956+ do { /* PaX: unpatched PLT emulation step 1 */
3957+ unsigned int sethi, ba, nop;
8be839c4 3958+
474a6d91
AM
3959+ err = get_user(sethi, (unsigned int*)regs->tpc);
3960+ err |= get_user(ba, (unsigned int*)(regs->tpc+4));
3961+ err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8be839c4 3962+
474a6d91 3963+ if (err)
8be839c4 3964+ break;
8be839c4 3965+
474a6d91
AM
3966+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3967+ (ba & 0xFFC00000U) == 0x30800000U &&
3968+ nop == 0x01000000U)
3969+ {
3970+ unsigned long addr;
3971+ unsigned int save, call;
8be839c4 3972+
474a6d91 3973+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8be839c4 3974+
474a6d91
AM
3975+ err = get_user(save, (unsigned int*)addr);
3976+ err |= get_user(call, (unsigned int*)(addr+4));
3977+ err |= get_user(nop, (unsigned int*)(addr+8));
8be839c4 3978+
474a6d91
AM
3979+ if (err)
3980+ break;
8be839c4 3981+
474a6d91
AM
3982+ if (save == 0x9DE3BFA8U &&
3983+ (call & 0xC0000000U) == 0x40000000U &&
3984+ nop == 0x01000000U)
3985+ {
3986+ struct vm_area_struct *vma;
3987+ unsigned long call_dl_resolve;
8be839c4 3988+
474a6d91
AM
3989+ down_read(&current->mm->mmap_sem);
3990+ call_dl_resolve = current->mm->call_dl_resolve;
3991+ up_read(&current->mm->mmap_sem);
3992+ if (likely(call_dl_resolve))
3993+ goto emulate;
8be839c4 3994+
474a6d91 3995+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8be839c4 3996+
474a6d91
AM
3997+ down_write(&current->mm->mmap_sem);
3998+ if (current->mm->call_dl_resolve) {
3999+ call_dl_resolve = current->mm->call_dl_resolve;
4000+ up_write(&current->mm->mmap_sem);
4001+ if (vma) kmem_cache_free(vm_area_cachep, vma);
4002+ goto emulate;
4003+ }
8be839c4 4004+
474a6d91
AM
4005+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4006+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4007+ up_write(&current->mm->mmap_sem);
4008+ if (vma) kmem_cache_free(vm_area_cachep, vma);
4009+ return 1;
4010+ }
8be839c4 4011+
474a6d91
AM
4012+ pax_insert_vma(vma, call_dl_resolve);
4013+ current->mm->call_dl_resolve = call_dl_resolve;
4014+ up_write(&current->mm->mmap_sem);
8be839c4 4015+
474a6d91
AM
4016+emulate:
4017+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4018+ regs->tpc = call_dl_resolve;
4019+ regs->tnpc = addr+4;
4020+ return 3;
4021+ }
4022+ }
4023+ } while (0);
8be839c4 4024+
474a6d91
AM
4025+ do { /* PaX: unpatched PLT emulation step 2 */
4026+ unsigned int save, call, nop;
8be839c4 4027+
474a6d91
AM
4028+ err = get_user(save, (unsigned int*)(regs->tpc-4));
4029+ err |= get_user(call, (unsigned int*)regs->tpc);
4030+ err |= get_user(nop, (unsigned int*)(regs->tpc+4));
4031+ if (err)
4032+ break;
8be839c4 4033+
474a6d91
AM
4034+ if (save == 0x9DE3BFA8U &&
4035+ (call & 0xC0000000U) == 0x40000000U &&
4036+ nop == 0x01000000U)
4037+ {
4038+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4039+
4040+ regs->u_regs[UREG_RETPC] = regs->tpc;
4041+ regs->tpc = dl_resolve;
4042+ regs->tnpc = dl_resolve+4;
4043+ return 3;
4044+ }
4045+ } while (0);
8be839c4
JR
4046+#endif
4047+
474a6d91 4048+ return 1;
8be839c4
JR
4049+}
4050+
474a6d91 4051+void pax_report_insns(void *pc)
8be839c4 4052+{
474a6d91 4053+ unsigned long i;
8be839c4 4054+
474a6d91
AM
4055+ printk(KERN_ERR "PAX: bytes at PC: ");
4056+ for (i = 0; i < 5; i++) {
4057+ unsigned int c;
4058+ if (get_user(c, (unsigned int*)pc+i)) {
4059+ printk("<invalid address>.");
4060+ break;
4061+ }
4062+ printk("%08x ", c);
4063+ }
4064+ printk("\n");
8be839c4 4065+}
474a6d91 4066+#endif
8be839c4 4067+
8be839c4 4068+
474a6d91
AM
4069 asmlinkage void do_sparc64_fault(struct pt_regs *regs)
4070 {
4071 struct mm_struct *mm = current->mm;
4072@@ -338,6 +602,7 @@
4073
4074 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
4075 regs->tpc &= 0xffffffff;
4076+ regs->tnpc &= 0xffffffff;
4077 address &= 0xffffffff;
4078 }
4079
4080@@ -346,6 +611,34 @@
4081 if (!vma)
4082 goto bad_area;
4083
4084+ /* PaX: detect ITLB misses on non-exec pages */
4085+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
4086+ if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address &&
4087+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
4088+ {
4089+ if (address != regs->tpc)
4090+ goto good_area;
8be839c4 4091+
474a6d91
AM
4092+ up_read(&mm->mmap_sem);
4093+ switch (pax_handle_fetch_fault(regs)) {
4094+
4095+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
4096+ case 2:
4097+ case 3:
4098+ goto fault_done;
4099+#endif
8be839c4
JR
4100+
4101+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
474a6d91
AM
4102+ case 4:
4103+ goto fault_done;
4104+#endif
8be839c4 4105+
8be839c4 4106+ }
474a6d91
AM
4107+ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
4108+ do_exit(SIGKILL);
8be839c4
JR
4109+ }
4110+#endif
4111+
474a6d91
AM
4112 /* Pure DTLB misses do not tell us whether the fault causing
4113 * load/store/atomic was a write or not, it only says that there
4114 * was no match. So in such a case we (carefully) read the
4115diff -urN linux-2.4.22.org/arch/sparc64/solaris/misc.c linux-2.4.22/arch/sparc64/solaris/misc.c
4116--- linux-2.4.22.org/arch/sparc64/solaris/misc.c 2003-11-22 22:12:19.000000000 +0100
4117+++ linux-2.4.22/arch/sparc64/solaris/misc.c 2003-11-22 22:14:07.000000000 +0100
4118@@ -54,6 +54,11 @@
4119 struct file *file = NULL;
4120 unsigned long retval, ret_type;
4121
4122+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
4123+ if (flags & MAP_MIRROR)
4124+ return -EINVAL;
4125+#endif
8be839c4 4126+
474a6d91
AM
4127 /* Do we need it here? */
4128 set_personality(PER_SVR4);
4129 if (flags & MAP_NORESERVE) {
4130diff -urN linux-2.4.22.org/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c
4131--- linux-2.4.22.org/arch/x86_64/ia32/ia32_ioctl.c 2003-11-22 22:11:53.000000000 +0100
4132+++ linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c 2003-11-22 22:14:07.000000000 +0100
4133@@ -1933,7 +1933,11 @@
4134 * To have permissions to do most of the vt ioctls, we either have
4135 * to be the owner of the tty, or super-user.
4136 */
4137+#ifdef CONFIG_GRKERNSEC
4138+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
4139+#else
4140 if (current->tty == tty || suser())
4141+#endif
4142 return 1;
4143 return 0;
4144 }
4145diff -urN linux-2.4.22.org/Documentation/Configure.help linux-2.4.22/Documentation/Configure.help
4146--- linux-2.4.22.org/Documentation/Configure.help 2003-11-22 22:12:56.000000000 +0100
4147+++ linux-2.4.22/Documentation/Configure.help 2003-11-22 22:14:06.000000000 +0100
4148@@ -2993,6 +2993,20 @@
4149 If you want to compile it as a module, say M here and read
4150 Documentation/modules.txt. If unsure, say `N'.
4151
4152+stealth networking support
4153+CONFIG_IP_NF_MATCH_STEALTH
4154+ Enabling this option will drop all syn packets coming to unserved tcp
4155+ ports as well as all packets coming to unserved udp ports. If you
4156+ are using your system to route any type of packets (ie. via NAT)
4157+ you should put this module at the end of your ruleset, since it will
4158+ drop packets that aren't going to ports that are listening on your
4159+ machine itself, it doesn't take into account that the packet might be
4160+ destined for someone on your internal network if you're using NAT for
4161+ instance.
8be839c4 4162+
474a6d91
AM
4163+ If you want to compile it as a module, say M here and read
4164+ Documentation/modules.txt. If unsure, say `N'.
8be839c4 4165+
474a6d91
AM
4166 MAC address match support
4167 CONFIG_IP_NF_MATCH_MAC
4168 MAC matching allows you to match packets based on the source
4169@@ -24221,6 +24235,871 @@
4170
4171 "Area6" will work for most boards. For ADX, select "Area5".
4172
4173+Grsecurity
4174+CONFIG_GRKERNSEC
4175+ If you say Y here, you will be able to configure many features that
4176+ will enhance the security of your system. It is highly recommended
4177+ that you say Y here and read through the help for each option so
4178+ you fully understand the features and can evaluate their usefulness
4179+ for your machine.
8be839c4 4180+
474a6d91
AM
4181+Additional security levels
4182+CONFIG_GRKERNSEC_LOW
8be839c4 4183+
474a6d91
AM
4184+ Low additional security
4185+ -----------------------------------------------------------------------
4186+ If you choose this option, several of the grsecurity options will
4187+ be enabled that will give you greater protection against a number
4188+ of attacks, while assuring that none of your software will have any
4189+ conflicts with the additional security measures. If you run a lot of
4190+ unusual software, or you are having problems with the higher security
4191+ levels, you should say Y here. With this option, the following features
4192+ are enabled:
4193+
4194+ linking restrictions
4195+ fifo restrictions
4196+ random pids
4197+ enforcing nproc on execve()
4198+ restricted dmesg
4199+ random ip ids
4200+ enforced chdir("/") on chroot
8be839c4 4201+
474a6d91
AM
4202+ Medium additional security
4203+ -----------------------------------------------------------------------
4204+ If you say Y here, several features in addition to those included in the
4205+ low additional security level will be enabled. These features provide
4206+ even more security to your system, though in rare cases they may
4207+ be incompatible with very old or poorly written software. If you
4208+ enable this option, make sure that your auth service (identd) is
4209+ running as gid 10 (usually group wheel). With this option the following
4210+ features (in addition to those provided in the low additional security
4211+ level) will be enabled:
8be839c4 4212+
474a6d91
AM
4213+ random tcp source ports
4214+ altered ping ids
4215+ failed fork logging
4216+ time change logging
4217+ signal logging
4218+ deny mounts in chroot
4219+ deny double chrooting
4220+ deny sysctl writes in chroot
4221+ deny mknod in chroot
4222+ deny access to abstract AF_UNIX sockets out of chroot
4223+ deny pivot_root in chroot
4224+ denied writes of /dev/kmem, /dev/mem, and /dev/port
4225+ /proc restrictions with special gid set to 10 (usually wheel)
4226+ address space layout randomization
8be839c4 4227+
474a6d91
AM
4228+ High additional security
4229+ ----------------------------------------------------------------------
4230+ If you say Y here, many of the features of grsecurity will be enabled,
4231+ that will protect you against many kinds of attacks against
4232+ your system. The heightened security comes at a cost of an
4233+ increased chance of incompatibilities with rare software on your
4234+ machine. It is highly recommended that you view
4235+ <http://grsecurity.net/features.htm> and read about each option. Since
4236+ this security level enabled PaX, you should also view
4237+ <http://pageexec.virtualave.net> and read about the PaX project. While
4238+ you are there, download chpax.c and run chpax -p on binaries that cause
4239+ problems with PaX. Also remember that since the /proc restrictions are
4240+ enabled, you must run your identd as group wheel (gid 10).
4241+ This security level enables the following features in addition to those
4242+ listed in the low and medium security levels:
8be839c4 4243+
474a6d91
AM
4244+ additional /proc restrictions
4245+ chmod restrictions in chroot
4246+ no signals, ptrace, or viewing processes outside of chroot
4247+ capability restrictions in chroot
4248+ deny fchdir out of chroot
4249+ priority restrictions in chroot
4250+ segmentation-based implementation of PaX
4251+ mprotect restrictions
4252+ removal of /proc/<pid>/[maps|mem]
4253+ kernel stack randomization
4254+ mount/unmount/remount logging
4255+ kernel symbol hiding
8be839c4 4256+
474a6d91
AM
4257+Customized additional security
4258+CONFIG_GRKERNSEC_CUSTOM
4259+ If you say Y here, you will be able to configure every grsecurity
4260+ option, which allows you to enable many more features that aren't
4261+ covered in the basic security levels. These additional features include
4262+ TPE, socket restrictions, and the sysctl system for grsecurity. It is
4263+ advised that you read through the help for each option to determine its
4264+ usefulness in your situation.
8be839c4 4265+
474a6d91
AM
4266+Enforce non-executable pages
4267+CONFIG_GRKERNSEC_PAX_NOEXEC
4268+ By design some architectures do not allow for protecting memory
4269+ pages against execution or even if they do, Linux does not make
4270+ use of this feature. In practice this means that if a page is
4271+ readable (such as the stack or heap) it is also executable.
8be839c4 4272+
474a6d91
AM
4273+ There is a well known exploit technique that makes use of this
4274+ fact and a common programming mistake where an attacker can
4275+ introduce code of his choice somewhere in the attacked program's
4276+ memory (typically the stack or the heap) and then execute it.
8be839c4 4277+
474a6d91
AM
4278+ If the attacked program was running with different (typically
4279+ higher) privileges than that of the attacker, then he can elevate
4280+ his own privilege level (e.g. get a root shell, write to files for
4281+ which he does not have write access to, etc).
8be839c4 4282+
474a6d91
AM
4283+ Enabling this option will let you choose from various features
4284+ that prevent the injection and execution of 'foreign' code in
4285+ a program.
8be839c4 4286+
474a6d91
AM
4287+ This will also break programs that rely on the old behaviour and
4288+ expect that dynamically allocated memory via the malloc() family
4289+ of functions is executable (which it is not). Notable examples
4290+ are the XFree86 4.x server, the java runtime and wine.
8be839c4 4291+
474a6d91
AM
4292+ NOTE: you can use the 'chpax' utility to enable/disable this
4293+ feature on a per file basis. chpax is available at
4294+ <http://pageexec.virtualave.net>
8be839c4 4295+
474a6d91
AM
4296+Paging based non-executable pages
4297+CONFIG_GRKERNSEC_PAX_PAGEEXEC
4298+ This implementation is based on the paging feature of the CPU.
4299+ On i386 it has a variable performance impact on applications
4300+ depending on their memory usage pattern. You should carefully
4301+ test your applications before using this feature in production.
4302+ On alpha, parisc, sparc and sparc64 there is no performance
4303+ impact. On ppc there is a slight performance impact.
8be839c4 4304+
474a6d91
AM
4305+Segmentation based non-executable pages
4306+CONFIG_GRKERNSEC_PAX_SEGMEXEC
4307+ This implementation is based on the segmentation feature of the
4308+ CPU and has little performance impact, however applications will
4309+ be limited to a 1.5 GB address space instead of the normal 3 GB.
8be839c4 4310+
474a6d91
AM
4311+Emulate trampolines
4312+CONFIG_GRKERNSEC_PAX_EMUTRAMP
4313+ There are some programs and libraries that for one reason or
4314+ another attempt to execute special small code snippets from
4315+ non-executable memory pages. Most notable examples are the
4316+ signal handler return code generated by the kernel itself and
4317+ the GCC trampolines.
8be839c4 4318+
474a6d91
AM
4319+ If you enabled CONFIG_GRKERNSEC_PAX_PAGEEXEC or
4320+ CONFIG_GRKERNSEC_PAX_SEGMEXEC then such programs will no longer
4321+ work under your kernel.
8be839c4 4322+
474a6d91
AM
4323+ As a remedy you can say Y here and use the 'chpax' utility to
4324+ enable trampoline emulation for the affected programs yet still
4325+ have the protection provided by the non-executable pages.
8be839c4 4326+
474a6d91
AM
4327+ On parisc and ppc you MUST enable this option and EMUSIGRT as
4328+ well, otherwise your system will not even boot.
8be839c4 4329+
474a6d91
AM
4330+ Alternatively you can say N here and use the 'chpax' utility
4331+ to disable CONFIG_GRKERNSEC_PAX_PAGEEXEC and
4332+ CONFIG_GRKERNSEC_PAX_SEGMEXEC for the affected files.
8be839c4 4333+
474a6d91
AM
4334+ NOTE: enabling this feature *may* open up a loophole in the
4335+ protection provided by non-executable pages that an attacker
4336+ could abuse. Therefore the best solution is to not have any
4337+ files on your system that would require this option. This can
4338+ be achieved by not using libc5 (which relies on the kernel
4339+ signal handler return code) and not using or rewriting programs
4340+ that make use of the nested function implementation of GCC.
4341+ Skilled users can just fix GCC itself so that it implements
4342+ nested function calls in a way that does not interfere with PaX.
8be839c4 4343+
474a6d91
AM
4344+Automatically emulate sigreturn trampolines
4345+CONFIG_GRKERNSEC_PAX_EMUSIGRT
4346+ Enabling this option will have the kernel automatically detect
4347+ and emulate signal return trampolines executing on the stack
4348+ that would otherwise lead to task termination.
8be839c4 4349+
474a6d91
AM
4350+ This solution is intended as a temporary one for users with
4351+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
4352+ Modula-3 runtime, etc) or executables linked to such, basically
4353+ everything that does not specify its own SA_RESTORER function in
4354+ normal executable memory like glibc 2.1+ does.
8be839c4 4355+
474a6d91
AM
4356+ On parisc and ppc you MUST enable this option, otherwise your
4357+ system will not even boot.
8be839c4 4358+
474a6d91
AM
4359+ NOTE: this feature cannot be disabled on a per executable basis
4360+ and since it *does* open up a loophole in the protection provided
4361+ by non-executable pages, the best solution is to not have any
4362+ files on your system that would require this option.
8be839c4 4363+
474a6d91
AM
4364+Restrict mprotect()
4365+CONFIG_GRKERNSEC_PAX_MPROTECT
4366+ Enabling this option will prevent programs from
4367+ - changing the executable status of memory pages that were
4368+ not originally created as executable,
4369+ - making read-only executable pages writable again,
4370+ - creating executable pages from anonymous memory.
8be839c4 4371+
474a6d91
AM
4372+ You should say Y here to complete the protection provided by
4373+ the enforcement of non-executable pages.
8be839c4 4374+
474a6d91
AM
4375+ NOTE: you can use the 'chpax' utility to control this
4376+ feature on a per file basis. chpax is available at
4377+ <http://pageexec.virtualave.net>
8be839c4 4378+
474a6d91
AM
4379+Disallow ELF text relocations
4380+CONFIG_GRKERNSEC_PAX_NOELFRELOCS
4381+ Non-executable pages and mprotect() restrictions are effective
4382+ in preventing the introduction of new executable code into an
4383+ attacked task's address space. There remain only two venues
4384+ for this kind of attack: if the attacker can execute already
4385+ existing code in the attacked task then he can either have it
4386+ create and mmap() a file containing his code or have it mmap()
4387+ an already existing ELF library that does not have position
4388+ independent code in it and use mprotect() on it to make it
4389+ writable and copy his code there. While protecting against
4390+ the former approach is beyond PaX, the latter can be prevented
4391+ by having only PIC ELF libraries on one's system (which do not
4392+ need to relocate their code). If you are sure this is your case,
4393+ then enable this option otherwise be careful as you may not even
4394+ be able to boot or log on your system (for example, some PAM
4395+ modules are erroneously compiled as non-PIC by default).
8be839c4 4396+
474a6d91
AM
4397+ NOTE: if you are using dynamic ELF executables (as suggested
4398+ when using ASLR) then you must have made sure that you linked
4399+ your files using the PIC version of crt1 (the et_dyn.zip package
4400+ referenced there has already been updated to support this).
8be839c4 4401+
474a6d91
AM
4402+Enforce non-executable kernel pages
4403+CONFIG_GRKERNSEC_PAX_KERNEXEC
4404+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
4405+ that is, enabling this option will make it harder to inject
4406+ and execute 'foreign' code in kernel memory itself.
8be839c4 4407+
474a6d91
AM
4408+Address Space Layout Randomization
4409+CONFIG_GRKERNSEC_PAX_ASLR
4410+ Many if not most exploit techniques rely on the knowledge of
4411+ certain addresses in the attacked program. The following options
4412+ will allow the kernel to apply a certain amount of randomization
4413+ to specific parts of the program thereby forcing an attacker to
4414+ guess them in most cases. Any failed guess will most likely crash
4415+ the attacked program which allows the kernel to detect such attempts
4416+ and react on them. PaX itself provides no reaction mechanisms,
4417+ instead it is strongly encouraged that you make use of grsecurity's
4418+ built-in crash detection features or develop one yourself.
8be839c4 4419+
474a6d91
AM
4420+ By saying Y here you can choose to randomize the following areas:
4421+ - top of the task's kernel stack
4422+ - top of the task's userland stack
4423+ - base address for mmap() requests that do not specify one
4424+ (this includes all libraries)
4425+ - base address of the main executable
8be839c4 4426+
474a6d91
AM
4427+ It is strongly recommended to say Y here as address space layout
4428+ randomization has negligible impact on performance yet it provides
4429+ a very effective protection.
8be839c4 4430+
474a6d91
AM
4431+ NOTE: you can use the 'chpax' utility to control most of these features
4432+ on a per file basis.
8be839c4 4433+
474a6d91
AM
4434+Randomize kernel stack base
4435+CONFIG_GRKERNSEC_PAX_RANDKSTACK
4436+ By saying Y here the kernel will randomize every task's kernel
4437+ stack on every system call. This will not only force an attacker
4438+ to guess it but also prevent him from making use of possible
4439+ leaked information about it.
8be839c4 4440+
474a6d91
AM
4441+ Since the kernel stack is a rather scarce resource, randomization
4442+ may cause unexpected stack overflows, therefore you should very
4443+ carefully test your system. Note that once enabled in the kernel
4444+ configuration, this feature cannot be disabled on a per file basis.
4445+
4446+Randomize user stack base
4447+CONFIG_GRKERNSEC_PAX_RANDUSTACK
4448+ By saying Y here the kernel will randomize every task's userland
4449+ stack. The randomization is done in two steps where the second
4450+ one may apply a big amount of shift to the top of the stack and
4451+ cause problems for programs that want to use lots of memory (more
4452+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
4453+ For this reason the second step can be controlled by 'chpax' on
4454+ a per file basis.
8be839c4 4455+
474a6d91
AM
4456+Randomize ET_EXEC base
4457+CONFIG_GRKERNSEC_PAX_RANDEXEC
4458+ By saying Y here the kernel will randomize the base address of normal
4459+ ET_EXEC ELF executables as well. This is accomplished by mapping the
4460+ executable in memory in a special way which also allows for detecting
4461+ attackers who attempt to execute its code for their purposes. Since
4462+ this special mapping causes performance degradation and the attack
4463+ detection may create false alarms as well, you should carefully test
4464+ your executables when this feature is enabled.
8be839c4 4465+
474a6d91
AM
4466+ This solution is intended only as a temporary one until you relink
4467+ your programs as a dynamic ELF file.
8be839c4 4468+
474a6d91
AM
4469+ NOTE: you can use the 'chpax' utility to control this feature
4470+ on a per file basis.
8be839c4 4471+
474a6d91
AM
4472+Allow ELF ET_EXEC text relocations
4473+CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
4474+ On some architectures like the alpha there are incorrectly
4475+ created applications that require text relocations and would
4476+ not work without enabling this option. If you are an alpha
4477+ user, you should enable this option and disable it once you
4478+ have made sure that none of your applications need it.
8be839c4 4479+
474a6d91
AM
4480+Automatically emulate ELF PLT
4481+CONFIG_GRKERNSEC_PAX_EMUPLT
4482+ Enabling this option will have the kernel automatically detect
4483+ and emulate the Procedure Linkage Table entries in ELF files.
4484+ On some architectures such entries are in writable memory, and
4485+ become non-executable leading to task termination. Therefore
4486+ it is mandatory that you enable this option on alpha, parisc, ppc,
4487+ sparc and sparc64, otherwise your system would not even boot.
8be839c4 4488+
474a6d91
AM
4489+ NOTE: this feature *does* open up a loophole in the protection
4490+ provided by the non-executable pages, therefore the proper
4491+ solution is to modify the toolchain to produce a PLT that does
4492+ not need to be writable.
8be839c4 4493+
8be839c4 4494+
474a6d91
AM
4495+Randomize mmap() base
4496+CONFIG_GRKERNSEC_PAX_RANDMMAP
4497+ By saying Y here the kernel will use a randomized base address for
4498+ mmap() requests that do not specify one themselves. As a result
4499+ all dynamically loaded libraries will appear at random addresses
4500+ and therefore be harder to exploit by a technique where an attacker
4501+ attempts to execute library code for his purposes (e.g. spawn a
4502+ shell from an exploited program that is running at an elevated
4503+ privilege level).
8be839c4 4504+
474a6d91
AM
4505+ Furthermore, if a program is relinked as a dynamic ELF file, its
4506+ base address will be randomized as well, completing the full
4507+ randomization of the address space layout. Attacking such programs
4508+ becomes a guess game. You can find an example of doing this at
4509+ <http://pageexec.virtualave.net/et_dyn.zip> and practical samples at
4510+ <http://www.grsecurity.net/grsec-gcc-specs.tar.gz> .
8be839c4 4511+
474a6d91
AM
4512+ NOTE: you can use the 'chpax' utility to control this feature
4513+ on a per file basis.
8be839c4 4514+
474a6d91
AM
4515+Deny writing to /dev/kmem, /dev/mem, and /dev/port
4516+CONFIG_GRKERNSEC_KMEM
4517+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
4518+ be written to via mmap or otherwise to modify the running kernel.
4519+ /dev/port will also not be allowed to be opened. If you have module
4520+ support disabled, enabling this will close up four ways that are
4521+ currently used to insert malicious code into the running kernel.
4522+ Even with all these features enabled, we still highly recommend that
4523+ you use the ACL system, as it is still possible for an attacker to
4524+ modify the running kernel through privileged I/O granted by ioperm/iopl.
4525+ If you are not using XFree86, you may be able to stop this additional
4526+ case by enabling the 'Disable privileged I/O' option. Though nothing
4527+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
4528+ but only to video memory, which is the only writing we allow in this
4529+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
4530+ not be allowed to mprotect it with PROT_WRITE later.
4531+ Enabling this feature could make certain apps like VMWare stop working,
4532+ as they need to write to other locations in /dev/mem.
4533+ It is highly recommended that you say Y here if you meet all the
4534+ conditions above.
8be839c4 4535+
474a6d91
AM
4536+Disable privileged I/O
4537+CONFIG_GRKERNSEC_IO
4538+ If you say Y here, all ioperm and iopl calls will return an error.
4539+ Ioperm and iopl can be used to modify the running kernel.
4540+ Unfortunately, some programs need this access to operate properly,
4541+ the most notable of which are XFree86 and hwclock. hwclock can be
4542+ remedied by having RTC support in the kernel, so CONFIG_RTC is
4543+ enabled if this option is enabled, to ensure that hwclock operates
4544+ correctly. XFree86 still will not operate correctly with this option
4545+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
4546+ and you still want to protect your kernel against modification,
4547+ use the ACL system.
8be839c4 4548+
474a6d91
AM
4549+Hide kernel symbols
4550+CONFIG_GRKERNSEC_HIDESYM
4551+ If you say Y here, getting information on loaded modules, and
4552+ displaying all kernel symbols through a syscall will be restricted
4553+ to users with CAP_SYS_MODULE. This option is only effective
4554+ provided the following conditions are met:
4555+ 1) The kernel using grsecurity is not precompiled by some distribution
4556+ 2) You are using the ACL system and hiding other files such as your
4557+ kernel image and System.map
4558+ 3) You have the additional /proc restrictions enabled, which removes
4559+ /proc/kcore
4560+ If the above conditions are met, this option will aid to provide a
4561+ useful protection against local and remote kernel exploitation of
4562+ overflows and arbitrary read/write vulnerabilities.
8be839c4 4563+
474a6d91
AM
4564+/proc/<pid>/ipaddr support
4565+CONFIG_GRKERNSEC_PROC_IPADDR
4566+ If you say Y here, a new entry will be added to each /proc/<pid>
4567+ directory that contains the IP address of the person using the task.
4568+ The IP is carried across local TCP and AF_UNIX stream sockets.
4569+ This information can be useful for IDS/IPSes to perform remote response
4570+ to a local attack. The entry is readable by only the owner of the
4571+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
4572+ the RBAC system), and thus does not create privacy concerns.
8be839c4 4573+
474a6d91
AM
4574+Proc Restrictions
4575+CONFIG_GRKERNSEC_PROC
4576+ If you say Y here, the permissions of the /proc filesystem
4577+ will be altered to enhance system security and privacy. Depending
4578+ upon the options you choose, you can either restrict users to see
4579+ only the processes they themselves run, or choose a group that can
4580+ view all processes and files normally restricted to root if you choose
4581+ the "restrict to user only" option. NOTE: If you're running identd as
4582+ a non-root user, you will have to run it as the group you specify here.
4583+
4584+Restrict /proc to user only
4585+CONFIG_GRKERNSEC_PROC_USER
4586+ If you say Y here, non-root users will only be able to view their own
4587+ processes, and restricts them from viewing network-related information,
4588+ and viewing kernel symbol and module information.
4589+
4590+Restrict /proc to user and group
4591+CONFIG_GRKERNSEC_PROC_USERGROUP
4592+ If you say Y here, you will be able to select a group that will be
4593+ able to view all processes, network-related information, and
4594+ kernel and symbol information. This option is useful if you want
4595+ to run identd as a non-root user.
4596+
4597+Remove addresses from /proc/pid/[maps|stat]
4598+CONFIG_GRKERNSEC_PROC_MEMMAP
4599+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
4600+ give no information about the addresses of its mappings if
4601+ PaX features that rely on random addresses are enabled on the task.
4602+ If you use PaX it is greatly recommended that you say Y here as it
4603+ closes up a hole that makes the full ASLR useless for suid
4604+ binaries.
8be839c4 4605+
474a6d91
AM
4606+Additional proc restrictions
4607+CONFIG_GRKERNSEC_PROC_ADD
4608+ If you say Y here, additional restrictions will be placed on
4609+ /proc that keep normal users from viewing cpu and device information.
8be839c4 4610+
474a6d91
AM
4611+Dmesg(8) Restriction
4612+CONFIG_GRKERNSEC_DMESG
4613+ If you say Y here, non-root users will not be able to use dmesg(8)
4614+ to view up to the last 4kb of messages in the kernel's log buffer.
4615+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
4616+ created.
8be839c4 4617+
474a6d91
AM
4618+Linking restrictions
4619+CONFIG_GRKERNSEC_LINK
4620+ If you say Y here, /tmp race exploits will be prevented, since users
4621+ will no longer be able to follow symlinks owned by other users in
4622+ world-writable +t directories (i.e. /tmp), unless the owner of the
4623+ symlink is the owner of the directory. users will also not be
4624+ able to hardlink to files they do not own. If the sysctl option is
4625+ enabled, a sysctl option with name "linking_restrictions" is created.
8be839c4 4626+
474a6d91
AM
4627+FIFO restrictions
4628+CONFIG_GRKERNSEC_FIFO
4629+ If you say Y here, users will not be able to write to FIFOs they don't
4630+ own in world-writable +t directories (i.e. /tmp), unless the owner of
4631+ the FIFO is the same owner of the directory it's held in. If the sysctl
4632+ option is enabled, a sysctl option with name "fifo_restrictions" is
4633+ created.
8be839c4 4634+
474a6d91
AM
4635+Enforce RLIMIT_NPROC on execs
4636+CONFIG_GRKERNSEC_EXECVE
4637+ If you say Y here, users with a resource limit on processes will
4638+ have the value checked during execve() calls. The current system
4639+ only checks the system limit during fork() calls. If the sysctl option
4640+ is enabled, a sysctl option with name "execve_limiting" is created.
8be839c4 4641+
474a6d91
AM
4642+Single group for auditing
4643+CONFIG_GRKERNSEC_AUDIT_GROUP
4644+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
4645+ will only operate on a group you specify. This option is recommended
4646+ if you only want to watch certain users instead of having a large
4647+ amount of logs from the entire system. If the sysctl option is enabled,
4648+ a sysctl option with name "audit_group" is created.
8be839c4 4649+
474a6d91
AM
4650+GID for auditing
4651+CONFIG_GRKERNSEC_AUDIT_GID
4652+ Here you can choose the GID that will be the target of kernel auditing.
4653+ Remember to add the users you want to log to the GID specified here.
4654+ If the sysctl option is enabled, whatever you choose here won't matter.
4655+ You'll have to specify the GID in your bootup script by echoing the GID
4656+ to the proper /proc entry. View the help on the sysctl option for more
4657+ information. If the sysctl option is enabled, a sysctl option with name
4658+ "audit_gid" is created.
8be839c4 4659+
474a6d91
AM
4660+Chdir logging
4661+CONFIG_GRKERNSEC_AUDIT_CHDIR
4662+ If you say Y here, all chdir() calls will be logged. If the sysctl
4663+ option is enabled, a sysctl option with name "audit_chdir" is created.
8be839c4 4664+
474a6d91
AM
4665+(Un)Mount logging
4666+CONFIG_GRKERNSEC_AUDIT_MOUNT
4667+ If you say Y here, all mounts and unmounts will be logged. If the
4668+ sysctl option is enabled, a sysctl option with name "audit_mount" is
4669+ created.
8be839c4 4670+
474a6d91
AM
4671+IPC logging
4672+CONFIG_GRKERNSEC_AUDIT_IPC
4673+ If you say Y here, creation and removal of message queues, semaphores,
4674+ and shared memory will be logged. If the sysctl option is enabled, a
4675+ sysctl option with name "audit_ipc" is created.
8be839c4 4676+
474a6d91
AM
4677+Exec logging
4678+CONFIG_GRKERNSEC_EXECLOG
4679+ If you say Y here, all execve() calls will be logged (since the
4680+ other exec*() calls are frontends to execve(), all execution
4681+ will be logged). Useful for shell-servers that like to keep track
4682+ of their users. If the sysctl option is enabled, a sysctl option with
4683+ name "exec_logging" is created.
4684+ WARNING: This option when enabled will produce a LOT of logs, especially
4685+ on an active system.
8be839c4 4686+
474a6d91
AM
4687+Resource logging
4688+CONFIG_GRKERNSEC_RESLOG
4689+ If you say Y here, all attempts to overstep resource limits will
4690+ be logged with the resource name, the requested size, and the current
4691+ limit. It is highly recommended that you say Y here.
8be839c4 4692+
474a6d91
AM
4693+Signal logging
4694+CONFIG_GRKERNSEC_SIGNAL
4695+ If you say Y here, certain important signals will be logged, such as
4696+ SIGSEGV, which will as a result inform you of when a error in a program
4697+ occurred, which in some cases could mean a possible exploit attempt.
4698+ If the sysctl option is enabled, a sysctl option with name
4699+ "signal_logging" is created.
8be839c4 4700+
474a6d91
AM
4701+Fork failure logging
4702+CONFIG_GRKERNSEC_FORKFAIL
4703+ If you say Y here, all failed fork() attempts will be logged.
4704+ This could suggest a fork bomb, or someone attempting to overstep
4705+ their process limit. If the sysctl option is enabled, a sysctl option
4706+ with name "forkfail_logging" is created.
8be839c4 4707+
474a6d91
AM
4708+Time change logging
4709+CONFIG_GRKERNSEC_TIME
4710+ If you say Y here, any changes of the system clock will be logged.
4711+ If the sysctl option is enabled, a sysctl option with name
4712+ "timechange_logging" is created.
8be839c4 4713+
474a6d91
AM
4714+Chroot jail restrictions
4715+CONFIG_GRKERNSEC_CHROOT
4716+ If you say Y here, you will be able to choose several options that will
4717+ make breaking out of a chrooted jail much more difficult. If you
4718+ encounter no software incompatibilities with the following options, it
4719+ is recommended that you enable each one.
8be839c4 4720+
474a6d91
AM
4721+Deny access to abstract AF_UNIX sockets out of chroot
4722+CONFIG_GRKERNSEC_CHROOT_UNIX
4723+ If you say Y here, processes inside a chroot will not be able to
4724+ connect to abstract (meaning not belonging to a filesystem) Unix
4725+ domain sockets that were bound outside of a chroot. It is recommended
4726+ that you say Y here. If the sysctl option is enabled, a sysctl option
4727+ with name "chroot_deny_unix" is created.
8be839c4 4728+
474a6d91
AM
4729+Deny shmat() out of chroot
4730+CONFIG_GRKERNSEC_CHROOT_SHMAT
4731+ If you say Y here, processes inside a chroot will not be able to attach
4732+ to shared memory segments that were created outside of the chroot jail.
4733+ It is recommended that you say Y here. If the sysctl option is enabled,
4734+ a sysctl option with name "chroot_deny_shmat" is created.
8be839c4 4735+
474a6d91
AM
4736+Protect outside processes
4737+CONFIG_GRKERNSEC_CHROOT_FINDTASK
4738+ If you say Y here, processes inside a chroot will not be able to
4739+ kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
4740+ getsid, or view any process outside of the chroot. If the sysctl
4741+ option is enabled, a sysctl option with name "chroot_findtask" is
4742+ created.
8be839c4 4743+
474a6d91
AM
4744+Deny mounts in chroot
4745+CONFIG_GRKERNSEC_CHROOT_MOUNT
4746+ If you say Y here, processes inside a chroot will not be able to
4747+ mount or remount filesystems. If the sysctl option is enabled, a
4748+ sysctl option with name "chroot_deny_mount" is created.
8be839c4 4749+
474a6d91
AM
4750+Deny pivot_root in chroot
4751+CONFIG_GRKERNSEC_CHROOT_PIVOT
4752+ If you say Y here, processes inside a chroot will not be able to use
4753+ a function called pivot_root() that was introduced in Linux 2.3.41. It
4754+ works similar to chroot in that it changes the root filesystem. This
4755+ function could be misused in a chrooted process to attempt to break out
4756+ of the chroot, and therefore should not be allowed. If the sysctl
4757+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
4758+ created.
8be839c4 4759+
474a6d91
AM
4760+Deny double-chroots
4761+CONFIG_GRKERNSEC_CHROOT_DOUBLE
4762+ If you say Y here, processes inside a chroot will not be able to chroot
4763+ again. This is a widely used method of breaking out of a chroot jail
4764+ and should not be allowed. If the sysctl option is enabled, a sysctl
4765+ option with name "chroot_deny_chroot" is created.
8be839c4 4766+
474a6d91
AM
4767+Deny fchdir outside of chroot
4768+CONFIG_GRKERNSEC_CHROOT_FCHDIR
4769+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
4770+ to a file descriptor of the chrooting process that points to a directory
4771+ outside the filesystem will be stopped. If the sysctl option
4772+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
8be839c4 4773+
474a6d91
AM
4774+Enforce chdir("/") on all chroots
4775+CONFIG_GRKERNSEC_CHROOT_CHDIR
4776+ If you say Y here, the current working directory of all newly-chrooted
4777+ applications will be set to the the root directory of the chroot.
4778+ The man page on chroot(2) states:
4779+ Note that this call does not change the current working
4780+ directory, so that `.' can be outside the tree rooted at
4781+ `/'. In particular, the super-user can escape from a
4782+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
8be839c4 4783+
474a6d91
AM
4784+ It is recommended that you say Y here, since it's not known to break
4785+ any software. If the sysctl option is enabled, a sysctl option with
4786+ name "chroot_enforce_chdir" is created.
8be839c4 4787+
474a6d91
AM
4788+Deny (f)chmod +s in chroot
4789+CONFIG_GRKERNSEC_CHROOT_CHMOD
4790+ If you say Y here, processes inside a chroot will not be able to chmod
4791+ or fchmod files to make them have suid or sgid bits. This protects
4792+ against another published method of breaking a chroot. If the sysctl
4793+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
4794+ created.
8be839c4 4795+
474a6d91
AM
4796+Deny mknod in chroot
4797+CONFIG_GRKERNSEC_CHROOT_MKNOD
4798+ If you say Y here, processes inside a chroot will not be allowed to
4799+ mknod. The problem with using mknod inside a chroot is that it
4800+ would allow an attacker to create a device entry that is the same
4801+ as one on the physical root of your system, which could range from
4802+ anything from the console device to a device for your harddrive (which
4803+ they could then use to wipe the drive or steal data). It is recommended
4804+ that you say Y here, unless you run into software incompatibilities.
4805+ If the sysctl option is enabled, a sysctl option with name
4806+ "chroot_deny_mknod" is created.
8be839c4 4807+
474a6d91
AM
4808+Restrict priority changes in chroot
4809+CONFIG_GRKERNSEC_CHROOT_NICE
4810+ If you say Y here, processes inside a chroot will not be able to raise
4811+ the priority of processes in the chroot, or alter the priority of
4812+ processes outside the chroot. This provides more security than simply
4813+ removing CAP_SYS_NICE from the process' capability set. If the
4814+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
4815+ is created.
8be839c4 4816+
474a6d91
AM
4817+Log all execs within chroot
4818+CONFIG_GRKERNSEC_CHROOT_EXECLOG
4819+ If you say Y here, all executions inside a chroot jail will be logged
4820+ to syslog. This can cause a large amount of logs if certain
4821+ applications (eg. djb's daemontools) are installed on the system, and
4822+ is therefore left as an option. If the sysctl option is enabled, a
4823+ sysctl option with name "chroot_execlog" is created.
8be839c4 4824+
474a6d91
AM
4825+Deny sysctl writes in chroot
4826+CONFIG_GRKERNSEC_CHROOT_SYSCTL
4827+ If you say Y here, an attacker in a chroot will not be able to
4828+ write to sysctl entries, either by sysctl(2) or through a /proc
4829+ interface. It is strongly recommended that you say Y here. If the
4830+ sysctl option is enabled, a sysctl option with name
4831+ "chroot_deny_sysctl" is created.
8be839c4 4832+
474a6d91
AM
4833+Chroot jail capability restrictions
4834+CONFIG_GRKERNSEC_CHROOT_CAPS
4835+ If you say Y here, the capabilities on all root processes within a
4836+ chroot jail will be lowered to stop module insertion, raw i/o,
4837+ system and net admin tasks, rebooting the system, modifying immutable
4838+ files, modifying IPC owned by another, and changing the system time.
4839+ This is left an option because it can break some apps. Disable this
4840+ if your chrooted apps are having problems performing those kinds of
4841+ tasks. If the sysctl option is enabled, a sysctl option with
4842+ name "chroot_caps" is created.
8be839c4 4843+
474a6d91
AM
4844+Trusted path execution
4845+CONFIG_GRKERNSEC_TPE
4846+ If you say Y here, you will be able to choose a gid to add to the
4847+ supplementary groups of users you want to mark as "untrusted."
4848+ These users will not be able to execute any files that are not in
4849+ root-owned directories writable only by root. If the sysctl option
4850+ is enabled, a sysctl option with name "tpe" is created.
8be839c4 4851+
474a6d91
AM
4852+Group for trusted path execution
4853+CONFIG_GRKERNSEC_TPE_GID
4854+ Here you can choose the GID to enable trusted path protection for.
4855+ Remember to add the users you want protection enabled for to the GID
4856+ specified here. If the sysctl option is enabled, whatever you choose
4857+ here won't matter. You'll have to specify the GID in your bootup
4858+ script by echoing the GID to the proper /proc entry. View the help
4859+ on the sysctl option for more information. If the sysctl option is
4860+ enabled, a sysctl option with name "tpe_gid" is created.
8be839c4 4861+
474a6d91
AM
4862+Partially restrict non-root users
4863+CONFIG_GRKERNSEC_TPE_ALL
4864+ If you say Y here, All non-root users other than the ones in the
4865+ group specified in the main TPE option will only be allowed to
4866+ execute files in directories they own that are not group or
4867+ world-writable, or in directories owned by root and writable only by
4868+ root. If the sysctl option is enabled, a sysctl option with name
4869+ "tpe_restrict_all" is created.
8be839c4 4870+
474a6d91
AM
4871+Randomized PIDs
4872+CONFIG_GRKERNSEC_RANDPID
4873+ If you say Y here, all PIDs created on the system will be
4874+ pseudo-randomly generated. This is extremely effective along
4875+ with the /proc restrictions to disallow an attacker from guessing
4876+ pids of daemons, etc. PIDs are also used in some cases as part
4877+ of a naming system for temporary files, so this option would keep
4878+ those filenames from being predicted as well. We also use code
4879+ to make sure that PID numbers aren't reused too soon. If the sysctl
4880+ option is enabled, a sysctl option with name "rand_pids" is created.
8be839c4 4881+
474a6d91
AM
4882+Larger entropy pools
4883+CONFIG_GRKERNSEC_RANDNET
4884+ If you say Y here, the entropy pools used for many features of Linux
4885+ and grsecurity will be doubled in size. Since several grsecurity
4886+ features use additional randomness, it is recommended that you say Y
4887+ here. Saying Y here has a similar effect as modifying
4888+ /proc/sys/kernel/random/poolsize.
8be839c4 4889+
474a6d91
AM
4890+Truly random TCP ISN selection
4891+CONFIG_GRKERNSEC_RANDISN
4892+ If you say Y here, Linux's default selection of TCP Initial Sequence
4893+ Numbers (ISNs) will be replaced with that of OpenBSD. Linux uses
4894+ an MD4 hash based on the connection plus a time value to create the
4895+ ISN, while OpenBSD's selection is random. If the sysctl option is
4896+ enabled, a sysctl option with name "rand_isns" is created.
8be839c4 4897+
474a6d91
AM
4898+Randomized IP IDs
4899+CONFIG_GRKERNSEC_RANDID
4900+ If you say Y here, all the id field on all outgoing packets
4901+ will be randomized. This hinders os fingerprinters and
4902+ keeps your machine from being used as a bounce for an untraceable
4903+ portscan. Ids are used for fragmented packets, fragments belonging
4904+ to the same packet have the same id. By default linux only
4905+ increments the id value on each packet sent to an individual host.
4906+ We use a port of the OpenBSD random ip id code to achieve the
4907+ randomness, while keeping the possibility of id duplicates to
4908+ near none. If the sysctl option is enabled, a sysctl option with name
4909+ "rand_ip_ids" is created.
8be839c4 4910+
474a6d91
AM
4911+Randomized TCP source ports
4912+CONFIG_GRKERNSEC_RANDSRC
4913+ If you say Y here, situations where a source port is generated on the
4914+ fly for the TCP protocol (ie. with connect() ) will be altered so that
4915+ the source port is generated at random, instead of a simple incrementing
4916+ algorithm. If the sysctl option is enabled, a sysctl option with name
4917+ "rand_tcp_src_ports" is created.
8be839c4 4918+
474a6d91
AM
4919+Randomized RPC XIDs
4920+CONFIG_GRKERNSEC_RANDRPC
4921+ If you say Y here, the method of determining XIDs for RPC requests will
4922+ be randomized, instead of using linux's default behavior of simply
4923+ incrementing the XID. If you want your RPC connections to be more
4924+ secure, say Y here. If the sysctl option is enabled, a sysctl option
4925+ with name "rand_rpc" is created.
8be839c4 4926+
474a6d91
AM
4927+Socket restrictions
4928+CONFIG_GRKERNSEC_SOCKET
4929+ If you say Y here, you will be able to choose from several options.
4930+ If you assign a GID on your system and add it to the supplementary
4931+ groups of users you want to restrict socket access to, this patch
4932+ will perform up to three things, based on the option(s) you choose.
8be839c4 4933+
474a6d91
AM
4934+Deny all socket access
4935+CONFIG_GRKERNSEC_SOCKET_ALL
4936+ If you say Y here, you will be able to choose a GID of whose users will
4937+ be unable to connect to other hosts from your machine or run server
4938+ applications from your machine. If the sysctl option is enabled, a
4939+ sysctl option with name "socket_all" is created.
8be839c4 4940+
474a6d91
AM
4941+Group for disabled socket access
4942+CONFIG_GRKERNSEC_SOCKET_ALL_GID
4943+ Here you can choose the GID to disable socket access for. Remember to
4944+ add the users you want socket access disabled for to the GID
4945+ specified here. If the sysctl option is enabled, whatever you choose
4946+ here won't matter. You'll have to specify the GID in your bootup
4947+ script by echoing the GID to the proper /proc entry. View the help
4948+ on the sysctl option for more information. If the sysctl option is
4949+ enabled, a sysctl option with name "socket_all_gid" is created.
8be839c4 4950+
474a6d91
AM
4951+Deny all client socket access
4952+CONFIG_GRKERNSEC_SOCKET_CLIENT
4953+ If you say Y here, you will be able to choose a GID of whose users will
4954+ be unable to connect to other hosts from your machine, but will be
4955+ able to run servers. If this option is enabled, all users in the group
4956+ you specify will have to use passive mode when initiating ftp transfers
4957+ from the shell on your machine. If the sysctl option is enabled, a
4958+ sysctl option with name "socket_client" is created.
8be839c4 4959+
474a6d91
AM
4960+Group for disabled client socket access
4961+CONFIG_GRKERNSEC_SOCKET_CLIENT_GID
4962+ Here you can choose the GID to disable client socket access for.
4963+ Remember to add the users you want client socket access disabled for to
4964+ the GID specified here. If the sysctl option is enabled, whatever you
4965+ choose here won't matter. You'll have to specify the GID in your bootup
4966+ script by echoing the GID to the proper /proc entry. View the help
4967+ on the sysctl option for more information. If the sysctl option is
4968+ enabled, a sysctl option with name "socket_client_gid" is created.
8be839c4 4969+
474a6d91
AM
4970+Deny all server socket access
4971+CONFIG_GRKERNSEC_SOCKET_SERVER
4972+ If you say Y here, you will be able to choose a GID of whose users will
4973+ be unable to run server applications from your machine. If the sysctl
4974+ option is enabled, a sysctl option with name "socket_server" is created.
8be839c4 4975+
474a6d91
AM
4976+Group for disabled server socket access
4977+CONFIG_GRKERNSEC_SOCKET_SERVER_GID
4978+ Here you can choose the GID to disable server socket access for.
4979+ Remember to add the users you want server socket access disabled for to
4980+ the GID specified here. If the sysctl option is enabled, whatever you
4981+ choose here won't matter. You'll have to specify the GID in your bootup
4982+ script by echoing the GID to the proper /proc entry. View the help
4983+ on the sysctl option for more information. If the sysctl option is
4984+ enabled, a sysctl option with name "socket_server_gid" is created.
8be839c4 4985+
474a6d91
AM
4986+Sysctl support
4987+CONFIG_GRKERNSEC_SYSCTL
4988+ If you say Y here, you will be able to change the options that
4989+ grsecurity runs with at bootup, without having to recompile your
4990+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
4991+ to enable (1) or disable (0) various features. All the sysctl entries
4992+ are mutable until the "grsec_lock" entry is set to a non-zero value.
4993+ All features are disabled by default. Please note that this option could
4994+ reduce the effectiveness of the added security of this patch if an ACL
4995+ system is not put in place. Your init scripts should be read-only, and
4996+ root should not have access to adding modules or performing raw i/o
4997+ operations. All options should be set at startup, and the grsec_lock
4998+ entry should be set to a non-zero value after all the options are set.
4999+ *THIS IS EXTREMELY IMPORTANT*
8be839c4 5000+
474a6d91
AM
5001+Number of burst messages
5002+CONFIG_GRKERNSEC_FLOODBURST
5003+ This option allows you to choose the maximum number of messages allowed
5004+ within the flood time interval you chose in a separate option. The
5005+ default should be suitable for most people, however if you find that
5006+ many of your logs are being interpreted as flooding, you may want to
5007+ raise this value.
8be839c4 5008+
474a6d91
AM
5009+Seconds in between log messages
5010+CONFIG_GRKERNSEC_FLOODTIME
5011+ This option allows you to enforce the number of seconds between
5012+ grsecurity log messages. The default should be suitable for most
5013+ people, however, if you choose to change it, choose a value small enough
5014+ to allow informative logs to be produced, but large enough to
5015+ prevent flooding.
8be839c4 5016+
474a6d91
AM
5017+Hide kernel processes
5018+CONFIG_GRKERNSEC_ACL_HIDEKERN
5019+ If you say Y here, when the ACL system is enabled via gradm -E,
5020+ an additional ACL will be passed to the kernel that hides all kernel
5021+ processes. These processes will only be viewable by the authenticated
5022+ admin, or processes that have viewing access set.
8be839c4 5023+
474a6d91
AM
5024+Maximum tries before password lockout
5025+CONFIG_GRKERNSEC_ACL_MAXTRIES
5026+ This option enforces the maximum number of times a user can attempt
5027+ to authorize themselves with the grsecurity ACL system before being
5028+ denied the ability to attempt authorization again for a specified time.
5029+ The lower the number, the harder it will be to brute-force a password.
8be839c4 5030+
474a6d91
AM
5031+Time to wait after max password tries, in seconds
5032+CONFIG_GRKERNSEC_ACL_TIMEOUT
5033+ This option specifies the time the user must wait after attempting to
5034+ authorize to the ACL system with the maximum number of invalid
5035+ passwords. The higher the number, the harder it will be to brute-force
5036+ a password.
8be839c4 5037+
474a6d91
AM
5038 Disable data cache
5039 CONFIG_DCACHE_DISABLE
5040 This option allows you to run the kernel with data cache disabled.
5041diff -urN linux-2.4.22.org/drivers/char/keyboard.c linux-2.4.22/drivers/char/keyboard.c
5042--- linux-2.4.22.org/drivers/char/keyboard.c 2003-11-22 22:10:20.000000000 +0100
5043+++ linux-2.4.22/drivers/char/keyboard.c 2003-11-22 22:14:07.000000000 +0100
5044@@ -545,6 +545,16 @@
8be839c4
JR
5045 if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
5046 !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
5047 return;
5048+
5049+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
5050+ {
5051+ void *func = spec_fn_table[value];
5052+ if (func == show_state || func == show_ptregs ||
5053+ func == show_mem)
5054+ return;
5055+ }
5056+#endif
5057+
5058 spec_fn_table[value]();
5059 }
5060
474a6d91
AM
5061diff -urN linux-2.4.22.org/drivers/char/mem.c linux-2.4.22/drivers/char/mem.c
5062--- linux-2.4.22.org/drivers/char/mem.c 2003-11-22 22:10:20.000000000 +0100
5063+++ linux-2.4.22/drivers/char/mem.c 2003-11-22 22:19:23.000000000 +0100
5064@@ -22,6 +22,7 @@
8be839c4
JR
5065 #include <linux/tty.h>
5066 #include <linux/capability.h>
474a6d91 5067 #include <linux/ptrace.h>
8be839c4
JR
5068+#include <linux/grsecurity.h>
5069
5070 #include <asm/uaccess.h>
5071 #include <asm/io.h>
474a6d91 5072@@ -42,6 +43,10 @@
8be839c4
JR
5073 #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
5074 extern void tapechar_init(void);
5075 #endif
5076+
5077+#ifdef CONFIG_GRKERNSEC
5078+extern struct file_operations grsec_fops;
5079+#endif
5080
5081 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
5082 const char * buf, size_t count, loff_t *ppos)
474a6d91 5083@@ -115,6 +120,11 @@
8be839c4
JR
5084 unsigned long p = *ppos;
5085 unsigned long end_mem;
5086
5087+#ifdef CONFIG_GRKERNSEC_KMEM
5088+ gr_handle_mem_write();
5089+ return -EPERM;
5090+#endif
5091+
5092 end_mem = __pa(high_memory);
5093 if (p >= end_mem)
5094 return 0;
474a6d91 5095@@ -187,6 +197,12 @@
8be839c4
JR
5096 {
5097 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5098
5099+#ifdef CONFIG_GRKERNSEC_KMEM
5100+ if (gr_handle_mem_mmap(offset, vma))
5101+ return -EPERM;
5102+#endif
5103+
5104+
5105 /*
5106 * Accessing memory above the top the kernel knows about or
5107 * through a file pointer that was marked O_SYNC will be
474a6d91 5108@@ -286,6 +302,11 @@
8be839c4
JR
5109 ssize_t virtr = 0;
5110 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
5111
5112+#ifdef CONFIG_GRKERNSEC_KMEM
5113+ gr_handle_kmem_write();
5114+ return -EPERM;
5115+#endif
5116+
5117 if (p < (unsigned long) high_memory) {
5118 wrote = count;
5119 if (count > (unsigned long) high_memory - p)
474a6d91 5120@@ -402,7 +423,7 @@
8be839c4
JR
5121 count = size;
5122
5123 zap_page_range(mm, addr, count);
5124- zeromap_page_range(addr, count, PAGE_COPY);
5125+ zeromap_page_range(addr, count, vma->vm_page_prot);
5126
5127 size -= count;
5128 buf += count;
474a6d91 5129@@ -525,6 +546,15 @@
8be839c4
JR
5130
5131 static int open_port(struct inode * inode, struct file * filp)
5132 {
5133+#ifdef CONFIG_GRKERNSEC_KMEM
5134+ gr_handle_open_port();
5135+ return -EPERM;
5136+#endif
5137+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5138+}
5139+
5140+static int open_mem(struct inode * inode, struct file * filp)
5141+{
5142 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
5143 }
5144
474a6d91 5145@@ -582,6 +612,11 @@
8be839c4
JR
5146 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5147 unsigned long size = vma->vm_end - vma->vm_start;
5148
5149+#ifdef CONFIG_GRKERNSEC_KMEM
5150+ if (gr_handle_mem_mmap(offset, vma))
5151+ return -EPERM;
5152+#endif
5153+
5154 /*
5155 * If the user is not attempting to mmap a high memory address then
5156 * the standard mmap_mem mechanism will work. High memory addresses
474a6d91 5157@@ -617,7 +652,6 @@
8be839c4
JR
5158 #define full_lseek null_lseek
5159 #define write_zero write_null
5160 #define read_full read_zero
5161-#define open_mem open_port
5162 #define open_kmem open_mem
5163
5164 static struct file_operations mem_fops = {
474a6d91 5165@@ -693,6 +727,11 @@
8be839c4
JR
5166 case 9:
5167 filp->f_op = &urandom_fops;
5168 break;
5169+#ifdef CONFIG_GRKERNSEC
5170+ case 10:
5171+ filp->f_op = &grsec_fops;
5172+ break;
5173+#endif
5174 default:
5175 return -ENXIO;
5176 }
474a6d91 5177@@ -719,7 +758,10 @@
8be839c4
JR
5178 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
5179 {7, "full", S_IRUGO | S_IWUGO, &full_fops},
5180 {8, "random", S_IRUGO | S_IWUSR, &random_fops},
5181- {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}
5182+ {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
5183+#ifdef CONFIG_GRKERNSEC
5184+ {10,"grsec", S_IRUSR | S_IWUGO, &grsec_fops}
5185+#endif
5186 };
5187 int i;
5188
474a6d91
AM
5189diff -urN linux-2.4.22.org/drivers/char/random.c linux-2.4.22/drivers/char/random.c
5190--- linux-2.4.22.org/drivers/char/random.c 2003-11-22 22:10:20.000000000 +0100
5191+++ linux-2.4.22/drivers/char/random.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
5192@@ -262,9 +262,15 @@
5193 /*
5194 * Configuration information
5195 */
5196+#ifdef CONFIG_GRKERNSEC_RANDNET
5197+#define DEFAULT_POOL_SIZE 1024
5198+#define SECONDARY_POOL_SIZE 256
5199+#define BATCH_ENTROPY_SIZE 512
5200+#else
5201 #define DEFAULT_POOL_SIZE 512
5202 #define SECONDARY_POOL_SIZE 128
5203 #define BATCH_ENTROPY_SIZE 256
5204+#endif
5205 #define USE_SHA
5206
5207 /*
5208@@ -389,6 +395,7 @@
5209 /*
5210 * Static global variables
5211 */
5212+
5213 static struct entropy_store *random_state; /* The default global store */
5214 static struct entropy_store *sec_random_state; /* secondary store */
5215 static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
5216@@ -2202,6 +2209,29 @@
5217 return halfMD4Transform(hash, keyptr->secret);
5218 }
5219
5220+#ifdef CONFIG_GRKERNSEC
5221+/* the following function is provided by PaX under the GPL */
5222+unsigned long get_random_long(void)
5223+{
5224+ static time_t rekey_time;
5225+ static __u32 secret[12];
5226+ time_t t;
5227+
5228+ /*
5229+ * Pick a random secret every REKEY_INTERVAL seconds
5230+ */
5231+ t = CURRENT_TIME;
5232+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
5233+ rekey_time = t;
5234+ get_random_bytes(secret, sizeof(secret));
5235+ }
5236+
5237+ secret[1] = halfMD4Transform(secret+8, secret);
5238+ secret[0] = halfMD4Transform(secret+8, secret);
5239+ return *(unsigned long *)secret;
5240+}
5241+#endif
5242+
5243 #ifdef CONFIG_SYN_COOKIES
5244 /*
5245 * Secure SYN cookie computation. This is the algorithm worked out by
474a6d91
AM
5246diff -urN linux-2.4.22.org/drivers/char/tty_io.c linux-2.4.22/drivers/char/tty_io.c
5247--- linux-2.4.22.org/drivers/char/tty_io.c 2003-11-22 22:10:19.000000000 +0100
5248+++ linux-2.4.22/drivers/char/tty_io.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
5249@@ -99,7 +99,7 @@
5250 #include <linux/vt_kern.h>
5251 #include <linux/selection.h>
5252 #include <linux/devfs_fs_kernel.h>
5253-
5254+#include <linux/grsecurity.h>
5255 #include <linux/kmod.h>
5256
5257 #ifdef CONFIG_VT
474a6d91 5258@@ -1426,7 +1426,11 @@
8be839c4
JR
5259 retval = -ENODEV;
5260 filp->f_flags = saved_flags;
5261
5262+#ifdef CONFIG_GRKERNSEC
5263+ if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG))
5264+#else
5265 if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
5266+#endif
5267 retval = -EBUSY;
5268
5269 if (retval) {
474a6d91 5270@@ -1533,7 +1537,11 @@
8be839c4
JR
5271 {
5272 char ch, mbz = 0;
5273
5274+#ifdef CONFIG_GRKERNSEC
5275+ if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG))
5276+#else
5277 if ((current->tty != tty) && !suser())
5278+#endif
5279 return -EPERM;
5280 if (get_user(ch, arg))
5281 return -EFAULT;
474a6d91 5282@@ -1571,7 +1579,11 @@
8be839c4
JR
5283 if (inode->i_rdev == SYSCONS_DEV ||
5284 inode->i_rdev == CONSOLE_DEV) {
5285 struct file *f;
5286+#ifdef CONFIG_GRKERNSEC
5287+ if (!capable(CAP_SYS_TTY_CONFIG))
5288+#else
5289 if (!suser())
5290+#endif
5291 return -EPERM;
5292 spin_lock(&redirect_lock);
5293 f = redirect;
474a6d91 5294@@ -1623,7 +1635,11 @@
8be839c4
JR
5295 * This tty is already the controlling
5296 * tty for another session group!
5297 */
5298+#ifdef CONFIG_GRKERNSEC
5299+ if ((arg == 1) && capable(CAP_SYS_ADMIN)) {
5300+#else
5301 if ((arg == 1) && suser()) {
5302+#endif
5303 /*
5304 * Steal it away
5305 */
474a6d91
AM
5306diff -urN linux-2.4.22.org/drivers/char/vt.c linux-2.4.22/drivers/char/vt.c
5307--- linux-2.4.22.org/drivers/char/vt.c 2003-11-22 22:10:20.000000000 +0100
5308+++ linux-2.4.22/drivers/char/vt.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
5309@@ -32,6 +32,7 @@
5310 #include <linux/vt_kern.h>
5311 #include <linux/kbd_diacr.h>
5312 #include <linux/selection.h>
5313+#include <linux/grsecurity.h>
5314
5315 #ifdef CONFIG_FB_COMPAT_XPMAC
5316 #include <asm/vc_ioctl.h>
5317@@ -443,7 +444,11 @@
5318 * to be the owner of the tty, or super-user.
5319 */
5320 perm = 0;
5321+#ifdef CONFIG_GRKERNSEC
5322+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
5323+#else
5324 if (current->tty == tty || suser())
5325+#endif
5326 perm = 1;
5327
5328 kbd = kbd_table + console;
5329@@ -1038,12 +1043,20 @@
5330 return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
5331
5332 case VT_LOCKSWITCH:
5333+#ifdef CONFIG_GRKERNSEC
5334+ if (!capable(CAP_SYS_TTY_CONFIG))
5335+#else
5336 if (!suser())
5337+#endif
5338 return -EPERM;
5339 vt_dont_switch = 1;
5340 return 0;
5341 case VT_UNLOCKSWITCH:
5342+#ifdef CONFIG_GRKERNSEC
5343+ if (!capable(CAP_SYS_TTY_CONFIG))
5344+#else
5345 if (!suser())
5346+#endif
5347 return -EPERM;
5348 vt_dont_switch = 0;
5349 return 0;
474a6d91
AM
5350diff -urN linux-2.4.22.org/drivers/pci/proc.c linux-2.4.22/drivers/pci/proc.c
5351--- linux-2.4.22.org/drivers/pci/proc.c 2003-11-22 22:10:57.000000000 +0100
5352+++ linux-2.4.22/drivers/pci/proc.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
5353@@ -562,7 +562,15 @@
5354 pci_for_each_dev(dev) {
5355 pci_proc_attach_device(dev);
5356 }
5357+#ifdef CONFIG_GRKERNSEC_PROC_ADD
5358+#ifdef CONFIG_GRKERNSEC_PROC_USER
5359+ entry = create_proc_entry("pci", S_IRUSR, NULL);
5360+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
5361+ entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
5362+#endif
5363+#else
5364 entry = create_proc_entry("pci", 0, NULL);
5365+#endif
5366 if (entry)
5367 entry->proc_fops = &proc_pci_operations;
5368 }
474a6d91
AM
5369diff -urN linux-2.4.22.org/fs/binfmt_aout.c linux-2.4.22/fs/binfmt_aout.c
5370--- linux-2.4.22.org/fs/binfmt_aout.c 2003-11-22 22:09:01.000000000 +0100
5371+++ linux-2.4.22/fs/binfmt_aout.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
5372@@ -5,6 +5,7 @@
5373 */
5374
5375 #include <linux/module.h>
5376+#include <linux/config.h>
5377
5378 #include <linux/sched.h>
5379 #include <linux/kernel.h>
5380@@ -113,10 +114,12 @@
5381 /* If the size of the dump file exceeds the rlimit, then see what would happen
5382 if we wrote the stack, but not the data area. */
5383 #ifdef __sparc__
5384+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize);
5385 if ((dump.u_dsize+dump.u_ssize) >
5386 current->rlim[RLIMIT_CORE].rlim_cur)
5387 dump.u_dsize = 0;
5388 #else
5389+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE);
5390 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
5391 current->rlim[RLIMIT_CORE].rlim_cur)
5392 dump.u_dsize = 0;
5393@@ -124,10 +127,12 @@
5394
5395 /* Make sure we have enough room to write the stack and data areas. */
5396 #ifdef __sparc__
5397+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize);
5398 if ((dump.u_ssize) >
5399 current->rlim[RLIMIT_CORE].rlim_cur)
5400 dump.u_ssize = 0;
5401 #else
5402+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE);
5403 if ((dump.u_ssize+1) * PAGE_SIZE >
5404 current->rlim[RLIMIT_CORE].rlim_cur)
5405 dump.u_ssize = 0;
5406@@ -276,6 +281,8 @@
5407 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
5408 if (rlim >= RLIM_INFINITY)
5409 rlim = ~0;
5410+
5411+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss);
5412 if (ex.a_data + ex.a_bss > rlim)
5413 return -ENOMEM;
5414
5415@@ -307,6 +314,24 @@
5416 current->mm->mmap = NULL;
5417 compute_creds(bprm);
5418 current->flags &= ~PF_FORKNOEXEC;
5419+
5420+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5421+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
5422+ current->flags |= PF_PAX_PAGEEXEC;
5423+
5424+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5425+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
5426+ current->flags |= PF_PAX_EMUTRAMP;
5427+#endif
5428+
5429+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5430+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
5431+ current->flags |= PF_PAX_MPROTECT;
5432+#endif
5433+
5434+ }
5435+#endif
5436+
5437 #ifdef __sparc__
5438 if (N_MAGIC(ex) == NMAGIC) {
5439 loff_t pos = fd_offset;
5440@@ -393,7 +418,7 @@
5441
5442 down_write(&current->mm->mmap_sem);
5443 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
5444- PROT_READ | PROT_WRITE | PROT_EXEC,
5445+ PROT_READ | PROT_WRITE,
5446 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
5447 fd_offset + ex.a_text);
5448 up_write(&current->mm->mmap_sem);
474a6d91
AM
5449diff -urN linux-2.4.22.org/fs/binfmt_elf.c linux-2.4.22/fs/binfmt_elf.c
5450--- linux-2.4.22.org/fs/binfmt_elf.c 2003-11-22 22:08:59.000000000 +0100
5451+++ linux-2.4.22/fs/binfmt_elf.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
5452@@ -11,6 +11,7 @@
5453
5454 #include <linux/module.h>
5455
5456+#include <linux/config.h>
5457 #include <linux/fs.h>
5458 #include <linux/stat.h>
5459 #include <linux/sched.h>
5460@@ -33,10 +34,13 @@
5461 #include <linux/smp_lock.h>
5462 #include <linux/compiler.h>
5463 #include <linux/highmem.h>
5464+#include <linux/random.h>
5465+#include <linux/grsecurity.h>
5466
5467 #include <asm/uaccess.h>
5468 #include <asm/param.h>
5469 #include <asm/pgalloc.h>
5470+#include <asm/system.h>
5471
5472 #define DLINFO_ITEMS 13
5473
5474@@ -86,6 +90,12 @@
5475 if (end <= start)
5476 return;
5477 do_brk(start, end - start);
5478+
5479+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5480+ if (current->flags & PF_PAX_RANDEXEC)
5481+ do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
5482+#endif
5483+
5484 }
5485
5486
474a6d91 5487@@ -446,6 +456,11 @@
8be839c4
JR
5488 struct exec interp_ex;
5489 char passed_fileno[6];
5490 struct files_struct *files;
5491+
5492+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5493+ unsigned long load_addr_random = 0UL;
5494+ unsigned long load_bias_random = 0UL;
5495+#endif
5496
5497 /* Get the exec-header */
5498 elf_ex = *((struct elfhdr *) bprm->buf);
474a6d91 5499@@ -618,7 +633,63 @@
8be839c4
JR
5500 current->mm->end_data = 0;
5501 current->mm->end_code = 0;
5502 current->mm->mmap = NULL;
5503+
5504+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5505+ current->mm->delta_mmap = 0UL;
5506+ current->mm->delta_exec = 0UL;
5507+ current->mm->delta_stack = 0UL;
5508+#endif
5509+
5510 current->flags &= ~PF_FORKNOEXEC;
5511+
5512+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5513+ if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) {
5514+ current->flags |= PF_PAX_PAGEEXEC;
5515+
5516+#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
5517+ current->mm->call_dl_resolve = 0UL;
5518+#endif
5519+
5520+ }
5521+#endif
5522+
5523+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5524+ if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
5525+ current->flags &= ~PF_PAX_PAGEEXEC;
5526+ current->flags |= PF_PAX_SEGMEXEC;
5527+ }
5528+#endif
5529+
5530+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5531+ if (elf_ex.e_ident[EI_PAX] & EF_PAX_EMUTRAMP)
5532+ current->flags |= PF_PAX_EMUTRAMP;
5533+#endif
5534+
5535+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5536+ if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex.e_ident[EI_PAX] & EF_PAX_MPROTECT))
5537+ current->flags |= PF_PAX_MPROTECT;
5538+#endif
5539+
5540+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5541+ if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_RANDMMAP)) {
5542+ current->flags |= PF_PAX_RANDMMAP;
5543+
5544+#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
5545+
5546+ current->mm->delta_mmap = pax_delta_mask(get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
5547+ current->mm->delta_exec = pax_delta_mask(get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
5548+ current->mm->delta_stack = pax_delta_mask(get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
5549+ }
5550+#endif
5551+
5552+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5553+ if ((elf_ex.e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC) &&
5554+ (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)))
5555+ current->flags |= PF_PAX_RANDEXEC;
5556+#endif
5557+
5558+ gr_set_pax_flags(current);
5559+
5560 elf_entry = (unsigned long) elf_ex.e_entry;
5561
5562 /* Do this so that we can load the interpreter, if need be. We will
474a6d91 5563@@ -674,11 +745,84 @@
8be839c4
JR
5564 base, as well as whatever program they might try to exec. This
5565 is because the brk will follow the loader, and is not movable. */
5566 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
5567+
5568+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
5569+ /* PaX: randomize base address at the default exe base if requested */
5570+ if (current->flags & PF_PAX_RANDMMAP) {
5571+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
5572+ elf_flags |= MAP_FIXED;
5573+ }
5574+#endif
5575+
5576 }
5577
5578- error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5579- if (BAD_ADDR(error))
5580- continue;
5581+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5582+ if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
5583+ unsigned long addr, len;
5584+
5585+ error = -ENOMEM;
5586+
5587+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5588+ if (current->flags & PF_PAX_PAGEEXEC)
5589+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
5590+#endif
5591+
5592+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5593+ if (current->flags & PF_PAX_SEGMEXEC) {
5594+ addr = ELF_PAGESTART(load_bias + vaddr);
5595+ len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
5596+ if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
5597+ continue;
5598+ down_write(&current->mm->mmap_sem);
5599+ error = do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
5600+ up_write(&current->mm->mmap_sem);
5601+ }
5602+#endif
5603+
5604+ if (BAD_ADDR(error))
5605+ continue;
5606+
5607+ /* PaX: mirror at a randomized base */
5608+ down_write(&current->mm->mmap_sem);
5609+
5610+ if (!load_addr_set) {
5611+ load_addr_random = get_unmapped_area(bprm->file, 0UL, elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT, MAP_PRIVATE);
5612+ if (BAD_ADDR(load_addr_random)) {
5613+ up_write(&current->mm->mmap_sem);
5614+ continue;
5615+ }
5616+ load_bias_random = load_addr_random - vaddr;
5617+ }
5618+
5619+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5620+ if (current->flags & PF_PAX_PAGEEXEC)
5621+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5622+#endif
5623+
5624+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5625+ if (current->flags & PF_PAX_SEGMEXEC) {
5626+ if (elf_prot & PROT_EXEC) {
5627+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), elf_ppnt->p_memsz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), PROT_NONE, MAP_PRIVATE | MAP_FIXED, 0UL);
5628+ if (!BAD_ADDR(load_addr_random)) {
5629+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5630+ if (!BAD_ADDR(load_addr_random))
5631+ load_addr_random -= SEGMEXEC_TASK_SIZE;
5632+ }
5633+ } else
5634+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5635+ }
5636+#endif
5637+
5638+ up_write(&current->mm->mmap_sem);
5639+ if (BAD_ADDR(load_addr_random))
5640+ continue;
5641+ } else
5642+#endif
5643+ {
5644+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5645+ if (BAD_ADDR(error))
5646+ continue;
5647+ }
5648
5649 if (!load_addr_set) {
5650 load_addr_set = 1;
474a6d91 5651@@ -689,6 +833,11 @@
8be839c4 5652 load_addr += load_bias;
474a6d91 5653 reloc_func_desc = load_addr;
8be839c4
JR
5654 }
5655+
5656+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5657+ current->mm->delta_exec = load_addr_random - load_addr;
5658+#endif
5659+
5660 }
5661 k = elf_ppnt->p_vaddr;
5662 if (k < start_code) start_code = k;
474a6d91 5663@@ -715,6 +864,18 @@
8be839c4
JR
5664 start_data += load_bias;
5665 end_data += load_bias;
5666
5667+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
5668+ elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT);
5669+#undef pax_delta_mask
5670+#endif
5671+
5672+ /* Calling set_brk effectively mmaps the pages that we need
5673+ * for the bss and break sections
5674+ */
5675+ set_brk(elf_bss, elf_brk);
5676+
5677+ padzero(elf_bss);
5678+
5679 if (elf_interpreter) {
5680 if (interpreter_type == INTERPRETER_AOUT)
5681 elf_entry = load_aout_interp(&interp_ex,
474a6d91 5682@@ -763,13 +924,6 @@
8be839c4
JR
5683 current->mm->end_data = end_data;
5684 current->mm->start_stack = bprm->p;
5685
5686- /* Calling set_brk effectively mmaps the pages that we need
5687- * for the bss and break sections
5688- */
5689- set_brk(elf_bss, elf_brk);
5690-
5691- padzero(elf_bss);
5692-
5693 #if 0
5694 printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
5695 printk("(end_code) %lx\n" , (long) current->mm->end_code);
474a6d91
AM
5696@@ -806,6 +960,10 @@
5697 ELF_PLAT_INIT(regs, reloc_func_desc);
8be839c4
JR
5698 #endif
5699
5700+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5701+ pax_switch_segments(current);
5702+#endif
5703+
5704 start_thread(regs, elf_entry, bprm->p);
5705 if (current->ptrace & PT_PTRACED)
5706 send_sig(SIGTRAP, current, 0);
474a6d91 5707@@ -1033,8 +1191,11 @@
8be839c4
JR
5708 #undef DUMP_SEEK
5709
5710 #define DUMP_WRITE(addr, nr) \
5711+ do { \
5712+ gr_learn_resource(current, RLIMIT_CORE, size + (nr)); \
5713 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
5714- goto end_coredump;
5715+ goto end_coredump; \
5716+ } while (0);
5717 #define DUMP_SEEK(off) \
5718 if (!dump_seek(file, (off))) \
5719 goto end_coredump;
474a6d91
AM
5720diff -urN linux-2.4.22.org/fs/buffer.c linux-2.4.22/fs/buffer.c
5721--- linux-2.4.22.org/fs/buffer.c 2003-11-22 22:09:07.000000000 +0100
5722+++ linux-2.4.22/fs/buffer.c 2003-11-22 22:14:07.000000000 +0100
5723@@ -1906,6 +1906,9 @@
8be839c4
JR
5724 int err;
5725
5726 err = -EFBIG;
5727+
5728+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size);
5729+
5730 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
5731 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
5732 send_sig(SIGXFSZ, current, 0);
474a6d91
AM
5733diff -urN linux-2.4.22.org/fs/exec.c linux-2.4.22/fs/exec.c
5734--- linux-2.4.22.org/fs/exec.c 2003-11-22 22:08:59.000000000 +0100
5735+++ linux-2.4.22/fs/exec.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
5736@@ -43,6 +43,9 @@
5737 #include <asm/uaccess.h>
5738 #include <asm/pgalloc.h>
5739 #include <asm/mmu_context.h>
5740+#include <linux/major.h>
5741+#include <linux/random.h>
5742+#include <linux/grsecurity.h>
5743
5744 #ifdef CONFIG_KMOD
5745 #include <linux/kmod.h>
474a6d91 5746@@ -346,6 +349,11 @@
8be839c4
JR
5747 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
5748 mpnt->vm_end = STACK_TOP;
5749 mpnt->vm_flags = VM_STACK_FLAGS;
5750+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5751+ if (!(current->flags & PF_PAX_PAGEEXEC))
5752+ mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7];
5753+ else
5754+#endif
5755 mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
5756 mpnt->vm_ops = NULL;
5757 mpnt->vm_pgoff = 0;
474a6d91 5758@@ -606,6 +614,30 @@
8be839c4
JR
5759 }
5760 current->comm[i] = '\0';
5761
5762+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
5763+ current->flags &= ~PF_PAX_PAGEEXEC;
5764+#endif
5765+
5766+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
5767+ current->flags &= ~PF_PAX_EMUTRAMP;
5768+#endif
5769+
5770+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
5771+ current->flags &= ~PF_PAX_MPROTECT;
5772+#endif
5773+
5774+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
5775+ current->flags &= ~PF_PAX_RANDMMAP;
5776+#endif
5777+
5778+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
5779+ current->flags &= ~PF_PAX_RANDEXEC;
5780+#endif
5781+
5782+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
5783+ current->flags &= ~PF_PAX_SEGMEXEC;
5784+#endif
5785+
5786 flush_thread();
5787
5788 de_thread(current);
474a6d91 5789@@ -705,6 +737,9 @@
8be839c4
JR
5790 cap_set_full(bprm->cap_effective);
5791 }
5792
5793+ if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
5794+ return -EACCES;
5795+
5796 memset(bprm->buf,0,BINPRM_BUF_SIZE);
5797 return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
5798 }
474a6d91 5799@@ -770,6 +805,8 @@
8be839c4
JR
5800 current->suid = current->euid = current->fsuid = bprm->e_uid;
5801 current->sgid = current->egid = current->fsgid = bprm->e_gid;
5802
5803+ gr_handle_chroot_caps(current);
5804+
5805 if(do_unlock)
5806 unlock_kernel();
5807 current->keep_capabilities = 0;
474a6d91 5808@@ -903,6 +940,11 @@
8be839c4
JR
5809 struct file *file;
5810 int retval;
5811 int i;
5812+#ifdef CONFIG_GRKERNSEC
5813+ struct file *old_exec_file;
5814+ struct acl_subject_label *old_acl;
5815+ struct rlimit old_rlim[RLIM_NLIMITS];
5816+#endif
5817
5818 file = open_exec(filename);
5819
474a6d91 5820@@ -910,7 +952,26 @@
8be839c4
JR
5821 if (IS_ERR(file))
5822 return retval;
5823
5824+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
5825+
5826+ if (gr_handle_nproc()) {
5827+ allow_write_access(file);
5828+ fput(file);
5829+ return -EAGAIN;
5830+ }
5831+
5832+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
5833+ allow_write_access(file);
5834+ fput(file);
5835+ return -EACCES;
5836+ }
5837+
5838 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
5839+
5840+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
5841+ bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
5842+#endif
5843+
5844 memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
5845
5846 bprm.file = file;
474a6d91 5847@@ -934,11 +995,26 @@
8be839c4
JR
5848 if (retval < 0)
5849 goto out;
5850
5851+ if (!gr_tpe_allow(file)) {
5852+ retval = -EACCES;
5853+ goto out;
5854+ }
5855+
5856+ if(gr_check_crash_exec(file)) {
5857+ retval = -EACCES;
5858+ goto out;
5859+ }
5860+
5861 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
5862 if (retval < 0)
5863 goto out;
5864
5865 bprm.exec = bprm.p;
5866+
5867+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
5868+
5869+ gr_handle_exec_args(&bprm, argv);
5870+
5871 retval = copy_strings(bprm.envc, envp, &bprm);
5872 if (retval < 0)
5873 goto out;
474a6d91 5874@@ -947,11 +1023,32 @@
8be839c4
JR
5875 if (retval < 0)
5876 goto out;
5877
5878+#ifdef CONFIG_GRKERNSEC
5879+ old_acl = current->acl;
5880+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
5881+ old_exec_file = current->exec_file;
5882+ get_file(file);
5883+ current->exec_file = file;
5884+#endif
5885+
5886+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
5887+
5888 retval = search_binary_handler(&bprm,regs);
5889- if (retval >= 0)
5890+ if (retval >= 0) {
5891+#ifdef CONFIG_GRKERNSEC
5892+ if (old_exec_file)
5893+ fput(old_exec_file);
5894+#endif
5895 /* execve success */
5896 return retval;
5897+ }
5898
5899+#ifdef CONFIG_GRKERNSEC
5900+ current->acl = old_acl;
5901+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
5902+ fput(current->exec_file);
5903+ current->exec_file = old_exec_file;
5904+#endif
5905 out:
5906 /* Something went wrong, return the inode and free the argument pages*/
5907 allow_write_access(bprm.file);
474a6d91 5908@@ -1093,6 +1190,43 @@
8be839c4
JR
5909 *out_ptr = 0;
5910 }
5911
5912+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
5913+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
5914+{
5915+ struct task_struct *tsk = current;
5916+ struct mm_struct *mm = current->mm;
5917+ char* buffer = (char*)__get_free_page(GFP_ATOMIC);
5918+ char* path=NULL;
5919+
5920+ if (buffer) {
5921+ struct vm_area_struct* vma;
5922+
5923+ down_read(&mm->mmap_sem);
5924+ vma = mm->mmap;
5925+ while (vma) {
5926+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
5927+ break;
5928+ }
5929+ vma = vma->vm_next;
5930+ }
5931+ if (vma)
5932+ path = d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt, buffer, PAGE_SIZE);
5933+ up_read(&mm->mmap_sem);
5934+ }
5935+ if (tsk->curr_ip)
5936+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: terminating task: %s(%s):%d, uid/euid: %u/%u, "
5937+ "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), path, tsk->comm, tsk->pid,
5938+ tsk->uid, tsk->euid, pc, sp);
5939+ else
5940+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
5941+ "PC: %p, SP: %p\n", path, tsk->comm, tsk->pid,
5942+ tsk->uid, tsk->euid, pc, sp);
5943+ if (buffer) free_page((unsigned long)buffer);
5944+ pax_report_insns(pc);
5945+ do_coredump(SIGKILL, regs);
5946+}
5947+#endif
5948+
5949 int do_coredump(long signr, struct pt_regs * regs)
5950 {
5951 struct linux_binfmt * binfmt;
474a6d91
AM
5952@@ -1113,6 +1247,7 @@
5953 current->fsuid = 0;
5954 }
8be839c4
JR
5955 current->mm->dumpable = 0;
5956+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump);
5957 if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
5958 goto fail;
5959
474a6d91 5960@@ -1132,7 +1267,7 @@
8be839c4
JR
5961 goto close_fail;
5962 if (!file->f_op->write)
5963 goto close_fail;
5964- if (do_truncate(file->f_dentry, 0) != 0)
5965+ if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
5966 goto close_fail;
5967
5968 retval = binfmt->core_dump(signr, regs, file);
474a6d91
AM
5969diff -urN linux-2.4.22.org/fs/fcntl.c linux-2.4.22/fs/fcntl.c
5970--- linux-2.4.22.org/fs/fcntl.c 2003-11-22 22:08:59.000000000 +0100
5971+++ linux-2.4.22/fs/fcntl.c 2003-11-22 22:19:45.000000000 +0100
5972@@ -12,6 +12,7 @@
8be839c4
JR
5973 #include <linux/slab.h>
5974 #include <linux/iobuf.h>
474a6d91 5975 #include <linux/ptrace.h>
8be839c4
JR
5976+#include <linux/grsecurity.h>
5977
5978 #include <asm/poll.h>
5979 #include <asm/siginfo.h>
474a6d91 5980@@ -65,6 +66,8 @@
8be839c4
JR
5981 int error;
5982 int start;
5983
5984+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start);
5985+
5986 write_lock(&files->file_lock);
5987
5988 error = -EINVAL;
474a6d91 5989@@ -87,6 +90,7 @@
8be839c4
JR
5990 }
5991
5992 error = -EMFILE;
5993+ gr_learn_resource(current, RLIMIT_NOFILE, newfd);
5994 if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
5995 goto out;
5996
474a6d91 5997@@ -142,6 +146,8 @@
8be839c4
JR
5998 struct file * file, *tofree;
5999 struct files_struct * files = current->files;
6000
6001+ gr_learn_resource(current, RLIMIT_NOFILE, newfd);
6002+
6003 write_lock(&files->file_lock);
6004 if (!(file = fcheck(oldfd)))
6005 goto out_unlock;
474a6d91 6006@@ -450,6 +456,10 @@
8be839c4
JR
6007 match = -p->pgrp;
6008 if (pid != match)
6009 continue;
6010+ if (gr_check_protected_task(p))
6011+ continue;
6012+ if (gr_pid_is_chrooted(p))
6013+ continue;
6014 send_sigio_to_task(p, fown, fd, band);
6015 }
6016 out:
474a6d91
AM
6017diff -urN linux-2.4.22.org/fs/locks.c linux-2.4.22/fs/locks.c
6018--- linux-2.4.22.org/fs/locks.c 2003-11-22 22:08:59.000000000 +0100
6019+++ linux-2.4.22/fs/locks.c 2003-11-22 22:14:07.000000000 +0100
fb7a42a0
AM
6020@@ -138,4 +138,5 @@
6021 static struct file_lock *locks_alloc_lock(void)
8be839c4 6022 {
d92391e6 6023+ gr_learn_resource(current, RLIMIT_LOCKS, current->locks);
fb7a42a0
AM
6024 return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
6025 }
474a6d91
AM
6026diff -urN linux-2.4.22.org/fs/namei.c linux-2.4.22/fs/namei.c
6027--- linux-2.4.22.org/fs/namei.c 2003-11-22 22:09:07.000000000 +0100
6028+++ linux-2.4.22/fs/namei.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
6029@@ -22,6 +22,7 @@
6030 #include <linux/dnotify.h>
6031 #include <linux/smp_lock.h>
6032 #include <linux/personality.h>
6033+#include <linux/grsecurity.h>
6034
6035 #include <asm/namei.h>
6036 #include <asm/uaccess.h>
6037@@ -343,6 +344,13 @@
6038 current->state = TASK_RUNNING;
6039 schedule();
6040 }
6041+
6042+ if (gr_handle_follow_link(dentry->d_parent->d_inode,
6043+ dentry->d_inode, dentry, nd->mnt)) {
6044+ path_release(nd);
6045+ return -EACCES;
6046+ }
6047+
6048 current->link_count++;
6049 current->total_link_count++;
6050 UPDATE_ATIME(dentry->d_inode);
6051@@ -643,6 +651,10 @@
6052 }
6053 }
6054 return_base:
6055+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
6056+ path_release(nd);
6057+ return -ENOENT;
6058+ }
6059 return 0;
6060 out_dput:
6061 dput(dentry);
6062@@ -1005,7 +1017,7 @@
6063 struct dentry *dentry;
6064 struct dentry *dir;
6065 int count = 0;
6066-
6067+
6068 acc_mode = ACC_MODE(flag);
6069
6070 /*
6071@@ -1015,7 +1027,19 @@
6072 error = path_lookup(pathname, lookup_flags(flag), nd);
6073 if (error)
6074 return error;
6075+
6076+ if (gr_handle_rawio(nd->dentry->d_inode)) {
6077+ error = -EPERM;
6078+ goto exit;
6079+ }
6080+
6081+ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
6082+ error = -EACCES;
6083+ goto exit;
6084+ }
6085+
6086 dentry = nd->dentry;
6087+
6088 goto ok;
6089 }
6090
6091@@ -1050,7 +1074,16 @@
6092 if (!dentry->d_inode) {
6093 if (!IS_POSIXACL(dir->d_inode))
6094 mode &= ~current->fs->umask;
6095+ if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
6096+ error = -EACCES;
6097+ up(&dir->d_inode->i_sem);
6098+ goto exit_dput;
6099+ }
6100+
6101 error = vfs_create(dir->d_inode, dentry, mode);
6102+ if (!error)
6103+ gr_handle_create(dentry, nd->mnt);
6104+
6105 up(&dir->d_inode->i_sem);
6106 dput(nd->dentry);
6107 nd->dentry = dentry;
6108@@ -1059,12 +1092,35 @@
6109 /* Don't check for write permission, don't truncate */
6110 acc_mode = 0;
6111 flag &= ~O_TRUNC;
6112+
6113 goto ok;
6114 }
6115
6116 /*
6117 * It already exists.
6118 */
6119+
6120+ if (gr_acl_is_enabled() && S_ISBLK(dentry->d_inode->i_mode) &&
6121+ !capable(CAP_SYS_RAWIO)) {
6122+ error = -EPERM;
6123+ up(&dir->d_inode->i_sem);
6124+ goto exit_dput;
6125+ }
6126+
6127+ if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
6128+ error = -EACCES;
6129+ up(&dir->d_inode->i_sem);
6130+ goto exit_dput;
6131+ }
6132+
6133+ inode = dentry->d_inode;
6134+
6135+ if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
6136+ up(&dir->d_inode->i_sem);
6137+ error = -EACCES;
6138+ goto exit_dput;
6139+ }
6140+
6141 up(&dir->d_inode->i_sem);
6142
6143 error = -EEXIST;
6144@@ -1154,7 +1210,7 @@
6145 if (!error) {
6146 DQUOT_INIT(inode);
6147
6148- error = do_truncate(dentry, 0);
6149+ error = do_truncate(dentry,0,nd->mnt);
6150 }
6151 put_write_access(inode);
6152 if (error)
6153@@ -1185,6 +1241,13 @@
6154 * stored in nd->last.name and we will have to putname() it when we
6155 * are done. Procfs-like symlinks just set LAST_BIND.
6156 */
6157+
6158+ if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
6159+ dentry, nd->mnt)) {
6160+ error = -EACCES;
6161+ goto exit_dput;
6162+ }
6163+
6164 UPDATE_ATIME(dentry->d_inode);
6165 error = dentry->d_inode->i_op->follow_link(dentry, nd);
6166 dput(dentry);
6167@@ -1284,6 +1347,18 @@
6168 if (!IS_POSIXACL(nd.dentry->d_inode))
6169 mode &= ~current->fs->umask;
6170 if (!IS_ERR(dentry)) {
6171+ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
6172+ error = -EPERM;
6173+ dput(dentry);
6174+ goto out_dput;
6175+ }
6176+
6177+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
6178+ error = -EACCES;
6179+ dput(dentry);
6180+ goto out_dput;
6181+ }
6182+
6183 switch (mode & S_IFMT) {
6184 case 0: case S_IFREG:
6185 error = vfs_create(nd.dentry->d_inode,dentry,mode);
6186@@ -1297,8 +1372,13 @@
6187 default:
6188 error = -EINVAL;
6189 }
6190+
6191+ if(!error)
6192+ gr_handle_create(dentry, nd.mnt);
6193+
6194 dput(dentry);
6195 }
6196+out_dput:
6197 up(&nd.dentry->d_inode->i_sem);
6198 path_release(&nd);
6199 out:
6200@@ -1352,7 +1432,16 @@
6201 if (!IS_ERR(dentry)) {
6202 if (!IS_POSIXACL(nd.dentry->d_inode))
6203 mode &= ~current->fs->umask;
6204- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6205+ error = 0;
6206+
6207+ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
6208+ error = -EACCES;
6209+
6210+ if(!error)
6211+ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6212+ if(!error)
6213+ gr_handle_create(dentry, nd.mnt);
6214+
6215 dput(dentry);
6216 }
6217 up(&nd.dentry->d_inode->i_sem);
6218@@ -1436,6 +1525,8 @@
6219 char * name;
6220 struct dentry *dentry;
6221 struct nameidata nd;
6222+ ino_t saved_ino = 0;
6223+ kdev_t saved_dev = 0;
6224
6225 name = getname(pathname);
6226 if(IS_ERR(name))
6227@@ -1460,7 +1551,22 @@
6228 dentry = lookup_hash(&nd.last, nd.dentry);
6229 error = PTR_ERR(dentry);
6230 if (!IS_ERR(dentry)) {
6231- error = vfs_rmdir(nd.dentry->d_inode, dentry);
6232+ error = 0;
6233+ if (dentry->d_inode) {
6234+ if (dentry->d_inode->i_nlink <= 1) {
6235+ saved_ino = dentry->d_inode->i_ino;
6236+ saved_dev = dentry->d_inode->i_dev;
6237+ }
6238+
6239+ if (!gr_acl_handle_rmdir(dentry, nd.mnt))
6240+ error = -EACCES;
6241+ }
6242+
6243+ if (!error)
6244+ error = vfs_rmdir(nd.dentry->d_inode, dentry);
6245+ if (!error && (saved_dev || saved_ino))
6246+ gr_handle_delete(saved_ino,saved_dev);
6247+
6248 dput(dentry);
6249 }
6250 up(&nd.dentry->d_inode->i_sem);
6251@@ -1505,6 +1611,8 @@
6252 char * name;
6253 struct dentry *dentry;
6254 struct nameidata nd;
6255+ ino_t saved_ino = 0;
6256+ kdev_t saved_dev = 0;
6257
6258 name = getname(pathname);
6259 if(IS_ERR(name))
6260@@ -1523,7 +1631,21 @@
6261 /* Why not before? Because we want correct error value */
6262 if (nd.last.name[nd.last.len])
6263 goto slashes;
6264- error = vfs_unlink(nd.dentry->d_inode, dentry);
6265+ error = 0;
6266+ if (dentry->d_inode) {
6267+ if (dentry->d_inode->i_nlink <= 1) {
6268+ saved_ino = dentry->d_inode->i_ino;
6269+ saved_dev = dentry->d_inode->i_dev;
6270+ }
6271+
6272+ if (!gr_acl_handle_unlink(dentry, nd.mnt))
6273+ error = -EACCES;
6274+ }
6275+
6276+ if (!error)
6277+ error = vfs_unlink(nd.dentry->d_inode, dentry);
6278+ if (!error && (saved_ino || saved_dev))
6279+ gr_handle_delete(saved_ino,saved_dev);
6280 exit2:
6281 dput(dentry);
6282 }
6283@@ -1587,7 +1709,15 @@
6284 dentry = lookup_create(&nd, 0);
6285 error = PTR_ERR(dentry);
6286 if (!IS_ERR(dentry)) {
6287- error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6288+ error = 0;
6289+
6290+ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
6291+ error = -EACCES;
6292+
6293+ if(!error)
6294+ error = vfs_symlink(nd.dentry->d_inode, dentry, from);
6295+ if (!error)
6296+ gr_handle_create(dentry, nd.mnt);
6297 dput(dentry);
6298 }
6299 up(&nd.dentry->d_inode->i_sem);
6300@@ -1671,7 +1801,27 @@
6301 new_dentry = lookup_create(&nd, 0);
6302 error = PTR_ERR(new_dentry);
6303 if (!IS_ERR(new_dentry)) {
6304- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
6305+ error = 0;
6306+
6307+ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
6308+ old_nd.dentry->d_inode,
6309+ old_nd.dentry->d_inode->i_mode, to)) {
6310+ error = -EPERM;
6311+ goto out_error;
6312+ }
6313+
6314+ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
6315+ old_nd.dentry, old_nd.mnt, to)) {
6316+ error = -EACCES;
6317+ goto out_error;
6318+ }
6319+
6320+ error = vfs_link(old_nd.dentry,
6321+ nd.dentry->d_inode, new_dentry);
6322+
6323+ if (!error)
6324+ gr_handle_create(new_dentry, nd.mnt);
6325+out_error:
6326 dput(new_dentry);
6327 }
6328 up(&nd.dentry->d_inode->i_sem);
6329@@ -1907,10 +2057,15 @@
6330 if (IS_ERR(new_dentry))
6331 goto exit4;
6332
6333- lock_kernel();
6334- error = vfs_rename(old_dir->d_inode, old_dentry,
6335+ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
6336+ old_dentry, old_dir->d_inode, oldnd.mnt, newname);
6337+
6338+ if (error == 1) {
6339+ lock_kernel();
6340+ error = vfs_rename(old_dir->d_inode, old_dentry,
6341 new_dir->d_inode, new_dentry);
6342- unlock_kernel();
6343+ unlock_kernel();
6344+ }
6345
6346 dput(new_dentry);
6347 exit4:
474a6d91
AM
6348diff -urN linux-2.4.22.org/fs/namespace.c linux-2.4.22/fs/namespace.c
6349--- linux-2.4.22.org/fs/namespace.c 2003-11-22 22:08:59.000000000 +0100
6350+++ linux-2.4.22/fs/namespace.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
6351@@ -15,6 +15,8 @@
6352 #include <linux/quotaops.h>
6353 #include <linux/acct.h>
6354 #include <linux/module.h>
6355+#include <linux/sched.h>
6356+#include <linux/grsecurity.h>
6357
6358 #include <asm/uaccess.h>
6359
6360@@ -325,6 +327,8 @@
6361 lock_kernel();
6362 retval = do_remount_sb(sb, MS_RDONLY, 0);
6363 unlock_kernel();
6364+
6365+ gr_log_remount(mnt->mnt_devname, retval);
6366 }
6367 up_write(&sb->s_umount);
6368 return retval;
6369@@ -350,6 +354,9 @@
6370 }
6371 spin_unlock(&dcache_lock);
6372 up_write(&current->namespace->sem);
6373+
6374+ gr_log_unmount(mnt->mnt_devname, retval);
6375+
6376 return retval;
6377 }
6378
6379@@ -729,6 +736,12 @@
6380 if (retval)
6381 return retval;
6382
6383+ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
6384+ retval = -EPERM;
6385+ path_release(&nd);
6386+ return retval;
6387+ }
6388+
6389 if (flags & MS_REMOUNT)
6390 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
6391 data_page);
6392@@ -740,6 +753,9 @@
6393 retval = do_add_mount(&nd, type_page, flags, mnt_flags,
6394 dev_name, data_page);
6395 path_release(&nd);
6396+
6397+ gr_log_mount(dev_name, dir_name, retval);
6398+
6399 return retval;
6400 }
6401
6402@@ -909,6 +925,9 @@
6403 if (!capable(CAP_SYS_ADMIN))
6404 return -EPERM;
6405
6406+ if (gr_handle_chroot_pivot())
6407+ return -EPERM;
6408+
6409 lock_kernel();
6410
6411 error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
474a6d91
AM
6412diff -urN linux-2.4.22.org/fs/open.c linux-2.4.22/fs/open.c
6413--- linux-2.4.22.org/fs/open.c 2003-11-22 22:08:59.000000000 +0100
6414+++ linux-2.4.22/fs/open.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
6415@@ -15,6 +15,7 @@
6416 #include <linux/slab.h>
6417 #include <linux/tty.h>
6418 #include <linux/iobuf.h>
6419+#include <linux/grsecurity.h>
6420
6421 #include <asm/uaccess.h>
6422
6423@@ -95,7 +96,7 @@
6424 write_unlock(&files->file_lock);
6425 }
6426
6427-int do_truncate(struct dentry *dentry, loff_t length)
6428+int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
6429 {
6430 struct inode *inode = dentry->d_inode;
6431 int error;
6432@@ -105,6 +106,9 @@
6433 if (length < 0)
6434 return -EINVAL;
6435
6436+ if (!gr_acl_handle_truncate(dentry, mnt))
6437+ return -EACCES;
6438+
6439 down_write(&inode->i_alloc_sem);
6440 down(&inode->i_sem);
6441 newattrs.ia_size = length;
6442@@ -165,7 +169,7 @@
6443 error = locks_verify_truncate(inode, NULL, length);
6444 if (!error) {
6445 DQUOT_INIT(inode);
6446- error = do_truncate(nd.dentry, length);
6447+ error = do_truncate(nd.dentry, length, nd.mnt);
6448 }
6449 put_write_access(inode);
6450
6451@@ -217,7 +221,7 @@
6452
6453 error = locks_verify_truncate(inode, file, length);
6454 if (!error)
6455- error = do_truncate(dentry, length);
6456+ error = do_truncate(dentry, length, file->f_vfsmnt);
6457 out_putf:
6458 fput(file);
6459 out:
474a6d91 6460@@ -292,6 +296,12 @@
8be839c4
JR
6461 (error = permission(inode,MAY_WRITE)) != 0)
6462 goto dput_and_out;
6463 }
6464+
6465+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6466+ error = -EACCES;
6467+ goto dput_and_out;
6468+ }
6469+
6470 error = notify_change(nd.dentry, &newattrs);
6471 dput_and_out:
6472 path_release(&nd);
474a6d91 6473@@ -344,6 +354,12 @@
8be839c4
JR
6474 (error = permission(inode,MAY_WRITE)) != 0)
6475 goto dput_and_out;
6476 }
6477+
6478+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6479+ error = -EACCES;
6480+ goto dput_and_out;
6481+ }
6482+
6483 error = notify_change(nd.dentry, &newattrs);
6484 dput_and_out:
6485 path_release(&nd);
474a6d91 6486@@ -386,6 +402,10 @@
8be839c4
JR
6487 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
6488 && !special_file(nd.dentry->d_inode->i_mode))
6489 res = -EROFS;
6490+
6491+ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
6492+ res = -EACCES;
6493+
6494 path_release(&nd);
6495 }
6496
474a6d91 6497@@ -409,6 +429,8 @@
8be839c4
JR
6498 if (error)
6499 goto dput_and_out;
6500
6501+ gr_log_chdir(nd.dentry, nd.mnt);
6502+
6503 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
6504
6505 dput_and_out:
474a6d91 6506@@ -439,6 +461,13 @@
8be839c4
JR
6507 goto out_putf;
6508
6509 error = permission(inode, MAY_EXEC);
6510+
6511+ if (!error && !gr_chroot_fchdir(dentry, mnt))
6512+ error = -EPERM;
6513+
6514+ if (!error)
6515+ gr_log_chdir(dentry, mnt);
6516+
6517 if (!error)
6518 set_fs_pwd(current->fs, mnt, dentry);
6519 out_putf:
474a6d91 6520@@ -465,8 +494,16 @@
8be839c4
JR
6521 if (!capable(CAP_SYS_CHROOT))
6522 goto dput_and_out;
6523
6524+ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
6525+ goto dput_and_out;
6526+
6527 set_fs_root(current->fs, nd.mnt, nd.dentry);
6528 set_fs_altroot();
6529+
6530+ gr_handle_chroot_caps(current);
6531+
6532+ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
6533+
6534 error = 0;
6535 dput_and_out:
6536 path_release(&nd);
474a6d91 6537@@ -495,8 +532,20 @@
8be839c4
JR
6538 err = -EPERM;
6539 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6540 goto out_putf;
6541+
6542+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
6543+ err = -EACCES;
6544+ goto out_putf;
6545+ }
6546+
6547 if (mode == (mode_t) -1)
6548 mode = inode->i_mode;
6549+
6550+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
6551+ err = -EPERM;
6552+ goto out_putf;
6553+ }
6554+
6555 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6556 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6557 err = notify_change(dentry, &newattrs);
474a6d91 6558@@ -527,8 +576,19 @@
8be839c4
JR
6559 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6560 goto dput_and_out;
6561
6562+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
6563+ error = -EACCES;
6564+ goto dput_and_out;
6565+ }
6566+
6567 if (mode == (mode_t) -1)
6568 mode = inode->i_mode;
6569+
6570+ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
6571+ error = -EACCES;
6572+ goto dput_and_out;
6573+ }
6574+
6575 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6576 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6577 error = notify_change(nd.dentry, &newattrs);
474a6d91 6578@@ -539,7 +599,7 @@
8be839c4
JR
6579 return error;
6580 }
6581
6582-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
6583+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
6584 {
6585 struct inode * inode;
6586 int error;
474a6d91 6587@@ -556,6 +616,12 @@
8be839c4
JR
6588 error = -EPERM;
6589 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6590 goto out;
6591+
6592+ if (!gr_acl_handle_chown(dentry, mnt)) {
6593+ error = -EACCES;
6594+ goto out;
6595+ }
6596+
6597 if (user == (uid_t) -1)
6598 user = inode->i_uid;
6599 if (group == (gid_t) -1)
474a6d91 6600@@ -606,7 +672,7 @@
8be839c4
JR
6601
6602 error = user_path_walk(filename, &nd);
6603 if (!error) {
6604- error = chown_common(nd.dentry, user, group);
6605+ error = chown_common(nd.dentry, user, group, nd.mnt);
6606 path_release(&nd);
6607 }
6608 return error;
474a6d91 6609@@ -619,7 +685,7 @@
8be839c4
JR
6610
6611 error = user_path_walk_link(filename, &nd);
6612 if (!error) {
6613- error = chown_common(nd.dentry, user, group);
6614+ error = chown_common(nd.dentry, user, group, nd.mnt);
6615 path_release(&nd);
6616 }
6617 return error;
474a6d91 6618@@ -633,7 +699,8 @@
8be839c4
JR
6619
6620 file = fget(fd);
6621 if (file) {
6622- error = chown_common(file->f_dentry, user, group);
6623+ error = chown_common(file->f_dentry, user,
6624+ group, file->f_vfsmnt);
6625 fput(file);
6626 }
6627 return error;
474a6d91 6628@@ -753,6 +820,7 @@
8be839c4
JR
6629 * N.B. For clone tasks sharing a files structure, this test
6630 * will limit the total number of files that can be opened.
6631 */
6632+ gr_learn_resource(current, RLIMIT_NOFILE, fd);
6633 if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6634 goto out;
6635
474a6d91
AM
6636diff -urN linux-2.4.22.org/fs/proc/array.c linux-2.4.22/fs/proc/array.c
6637--- linux-2.4.22.org/fs/proc/array.c 2003-11-22 22:08:59.000000000 +0100
6638+++ linux-2.4.22/fs/proc/array.c 2003-11-22 22:31:12.000000000 +0100
6639@@ -298,6 +298,12 @@
8be839c4
JR
6640 return buffer - orig;
6641 }
6642
6643+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6644+#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
6645+ task->flags & PF_PAX_SEGMEXEC || \
6646+ task->flags & PF_PAX_RANDEXEC)
6647+#endif
6648+
6649 int proc_pid_stat(struct task_struct *task, char * buffer)
6650 {
6651 unsigned long vsize, eip, esp, wchan;
474a6d91 6652@@ -335,6 +341,19 @@
8be839c4
JR
6653
6654 wchan = get_wchan(task);
6655
6656+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6657+ if (PAX_RAND_FLAGS) {
6658+ eip = 0;
6659+ esp = 0;
6660+ wchan = 0;
6661+ }
6662+#endif
6663+#ifdef CONFIG_GRKERNSEC_HIDESYM
6664+ wchan = 0;
6665+ eip = 0;
6666+ esp = 0;
6667+#endif
6668+
6669 collect_sigign_sigcatch(task, &sigign, &sigcatch);
6670
6671 /* scale priority and nice values from timeslices to -20..20 */
474a6d91 6672@@ -373,9 +392,15 @@
8be839c4
JR
6673 vsize,
6674 mm ? mm->rss : 0, /* you might want to shift this left 3 */
6675 task->rlim[RLIMIT_RSS].rlim_cur,
6676+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6677+ PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
6678+ PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
6679+ PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
6680+#else
6681 mm ? mm->start_code : 0,
6682 mm ? mm->end_code : 0,
6683 mm ? mm->start_stack : 0,
6684+#endif
6685 esp,
6686 eip,
6687 /* The signal information here is obsolete.
f6c0171e
JR
6688@@ -513,6 +538,7 @@
6689
6690 static int show_map(struct seq_file *m, void *v)
6691 {
6692+ struct task_struct *task = m->private;
6693 struct vm_area_struct *map = v;
6694 struct file *file = map->vm_file;
6695 int flags = map->vm_flags;
6696@@ -526,8 +551,13 @@
474a6d91 6697 }
8be839c4 6698
474a6d91 6699 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
f6c0171e
JR
6700+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6701+ PAX_RAND_FLAGS ? 0UL : map->vm_start,
6702+ PAX_RAND_FLAGS ? 0UL : map->vm_end,
6703+#else
474a6d91
AM
6704 map->vm_start,
6705 map->vm_end,
f6c0171e
JR
6706+#endif
6707 flags & VM_READ ? 'r' : '-',
6708 flags & VM_WRITE ? 'w' : '-',
6709 flags & VM_EXEC ? 'x' : '-',
474a6d91
AM
6710@@ -601,6 +643,16 @@
6711 .show = show_map
6712 };
8be839c4
JR
6713
6714+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6715+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
6716+{
6717+ int len;
6718+
6719+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
6720+ return len;
6721+}
6722+#endif
6723+
6724 #ifdef CONFIG_SMP
6725 int proc_pid_cpu(struct task_struct *task, char * buffer)
6726 {
474a6d91
AM
6727diff -urN linux-2.4.22.org/fs/proc/base.c linux-2.4.22/fs/proc/base.c
6728--- linux-2.4.22.org/fs/proc/base.c 2003-11-22 22:08:59.000000000 +0100
6729+++ linux-2.4.22/fs/proc/base.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
6730@@ -25,6 +25,7 @@
6731 #include <linux/string.h>
6732 #include <linux/seq_file.h>
6733 #include <linux/namespace.h>
6734+#include <linux/grsecurity.h>
6735
6736 /*
6737 * For hysterical raisins we keep the same inumbers as in the old procfs.
474a6d91 6738@@ -40,6 +41,9 @@
8be839c4
JR
6739 int proc_pid_status(struct task_struct*,char*);
6740 int proc_pid_statm(struct task_struct*,char*);
6741 int proc_pid_cpu(struct task_struct*,char*);
6742+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6743+int proc_pid_ipaddr(struct task_struct*,char*);
6744+#endif
6745
6746 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
6747 {
474a6d91 6748@@ -263,9 +267,22 @@
8be839c4
JR
6749
6750 static int proc_permission(struct inode *inode, int mask)
6751 {
6752+ int ret;
6753+ struct task_struct *task;
6754+
6755 if (vfs_permission(inode, mask) != 0)
6756 return -EACCES;
6757- return proc_check_root(inode);
6758+ ret = proc_check_root(inode);
6759+
6760+ if (ret)
6761+ return ret;
6762+
6763+ task = inode->u.proc_i.task;
6764+
6765+ if (!task)
6766+ return 0;
6767+
6768+ return gr_acl_handle_procpidmem(task);
6769 }
6770
474a6d91
AM
6771 extern struct seq_operations proc_pid_maps_op;
6772@@ -598,6 +615,9 @@
8be839c4
JR
6773 PROC_PID_STATM,
6774 PROC_PID_MAPS,
6775 PROC_PID_CPU,
6776+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6777+ PROC_PID_IPADDR,
6778+#endif
6779 PROC_PID_MOUNTS,
6780 PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */
6781 };
474a6d91 6782@@ -613,6 +633,9 @@
8be839c4
JR
6783 #ifdef CONFIG_SMP
6784 E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUGO),
6785 #endif
6786+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6787+ E(PROC_PID_IPADDR, "ipaddr", S_IFREG|S_IRUSR),
6788+#endif
6789 E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUGO),
6790 E(PROC_PID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
6791 E(PROC_PID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
474a6d91 6792@@ -769,10 +792,17 @@
8be839c4
JR
6793 get_task_struct(task);
6794 inode->u.proc_i.task = task;
6795 inode->i_uid = 0;
6796+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6797+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6798+#else
6799 inode->i_gid = 0;
6800+#endif
6801+
6802 if (ino == PROC_PID_INO || task_dumpable(task)) {
6803 inode->i_uid = task->euid;
6804+#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
6805 inode->i_gid = task->egid;
6806+#endif
6807 }
6808
6809 out:
474a6d91 6810@@ -980,6 +1010,12 @@
8be839c4
JR
6811 inode->u.proc_i.op.proc_read = proc_pid_cpu;
6812 break;
6813 #endif
6814+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6815+ case PROC_PID_IPADDR:
6816+ inode->i_fop = &proc_info_file_operations;
6817+ inode->u.proc_i.op.proc_read = proc_pid_ipaddr;
6818+ break;
6819+#endif
6820 case PROC_PID_MEM:
6821 inode->i_op = &proc_mem_inode_operations;
6822 inode->i_fop = &proc_mem_operations;
474a6d91 6823@@ -1078,13 +1114,34 @@
8be839c4
JR
6824 if (!task)
6825 goto out;
6826
6827+ if(gr_check_hidden_task(task)) {
6828+ free_task_struct(task);
6829+ goto out;
6830+ }
6831+
6832+#ifdef CONFIG_GRKERNSEC_PROC
6833+ if (current->uid && (task->uid != current->uid)
6834+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6835+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
6836+#endif
6837+ ) {
6838+ free_task_struct(task);
6839+ goto out;
6840+ }
6841+#endif
6842 inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
6843
6844 free_task_struct(task);
6845
6846 if (!inode)
6847 goto out;
6848+#ifdef CONFIG_GRKERNSEC_PROC_USER
6849+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
6850+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6851+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
6852+#else
6853 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
6854+#endif
6855 inode->i_op = &proc_base_inode_operations;
6856 inode->i_fop = &proc_base_operations;
6857 inode->i_nlink = 3;
474a6d91 6858@@ -1124,6 +1181,18 @@
8be839c4
JR
6859 int pid = p->pid;
6860 if (!pid)
6861 continue;
6862+ if(gr_pid_is_chrooted(p))
6863+ continue;
6864+ if(gr_check_hidden_task(p))
6865+ continue;
6866+#ifdef CONFIG_GRKERNSEC_PROC
6867+ if (current->uid && (p->uid != current->uid)
6868+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6869+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
6870+#endif
6871+ )
6872+ continue;
6873+#endif
6874 if (--index >= 0)
6875 continue;
6876 pids[nr_pids] = pid;
474a6d91
AM
6877diff -urN linux-2.4.22.org/fs/proc/generic.c linux-2.4.22/fs/proc/generic.c
6878--- linux-2.4.22.org/fs/proc/generic.c 2003-11-22 22:08:59.000000000 +0100
6879+++ linux-2.4.22/fs/proc/generic.c 2003-11-22 22:14:07.000000000 +0100
6880@@ -504,6 +504,32 @@
8be839c4
JR
6881 return ent;
6882 }
6883
6884+#ifdef CONFIG_GRKERNSEC_PROC
6885+struct proc_dir_entry *proc_priv_mkdir(const char *name, struct proc_dir_entry *parent)
6886+{
6887+ struct proc_dir_entry *ent;
6888+ mode_t mode = 0;
6889+
6890+#ifdef CONFIG_GRKERNSEC_PROC_USER
6891+ mode = S_IFDIR | S_IRUSR | S_IXUSR;
6892+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6893+ mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP;
6894+#endif
6895+
6896+ ent = proc_create(&parent, name, mode, 2);
6897+ if (ent) {
6898+ ent->proc_fops = &proc_dir_operations;
6899+ ent->proc_iops = &proc_dir_inode_operations;
6900+
6901+ if (proc_register(parent, ent) < 0) {
6902+ kfree(ent);
6903+ ent = NULL;
6904+ }
6905+ }
6906+ return ent;
6907+}
6908+#endif
6909+
6910 struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
6911 struct proc_dir_entry *parent)
6912 {
474a6d91
AM
6913diff -urN linux-2.4.22.org/fs/proc/inode.c linux-2.4.22/fs/proc/inode.c
6914--- linux-2.4.22.org/fs/proc/inode.c 2003-11-22 22:08:59.000000000 +0100
6915+++ linux-2.4.22/fs/proc/inode.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
6916@@ -152,7 +152,11 @@
6917 if (de->mode) {
6918 inode->i_mode = de->mode;
6919 inode->i_uid = de->uid;
6920+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6921+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6922+#else
6923 inode->i_gid = de->gid;
6924+#endif
6925 }
6926 if (de->size)
6927 inode->i_size = de->size;
207c73d5
AM
6928
6929diff -urN linux-2.4.23/fs/proc/proc_misc.c linux-2.4.23/fs/proc/proc_misc.c
6930--- linux-2.4.23/fs/proc/proc_misc.c 2003-11-28 13:26:21.000000000 -0500
6931+++ linux-2.4.23/fs/proc/proc_misc.c 2003-11-30 16:37:16.000000000 -0500
474a6d91 6932@@ -590,6 +590,7 @@
8be839c4
JR
6933 void __init proc_misc_init(void)
6934 {
6935 struct proc_dir_entry *entry;
6936+ int gr_mode = 0;
6937 static struct {
6938 char *name;
6939 int (*read_proc)(char*,char**,off_t,int,int*,void*);
474a6d91 6940@@ -604,17 +605,21 @@
8be839c4
JR
6941 #ifdef CONFIG_STRAM_PROC
6942 {"stram", stram_read_proc},
6943 #endif
6944-#ifdef CONFIG_MODULES
207c73d5 6945+#if defined(CONFIG_MODULES) && !defined(CONFIG_GRKERNSEC_PROC)
8be839c4
JR
6946 {"modules", modules_read_proc},
6947 #endif
6948 {"stat", kstat_read_proc},
6949+#ifndef CONFIG_GRKERNSEC_PROC_ADD
6950 {"devices", devices_read_proc},
474a6d91 6951-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
8be839c4 6952+#endif
474a6d91 6953+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
8be839c4
JR
6954 {"interrupts", interrupts_read_proc},
6955 #endif
6956 {"filesystems", filesystems_read_proc},
6957+#ifndef CONFIG_GRKERNSEC_PROC_ADD
6958 {"dma", dma_read_proc},
8be839c4
JR
6959 {"cmdline", cmdline_read_proc},
6960+#endif
6961 #ifdef CONFIG_SGI_DS1286
6962 {"rtc", ds1286_read_proc},
6963 #endif
207c73d5 6964@@ -626,29 +631,60 @@
8be839c4
JR
6965 for (p = simple_ones; p->name; p++)
6966 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
6967
6968+#ifdef CONFIG_GRKERNSEC_PROC_USER
207c73d5 6969+ gr_mode = S_IRUSR;
8be839c4 6970+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
207c73d5 6971+ gr_mode = S_IRUSR | S_IRGRP;
8be839c4 6972+#endif
8be839c4 6973+#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES)
207c73d5 6974+ create_proc_read_entry("modules", gr_mode, NULL, &modules_read_proc, NULL);
8be839c4
JR
6975+#endif
6976+#ifdef CONFIG_GRKERNSEC_PROC_ADD
207c73d5
AM
6977+ create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
6978+ create_proc_read_entry("dma", gr_mode, NULL, &dma_read_proc, NULL);
6979+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
6980+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86)
6981+ create_proc_read_entry("interrupts", gr_mode, NULL, &interrupts_read_proc, NULL);
8be839c4
JR
6982+#endif
6983+#endif
6984+
6985 proc_symlink("mounts", NULL, "self/mounts");
6986
6987 /* And now for trickier ones */
6988 entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
6989 if (entry)
6990 entry->proc_fops = &proc_kmsg_operations;
6991+#ifdef CONFIG_GRKERNSEC_PROC_ADD
6992+ create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
8be839c4
JR
6993+#else
6994 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
207c73d5 6995-#if defined(CONFIG_X86)
474a6d91 6996+#endif
207c73d5
AM
6997+#if defined(CONFIG_X86) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
6998 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
6999+#elif defined(CONFIG_X86)
474a6d91
AM
7000+ create_seq_entry("interrupts", gr_mode, &proc_interrupts_operations);
7001 #endif
207c73d5
AM
7002+#ifdef CONFIG_GRKERNSEC_PROC_ADD
7003+ create_seq_entry("ioports", gr_mode, &proc_ioports_operations);
7004+ create_seq_entry("iomem", gr_mode, &proc_iomem_operations);
7005+ create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
7006+#else
474a6d91
AM
7007 create_seq_entry("ioports", 0, &proc_ioports_operations);
7008 create_seq_entry("iomem", 0, &proc_iomem_operations);
207c73d5
AM
7009- create_seq_entry("partitions", 0, &proc_partitions_operations);
7010 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
8be839c4 7011+#endif
207c73d5 7012+ create_seq_entry("partitions", 0, &proc_partitions_operations);
8be839c4
JR
7013 #ifdef CONFIG_MODULES
7014- create_seq_entry("ksyms", 0, &proc_ksyms_operations);
7015+ create_seq_entry("ksyms", gr_mode, &proc_ksyms_operations);
7016 #endif
7017+#ifndef CONFIG_GRKERNSEC_PROC_ADD
7018 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
7019 if (proc_root_kcore) {
7020 proc_root_kcore->proc_fops = &proc_kcore_operations;
7021 proc_root_kcore->size =
7022 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
7023 }
7024+#endif
7025 if (prof_shift) {
7026 entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
7027 if (entry) {
474a6d91
AM
7028diff -urN linux-2.4.22.org/fs/proc/proc_tty.c linux-2.4.22/fs/proc/proc_tty.c
7029--- linux-2.4.22.org/fs/proc/proc_tty.c 2003-11-22 22:09:00.000000000 +0100
7030+++ linux-2.4.22/fs/proc/proc_tty.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
7031@@ -174,7 +174,11 @@
7032 if (!proc_mkdir("tty", 0))
7033 return;
7034 proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
7035+#ifdef CONFIG_GRKERNSEC_PROC
7036+ proc_tty_driver = proc_priv_mkdir("tty/driver", 0);
7037+#else
7038 proc_tty_driver = proc_mkdir("tty/driver", 0);
7039+#endif
7040
7041 create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
7042 create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
474a6d91
AM
7043diff -urN linux-2.4.22.org/fs/proc/root.c linux-2.4.22/fs/proc/root.c
7044--- linux-2.4.22.org/fs/proc/root.c 2003-11-22 22:08:59.000000000 +0100
7045+++ linux-2.4.22/fs/proc/root.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
7046@@ -37,13 +37,21 @@
7047 return;
7048 }
7049 proc_misc_init();
7050+#ifdef CONFIG_GRKERNSEC_PROC
7051+ proc_net = proc_priv_mkdir("net", 0);
7052+#else
7053 proc_net = proc_mkdir("net", 0);
7054+#endif
7055 #ifdef CONFIG_SYSVIPC
7056 proc_mkdir("sysvipc", 0);
7057 #endif
7058 #ifdef CONFIG_SYSCTL
7059+#ifdef CONFIG_GRKERNSEC_PROC
7060+ proc_sys_root = proc_priv_mkdir("sys", 0);
7061+#else
7062 proc_sys_root = proc_mkdir("sys", 0);
7063 #endif
7064+#endif
7065 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
7066 proc_mkdir("sys/fs", 0);
7067 proc_mkdir("sys/fs/binfmt_misc", 0);
7068@@ -67,7 +75,12 @@
7069 #ifdef CONFIG_PPC_RTAS
7070 proc_rtas_init();
7071 #endif
7072+
7073+#ifdef CONFIG_GRKERNSEC_PROC_ADD
7074+ proc_bus = proc_priv_mkdir("bus", 0);
7075+#else
7076 proc_bus = proc_mkdir("bus", 0);
7077+#endif
7078 }
7079
7080 static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
474a6d91
AM
7081diff -urN linux-2.4.22.org/fs/readdir.c linux-2.4.22/fs/readdir.c
7082--- linux-2.4.22.org/fs/readdir.c 2003-11-22 22:08:59.000000000 +0100
7083+++ linux-2.4.22/fs/readdir.c 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
7084@@ -10,6 +10,7 @@
7085 #include <linux/stat.h>
7086 #include <linux/file.h>
7087 #include <linux/smp_lock.h>
7088+#include <linux/grsecurity.h>
7089
7090 #include <asm/uaccess.h>
7091
7092@@ -181,6 +182,7 @@
7093 struct readdir_callback {
7094 struct old_linux_dirent * dirent;
7095 int count;
7096+ struct nameidata nd;
7097 };
7098
7099 static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
7100@@ -191,6 +193,10 @@
7101
7102 if (buf->count)
7103 return -EINVAL;
7104+
7105+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7106+ return 0;
7107+
7108 buf->count++;
7109 dirent = buf->dirent;
7110 put_user(ino, &dirent->d_ino);
7111@@ -215,6 +221,9 @@
7112 buf.count = 0;
7113 buf.dirent = dirent;
7114
7115+ buf.nd.dentry = file->f_dentry;
7116+ buf.nd.mnt = file->f_vfsmnt;
7117+
7118 error = vfs_readdir(file, fillonedir, &buf);
7119 if (error >= 0)
7120 error = buf.count;
7121@@ -242,6 +251,7 @@
7122 struct linux_dirent * previous;
7123 int count;
7124 int error;
7125+ struct nameidata nd;
7126 };
7127
7128 static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
7129@@ -254,6 +264,10 @@
7130 buf->error = -EINVAL; /* only used if we fail.. */
7131 if (reclen > buf->count)
7132 return -EINVAL;
7133+
7134+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7135+ return 0;
7136+
7137 dirent = buf->previous;
7138 if (dirent)
7139 put_user(offset, &dirent->d_off);
7140@@ -286,6 +300,9 @@
7141 buf.count = count;
7142 buf.error = 0;
7143
7144+ buf.nd.dentry = file->f_dentry;
7145+ buf.nd.mnt = file->f_vfsmnt;
7146+
7147 error = vfs_readdir(file, filldir, &buf);
7148 if (error < 0)
7149 goto out_putf;
7150@@ -320,6 +337,7 @@
7151 struct linux_dirent64 * previous;
7152 int count;
7153 int error;
7154+ struct nameidata nd;
7155 };
7156
7157 static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
7158@@ -332,6 +350,10 @@
7159 buf->error = -EINVAL; /* only used if we fail.. */
7160 if (reclen > buf->count)
7161 return -EINVAL;
7162+
7163+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7164+ return 0;
7165+
7166 dirent = buf->previous;
7167 if (dirent) {
7168 d.d_off = offset;
7169@@ -369,6 +391,9 @@
7170 buf.count = count;
7171 buf.error = 0;
7172
7173+ buf.nd.mnt = file->f_vfsmnt;
7174+ buf.nd.dentry = file->f_dentry;
7175+
7176 error = vfs_readdir(file, filldir64, &buf);
7177 if (error < 0)
7178 goto out_putf;
474a6d91
AM
7179diff -urN linux-2.4.22.org/grsecurity/Config.in linux-2.4.22/grsecurity/Config.in
7180--- linux-2.4.22.org/grsecurity/Config.in 1970-01-01 01:00:00.000000000 +0100
7181+++ linux-2.4.22/grsecurity/Config.in 2003-11-22 22:14:07.000000000 +0100
8be839c4
JR
7182@@ -0,0 +1,366 @@
7183+define_bool CONFIG_CRYPTO y
7184+define_bool CONFIG_CRYPTO_SHA256 y
7185+choice 'Security level' \
7186+ "Low CONFIG_GRKERNSEC_LOW \
7187+ Medium CONFIG_GRKERNSEC_MID \
7188+ High CONFIG_GRKERNSEC_HI \
7189+ Customized CONFIG_GRKERNSEC_CUSTOM" Customized
7190+if [ "$CONFIG_GRKERNSEC_LOW" = "y" ]; then
7191+define_bool CONFIG_GRKERNSEC_RANDSRC n
7192+define_bool CONFIG_GRKERNSEC_RANDRPC n
7193+define_bool CONFIG_GRKERNSEC_FORKFAIL n
7194+define_bool CONFIG_GRKERNSEC_TIME n
7195+define_bool CONFIG_GRKERNSEC_SIGNAL n
7196+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7197+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT n
7198+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7199+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE n
7200+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT n
7201+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD n
7202+define_bool CONFIG_GRKERNSEC_PROC n
7203+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7204+define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
7205+define_bool CONFIG_GRKERNSEC_HIDESYM n
7206+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7207+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n
7208+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n
7209+define_bool CONFIG_GRKERNSEC_KMEM n
7210+define_bool CONFIG_GRKERNSEC_PROC_ADD n
7211+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7212+define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7213+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7214+define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK n
7215+define_bool CONFIG_GRKERNSEC_PAX_ASLR n
7216+define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP n
7217+define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7218+define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7219+define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7220+define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7221+define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7222+if [ "$CONFIG_X86" = "y" ]; then
7223+define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7224+define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7225+define_bool CONFIG_GRKERNSEC_IO n
7226+define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7227+define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7228+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7229+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7230+fi
7231+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7232+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7233+define_bool CONFIG_GRKERNSEC_RESLOG n
7234+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7235+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7236+
7237+define_int CONFIG_GRKERNSEC_FLOODTIME 10
7238+define_int CONFIG_GRKERNSEC_FLOODBURST 4
7239+define_bool CONFIG_GRKERNSEC_LINK y
7240+define_bool CONFIG_GRKERNSEC_FIFO y
7241+define_bool CONFIG_GRKERNSEC_RANDPID y
7242+define_bool CONFIG_GRKERNSEC_EXECVE y
7243+define_bool CONFIG_GRKERNSEC_RANDNET y
7244+define_bool CONFIG_GRKERNSEC_RANDISN n
7245+define_bool CONFIG_GRKERNSEC_DMESG y
7246+define_bool CONFIG_GRKERNSEC_RANDID y
7247+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7248+fi
7249+if [ "$CONFIG_GRKERNSEC_MID" = "y" ]; then
7250+define_bool CONFIG_GRKERNSEC_KMEM n
7251+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7252+define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
7253+define_bool CONFIG_GRKERNSEC_HIDESYM n
7254+define_bool CONFIG_GRKERNSEC_PROC_ADD n
7255+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
7256+define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
7257+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
7258+define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
7259+define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7260+define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7261+define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7262+define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
7263+if [ "$CONFIG_X86" = "y" ]; then
7264+define_bool CONFIG_GRKERNSEC_IO n
7265+define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
7266+define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
7267+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7268+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7269+fi
7270+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7271+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
7272+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7273+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7274+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
7275+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7276+define_bool CONFIG_GRKERNSEC_RESLOG n
7277+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7278+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7279+
7280+define_int CONFIG_GRKERNSEC_FLOODTIME 10
7281+define_int CONFIG_GRKERNSEC_FLOODBURST 4
7282+define_bool CONFIG_GRKERNSEC_LINK y
7283+define_bool CONFIG_GRKERNSEC_FIFO y
7284+define_bool CONFIG_GRKERNSEC_RANDPID y
7285+define_bool CONFIG_GRKERNSEC_EXECVE y
7286+define_bool CONFIG_GRKERNSEC_DMESG y
7287+define_bool CONFIG_GRKERNSEC_RANDID y
7288+define_bool CONFIG_GRKERNSEC_RANDNET y
7289+define_bool CONFIG_GRKERNSEC_RANDISN y
7290+define_bool CONFIG_GRKERNSEC_RANDSRC y
7291+define_bool CONFIG_GRKERNSEC_RANDRPC y
7292+define_bool CONFIG_GRKERNSEC_FORKFAIL y
7293+define_bool CONFIG_GRKERNSEC_TIME y
7294+define_bool CONFIG_GRKERNSEC_SIGNAL y
7295+define_bool CONFIG_GRKERNSEC_CHROOT y
7296+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
7297+define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7298+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7299+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7300+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7301+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7302+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7303+define_bool CONFIG_GRKERNSEC_PROC y
7304+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7305+define_int CONFIG_GRKERNSEC_PROC_GID 10
7306+define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7307+define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
7308+define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
7309+define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7310+define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7311+fi
7312+if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then
7313+define_int CONFIG_GRKERNSEC_FLOODTIME 10
7314+define_int CONFIG_GRKERNSEC_FLOODBURST 4
7315+define_bool CONFIG_GRKERNSEC_LINK y
7316+define_bool CONFIG_GRKERNSEC_FIFO y
7317+define_bool CONFIG_GRKERNSEC_RANDPID y
7318+define_bool CONFIG_GRKERNSEC_EXECVE y
7319+define_bool CONFIG_GRKERNSEC_DMESG y
7320+define_bool CONFIG_GRKERNSEC_RANDID y
7321+define_bool CONFIG_GRKERNSEC_RANDSRC y
7322+define_bool CONFIG_GRKERNSEC_RANDRPC y
7323+define_bool CONFIG_GRKERNSEC_FORKFAIL y
7324+define_bool CONFIG_GRKERNSEC_TIME y
7325+define_bool CONFIG_GRKERNSEC_SIGNAL y
7326+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT y
7327+define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
7328+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
7329+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR y
7330+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
7331+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
7332+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
7333+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
7334+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS y
7335+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
7336+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK y
7337+define_bool CONFIG_GRKERNSEC_PROC y
7338+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
7339+define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y
7340+define_bool CONFIG_GRKERNSEC_HIDESYM y
7341+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
7342+define_int CONFIG_GRKERNSEC_PROC_GID 10
7343+define_bool CONFIG_GRKERNSEC_KMEM y
7344+define_bool CONFIG_GRKERNSEC_RESLOG y
7345+define_bool CONFIG_GRKERNSEC_RANDNET y
7346+define_bool CONFIG_GRKERNSEC_RANDISN y
7347+
7348+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
7349+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
7350+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7351+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7352+
7353+define_bool CONFIG_GRKERNSEC_PROC_ADD y
7354+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD y
7355+define_bool CONFIG_GRKERNSEC_CHROOT_NICE y
7356+define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
7357+define_bool CONFIG_GRKERNSEC_PAX_ASLR y
7358+define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
7359+define_bool CONFIG_GRKERNSEC_PAX_NOEXEC y
7360+define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
7361+define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
7362+define_bool CONFIG_GRKERNSEC_PAX_MPROTECT y
7363+define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
7364+if [ "$CONFIG_X86" = "y" ]; then
7365+define_bool CONFIG_GRKERNSEC_IO n
7366+if [ "$CONFIG_MODULES" = "n" ]; then
7367+define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC y
7368+fi
7369+define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK y
7370+define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC y
7371+define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC y
7372+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
7373+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
7374+fi
7375+if [ "$CONFIG_PARISC" = "y" ]; then
7376+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP y
7377+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT y
7378+fi
7379+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT y
7380+fi
7381+if [ "$CONFIG_GRKERNSEC_CUSTOM" = "y" ]; then
7382+mainmenu_option next_comment
7383+comment 'Address Space Protection'
7384+bool 'Enforce non-executable pages' CONFIG_GRKERNSEC_PAX_NOEXEC
7385+if [ "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7386+ bool 'Paging based non-executable pages' CONFIG_GRKERNSEC_PAX_PAGEEXEC
7387+ if [ "$CONFIG_X86" = "y" ]; then
7388+ bool 'Segmentation based non-executable pages' CONFIG_GRKERNSEC_PAX_SEGMEXEC
7389+ fi
7390+ if [ "$CONFIG_X86" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7391+ if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7392+ bool ' Emulate trampolines' CONFIG_GRKERNSEC_PAX_EMUTRAMP
7393+ if [ "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then
7394+ bool ' Automatically emulate sigreturn trampolines' CONFIG_GRKERNSEC_PAX_EMUSIGRT
7395+ fi
7396+ fi
7397+ fi
7398+ bool ' Restrict mprotect()' CONFIG_GRKERNSEC_PAX_MPROTECT
7399+ if [ "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then
7400+ if [ "$CONFIG_X86" = "y" ]; then
7401+ bool ' Disallow ELF text relocations (DANGEROUS)' CONFIG_GRKERNSEC_PAX_NOELFRELOCS
7402+ else
7403+ if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" ]; then
7404+ bool ' Allow ELF ET_EXEC text relocations' CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
7405+ fi
7406+ if [ "$CONFIG_PPC32" = "y" ]; then
7407+ define_bool CONFIG_GRKERNSEC_PAX_SYSCALL y
7408+ fi
7409+ if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" -o "$CONFIG_PPC32" = "y" ]; then
7410+ bool ' Automatically emulate ELF PLT' CONFIG_GRKERNSEC_PAX_EMUPLT
7411+ if [ "$CONFIG_GRKERNSEC_PAX_EMUPLT" = "y" ]; then
7412+ if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
7413+ define_bool CONFIG_GRKERNSEC_PAX_DLRESOLVE y
7414+ fi
7415+ fi
7416+ fi
7417+ fi
7418+ fi
7419+fi
7420+if [ "$CONFIG_X86" = "y" -a "$CONFIG_MODULES" = "n" ]; then
7421+ bool 'Enforce non-executable kernel pages' CONFIG_GRKERNSEC_PAX_KERNEXEC
7422+fi
7423+bool 'Address Space Layout Randomization' CONFIG_GRKERNSEC_PAX_ASLR
7424+if [ "$CONFIG_GRKERNSEC_PAX_ASLR" = "y" ]; then
7425+ if [ "$CONFIG_X86_TSC" = "y" ]; then
7426+ bool ' Randomize kernel stack base' CONFIG_GRKERNSEC_PAX_RANDKSTACK
7427+ fi
7428+ bool ' Randomize user stack base' CONFIG_GRKERNSEC_PAX_RANDUSTACK
7429+ bool ' Randomize mmap() base' CONFIG_GRKERNSEC_PAX_RANDMMAP
7430+ if [ "$CONFIG_GRKERNSEC_PAX_RANDMMAP" = "y" -a "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
7431+ if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
7432+ bool ' Randomize ET_EXEC base' CONFIG_GRKERNSEC_PAX_RANDEXEC
7433+ fi
7434+ fi
7435+fi
7436+bool 'Deny writing to /dev/kmem, /dev/mem, and /dev/port' CONFIG_GRKERNSEC_KMEM
7437+if [ "$CONFIG_X86" = "y" ]; then
7438+ bool 'Disable privileged I/O' CONFIG_GRKERNSEC_IO
7439+ if [ "$CONFIG_GRKERNSEC_IO" = "y" ]; then
7440+ define_bool CONFIG_RTC y
7441+ fi
7442+fi
7443+bool 'Remove addresses from /proc/pid/[maps|stat]' CONFIG_GRKERNSEC_PROC_MEMMAP
7444+bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM
7445+endmenu
7446+mainmenu_option next_comment
7447+comment 'Role Based Access Control Options'
7448+bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN
7449+int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3
7450+int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30
7451+endmenu
7452+mainmenu_option next_comment
7453+comment 'Filesystem Protections'
7454+bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC
7455+if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then
7456+ bool ' Restrict to user only' CONFIG_GRKERNSEC_PROC_USER
7457+ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then
7458+ bool ' Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP
7459+ if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7460+ int ' GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001
7461+ fi
7462+ fi
7463+ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "n" -o "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
7464+ bool ' Additional restrictions' CONFIG_GRKERNSEC_PROC_ADD
7465+ fi
7466+fi
7467+bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK
7468+bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO
7469+bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT
7470+if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then
7471+bool ' Deny mounts' CONFIG_GRKERNSEC_CHROOT_MOUNT
7472+bool ' Deny double-chroots' CONFIG_GRKERNSEC_CHROOT_DOUBLE
7473+bool ' Deny pivot_root in chroot' CONFIG_GRKERNSEC_CHROOT_PIVOT
7474+bool ' Enforce chdir("/") on all chroots' CONFIG_GRKERNSEC_CHROOT_CHDIR
7475+bool ' Deny (f)chmod +s' CONFIG_GRKERNSEC_CHROOT_CHMOD
7476+bool ' Deny fchdir out of chroot' CONFIG_GRKERNSEC_CHROOT_FCHDIR
7477+bool ' Deny mknod' CONFIG_GRKERNSEC_CHROOT_MKNOD
7478+bool ' Deny shmat() out of chroot' CONFIG_GRKERNSEC_CHROOT_SHMAT
7479+bool ' Deny access to abstract AF_UNIX sockets out of chroot' CONFIG_GRKERNSEC_CHROOT_UNIX
7480+bool ' Protect outside processes' CONFIG_GRKERNSEC_CHROOT_FINDTASK
7481+bool ' Restrict priority changes' CONFIG_GRKERNSEC_CHROOT_NICE
7482+bool ' Deny sysctl writes in chroot' CONFIG_GRKERNSEC_CHROOT_SYSCTL
7483+bool ' Capability restrictions within chroot' CONFIG_GRKERNSEC_CHROOT_CAPS
7484+fi
7485+endmenu
7486+mainmenu_option next_comment
7487+comment 'Kernel Auditing'
7488+bool 'Single group for auditing' CONFIG_GRKERNSEC_AUDIT_GROUP
7489+if [ "$CONFIG_GRKERNSEC_AUDIT_GROUP" != "n" ]; then
7490+int ' GID for auditing' CONFIG_GRKERNSEC_AUDIT_GID 1007
7491+fi
7492+bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG
7493+bool 'Resource logging' CONFIG_GRKERNSEC_RESLOG
7494+bool 'Log execs within chroot' CONFIG_GRKERNSEC_CHROOT_EXECLOG
7495+bool 'Chdir logging' CONFIG_GRKERNSEC_AUDIT_CHDIR
7496+bool '(Un)Mount logging' CONFIG_GRKERNSEC_AUDIT_MOUNT
7497+bool 'IPC logging' CONFIG_GRKERNSEC_AUDIT_IPC
7498+bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL
7499+bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL
7500+bool 'Time change logging' CONFIG_GRKERNSEC_TIME
7501+bool '/proc/<pid>/ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR
7502+endmenu
7503+mainmenu_option next_comment
7504+comment 'Executable Protections'
7505+bool 'Enforce RLIMIT_NPROC on execs' CONFIG_GRKERNSEC_EXECVE
7506+bool 'Dmesg(8) restriction' CONFIG_GRKERNSEC_DMESG
7507+bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID
7508+bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE
7509+if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then
7510+bool ' Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
7511+int ' GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
7512+fi
7513+endmenu
7514+mainmenu_option next_comment
7515+comment 'Network Protections'
7516+bool 'Larger entropy pools' CONFIG_GRKERNSEC_RANDNET
7517+bool 'Truly random TCP ISN selection' CONFIG_GRKERNSEC_RANDISN
7518+bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID
7519+bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC
7520+bool 'Randomized RPC XIDs' CONFIG_GRKERNSEC_RANDRPC
7521+bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET
7522+if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then
7523+bool ' Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL
7524+if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then
7525+int ' GID to deny all sockets for:' CONFIG_GRKERNSEC_SOCKET_ALL_GID 1004
7526+fi
7527+bool ' Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT
7528+if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then
7529+int ' GID to deny client sockets for:' CONFIG_GRKERNSEC_SOCKET_CLIENT_GID 1003
7530+fi
7531+bool ' Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER
7532+if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then
7533+int ' GID to deny server sockets for:' CONFIG_GRKERNSEC_SOCKET_SERVER_GID 1002
7534+fi
7535+fi
7536+endmenu
7537+if [ "$CONFIG_SYSCTL" != "n" ]; then
7538+mainmenu_option next_comment
7539+comment 'Sysctl support'
7540+bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL
7541+endmenu
7542+fi
7543+mainmenu_option next_comment
7544+comment 'Logging options'
7545+int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10
7546+int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4
7547+endmenu
7548+fi
474a6d91
AM
7549diff -urN linux-2.4.22.org/grsecurity/gracl_alloc.c linux-2.4.22/grsecurity/gracl_alloc.c
7550--- linux-2.4.22.org/grsecurity/gracl_alloc.c 1970-01-01 01:00:00.000000000 +0100
7551+++ linux-2.4.22/grsecurity/gracl_alloc.c 2003-11-22 22:14:08.000000000 +0100
7552@@ -0,0 +1,94 @@
7553+/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
7554+
7555+#include <linux/kernel.h>
7556+#include <linux/mm.h>
7557+#include <linux/slab.h>
7558+#include <linux/vmalloc.h>
7559+#include <linux/gracl.h>
7560+#include <linux/grsecurity.h>
7561+
7562+static unsigned long alloc_stack_next = 1;
7563+static unsigned long alloc_stack_size = 1;
7564+static void **alloc_stack;
7565+
7566+static __inline__ int
7567+alloc_pop(void)
7568+{
7569+ if ((alloc_stack_next - 1) == 0)
7570+ return 0;
8be839c4 7571+
474a6d91
AM
7572+ if (*(alloc_stack + alloc_stack_next - 2))
7573+ kfree(*(alloc_stack + alloc_stack_next - 2));
8be839c4 7574+
474a6d91 7575+ alloc_stack_next--;
8be839c4 7576+
474a6d91
AM
7577+ return 1;
7578+}
8be839c4 7579+
474a6d91
AM
7580+static __inline__ void
7581+alloc_push(void *buf)
7582+{
7583+ if (alloc_stack_next >= alloc_stack_size)
7584+ BUG();
7585+
7586+ *(alloc_stack + alloc_stack_next - 1) = buf;
7587+
7588+ alloc_stack_next++;
7589+
7590+ return;
7591+}
7592+
7593+void *
7594+acl_alloc(unsigned long len)
7595+{
7596+ void *ret;
7597+
7598+ if (len > PAGE_SIZE)
7599+ BUG();
7600+
7601+ ret = kmalloc(len, GFP_KERNEL);
7602+
7603+ if (ret)
7604+ alloc_push(ret);
7605+
7606+ return ret;
7607+}
7608+
7609+void
7610+acl_free_all(void)
7611+{
7612+ if (gr_acl_is_enabled() || !alloc_stack)
7613+ return;
7614+
7615+ while (alloc_pop()) ;
7616+
7617+ if (alloc_stack) {
7618+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
7619+ kfree(alloc_stack);
7620+ else
7621+ vfree(alloc_stack);
7622+ }
7623+
7624+ alloc_stack = NULL;
7625+ alloc_stack_size = 1;
7626+ alloc_stack_next = 1;
7627+
7628+ return;
7629+}
7630+
7631+int
7632+acl_alloc_stack_init(unsigned long size)
7633+{
7634+ if ((size * sizeof (void *)) <= PAGE_SIZE)
7635+ alloc_stack =
7636+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
7637+ else
7638+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
7639+
7640+ alloc_stack_size = size;
7641+
7642+ if (!alloc_stack)
7643+ return 0;
7644+ else
7645+ return 1;
7646+}
7647diff -urN linux-2.4.22.org/grsecurity/gracl.c linux-2.4.22/grsecurity/gracl.c
7648--- linux-2.4.22.org/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100
7649+++ linux-2.4.22/grsecurity/gracl.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
7650@@ -0,0 +1,2766 @@
7651+/*
7652+ * grsecurity/gracl.c
7653+ * Copyright Brad Spengler 2001, 2002, 2003
7654+ *
7655+ */
7656+
7657+#include <linux/kernel.h>
7658+#include <linux/sched.h>
7659+#include <linux/mm.h>
7660+#include <linux/file.h>
7661+#include <linux/fs.h>
7662+#include <linux/proc_fs.h>
7663+#include <linux/smp_lock.h>
7664+#include <linux/slab.h>
7665+#include <linux/vmalloc.h>
7666+#include <linux/types.h>
7667+#include <linux/capability.h>
7668+#include <linux/sysctl.h>
7669+#include <linux/gracl.h>
7670+#include <linux/gralloc.h>
7671+#include <linux/grsecurity.h>
7672+#include <linux/grinternal.h>
7673+
7674+#include <asm/uaccess.h>
7675+#include <asm/errno.h>
7676+#include <asm/mman.h>
7677+
7678+static struct acl_role_db acl_role_set;
7679+static struct acl_role_label *role_list_head;
7680+static struct name_db name_set;
7681+static struct name_db inodev_set;
7682+
7683+static struct acl_role_label *default_role;
7684+
7685+static u16 acl_sp_role_value;
7686+
7687+static DECLARE_MUTEX(gr_dev_sem);
7688+rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
7689+
7690+extern char *gr_shared_page[4][NR_CPUS];
7691+struct gr_arg *gr_usermode;
7692+
7693+static unsigned long gr_status = GR_STATUS_INIT;
7694+
7695+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
7696+extern void gr_clear_learn_entries(void);
7697+
7698+#ifdef CONFIG_GRKERNSEC_RESLOG
7699+extern __inline__ void gr_log_resource(const struct task_struct *task,
7700+ const int res,
7701+ const unsigned long wanted);
7702+#endif
7703+
7704+unsigned char *gr_system_salt;
7705+unsigned char *gr_system_sum;
7706+
7707+static struct sprole_pw **acl_special_roles = NULL;
7708+static __u16 num_sprole_pws = 0;
7709+
7710+static struct acl_role_label *kernel_role = NULL;
7711+
7712+/* The following are used to keep a place held in the hash table when we move
7713+ entries around. They can be replaced during insert. */
7714+
7715+static struct acl_subject_label *deleted_subject;
7716+static struct acl_object_label *deleted_object;
7717+static struct name_entry *deleted_inodev;
7718+
7719+/* for keeping track of the last and final allocated subjects, since
7720+ nested subject parsing is tricky
7721+*/
7722+static struct acl_subject_label *s_last = NULL;
7723+static struct acl_subject_label *s_final = NULL;
7724+
7725+static unsigned int gr_auth_attempts = 0;
7726+static unsigned long gr_auth_expires = 0UL;
7727+
7728+extern int gr_init_uidset(void);
7729+extern void gr_free_uidset(void);
7730+extern void gr_remove_uid(uid_t uid);
7731+extern int gr_find_uid(uid_t uid);
7732+
7733+__inline__ int
7734+gr_acl_is_enabled(void)
7735+{
7736+ return (gr_status & GR_READY);
7737+}
7738+
7739+__inline__ int
7740+gr_acl_tpe_check(void)
7741+{
7742+ if (unlikely(!(gr_status & GR_READY)))
7743+ return 0;
7744+ if (current->role->roletype & GR_ROLE_TPE)
7745+ return 1;
7746+ else
7747+ return 0;
7748+}
7749+
7750+int
7751+gr_handle_rawio(const struct inode *inode)
7752+{
7753+ if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
7754+ ((gr_status & GR_READY)
7755+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7756+ || (grsec_enable_chroot_caps && proc_is_chrooted(current))
7757+#endif
7758+ ))
7759+ return 1;
7760+ return 0;
7761+}
7762+
7763+
7764+static __inline__ int
7765+gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
7766+{
7767+ int i;
7768+ unsigned long *l1;
7769+ unsigned long *l2;
7770+ unsigned char *c1;
7771+ unsigned char *c2;
7772+ int num_longs;
7773+
7774+ if (likely(lena != lenb))
7775+ return 0;
7776+
7777+ l1 = (unsigned long *)a;
7778+ l2 = (unsigned long *)b;
7779+
7780+ num_longs = lena / sizeof(unsigned long);
7781+
7782+ for (i = num_longs; i--; l1++, l2++) {
7783+ if (unlikely(*l1 != *l2))
7784+ return 0;
7785+ }
7786+
7787+ c1 = (unsigned char *) l1;
7788+ c2 = (unsigned char *) l2;
7789+
7790+ i = lena - (num_longs * sizeof(unsigned long));
7791+
7792+ for (; i--; c1++, c2++) {
7793+ if (unlikely(*c1 != *c2))
7794+ return 0;
7795+ }
7796+
7797+ return 1;
7798+}
7799+
7800+static __inline__ char *
7801+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
7802+ char *buf, int buflen)
7803+{
7804+ char *res;
7805+ struct dentry *our_dentry;
7806+ struct vfsmount *our_mount;
7807+ struct vfsmount *rootmnt;
7808+ struct dentry *root;
7809+
7810+ our_dentry = (struct dentry *) dentry;
7811+ our_mount = (struct vfsmount *) vfsmnt;
7812+
7813+ read_lock(&child_reaper->fs->lock);
7814+ rootmnt = mntget(child_reaper->fs->rootmnt);
7815+ root = dget(child_reaper->fs->root);
7816+ read_unlock(&child_reaper->fs->lock);
7817+
7818+ spin_lock(&dcache_lock);
7819+ res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
7820+ spin_unlock(&dcache_lock);
7821+ dput(root);
7822+ mntput(rootmnt);
7823+ return res;
7824+}
7825+
7826+char *
7827+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
7828+{
7829+ return d_real_path(dentry, mnt, gr_shared_page[0][smp_processor_id()],
7830+ PAGE_SIZE);
7831+}
7832+
7833+char *
7834+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
7835+{
7836+ return d_real_path(dentry, mnt, gr_shared_page[1][smp_processor_id()],
7837+ PAGE_SIZE);
7838+}
7839+
7840+char *
7841+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
7842+{
7843+ return d_real_path(dentry, mnt, gr_shared_page[2][smp_processor_id()],
7844+ PAGE_SIZE);
7845+}
7846+
7847+char *
7848+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
7849+{
7850+ return d_real_path(dentry, mnt, gr_shared_page[3][smp_processor_id()],
7851+ PAGE_SIZE);
7852+}
7853+
7854+__inline__ __u32
7855+to_gr_audit(const __u32 reqmode)
7856+{
7857+ __u32 retmode = 0;
7858+
7859+ retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
7860+ retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
7861+ retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
7862+ retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
7863+ retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
7864+ retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
7865+ retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
7866+ retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
7867+ retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
7868+
7869+ return retmode;
7870+}
7871+
7872+__inline__ struct acl_role_label *
7873+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
7874+ const gid_t gid)
7875+{
7876+ unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
7877+ struct acl_role_label *match;
7878+ struct role_allowed_ip *ipp;
7879+ __u8 i = 0;
7880+
7881+ match = acl_role_set.r_hash[index];
7882+
7883+ while (match
7884+ && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
7885+ index = (index + (1 << i)) % acl_role_set.r_size;
7886+ match = acl_role_set.r_hash[index];
7887+ i = (i + 1) % 32;
7888+ }
7889+
7890+ if (!match || match->uidgid != uid || !(match->roletype & GR_ROLE_USER)) {
7891+ try_group:
7892+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
7893+ match = acl_role_set.r_hash[index];
7894+ i = 0;
7895+
7896+ while (match
7897+ && (match->uidgid != gid
7898+ || !(match->roletype & GR_ROLE_GROUP))) {
7899+ index = (index + (1 << i)) % acl_role_set.r_size;
7900+ match = acl_role_set.r_hash[index];
7901+ i = (i + 1) % 32;
7902+ }
7903+
7904+ if (!match || match->uidgid != gid
7905+ || !(match->roletype & GR_ROLE_GROUP))
7906+ match = default_role;
7907+ else if (likely(!match->allowed_ips)) {
7908+ return match;
7909+ } else {
7910+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7911+ if (likely
7912+ ((task->curr_ip & ipp->netmask) ==
7913+ (ipp->addr & ipp->netmask)))
7914+ return match;
7915+ }
7916+ match = default_role;
7917+ }
7918+ } else if (likely(!match->allowed_ips)) {
7919+ return match;
7920+ } else {
7921+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7922+ if (likely
7923+ ((task->curr_ip & ipp->netmask) ==
7924+ (ipp->addr & ipp->netmask)))
7925+ return match;
7926+ }
7927+ goto try_group;
7928+ }
7929+
7930+ return match;
7931+}
7932+
7933+__inline__ struct acl_subject_label *
7934+lookup_acl_subj_label(const ino_t ino, const kdev_t dev,
7935+ const struct acl_role_label *role)
7936+{
7937+ unsigned long subj_size = role->subj_hash_size;
7938+ struct acl_subject_label **s_hash = role->subj_hash;
7939+ unsigned long index = fhash(ino, dev, subj_size);
7940+ struct acl_subject_label *match;
7941+ __u8 i = 0;
7942+
7943+ match = s_hash[index];
7944+
7945+ while (match && (match->inode != ino || match->device != dev ||
7946+ (match->mode & GR_DELETED))) {
7947+ index = (index + (1 << i)) % subj_size;
7948+ match = s_hash[index];
7949+ i = (i + 1) % 32;
7950+ }
7951+
7952+ if (unlikely(match && (match != deleted_subject) &&
7953+ (match->inode == ino) && (match->device == dev) &&
7954+ !(match->mode & GR_DELETED)))
7955+ return match;
7956+ else
7957+ return NULL;
7958+}
7959+
7960+static __inline__ struct acl_object_label *
7961+lookup_acl_obj_label(const ino_t ino, const kdev_t dev,
7962+ const struct acl_subject_label *subj)
7963+{
7964+ unsigned long obj_size = subj->obj_hash_size;
7965+ struct acl_object_label **o_hash = subj->obj_hash;
7966+ unsigned long index = fhash(ino, dev, obj_size);
7967+ struct acl_object_label *match;
7968+ __u8 i = 0;
7969+
7970+ match = o_hash[index];
7971+
7972+ while (match && (match->inode != ino || match->device != dev ||
7973+ (match->mode & GR_DELETED))) {
7974+ index = (index + (1 << i)) % obj_size;
7975+ match = o_hash[index];
7976+ i = (i + 1) % 32;
7977+ }
7978+
7979+ if (unlikely(match && (match != deleted_object) &&
7980+ (match->inode == ino) && (match->device == dev) &&
7981+ !(match->mode & GR_DELETED)))
7982+ return match;
7983+ else
7984+ return NULL;
7985+}
7986+
7987+static __inline__ struct acl_object_label *
7988+lookup_acl_obj_label_create(const ino_t ino, const kdev_t dev,
7989+ const struct acl_subject_label *subj)
7990+{
7991+ unsigned long obj_size = subj->obj_hash_size;
7992+ struct acl_object_label **o_hash = subj->obj_hash;
7993+ unsigned long index = fhash(ino, dev, obj_size);
7994+ struct acl_object_label *match;
7995+ __u8 i = 0;
7996+
7997+ match = o_hash[index];
7998+
7999+ while (match && (match->inode != ino || match->device != dev ||
8000+ !(match->mode & GR_DELETED))) {
8001+ index = (index + (1 << i)) % obj_size;
8002+ match = o_hash[index];
8003+ i = (i + 1) % 32;
8004+ }
8005+
8006+ if (unlikely(match && (match != deleted_object) &&
8007+ (match->inode == ino) && (match->device == dev) &&
8008+ (match->mode & GR_DELETED)))
8009+ return match;
8010+
8011+ i = 0;
8012+ index = fhash(ino, dev, obj_size);
8013+ match = o_hash[index];
8014+
8015+ while (match && (match->inode != ino || match->device != dev ||
8016+ (match->mode & GR_DELETED))) {
8017+ index = (index + (1 << i)) % obj_size;
8018+ match = o_hash[index];
8019+ i = (i + 1) % 32;
8020+ }
8021+
8022+ if (unlikely(match && (match != deleted_object) &&
8023+ (match->inode == ino) && (match->device == dev) &&
8024+ !(match->mode & GR_DELETED)))
8025+ return match;
8026+ else
8027+ return NULL;
8028+}
8029+
8030+static __inline__ struct name_entry *
8031+lookup_name_entry(const char *name)
8032+{
8033+ __u16 len = strlen(name);
8034+ unsigned long index = nhash(name, len, name_set.n_size);
8035+ struct name_entry *match;
8036+ __u8 i = 0;
8037+
8038+ match = name_set.n_hash[index];
8039+
8040+ while (match && !gr_streq(match->name, name, match->len, len)) {
8041+ index = (index + (1 << i)) % name_set.n_size;
8042+ match = name_set.n_hash[index];
8043+ i = (i + 1) % 32;
8044+ }
8045+
8046+ if (unlikely(!match || !gr_streq(match->name, name, match->len, len)))
8047+ return NULL;
8048+ else
8049+ return match;
8050+}
8051+
8052+static __inline__ struct name_entry *
8053+lookup_inodev_entry(const ino_t ino, const kdev_t dev)
8054+{
8055+ unsigned long index = fhash(ino, dev, inodev_set.n_size);
8056+ struct name_entry *match;
8057+ __u8 i = 0;
8058+
8059+ match = inodev_set.n_hash[index];
8060+
8061+ while (match && (match->inode != ino || match->device != dev)) {
8062+ index = (index + (1 << i)) % inodev_set.n_size;
8063+ match = inodev_set.n_hash[index];
8064+ i = (i + 1) % 32;
8065+ }
8066+
8067+ if (unlikely(match && (match != deleted_inodev) &&
8068+ (match->inode == ino) && (match->device == dev)))
8069+ return match;
8070+ else
8071+ return NULL;
8072+}
8073+
8074+static void
8075+insert_inodev_entry(struct name_entry *nentry)
8076+{
8077+ unsigned long index = fhash(nentry->inode, nentry->device,
8078+ inodev_set.n_size);
8079+ struct name_entry **curr;
8080+ __u8 i = 0;
8081+
8082+ curr = &inodev_set.n_hash[index];
8083+
8084+ while (*curr && *curr != deleted_inodev) {
8085+ index = (index + (1 << i)) % inodev_set.n_size;
8086+ curr = &inodev_set.n_hash[index];
8087+ i = (i + 1) % 32;
8088+ }
8089+
8090+ *curr = nentry;
8091+
8092+ return;
8093+}
8094+
8095+static void
8096+insert_acl_role_label(struct acl_role_label *role)
8097+{
8098+ unsigned long index =
8099+ rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
8100+ struct acl_role_label **curr;
8101+ __u8 i = 0;
8102+
8103+ curr = &acl_role_set.r_hash[index];
8104+
8105+ while (*curr) {
8106+ index = (index + (1 << i)) % acl_role_set.r_size;
8107+ curr = &acl_role_set.r_hash[index];
8108+ i = (i + 1) % 32;
8109+ }
8110+
8111+ *curr = role;
8112+
8113+ return;
8114+}
8115+
8116+static int
8117+insert_name_entry(char *name, const ino_t inode, const kdev_t device)
8118+{
8119+ struct name_entry **curr;
8120+ __u8 i = 0;
8121+ __u16 len = strlen(name);
8122+ unsigned long index = nhash(name, len, name_set.n_size);
8123+
8124+ curr = &name_set.n_hash[index];
8125+
8126+ while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
8127+ index = (index + (1 << i)) % name_set.n_size;
8128+ curr = &name_set.n_hash[index];
8129+ i = (i + 1) % 32;
8130+ }
8131+
8132+ if (!(*curr)) {
8133+ struct name_entry *nentry =
8134+ acl_alloc(sizeof (struct name_entry));
8135+ if (!nentry)
8136+ return 0;
8137+ nentry->name = name;
8138+ nentry->inode = inode;
8139+ nentry->device = device;
8140+ nentry->len = len;
8141+ *curr = nentry;
8142+ /* insert us into the table searchable by inode/dev */
8143+ insert_inodev_entry(nentry);
8144+ }
8145+
8146+ return 1;
8147+}
8148+
8149+static void
8150+insert_acl_obj_label(struct acl_object_label *obj,
8151+ struct acl_subject_label *subj)
8152+{
8153+ unsigned long index =
8154+ fhash(obj->inode, obj->device, subj->obj_hash_size);
8155+ struct acl_object_label **curr;
8156+ __u8 i = 0;
8157+
8158+ curr = &subj->obj_hash[index];
8159+
8160+ while (*curr && *curr != deleted_object) {
8161+ index = (index + (1 << i)) % subj->obj_hash_size;
8162+ curr = &subj->obj_hash[index];
8163+ i = (i + 1) % 32;
8164+ }
8165+
8166+ *curr = obj;
8167+
8168+ return;
8169+}
8170+
8171+static void
8172+insert_acl_subj_label(struct acl_subject_label *obj,
8173+ struct acl_role_label *role)
8174+{
8175+ unsigned long subj_size = role->subj_hash_size;
8176+ struct acl_subject_label **s_hash = role->subj_hash;
8177+ unsigned long index = fhash(obj->inode, obj->device, subj_size);
8178+ struct acl_subject_label **curr;
8179+ __u8 i = 0;
8180+
8181+ curr = &s_hash[index];
8182+
8183+ while (*curr && *curr != deleted_subject) {
8184+ index = (index + (1 << i)) % subj_size;
8185+ curr = &s_hash[index];
8186+ i = (i + 1) % 32;
8187+ }
8188+
8189+ *curr = obj;
8190+
8191+ return;
8192+}
8193+
8194+static void **
8195+create_table(__u32 * len)
8196+{
8197+ unsigned long table_sizes[] = {
8198+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
8199+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
8200+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
8201+ 268435399, 536870909, 1073741789, 2147483647
8202+ };
8203+ void *newtable = NULL;
8204+ unsigned int pwr = 0;
8205+
8206+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
8207+ table_sizes[pwr] <= (2 * (*len)))
8208+ pwr++;
8209+
8210+ if (table_sizes[pwr] <= (2 * (*len)))
8211+ return newtable;
8212+
8213+ if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
8214+ newtable =
8215+ kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
8216+ else
8217+ newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
8218+
8219+ *len = table_sizes[pwr];
8220+
8221+ return newtable;
8222+}
8223+
8224+static int
8225+init_variables(const unsigned long acl_obj_size,
8226+ const unsigned long acl_subj_size,
8227+ const unsigned long acl_ip_size,
8228+ const unsigned long acl_role_size,
8229+ const unsigned long allowed_ip_size,
8230+ const unsigned long acl_trans_size,
8231+ const __u16 num_sprole_pws)
8232+{
8233+ unsigned long stacksize;
8234+
8235+ acl_role_set.r_size = acl_role_size;
8236+ name_set.n_size = (acl_obj_size + acl_subj_size);
8237+ inodev_set.n_size = (acl_obj_size + acl_subj_size);
8238+
8239+ if (!gr_init_uidset())
8240+ return 1;
8241+
8242+ /* set up the stack that holds allocation info */
8243+
8244+ stacksize = (3 * acl_obj_size) + (2 * acl_role_size) +
8245+ (4 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
8246+ allowed_ip_size + (2 * num_sprole_pws) + 5;
8247+
8248+ if (!acl_alloc_stack_init(stacksize))
8249+ return 1;
8250+
8251+ /* create our empty, fake deleted acls */
8252+ deleted_subject =
8253+ (struct acl_subject_label *)
8254+ acl_alloc(sizeof (struct acl_subject_label));
8255+ deleted_object =
8256+ (struct acl_object_label *)
8257+ acl_alloc(sizeof (struct acl_object_label));
8258+ deleted_inodev =
8259+ (struct name_entry *) acl_alloc(sizeof (struct name_entry));
8260+
8261+ if (!deleted_subject || !deleted_object || !deleted_inodev)
8262+ return 1;
8263+
8264+ memset(deleted_subject, 0, sizeof (struct acl_subject_label));
8265+ memset(deleted_object, 0, sizeof (struct acl_object_label));
8266+ memset(deleted_inodev, 0, sizeof (struct name_entry));
8267+
8268+ /* We only want 50% full tables for now */
8269+
8270+ acl_role_set.r_hash =
8271+ (struct acl_role_label **) create_table(&acl_role_set.r_size);
8272+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
8273+ inodev_set.n_hash =
8274+ (struct name_entry **) create_table(&inodev_set.n_size);
8275+
8276+ if (!acl_role_set.r_hash || !name_set.n_hash || !inodev_set.n_hash)
8277+ return 1;
8278+ memset(acl_role_set.r_hash, 0,
8279+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
8280+ memset(name_set.n_hash, 0,
8281+ sizeof (struct name_entry *) * name_set.n_size);
8282+ memset(inodev_set.n_hash, 0,
8283+ sizeof (struct name_entry *) * inodev_set.n_size);
8284+
8285+ return 0;
8286+}
8287+
8288+static void
8289+free_variables(void)
8290+{
8291+ struct acl_subject_label *s;
8292+ struct acl_role_label *r;
8293+ struct task_struct *task;
8294+
8295+ gr_clear_learn_entries();
8296+
8297+ read_lock(&tasklist_lock);
8298+ for_each_task(task) {
8299+ task->acl_sp_role = 0;
8300+ task->acl_role_id = 0;
8301+ task->acl = NULL;
8302+ task->role = NULL;
8303+ }
8304+ read_unlock(&tasklist_lock);
8305+
8306+ /* free all object hash tables */
8307+
8308+ if (role_list_head) {
8309+ for (r = role_list_head; r; r = r->next) {
8310+ if (!r->subj_hash)
8311+ break;
8312+ for (s = r->proc_subject; s; s = s->next) {
8313+ if (!s->obj_hash)
8314+ break;
8315+ if ((s->obj_hash_size *
8316+ sizeof (struct acl_object_label *)) <=
8317+ PAGE_SIZE)
8318+ kfree(s->obj_hash);
8319+ else
8320+ vfree(s->obj_hash);
8321+ }
8322+ if ((r->subj_hash_size *
8323+ sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
8324+ kfree(r->subj_hash);
8325+ else
8326+ vfree(r->subj_hash);
8327+ }
8328+ }
8329+
8330+ acl_free_all();
8331+
8332+ if (acl_role_set.r_hash) {
8333+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
8334+ PAGE_SIZE)
8335+ kfree(acl_role_set.r_hash);
8336+ else
8337+ vfree(acl_role_set.r_hash);
8338+ }
8339+ if (name_set.n_hash) {
8340+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
8341+ PAGE_SIZE)
8342+ kfree(name_set.n_hash);
8343+ else
8344+ vfree(name_set.n_hash);
8345+ }
8346+
8347+ if (inodev_set.n_hash) {
8348+ if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
8349+ PAGE_SIZE)
8350+ kfree(inodev_set.n_hash);
8351+ else
8352+ vfree(inodev_set.n_hash);
8353+ }
8354+
8355+ gr_free_uidset();
8356+
8357+ memset(&name_set, 0, sizeof (struct name_db));
8358+ memset(&inodev_set, 0, sizeof (struct name_db));
8359+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
8360+
8361+ role_list_head = NULL;
8362+ default_role = NULL;
8363+
8364+ return;
8365+}
8366+
8367+static __u32
8368+count_user_objs(struct acl_object_label *userp)
8369+{
8370+ struct acl_object_label o_tmp;
8371+ __u32 num = 0;
8372+
8373+ while (userp) {
8374+ if (copy_from_user(&o_tmp, userp,
8375+ sizeof (struct acl_object_label)))
8376+ break;
8377+
8378+ userp = o_tmp.prev;
8379+ num++;
8380+ }
8381+
8382+ return num;
8383+}
8384+
8385+static struct acl_subject_label *
8386+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
8387+
8388+static int
8389+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
8390+ struct acl_role_label *role)
8391+{
8392+ struct acl_object_label *o_tmp;
8393+ unsigned int len;
8394+ char *tmp;
8395+
8396+ while (userp) {
8397+ if ((o_tmp = (struct acl_object_label *)
8398+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
8399+ return -ENOMEM;
8400+
8401+ if (copy_from_user(o_tmp, userp,
8402+ sizeof (struct acl_object_label)))
8403+ return -EFAULT;
8404+
8405+ userp = o_tmp->prev;
8406+
8407+ len = strnlen_user(o_tmp->filename, PATH_MAX);
8408+
8409+ if (!len || len >= PATH_MAX)
8410+ return -EINVAL;
8411+
8412+ if ((tmp = (char *) acl_alloc(len)) == NULL)
8413+ return -ENOMEM;
8414+
8415+ if (copy_from_user(tmp, o_tmp->filename, len))
8416+ return -EFAULT;
8417+
8418+ o_tmp->filename = tmp;
8419+
8420+ insert_acl_obj_label(o_tmp, subj);
8421+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
8422+ o_tmp->device))
8423+ return -ENOMEM;
8424+
8425+ if (o_tmp->nested) {
8426+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
8427+ if (IS_ERR(o_tmp->nested))
8428+ return PTR_ERR(o_tmp->nested);
8429+
8430+ s_final = o_tmp->nested;
8431+ }
8432+ }
8433+
8434+ return 0;
8435+}
8436+
8437+static __u32
8438+count_user_subjs(struct acl_subject_label *userp)
8439+{
8440+ struct acl_subject_label s_tmp;
8441+ __u32 num = 0;
8442+
8443+ while (userp) {
8444+ if (copy_from_user(&s_tmp, userp,
8445+ sizeof (struct acl_subject_label)))
8446+ break;
8447+
8448+ userp = s_tmp.prev;
8449+ /* do not count nested subjects against this count, since
8450+ they are not included in the hash table, but are
8451+ attached to objects. We have already counted
8452+ the subjects in userspace for the allocation
8453+ stack
8454+ */
8455+ if (!s_tmp.parent_subject)
8456+ num++;
8457+ }
8458+
8459+ return num;
8460+}
8461+
8462+static int
8463+copy_user_allowedips(struct acl_role_label *rolep)
8464+{
8465+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
8466+
8467+ ruserip = rolep->allowed_ips;
8468+
8469+ while (ruserip) {
8470+ rlast = rtmp;
8471+
8472+ if ((rtmp = (struct role_allowed_ip *)
8473+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
8474+ return -ENOMEM;
8475+
8476+ if (copy_from_user(rtmp, ruserip,
8477+ sizeof (struct role_allowed_ip)))
8478+ return -EFAULT;
8479+
8480+ ruserip = rtmp->prev;
8481+
8482+ if (!rlast) {
8483+ rtmp->prev = NULL;
8484+ rolep->allowed_ips = rtmp;
8485+ } else {
8486+ rlast->next = rtmp;
8487+ rtmp->prev = rlast;
8488+ }
8489+
8490+ if (!ruserip)
8491+ rtmp->next = NULL;
8492+ }
8493+
8494+ return 0;
8495+}
8496+
8497+static int
8498+copy_user_transitions(struct acl_role_label *rolep)
8499+{
8500+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
8501+ unsigned int len;
8502+ char *tmp;
8503+
8504+ rusertp = rolep->transitions;
8505+
8506+ while (rusertp) {
8507+ rlast = rtmp;
8508+
8509+ if ((rtmp = (struct role_transition *)
8510+ acl_alloc(sizeof (struct role_transition))) == NULL)
8511+ return -ENOMEM;
8512+
8513+ if (copy_from_user(rtmp, rusertp,
8514+ sizeof (struct role_transition)))
8515+ return -EFAULT;
8516+
8517+ rusertp = rtmp->prev;
8518+
8519+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
8520+
8521+ if (!len || len >= GR_SPROLE_LEN)
8522+ return -EINVAL;
8523+
8524+ if ((tmp = (char *) acl_alloc(len)) == NULL)
8525+ return -ENOMEM;
8526+
8527+ if (copy_from_user(tmp, rtmp->rolename, len))
8528+ return -EFAULT;
8529+
8530+ rtmp->rolename = tmp;
8531+
8532+ if (!rlast) {
8533+ rtmp->prev = NULL;
8534+ rolep->transitions = rtmp;
8535+ } else {
8536+ rlast->next = rtmp;
8537+ rtmp->prev = rlast;
8538+ }
8539+
8540+ if (!rusertp)
8541+ rtmp->next = NULL;
8542+ }
8543+
8544+ return 0;
8545+}
8546+
8547+static struct acl_subject_label *
8548+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
8549+{
8550+ struct acl_subject_label *s_tmp = NULL;
8551+ unsigned int len;
8552+ char *tmp;
8553+ __u32 num_objs;
8554+ struct acl_ip_label **i_tmp, *i_utmp2;
8555+ unsigned long i_num;
8556+ int err;
8557+
8558+
8559+ if ((s_tmp = (struct acl_subject_label *)
8560+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
8561+ return ERR_PTR(-ENOMEM);
8562+
8563+ if (copy_from_user(s_tmp, userp,
8564+ sizeof (struct acl_subject_label)))
8565+ return ERR_PTR(-EFAULT);
8566+
8567+ if (!s_last) {
8568+ s_tmp->prev = NULL;
8569+ role->proc_subject = s_tmp;
8570+ } else {
8571+ s_last->next = s_tmp;
8572+ s_tmp->prev = s_last;
8573+ }
8574+
8575+ s_last = s_tmp;
8576+
8577+ len = strnlen_user(s_tmp->filename, PATH_MAX);
8578+
8579+ if (!len || len >= PATH_MAX)
8580+ return ERR_PTR(-EINVAL);
8581+
8582+ if ((tmp = (char *) acl_alloc(len)) == NULL)
8583+ return ERR_PTR(-ENOMEM);
8584+
8585+ if (copy_from_user(tmp, s_tmp->filename, len))
8586+ return ERR_PTR(-EFAULT);
8587+
8588+ s_tmp->filename = tmp;
8589+
8590+ if (!strcmp(s_tmp->filename, "/"))
8591+ role->root_label = s_tmp;
8592+
8593+ /* set up object hash table */
8594+ num_objs = count_user_objs(s_tmp->proc_object);
8595+
8596+ s_tmp->obj_hash_size = num_objs;
8597+ s_tmp->obj_hash =
8598+ (struct acl_object_label **)
8599+ create_table(&(s_tmp->obj_hash_size));
8600+
8601+ if (!s_tmp->obj_hash)
8602+ return ERR_PTR(-ENOMEM);
8603+
8604+ memset(s_tmp->obj_hash, 0,
8605+ s_tmp->obj_hash_size *
8606+ sizeof (struct acl_object_label *));
8607+
8608+ /* copy before adding in objects, since a nested
8609+ acl could be found and be the final subject
8610+ copied
8611+ */
8612+
8613+ s_final = s_tmp;
8614+
8615+ /* add in objects */
8616+ err = copy_user_objs(s_tmp->proc_object, s_tmp, role);
8617+
8618+ if (err)
8619+ return ERR_PTR(err);
8620+
8621+ /* add in ip acls */
8622+
8623+ if (!s_tmp->ip_num) {
8624+ s_tmp->ips = NULL;
8625+ goto insert;
8626+ }
8627+
8628+ i_tmp =
8629+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
8630+ sizeof (struct
8631+ acl_ip_label *));
8632+
8633+ if (!i_tmp)
8634+ return ERR_PTR(-ENOMEM);
8635+
8636+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
8637+ *(i_tmp + i_num) =
8638+ (struct acl_ip_label *)
8639+ acl_alloc(sizeof (struct acl_ip_label));
8640+ if (!*(i_tmp + i_num))
8641+ return ERR_PTR(-ENOMEM);
8642+
8643+ if (copy_from_user
8644+ (&i_utmp2, s_tmp->ips + i_num,
8645+ sizeof (struct acl_ip_label *)))
8646+ return ERR_PTR(-EFAULT);
8647+
8648+ if (copy_from_user
8649+ (*(i_tmp + i_num), i_utmp2,
8650+ sizeof (struct acl_ip_label)))
8651+ return ERR_PTR(-EFAULT);
8652+ }
8653+
8654+ s_tmp->ips = i_tmp;
8655+
8656+insert:
8657+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
8658+ s_tmp->device))
8659+ return ERR_PTR(-ENOMEM);
8660+
8661+ return s_tmp;
8662+}
8663+
8664+static int
8665+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
8666+{
8667+ struct acl_subject_label s_pre;
8668+ struct acl_subject_label * ret;
8669+ int err;
8670+
8671+ while (userp) {
8672+ if (copy_from_user(&s_pre, userp,
8673+ sizeof (struct acl_subject_label)))
8674+ return -EFAULT;
8675+
8676+ /* do not add nested subjects here, add
8677+ while parsing objects
8678+ */
8679+
8680+ if (s_pre.parent_subject) {
8681+ userp = s_pre.prev;
8682+ continue;
8683+ }
8684+
8685+ ret = do_copy_user_subj(userp, role);
8686+
8687+ err = PTR_ERR(ret);
8688+ if (IS_ERR(ret))
8689+ return err;
8690+
8691+ insert_acl_subj_label(ret, role);
8692+
8693+ userp = s_pre.prev;
8694+ }
8695+
8696+ s_final->next = NULL;
8697+
8698+ return 0;
8699+}
8700+
8701+static int
8702+copy_user_acl(struct gr_arg *arg)
8703+{
8704+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
8705+ struct sprole_pw *sptmp;
8706+ unsigned long r_num;
8707+ unsigned int len;
8708+ char *tmp;
8709+ int err = 0;
8710+ __u16 i;
8711+ __u32 num_subjs;
8712+
8713+ /* we need a default and kernel role */
8714+ if (arg->role_db.r_entries < 2)
8715+ return -EINVAL;
8716+
8717+ /* copy special role authentication info from userspace */
8718+
8719+ num_sprole_pws = arg->num_sprole_pws;
8720+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
8721+
8722+ if (!acl_special_roles) {
8723+ err = -ENOMEM;
8724+ goto cleanup;
8725+ }
8726+
8727+ for (i = 0; i < num_sprole_pws; i++) {
8728+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
8729+ if (!sptmp) {
8730+ err = -ENOMEM;
8731+ goto cleanup;
8732+ }
8733+ if (copy_from_user(sptmp, arg->sprole_pws + i,
8734+ sizeof (struct sprole_pw))) {
8735+ err = -EFAULT;
8736+ goto cleanup;
8737+ }
8738+
8739+ len =
8740+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
8741+
8742+ if (!len || len >= GR_SPROLE_LEN) {
8743+ err = -EINVAL;
8744+ goto cleanup;
8745+ }
8746+
8747+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
8748+ err = -ENOMEM;
8749+ goto cleanup;
8750+ }
8751+
8752+ if (copy_from_user(tmp, sptmp->rolename, len)) {
8753+ err = -EFAULT;
8754+ goto cleanup;
8755+ }
8756+
8757+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
8758+ printk(KERN_ALERT "Copying special role %s\n", tmp);
8759+#endif
8760+ sptmp->rolename = tmp;
8761+ acl_special_roles[i] = sptmp;
8762+ }
8763+
8764+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
8765+
8766+ for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
8767+ r_last = r_tmp;
8768+
8769+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
8770+
8771+ if (!r_tmp) {
8772+ err = -ENOMEM;
8773+ goto cleanup;
8774+ }
8775+
8776+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
8777+ sizeof (struct acl_role_label *))) {
8778+ err = -EFAULT;
8779+ goto cleanup;
8780+ }
8781+
8782+ if (copy_from_user(r_tmp, r_utmp2,
8783+ sizeof (struct acl_role_label))) {
8784+ err = -EFAULT;
8785+ goto cleanup;
8786+ }
8787+
8788+ if (!r_last) {
8789+ r_tmp->prev = NULL;
8790+ role_list_head = r_tmp;
8791+ } else {
8792+ r_last->next = r_tmp;
8793+ r_tmp->prev = r_last;
8794+ }
8795+
8796+ if (r_num == (arg->role_db.r_entries - 1))
8797+ r_tmp->next = NULL;
8798+
8799+ len = strnlen_user(r_tmp->rolename, PATH_MAX);
8800+
8801+ if (!len || len >= PATH_MAX) {
8802+ err = -EINVAL;
8803+ goto cleanup;
8804+ }
8805+
8806+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
8807+ err = -ENOMEM;
8808+ goto cleanup;
8809+ }
8810+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
8811+ err = -EFAULT;
8812+ goto cleanup;
8813+ }
8814+ r_tmp->rolename = tmp;
8815+
8816+ if (!strcmp(r_tmp->rolename, "default")
8817+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
8818+ default_role = r_tmp;
8819+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
8820+ kernel_role = r_tmp;
8821+ }
8822+
8823+ num_subjs = count_user_subjs(r_tmp->proc_subject);
8824+
8825+ r_tmp->subj_hash_size = num_subjs;
8826+ r_tmp->subj_hash =
8827+ (struct acl_subject_label **)
8828+ create_table(&(r_tmp->subj_hash_size));
8829+
8830+ if (!r_tmp->subj_hash) {
8831+ err = -ENOMEM;
8832+ goto cleanup;
8833+ }
8834+
8835+ err = copy_user_allowedips(r_tmp);
8836+ if (err)
8837+ goto cleanup;
8838+
8839+ err = copy_user_transitions(r_tmp);
8840+ if (err)
8841+ goto cleanup;
8842+
8843+ memset(r_tmp->subj_hash, 0,
8844+ r_tmp->subj_hash_size *
8845+ sizeof (struct acl_subject_label *));
8846+
8847+ s_last = NULL;
8848+
8849+ err = copy_user_subjs(r_tmp->proc_subject, r_tmp);
8850+
8851+ if (err)
8852+ goto cleanup;
8853+
8854+ insert_acl_role_label(r_tmp);
8855+ }
8856+
8857+ goto return_err;
8858+ cleanup:
8859+ free_variables();
8860+ return_err:
8861+ return err;
8862+
8863+}
8864+
8865+static int
8866+gracl_init(struct gr_arg *args)
8867+{
8868+ int error = 0;
8869+
8870+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
8871+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
8872+
8873+ if (init_variables(args->role_db.o_entries, args->role_db.s_entries,
8874+ args->role_db.i_entries, args->role_db.r_entries,
8875+ args->role_db.a_entries, args->role_db.t_entries,
8876+ args->num_sprole_pws)) {
8877+ security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
8878+ error = -ENOMEM;
8879+ free_variables();
8880+ goto out;
8881+ }
8882+
8883+ error = copy_user_acl(args);
8884+ if (error)
8885+ goto out;
8886+
8887+ if ((error = gr_set_acls(0))) {
8888+ free_variables();
8889+ goto out;
8890+ }
8891+
8892+ gr_status |= GR_READY;
8893+ out:
8894+ return error;
8895+}
8896+
8897+static struct acl_object_label *
8898+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
8899+ const struct acl_subject_label *subj)
8900+{
8901+ struct dentry *dentry = (struct dentry *) l_dentry;
8902+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
8903+ struct dentry *root;
8904+ struct vfsmount *rootmnt;
8905+ struct acl_object_label *retval;
8906+
8907+ read_lock(&child_reaper->fs->lock);
8908+ rootmnt = mntget(child_reaper->fs->rootmnt);
8909+ root = dget(child_reaper->fs->root);
8910+ read_unlock(&child_reaper->fs->lock);
8911+ spin_lock(&dcache_lock);
8912+
8913+ for (;;) {
8914+ if (unlikely(dentry == root && mnt == rootmnt))
8915+ break;
8916+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
8917+ if (mnt->mnt_parent == mnt)
8918+ break;
8919+
8920+ read_lock(&gr_inode_lock);
8921+ retval =
8922+ lookup_acl_obj_label(dentry->d_inode->i_ino,
8923+ dentry->d_inode->i_dev, subj);
8924+ read_unlock(&gr_inode_lock);
8925+ if (unlikely(retval != NULL))
8926+ goto out;
8927+
8928+ dentry = mnt->mnt_mountpoint;
8929+ mnt = mnt->mnt_parent;
8930+ continue;
8931+ }
8932+
8933+ read_lock(&gr_inode_lock);
8934+ retval =
8935+ lookup_acl_obj_label(dentry->d_inode->i_ino,
8936+ dentry->d_inode->i_dev, subj);
8937+ read_unlock(&gr_inode_lock);
8938+ if (unlikely(retval != NULL))
8939+ goto out;
8940+
8941+ dentry = dentry->d_parent;
8942+ }
8943+
8944+ read_lock(&gr_inode_lock);
8945+ retval =
8946+ lookup_acl_obj_label(dentry->d_inode->i_ino, dentry->d_inode->i_dev,
8947+ subj);
8948+ read_unlock(&gr_inode_lock);
8949+
8950+ if (unlikely(retval == NULL)) {
8951+ read_lock(&gr_inode_lock);
8952+ retval =
8953+ lookup_acl_obj_label(root->d_inode->i_ino,
8954+ root->d_inode->i_dev, subj);
8955+ read_unlock(&gr_inode_lock);
8956+ }
8957+ out:
8958+ spin_unlock(&dcache_lock);
8959+ dput(root);
8960+ mntput(rootmnt);
8961+
8962+ return retval;
8963+}
8964+
8965+static struct acl_subject_label *
8966+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
8967+ const struct acl_role_label *role)
8968+{
8969+ struct dentry *dentry = (struct dentry *) l_dentry;
8970+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
8971+ struct dentry *root;
8972+ struct vfsmount *rootmnt;
8973+ struct acl_subject_label *retval;
8974+
8975+ read_lock(&child_reaper->fs->lock);
8976+ rootmnt = mntget(child_reaper->fs->rootmnt);
8977+ root = dget(child_reaper->fs->root);
8978+ read_unlock(&child_reaper->fs->lock);
8979+ spin_lock(&dcache_lock);
8980+
8981+ for (;;) {
8982+ if (unlikely(dentry == root && mnt == rootmnt))
8983+ break;
8984+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
8985+ if (mnt->mnt_parent == mnt)
8986+ break;
8987+
8988+ read_lock(&gr_inode_lock);
8989+ retval =
8990+ lookup_acl_subj_label(dentry->d_inode->i_ino,
8991+ dentry->d_inode->i_dev, role);
8992+ read_unlock(&gr_inode_lock);
8993+ if (unlikely(retval != NULL))
8994+ goto out;
8995+
8996+ dentry = mnt->mnt_mountpoint;
8997+ mnt = mnt->mnt_parent;
8998+ continue;
8999+ }
9000+
9001+ read_lock(&gr_inode_lock);
9002+ retval =
9003+ lookup_acl_subj_label(dentry->d_inode->i_ino,
9004+ dentry->d_inode->i_dev, role);
9005+ read_unlock(&gr_inode_lock);
9006+ if (unlikely(retval != NULL))
9007+ goto out;
9008+
9009+ dentry = dentry->d_parent;
9010+ }
9011+
9012+ read_lock(&gr_inode_lock);
9013+ retval =
9014+ lookup_acl_subj_label(dentry->d_inode->i_ino,
9015+ dentry->d_inode->i_dev, role);
9016+ read_unlock(&gr_inode_lock);
9017+
9018+ if (unlikely(retval == NULL)) {
9019+ read_lock(&gr_inode_lock);
9020+ retval =
9021+ lookup_acl_subj_label(root->d_inode->i_ino,
9022+ root->d_inode->i_dev, role);
9023+ read_unlock(&gr_inode_lock);
9024+ }
9025+ out:
9026+ spin_unlock(&dcache_lock);
9027+ dput(root);
9028+ mntput(rootmnt);
9029+
9030+ return retval;
9031+}
9032+
9033+static __inline__ void
9034+gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
9035+ const struct task_struct *task, const char *pathname,
9036+ const __u32 mode)
9037+{
9038+ security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
9039+ uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
9040+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
9041+ 1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
9042+
9043+ return;
9044+}
9045+
9046+__u32
9047+gr_check_link(const struct dentry * new_dentry,
9048+ const struct dentry * parent_dentry,
9049+ const struct vfsmount * parent_mnt,
9050+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
9051+{
9052+ struct acl_object_label *obj;
9053+ __u32 oldmode, newmode;
9054+
9055+ if (unlikely(!(gr_status & GR_READY)))
9056+ return (GR_WRITE | GR_CREATE);
9057+
9058+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
9059+ oldmode = obj->mode;
9060+
9061+ if (current->acl->mode & GR_LEARN)
9062+ oldmode |= (GR_WRITE | GR_CREATE);
9063+ newmode =
9064+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
9065+ oldmode | GR_CREATE | GR_AUDIT_CREATE |
9066+ GR_AUDIT_WRITE | GR_SUPPRESS);
9067+
9068+ if ((newmode & oldmode) == oldmode)
9069+ return newmode;
9070+ else if (current->acl->mode & GR_LEARN) {
9071+ gr_log_learn(current->role, current->uid, current->gid,
9072+ current, gr_to_filename(old_dentry, old_mnt), oldmode);
9073+ return (GR_WRITE | GR_CREATE);
9074+ } else if (newmode & GR_SUPPRESS)
9075+ return GR_SUPPRESS;
9076+ else
9077+ return 0;
9078+}
9079+
9080+__u32
9081+gr_search_file(const struct dentry * dentry, const __u32 mode,
9082+ const struct vfsmount * mnt)
9083+{
9084+ __u32 retval = mode;
9085+ struct acl_subject_label *curracl;
9086+ struct acl_object_label *currobj;
9087+
9088+ if (unlikely(!(gr_status & GR_READY)))
9089+ return (mode & ~GR_AUDITS);
9090+
9091+ curracl = current->acl;
9092+
9093+ currobj = chk_obj_label(dentry, mnt, curracl);
9094+ retval = currobj->mode & mode;
9095+
9096+ if (unlikely
9097+ ((curracl->mode & GR_LEARN) && (mode != GR_PTRACERD)
9098+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
9099+ __u32 new_mode = mode;
9100+
9101+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9102+
9103+ retval = new_mode;
9104+
9105+ if (!(mode & GR_NOLEARN))
9106+ gr_log_learn(current->role, current->uid, current->gid,
9107+ current, gr_to_filename(dentry, mnt), new_mode);
9108+ }
9109+
9110+ return retval;
9111+}
9112+
9113+__u32
9114+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
9115+ const struct vfsmount * mnt, const __u32 mode)
9116+{
9117+ struct name_entry *match;
9118+ struct acl_object_label *matchpo;
9119+ struct acl_subject_label *curracl;
9120+ __u32 retval;
9121+
9122+ if (unlikely(!(gr_status & GR_READY)))
9123+ return (mode & ~GR_AUDITS);
9124+
9125+ match = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9126+
9127+ if (!match)
9128+ goto check_parent;
9129+
9130+ curracl = current->acl;
9131+
9132+ read_lock(&gr_inode_lock);
9133+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
9134+ read_unlock(&gr_inode_lock);
9135+
9136+ if (matchpo) {
9137+ if ((matchpo->mode & mode) !=
9138+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
9139+ && curracl->mode & GR_LEARN) {
9140+ __u32 new_mode = mode;
9141+
9142+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9143+
9144+ gr_log_learn(current->role, current->uid, current->gid,
9145+ current, gr_to_filename(new_dentry, mnt), new_mode);
9146+
9147+ return new_mode;
9148+ }
9149+ return (matchpo->mode & mode);
9150+ }
9151+
9152+ check_parent:
9153+ curracl = current->acl;
9154+
9155+ matchpo = chk_obj_label(parent, mnt, curracl);
9156+ retval = matchpo->mode & mode;
9157+
9158+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
9159+ && (curracl->mode & GR_LEARN)) {
9160+ __u32 new_mode = mode;
9161+
9162+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9163+
9164+ gr_log_learn(current->role, current->uid, current->gid,
9165+ current, gr_to_filename(new_dentry, mnt), new_mode);
9166+ return new_mode;
9167+ }
9168+
9169+ return retval;
9170+}
9171+
9172+int
9173+gr_check_hidden_task(const struct task_struct *task)
9174+{
9175+ if (unlikely(!(gr_status & GR_READY)))
9176+ return 0;
9177+
9178+ if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
9179+ return 1;
9180+
9181+ return 0;
9182+}
9183+
9184+int
9185+gr_check_protected_task(const struct task_struct *task)
9186+{
9187+ if (unlikely(!(gr_status & GR_READY) || !task))
9188+ return 0;
9189+
9190+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
9191+ return 1;
9192+
9193+ return 0;
9194+}
9195+
9196+__inline__ void
9197+gr_copy_label(struct task_struct *tsk)
9198+{
9199+ tsk->used_accept = 0;
9200+ tsk->used_connect = 0;
9201+ tsk->acl_sp_role = 0;
9202+ tsk->acl_role_id = current->acl_role_id;
9203+ tsk->acl = current->acl;
9204+ tsk->role = current->role;
9205+ tsk->curr_ip = current->curr_ip;
9206+ if (current->exec_file)
9207+ get_file(current->exec_file);
9208+ tsk->exec_file = current->exec_file;
9209+ tsk->is_writable = current->is_writable;
9210+ if (unlikely(current->used_accept))
9211+ current->curr_ip = 0;
9212+
9213+ return;
9214+}
9215+
9216+static __inline__ void
9217+gr_set_proc_res(void)
9218+{
9219+ struct acl_subject_label *proc;
9220+ unsigned short i;
9221+
9222+ proc = current->acl;
9223+
9224+ if (proc->mode & GR_LEARN)
9225+ return;
9226+
9227+ for (i = 0; i < RLIM_NLIMITS; i++) {
9228+ if (!(proc->resmask & (1 << i)))
9229+ continue;
9230+
9231+ current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
9232+ current->rlim[i].rlim_max = proc->res[i].rlim_max;
9233+ }
9234+
9235+ return;
9236+}
9237+
9238+void
9239+gr_set_pax_flags(struct task_struct *task)
9240+{
9241+ struct acl_subject_label *proc;
9242+
9243+ if (unlikely(!(gr_status & GR_READY)))
9244+ return;
9245+
9246+ proc = task->acl;
9247+
9248+ if (proc->mode & GR_PAXPAGE)
9249+ task->flags &= ~PF_PAX_PAGEEXEC;
9250+ if (proc->mode & GR_PAXSEGM)
9251+ task->flags &= ~PF_PAX_SEGMEXEC;
9252+ if (proc->mode & GR_PAXGCC)
9253+ task->flags |= PF_PAX_EMUTRAMP;
9254+ if (proc->mode & GR_PAXMPROTECT)
9255+ task->flags &= ~PF_PAX_MPROTECT;
9256+ if (proc->mode & GR_PAXRANDMMAP)
9257+ task->flags &= ~PF_PAX_RANDMMAP;
9258+ if (proc->mode & GR_PAXRANDEXEC)
9259+ task->flags |= PF_PAX_RANDEXEC;
9260+
9261+ return;
9262+}
9263+
9264+static __inline__ void
9265+do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
9266+{
9267+ task->role = lookup_acl_role_label(task, uid, gid);
9268+
9269+ return;
9270+}
9271+
9272+void
9273+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
9274+{
9275+ struct acl_object_label *obj;
9276+ struct file *filp;
9277+
9278+ if (unlikely(!(gr_status & GR_READY)))
9279+ return;
9280+
9281+ filp = task->exec_file;
9282+
9283+ /* kernel process, we'll give them the kernel role */
9284+ if (unlikely(!filp)) {
9285+ task->role = kernel_role;
9286+ task->acl = kernel_role->root_label;
9287+ return;
9288+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
9289+ do_set_role_label(task, uid, gid);
9290+
9291+ task->acl =
9292+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
9293+
9294+ task->is_writable = 0;
9295+
9296+ /* ignore additional mmap checks for processes that are writable
9297+ by the default ACL */
9298+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9299+ if (unlikely(obj->mode & GR_WRITE))
9300+ task->is_writable = 1;
9301+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9302+ if (unlikely(obj->mode & GR_WRITE))
9303+ task->is_writable = 1;
9304+
9305+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9306+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9307+#endif
9308+
9309+ gr_set_proc_res();
9310+
9311+ return;
9312+}
9313+
9314+void
9315+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
9316+{
9317+ struct acl_subject_label *newacl;
9318+ struct acl_object_label *obj;
9319+ __u32 retmode;
9320+
9321+ if (unlikely(!(gr_status & GR_READY)))
9322+ return;
9323+
9324+ newacl = chk_subj_label(dentry, mnt, current->role);
9325+
9326+ obj = chk_obj_label(dentry, mnt, current->acl);
9327+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
9328+
9329+ if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
9330+ if (obj->nested)
9331+ current->acl = obj->nested;
9332+ else
9333+ current->acl = newacl;
9334+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
9335+ security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
9336+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
9337+
9338+ current->is_writable = 0;
9339+
9340+ /* ignore additional mmap checks for processes that are writable
9341+ by the default ACL */
9342+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
9343+ if (unlikely(obj->mode & GR_WRITE))
9344+ current->is_writable = 1;
9345+ obj = chk_obj_label(dentry, mnt, current->role->root_label);
9346+ if (unlikely(obj->mode & GR_WRITE))
9347+ current->is_writable = 1;
9348+
9349+ gr_set_proc_res();
9350+
9351+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9352+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
9353+#endif
9354+ return;
9355+}
9356+
9357+static __inline__ void
9358+do_handle_delete(const ino_t ino, const kdev_t dev)
9359+{
9360+ struct acl_object_label *matchpo;
9361+ struct acl_subject_label *matchps;
9362+ struct acl_subject_label *i;
9363+ struct acl_role_label *role;
9364+
9365+ for (role = role_list_head; role; role = role->next) {
9366+ for (i = role->proc_subject; i; i = i->next) {
9367+ if (unlikely(i->parent_subject &&
9368+ (i->inode == ino) &&
9369+ (i->device == dev)))
9370+ i->mode |= GR_DELETED;
9371+ if (unlikely((matchpo =
9372+ lookup_acl_obj_label(ino, dev, i)) != NULL))
9373+ matchpo->mode |= GR_DELETED;
9374+ }
9375+
9376+ if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
9377+ matchps->mode |= GR_DELETED;
9378+ }
9379+
9380+ return;
9381+}
9382+
9383+void
9384+gr_handle_delete(const ino_t ino, const kdev_t dev)
9385+{
9386+ if (unlikely(!(gr_status & GR_READY)))
9387+ return;
9388+
9389+ write_lock(&gr_inode_lock);
9390+ if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
9391+ do_handle_delete(ino, dev);
9392+ write_unlock(&gr_inode_lock);
9393+
9394+ return;
9395+}
9396+
9397+static __inline__ void
9398+update_acl_obj_label(const ino_t oldinode, const kdev_t olddevice,
9399+ const ino_t newinode, const kdev_t newdevice,
9400+ struct acl_subject_label *subj)
9401+{
9402+ unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
9403+ struct acl_object_label **match;
9404+ struct acl_object_label *tmp;
9405+ __u8 i = 0;
9406+
9407+ match = &subj->obj_hash[index];
9408+
9409+ while (*match && ((*match)->inode != oldinode ||
9410+ (*match)->device != olddevice ||
9411+ !((*match)->mode & GR_DELETED))) {
9412+ index = (index + (1 << i)) % subj->obj_hash_size;
9413+ match = &subj->obj_hash[index];
9414+ i = (i + 1) % 32;
9415+ }
9416+
9417+ if (*match && ((*match) != deleted_object)
9418+ && ((*match)->inode == oldinode)
9419+ && ((*match)->device == olddevice)
9420+ && ((*match)->mode & GR_DELETED)) {
9421+ tmp = *match;
9422+ tmp->inode = newinode;
9423+ tmp->device = newdevice;
9424+ tmp->mode &= ~GR_DELETED;
9425+
9426+ *match = deleted_object;
9427+
9428+ insert_acl_obj_label(tmp, subj);
9429+ }
9430+
9431+ return;
9432+}
9433+
9434+static __inline__ void
9435+update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice,
9436+ const ino_t newinode, const kdev_t newdevice,
9437+ struct acl_role_label *role)
9438+{
9439+ struct acl_subject_label **s_hash = role->subj_hash;
9440+ unsigned long subj_size = role->subj_hash_size;
9441+ unsigned long index = fhash(oldinode, olddevice, subj_size);
9442+ struct acl_subject_label **match;
9443+ struct acl_subject_label *tmp;
9444+ __u8 i = 0;
9445+
9446+ match = &s_hash[index];
9447+
9448+ while (*match && ((*match)->inode != oldinode ||
9449+ (*match)->device != olddevice ||
9450+ !((*match)->mode & GR_DELETED))) {
9451+ index = (index + (1 << i)) % subj_size;
9452+ i = (i + 1) % 32;
9453+ match = &s_hash[index];
9454+ }
9455+
9456+ if (*match && (*match != deleted_subject)
9457+ && ((*match)->inode == oldinode)
9458+ && ((*match)->device == olddevice)
9459+ && ((*match)->mode & GR_DELETED)) {
9460+ tmp = *match;
9461+
9462+ tmp->inode = newinode;
9463+ tmp->device = newdevice;
9464+ tmp->mode &= ~GR_DELETED;
9465+
9466+ *match = deleted_subject;
9467+
9468+ insert_acl_subj_label(tmp, role);
9469+ }
9470+
9471+ return;
9472+}
9473+
9474+static __inline__ void
9475+update_inodev_entry(const ino_t oldinode, const kdev_t olddevice,
9476+ const ino_t newinode, const kdev_t newdevice)
9477+{
9478+ unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
9479+ struct name_entry **match;
9480+ struct name_entry *tmp;
9481+ __u8 i = 0;
9482+
9483+ match = &inodev_set.n_hash[index];
9484+
9485+ while (*match
9486+ && ((*match)->inode != oldinode
9487+ || (*match)->device != olddevice)) {
9488+ index = (index + (1 << i)) % inodev_set.n_size;
9489+ i = (i + 1) % 32;
9490+ match = &inodev_set.n_hash[index];
9491+ }
9492+
9493+ if (*match && (*match != deleted_inodev)
9494+ && ((*match)->inode == oldinode)
9495+ && ((*match)->device == olddevice)) {
9496+ tmp = *match;
9497+
9498+ tmp->inode = newinode;
9499+ tmp->device = newdevice;
9500+
9501+ *match = deleted_inodev;
9502+
9503+ insert_inodev_entry(tmp);
9504+ }
9505+
9506+ return;
9507+}
9508+
9509+static __inline__ void
9510+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
9511+ const struct vfsmount *mnt)
9512+{
9513+ struct acl_subject_label *i;
9514+ struct acl_role_label *role;
9515+
9516+ for (role = role_list_head; role; role = role->next) {
9517+ update_acl_subj_label(matchn->inode, matchn->device,
9518+ dentry->d_inode->i_ino,
9519+ dentry->d_inode->i_dev, role);
9520+
9521+ for (i = role->proc_subject; i; i = i->next) {
9522+ if (unlikely(i->parent_subject &&
9523+ (i->inode == dentry->d_inode->i_ino) &&
9524+ (i->device == dentry->d_inode->i_dev))) {
9525+ i->inode = dentry->d_inode->i_ino;
9526+ i->device = dentry->d_inode->i_dev;
9527+ }
9528+ update_acl_obj_label(matchn->inode, matchn->device,
9529+ dentry->d_inode->i_ino,
9530+ dentry->d_inode->i_dev, i);
9531+ }
9532+ }
9533+
9534+ update_inodev_entry(matchn->inode, matchn->device,
9535+ dentry->d_inode->i_ino, dentry->d_inode->i_dev);
9536+
9537+ return;
9538+}
9539+
9540+void
9541+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
9542+{
9543+ struct name_entry *matchn;
9544+
9545+ if (unlikely(!(gr_status & GR_READY)))
9546+ return;
9547+
9548+ matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
9549+
9550+ if (unlikely((unsigned long)matchn)) {
9551+ write_lock(&gr_inode_lock);
9552+ do_handle_create(matchn, dentry, mnt);
9553+ write_unlock(&gr_inode_lock);
9554+ }
9555+
9556+ return;
9557+}
9558+
9559+int
9560+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
9561+ struct dentry *old_dentry,
9562+ struct dentry *new_dentry,
9563+ struct vfsmount *mnt, const __u8 replace)
9564+{
9565+ struct name_entry *matchn;
9566+ int error = 0;
9567+
9568+ matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9569+
9570+ lock_kernel();
9571+ error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
9572+ unlock_kernel();
9573+
9574+ if (unlikely(error))
9575+ return error;
9576+
9577+ /* we wouldn't have to check d_inode if it weren't for
9578+ NFS silly-renaming
9579+ */
9580+
9581+ write_lock(&gr_inode_lock);
9582+ if (unlikely(replace && new_dentry->d_inode)) {
9583+ if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
9584+ new_dentry->d_inode->i_dev) &&
9585+ (old_dentry->d_inode->i_nlink <= 1)))
9586+ do_handle_delete(new_dentry->d_inode->i_ino,
9587+ new_dentry->d_inode->i_dev);
9588+ }
9589+
9590+ if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
9591+ old_dentry->d_inode->i_dev) &&
9592+ (old_dentry->d_inode->i_nlink <= 1)))
9593+ do_handle_delete(old_dentry->d_inode->i_ino,
9594+ old_dentry->d_inode->i_dev);
9595+
9596+ if (unlikely((unsigned long)matchn))
9597+ do_handle_create(matchn, old_dentry, mnt);
9598+ write_unlock(&gr_inode_lock);
9599+
9600+ return error;
9601+}
9602+
9603+static int
9604+lookup_special_role_auth(const char *rolename, unsigned char **salt,
9605+ unsigned char **sum)
9606+{
9607+ struct acl_role_label *r;
9608+ struct role_transition *trans;
9609+ __u16 i;
9610+ int found = 0;
9611+
9612+ /* check transition table */
9613+
9614+ for (trans = current->role->transitions; trans; trans = trans->next) {
9615+ if (!strcmp(rolename, trans->rolename)) {
9616+ found = 1;
9617+ break;
9618+ }
9619+ }
9620+
9621+ if (!found)
9622+ return 0;
9623+
9624+ /* handle special roles that do not require authentication */
9625+
9626+ for (r = role_list_head; r; r = r->next) {
9627+ if (!strcmp(rolename, r->rolename)
9628+ && (r->roletype & GR_ROLE_NOPW)) {
9629+ *salt = NULL;
9630+ *sum = NULL;
9631+ return 1;
9632+ }
9633+ }
9634+
9635+ for (i = 0; i < num_sprole_pws; i++) {
9636+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
9637+ *salt = acl_special_roles[i]->salt;
9638+ *sum = acl_special_roles[i]->sum;
9639+ return 1;
9640+ }
9641+ }
9642+
9643+ return 0;
9644+}
9645+
9646+static void
9647+assign_special_role(char *rolename)
9648+{
9649+ struct acl_object_label *obj;
9650+ struct acl_role_label *r;
9651+ struct acl_role_label *assigned = NULL;
9652+ struct task_struct *tsk;
9653+ struct file *filp;
9654+
9655+ for (r = role_list_head; r; r = r->next)
9656+ if (!strcmp(rolename, r->rolename) &&
9657+ (r->roletype & GR_ROLE_SPECIAL))
9658+ assigned = r;
9659+
9660+ if (!assigned)
9661+ return;
9662+
9663+ tsk = current->p_pptr;
9664+ filp = tsk->exec_file;
9665+
9666+ if (tsk && filp) {
9667+ tsk->is_writable = 0;
9668+
9669+ acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
9670+ tsk->acl_sp_role = 1;
9671+ tsk->acl_role_id = acl_sp_role_value;
9672+ tsk->role = assigned;
9673+ tsk->acl =
9674+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
9675+
9676+ /* ignore additional mmap checks for processes that are writable
9677+ by the default ACL */
9678+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9679+ if (unlikely(obj->mode & GR_WRITE))
9680+ tsk->is_writable = 1;
9681+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
9682+ if (unlikely(obj->mode & GR_WRITE))
9683+ tsk->is_writable = 1;
9684+
9685+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9686+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
9687+#endif
9688+ }
9689+
9690+ return;
9691+}
9692+
9693+ssize_t
9694+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
9695+{
9696+ struct gr_arg *arg;
9697+ unsigned char *sprole_salt;
9698+ unsigned char *sprole_sum;
9699+ int error = sizeof (struct gr_arg);
9700+ int error2 = 0;
9701+
9702+ down(&gr_dev_sem);
9703+
9704+ arg = (struct gr_arg *) buf;
9705+
9706+ if (count != sizeof (struct gr_arg)) {
9707+ security_alert_good(GR_DEV_ACL_MSG, count,
9708+ (int) sizeof (struct gr_arg));
9709+ error = -EINVAL;
9710+ goto out;
9711+ }
9712+
9713+ if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9714+ && time_before_eq(gr_auth_expires, jiffies)) {
9715+ gr_auth_expires = 0;
9716+ gr_auth_attempts = 0;
9717+ }
9718+
9719+ if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
9720+ error = -EFAULT;
9721+ goto out;
9722+ }
9723+
9724+ if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) {
9725+ error = -EBUSY;
9726+ goto out;
9727+ }
9728+
9729+ /* if non-root trying to do anything other than use a special role,
9730+ do not attempt authentication, do not count towards authentication
9731+ locking
9732+ */
9733+
9734+ if (gr_usermode->mode != SPROLE && current->uid) {
9735+ error = -EPERM;
9736+ goto out;
9737+ }
9738+
9739+ /* ensure pw and special role name are null terminated */
9740+
9741+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
9742+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
9743+
9744+ /* Okay.
9745+ * We have our enough of the argument structure..(we have yet
9746+ * to copy_from_user the tables themselves) . Copy the tables
9747+ * only if we need them, i.e. for loading operations. */
9748+
9749+ switch (gr_usermode->mode) {
9750+ case STATUS:
9751+ if (gr_status & GR_READY)
9752+ error = 1;
9753+ else
9754+ error = 2;
9755+ goto out;
9756+ case SHUTDOWN:
9757+ if ((gr_status & GR_READY)
9758+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9759+ gr_status &= ~GR_READY;
9760+ security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
9761+ free_variables();
9762+ memset(gr_usermode, 0, sizeof (struct gr_arg));
9763+ memset(gr_system_salt, 0, GR_SALT_LEN);
9764+ memset(gr_system_sum, 0, GR_SHA_LEN);
9765+ } else if (gr_status & GR_READY) {
9766+ security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
9767+ error = -EPERM;
9768+ } else {
9769+ security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
9770+ error = -EAGAIN;
9771+ }
9772+ break;
9773+ case ENABLE:
9774+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
9775+ security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
9776+ else {
9777+ if (gr_status & GR_READY)
9778+ error = -EAGAIN;
9779+ else
9780+ error = error2;
9781+ security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
9782+ DEFAULTSECARGS);
9783+ }
9784+ break;
9785+ case RELOAD:
9786+ if (!(gr_status & GR_READY)) {
9787+ security_alert_good(GR_RELOADI_ACL_MSG);
9788+ error = -EAGAIN;
9789+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9790+ lock_kernel();
9791+ gr_status &= ~GR_READY;
9792+ free_variables();
9793+ if (!(error2 = gracl_init(gr_usermode))) {
9794+ unlock_kernel();
9795+ security_alert_good(GR_RELOAD_ACL_MSG,
9796+ GR_VERSION);
9797+ } else {
9798+ unlock_kernel();
9799+ error = error2;
9800+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
9801+ DEFAULTSECARGS);
9802+ }
9803+ } else {
9804+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
9805+ DEFAULTSECARGS);
9806+ error = -EPERM;
9807+ }
9808+ break;
9809+ case SEGVMOD:
9810+ if (unlikely(!(gr_status & GR_READY))) {
9811+ security_alert_good(GR_SEGVMODI_ACL_MSG,
9812+ DEFAULTSECARGS);
9813+ error = -EAGAIN;
9814+ break;
9815+ }
9816+
9817+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9818+ security_alert_good(GR_SEGVMODS_ACL_MSG,
9819+ DEFAULTSECARGS);
9820+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
9821+ struct acl_subject_label *segvacl;
9822+ segvacl =
9823+ lookup_acl_subj_label(gr_usermode->segv_inode,
9824+ gr_usermode->segv_device,
9825+ current->role);
9826+ if (segvacl) {
9827+ segvacl->crashes = 0;
9828+ segvacl->expires = 0;
9829+ }
9830+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
9831+ gr_remove_uid(gr_usermode->segv_uid);
9832+ }
9833+ } else {
9834+ security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
9835+ error = -EPERM;
9836+ }
9837+ break;
9838+ case SPROLE:
9839+ if (unlikely(!(gr_status & GR_READY))) {
9840+ security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
9841+ error = -EAGAIN;
9842+ break;
9843+ }
9844+
9845+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9846+ && time_before_eq(current->role->expires, jiffies)) {
9847+ current->role->expires = 0;
9848+ current->role->auth_attempts = 0;
9849+ }
9850+
9851+ if (time_after(current->role->expires, jiffies)) {
9852+ error = -EBUSY;
9853+ goto out;
9854+ }
9855+
9856+ if (lookup_special_role_auth
9857+ (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
9858+ && ((!sprole_salt && !sprole_sum)
9859+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
9860+ assign_special_role(gr_usermode->sp_role);
9861+ security_alert_good(GR_SPROLES_ACL_MSG,
9862+ (current->p_pptr) ? current->
9863+ p_pptr->role->rolename : "",
9864+ acl_sp_role_value, DEFAULTSECARGS);
9865+ } else {
9866+ security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
9867+ DEFAULTSECARGS);
9868+ error = -EPERM;
9869+ current->role->auth_attempts++;
9870+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9871+ current->role->expires =
9872+ jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
9873+ security_alert(GR_MAXROLEPW_ACL_MSG,
9874+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
9875+ gr_usermode->sp_role, DEFAULTSECARGS);
9876+ }
9877+
9878+ goto out;
9879+ }
9880+ break;
9881+ case UNSPROLE:
9882+ if (unlikely(!(gr_status & GR_READY))) {
9883+ security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
9884+ error = -EAGAIN;
9885+ break;
9886+ }
9887+
9888+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9889+ && time_before_eq(current->role->expires, jiffies)) {
9890+ current->role->expires = 0;
9891+ current->role->auth_attempts = 0;
9892+ }
9893+
9894+ if (time_after(current->role->expires, jiffies)) {
9895+ error = -EBUSY;
9896+ goto out;
9897+ }
9898+
9899+ if ((current->role->roletype & GR_ROLE_SPECIAL) &&
9900+ lookup_special_role_auth
9901+ (current->role->rolename, &sprole_salt, &sprole_sum)
9902+ && ((!sprole_salt && !sprole_sum)
9903+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
9904+ security_alert_good(GR_UNSPROLES_ACL_MSG,
9905+ (current->p_pptr) ? current->
9906+ p_pptr->role->rolename : "",
9907+ (current->p_pptr) ? current->
9908+ p_pptr->acl_role_id : 0, DEFAULTSECARGS);
9909+ gr_set_acls(1);
9910+ if (current->p_pptr)
9911+ current->p_pptr->acl_sp_role = 0;
9912+ } else {
9913+ security_alert(GR_UNSPROLEF_ACL_MSG, gr_usermode->sp_role,
9914+ DEFAULTSECARGS);
9915+ error = -EPERM;
9916+ current->role->auth_attempts++;
9917+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9918+ current->role->expires =
9919+ jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
9920+ security_alert(GR_MAXROLEPW_ACL_MSG,
9921+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
9922+ current->role->rolename, DEFAULTSECARGS);
9923+ }
9924+
9925+ goto out;
9926+ }
9927+ break;
9928+ default:
9929+ security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
9930+ DEFAULTSECARGS);
9931+ error = -EINVAL;
9932+ break;
9933+ }
9934+
9935+ if (error != -EPERM)
9936+ goto out;
9937+
9938+ gr_auth_attempts++;
9939+
9940+ if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9941+ security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
9942+ gr_auth_expires = jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
9943+ }
9944+
9945+ out:
9946+ up(&gr_dev_sem);
9947+ return error;
9948+}
9949+
9950+int
9951+gr_set_acls(const int type)
9952+{
9953+ struct acl_object_label *obj;
9954+ struct task_struct *task;
9955+ struct file *filp;
9956+ unsigned short i;
9957+
9958+ read_lock(&tasklist_lock);
9959+ for_each_task(task) {
9960+ /* check to see if we're called from the exit handler,
9961+ if so, only replace ACLs that have inherited the admin
9962+ ACL */
9963+
9964+ if (type && (task->role != current->role ||
9965+ task->acl_role_id != current->acl_role_id))
9966+ continue;
9967+
9968+ task->acl_role_id = 0;
9969+
9970+ if ((filp = task->exec_file)) {
9971+ do_set_role_label(task, task->uid, task->gid);
9972+
9973+ task->acl =
9974+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
9975+ task->role);
9976+ if (task->acl) {
9977+ struct acl_subject_label *curr;
9978+ curr = task->acl;
9979+
9980+ task->is_writable = 0;
9981+ /* ignore additional mmap checks for processes that are writable
9982+ by the default ACL */
9983+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9984+ if (unlikely(obj->mode & GR_WRITE))
9985+ task->is_writable = 1;
9986+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9987+ if (unlikely(obj->mode & GR_WRITE))
9988+ task->is_writable = 1;
9989+
9990+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9991+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9992+#endif
9993+ if (!(curr->mode & GR_LEARN))
9994+ for (i = 0; i < RLIM_NLIMITS; i++) {
9995+ if (!(curr->resmask & (1 << i)))
9996+ continue;
9997+
9998+ task->rlim[i].rlim_cur =
9999+ curr->res[i].rlim_cur;
10000+ task->rlim[i].rlim_max =
10001+ curr->res[i].rlim_max;
10002+ }
10003+ } else {
10004+ read_unlock(&tasklist_lock);
10005+ security_alert_good(GR_DEFACL_MSG, task->comm,
10006+ task->pid);
10007+ return 1;
10008+ }
10009+ } else {
10010+ // it's a kernel process
10011+ task->role = kernel_role;
10012+ task->acl = kernel_role->root_label;
10013+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
10014+ task->acl->mode &= ~GR_FIND;
10015+#endif
10016+ }
10017+ }
10018+ read_unlock(&tasklist_lock);
10019+ return 0;
10020+}
10021+
10022+void
10023+gr_learn_resource(const struct task_struct *task,
10024+ const int res, const unsigned long wanted)
10025+{
10026+ struct acl_subject_label *acl;
10027+
10028+ if (unlikely((gr_status & GR_READY) &&
10029+ task->acl && (task->acl->mode & GR_LEARN)))
10030+ goto skip_reslog;
10031+
10032+#ifdef CONFIG_GRKERNSEC_RESLOG
10033+ gr_log_resource(task, res, wanted);
10034+#endif
10035+ skip_reslog:
10036+
10037+ if (unlikely(!(gr_status & GR_READY) || !wanted))
10038+ return;
10039+
10040+ acl = task->acl;
10041+
10042+ if (likely(!acl || !(acl->mode & GR_LEARN) ||
10043+ !(acl->resmask & (1 << (unsigned short) res))))
10044+ return;
10045+
10046+ if (wanted >= acl->res[res].rlim_cur) {
10047+ unsigned long res_add;
10048+
10049+ res_add = wanted;
10050+ switch (res) {
10051+ case RLIMIT_CPU:
10052+ res_add += GR_RLIM_CPU_BUMP;
10053+ break;
10054+ case RLIMIT_FSIZE:
10055+ res_add += GR_RLIM_FSIZE_BUMP;
10056+ break;
10057+ case RLIMIT_DATA:
10058+ res_add += GR_RLIM_DATA_BUMP;
10059+ break;
10060+ case RLIMIT_STACK:
10061+ res_add += GR_RLIM_STACK_BUMP;
10062+ break;
10063+ case RLIMIT_CORE:
10064+ res_add += GR_RLIM_CORE_BUMP;
10065+ break;
10066+ case RLIMIT_RSS:
10067+ res_add += GR_RLIM_RSS_BUMP;
10068+ break;
10069+ case RLIMIT_NPROC:
10070+ res_add += GR_RLIM_NPROC_BUMP;
10071+ break;
10072+ case RLIMIT_NOFILE:
10073+ res_add += GR_RLIM_NOFILE_BUMP;
10074+ break;
10075+ case RLIMIT_MEMLOCK:
10076+ res_add += GR_RLIM_MEMLOCK_BUMP;
10077+ break;
10078+ case RLIMIT_AS:
10079+ res_add += GR_RLIM_AS_BUMP;
10080+ break;
10081+ case RLIMIT_LOCKS:
10082+ res_add += GR_RLIM_LOCKS_BUMP;
10083+ break;
10084+ }
10085+
10086+ acl->res[res].rlim_cur = res_add;
10087+
10088+ if (wanted > acl->res[res].rlim_max)
10089+ acl->res[res].rlim_max = res_add;
10090+
10091+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10092+ current->role->roletype, acl->filename,
10093+ acl->res[res].rlim_cur, acl->res[res].rlim_max,
10094+ "", (unsigned long) res);
10095+ }
10096+
10097+ return;
10098+}
10099+
10100+#ifdef CONFIG_SYSCTL
10101+extern struct proc_dir_entry *proc_sys_root;
10102+
10103+__u32
10104+gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
10105+ const void *newval)
10106+{
10107+ struct proc_dir_entry *tmp;
10108+ struct nameidata nd;
10109+ const char *proc_sys = "/proc/sys";
10110+ char *path = gr_shared_page[0][smp_processor_id()];
10111+ struct acl_object_label *obj;
10112+ unsigned short len = 0, pos = 0, depth = 0, i;
10113+ __u32 err = 0;
10114+ __u32 mode = 0;
10115+
10116+ if (unlikely(!(gr_status & GR_READY)))
10117+ return 1;
10118+
10119+ if (oldval)
10120+ mode |= GR_READ;
10121+ if (newval)
10122+ mode |= GR_WRITE;
10123+
10124+ /* convert the requested sysctl entry into a pathname */
10125+
10126+ for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
10127+ len += strlen(tmp->name);
10128+ len++;
10129+ depth++;
10130+ }
10131+
10132+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
10133+ return 0; // deny
10134+
10135+ memset(path, 0, PAGE_SIZE);
10136+
10137+ memcpy(path, proc_sys, strlen(proc_sys));
10138+
10139+ pos += strlen(proc_sys);
10140+
10141+ for (; depth > 0; depth--) {
10142+ path[pos] = '/';
10143+ pos++;
10144+ for (i = 1, tmp = table->de; tmp != proc_sys_root;
10145+ tmp = tmp->parent) {
10146+ if (depth == i) {
10147+ memcpy(path + pos, tmp->name,
10148+ strlen(tmp->name));
10149+ pos += strlen(tmp->name);
10150+ }
10151+ i++;
10152+ }
10153+ }
10154+
10155+ if (path_init(path, LOOKUP_FOLLOW, &nd))
10156+ err = path_walk(path, &nd);
10157+
10158+ if (err)
10159+ goto out;
10160+
10161+ obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
10162+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
10163+
10164+ if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
10165+ __u32 new_mode = mode;
10166+
10167+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10168+
10169+ err = new_mode;
10170+ gr_log_learn(current->role, current->uid, current->gid,
10171+ current, path, new_mode);
10172+ } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
10173+ security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
10174+ (mode & GR_READ) ? " reading" : "",
10175+ (mode & GR_WRITE) ? " writing" : "",
10176+ DEFAULTSECARGS);
10177+ err = 0;
10178+ } else if ((err & mode) != mode) {
10179+ err = 0;
10180+ } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
10181+ security_audit(GR_SYSCTL_ACL_MSG, "successful",
10182+ path, (mode & GR_READ) ? " reading" : "",
10183+ (mode & GR_WRITE) ? " writing" : "",
10184+ DEFAULTSECARGS);
10185+ }
10186+
10187+ path_release(&nd);
10188+
10189+ out:
10190+ return err;
10191+}
10192+#endif
10193+
10194+int
10195+gr_handle_ptrace(struct task_struct *task, const long request)
10196+{
10197+ struct file *filp;
10198+ __u32 retmode;
10199+
10200+ if (unlikely(!(gr_status & GR_READY)))
10201+ return 0;
10202+
10203+ filp = task->exec_file;
10204+
10205+ if (unlikely(!filp))
10206+ return 0;
10207+
10208+ retmode = gr_search_file(filp->f_dentry, GR_PTRACERD, filp->f_vfsmnt);
10209+
10210+ if (retmode & GR_PTRACERD) {
10211+ switch (request) {
10212+ case PTRACE_POKETEXT:
10213+ case PTRACE_POKEDATA:
10214+ case PTRACE_POKEUSR:
10215+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
10216+ case PTRACE_SETREGS:
10217+ case PTRACE_SETFPREGS:
10218+#endif
10219+#ifdef CONFIG_X86
10220+ case PTRACE_SETFPXREGS:
10221+#endif
10222+#ifdef CONFIG_ALTIVEC
10223+ case PTRACE_SETVRREGS:
10224+#endif
10225+ return 1;
10226+ default:
10227+ return 0;
10228+ }
10229+ } else if (!(current->acl->mode & GR_OVERRIDE) &&
10230+ !(current->role->roletype & GR_ROLE_GOD)
10231+ && (current->acl != task->acl
10232+ || (current->acl != current->role->root_label
10233+ && current->pid != task->pid))) {
10234+ security_alert(GR_PTRACE_ACL_MSG,
10235+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10236+ task->comm, task->pid, DEFAULTSECARGS);
10237+ return 1;
10238+ }
10239+
10240+ return 0;
10241+}
10242+
10243+int
10244+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
10245+{
10246+ __u32 retmode;
10247+ struct acl_subject_label *subj;
10248+
10249+ if (unlikely(!(gr_status & GR_READY)))
10250+ return 0;
10251+
10252+ if (unlikely
10253+ ((current->ptrace & PT_PTRACED)
10254+ && !(current->acl->mode & GR_OVERRIDE)))
10255+ retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
10256+ else
10257+ return 0;
10258+
10259+ subj = chk_subj_label(dentry, mnt, current->role);
10260+
10261+ if (!(retmode & GR_PTRACERD) &&
10262+ !(current->role->roletype & GR_ROLE_GOD) &&
10263+ (current->acl != subj)) {
10264+ security_alert(GR_PTRACE_EXEC_ACL_MSG,
10265+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
10266+ return 1;
10267+ }
10268+
10269+ return 0;
10270+}
10271+
10272+int
10273+gr_handle_mmap(const struct file *filp, const unsigned long prot)
10274+{
10275+ struct acl_object_label *obj, *obj2;
10276+
10277+ if (unlikely(!(gr_status & GR_READY) ||
10278+ (current->acl->mode & GR_OVERRIDE) || !filp ||
10279+ !(prot & PROT_EXEC)))
10280+ return 0;
10281+
10282+ if (unlikely(current->is_writable))
10283+ return 0;
10284+
10285+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10286+ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
10287+ current->role->root_label);
10288+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
10289+ security_alert(GR_WRITLIB_ACL_MSG,
10290+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10291+ DEFAULTSECARGS);
10292+ return 1;
10293+ }
10294+
10295+ return 0;
10296+}
10297+
10298+int
10299+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
10300+{
10301+ __u32 mode;
10302+
10303+ if (unlikely(!file || !(prot & PROT_EXEC)))
10304+ return 1;
10305+
10306+ mode =
10307+ gr_search_file(file->f_dentry,
10308+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10309+ file->f_vfsmnt);
10310+
10311+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10312+ security_alert(GR_MMAP_ACL_MSG, "denied",
10313+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
10314+ DEFAULTSECARGS);
10315+ return 0;
10316+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10317+ return 0;
10318+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10319+ security_audit(GR_MMAP_ACL_MSG, "successful",
10320+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
10321+ DEFAULTSECARGS);
10322+ return 1;
10323+ }
10324+
10325+ return 1;
10326+}
10327+
10328+int
10329+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
10330+{
10331+ __u32 mode;
10332+
10333+ if (unlikely(!file || !(prot & PROT_EXEC)))
10334+ return 1;
10335+
10336+ mode =
10337+ gr_search_file(file->f_dentry,
10338+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10339+ file->f_vfsmnt);
10340+
10341+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10342+ security_alert(GR_MPROTECT_ACL_MSG, "denied",
10343+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
10344+ DEFAULTSECARGS);
10345+ return 0;
10346+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10347+ return 0;
10348+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10349+ security_audit(GR_MPROTECT_ACL_MSG, "successful",
10350+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
10351+ DEFAULTSECARGS);
10352+ return 1;
10353+ }
10354+
10355+ return 1;
10356+}
10357+
10358+void
10359+gr_acl_handle_psacct(struct task_struct *task, const long code)
10360+{
10361+ unsigned long runtime;
10362+ unsigned long cputime;
10363+ unsigned int wday, cday;
10364+ __u8 whr, chr;
10365+ __u8 wmin, cmin;
10366+ __u8 wsec, csec;
10367+ char cur_tty[64] = { 0 };
10368+ char parent_tty[64] = { 0 };
10369+
10370+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
10371+ !(task->acl->mode & GR_PROCACCT)))
10372+ return;
10373+
10374+ runtime = (jiffies - task->start_time) / HZ;
10375+ wday = runtime / (3600 * 24);
10376+ runtime -= wday * (3600 * 24);
10377+ whr = runtime / 3600;
10378+ runtime -= whr * 3600;
10379+ wmin = runtime / 60;
10380+ runtime -= wmin * 60;
10381+ wsec = runtime;
10382+
10383+ cputime = (task->times.tms_utime + task->times.tms_stime) / HZ;
10384+ cday = cputime / (3600 * 24);
10385+ cputime -= cday * (3600 * 24);
10386+ chr = cputime / 3600;
10387+ cputime -= chr * 3600;
10388+ cmin = cputime / 60;
10389+ cputime -= cmin * 60;
10390+ csec = cputime;
10391+
10392+ security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
10393+ task->pid, NIPQUAD(task->curr_ip), tty_name(task->tty,
10394+ cur_tty),
10395+ task->uid, task->euid, task->gid, task->egid, wday, whr,
10396+ wmin, wsec, cday, chr, cmin, csec,
10397+ (task->
10398+ flags & PF_SIGNALED) ? "killed by signal" : "exited",
10399+ code, gr_parent_task_fullpath(task),
10400+ task->p_pptr->comm, task->p_pptr->pid,
10401+ NIPQUAD(task->p_pptr->curr_ip),
10402+ tty_name(task->p_pptr->tty, parent_tty),
10403+ task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid,
10404+ task->p_pptr->egid);
10405+
10406+ return;
10407+}
10408+
10409+void gr_set_kernel_label(struct task_struct *task)
10410+{
10411+ if (gr_status & GR_READY) {
10412+ task->role = kernel_role;
10413+ task->acl = kernel_role->root_label;
10414+ }
10415+ return;
10416+}
474a6d91
AM
10417diff -urN linux-2.4.22.org/grsecurity/gracl_cap.c linux-2.4.22/grsecurity/gracl_cap.c
10418--- linux-2.4.22.org/grsecurity/gracl_cap.c 1970-01-01 01:00:00.000000000 +0100
10419+++ linux-2.4.22/grsecurity/gracl_cap.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
10420@@ -0,0 +1,71 @@
10421+/* capability handling routines, (c) Brad Spengler 2002,2003 */
10422+
10423+#include <linux/kernel.h>
10424+#include <linux/sched.h>
10425+#include <linux/capability.h>
10426+#include <linux/gracl.h>
10427+#include <linux/grsecurity.h>
10428+#include <linux/grinternal.h>
10429+
10430+static const char *captab_log[29] = {
10431+ "CAP_CHOWN",
10432+ "CAP_DAC_OVERRIDE",
10433+ "CAP_DAC_READ_SEARCH",
10434+ "CAP_FOWNER",
10435+ "CAP_FSETID",
10436+ "CAP_KILL",
10437+ "CAP_SETGID",
10438+ "CAP_SETUID",
10439+ "CAP_SETPCAP",
10440+ "CAP_LINUX_IMMUTABLE",
10441+ "CAP_NET_BIND_SERVICE",
10442+ "CAP_NET_BROADCAST",
10443+ "CAP_NET_ADMIN",
10444+ "CAP_NET_RAW",
10445+ "CAP_IPC_LOCK",
10446+ "CAP_IPC_OWNER",
10447+ "CAP_SYS_MODULE",
10448+ "CAP_SYS_RAWIO",
10449+ "CAP_SYS_CHROOT",
10450+ "CAP_SYS_PTRACE",
10451+ "CAP_SYS_PACCT",
10452+ "CAP_SYS_ADMIN",
10453+ "CAP_SYS_BOOT",
10454+ "CAP_SYS_NICE",
10455+ "CAP_SYS_RESOURCE",
10456+ "CAP_SYS_TIME",
10457+ "CAP_SYS_TTY_CONFIG",
10458+ "CAP_MKNOD",
10459+ "CAP_LEASE"
10460+};
10461+
10462+int
10463+gr_is_capable(const int cap)
10464+{
10465+ struct acl_subject_label *curracl;
10466+
10467+ if (!gr_acl_is_enabled())
10468+ return 1;
10469+
10470+ curracl = current->acl;
10471+
10472+ if (!cap_raised(curracl->cap_lower, cap))
10473+ return 1;
10474+
10475+ if ((curracl->mode & GR_LEARN)
10476+ && cap_raised(current->cap_effective, cap)) {
10477+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10478+ current->role->roletype, current->uid,
10479+ current->gid, current->exec_file ?
10480+ gr_to_filename(current->exec_file->f_dentry,
10481+ current->exec_file->f_vfsmnt) : curracl->filename,
10482+ curracl->filename, 0UL,
10483+ 0UL, "", (unsigned long) cap, NIPQUAD(current->curr_ip));
10484+ return 1;
10485+ }
10486+
10487+ if ((cap >= 0) && (cap < 29) && cap_raised(current->cap_effective, cap))
10488+ security_alert(GR_CAP_ACL_MSG, captab_log[cap], DEFAULTSECARGS);
10489+
10490+ return 0;
10491+}
474a6d91
AM
10492diff -urN linux-2.4.22.org/grsecurity/gracl_fs.c linux-2.4.22/grsecurity/gracl_fs.c
10493--- linux-2.4.22.org/grsecurity/gracl_fs.c 1970-01-01 01:00:00.000000000 +0100
10494+++ linux-2.4.22/grsecurity/gracl_fs.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
10495@@ -0,0 +1,469 @@
10496+#include <linux/kernel.h>
10497+#include <linux/sched.h>
10498+#include <linux/types.h>
10499+#include <linux/fs.h>
10500+#include <linux/file.h>
10501+#include <linux/grsecurity.h>
10502+#include <linux/grinternal.h>
10503+#include <linux/gracl.h>
10504+
10505+__u32
10506+gr_acl_handle_hidden_file(const struct dentry * dentry,
10507+ const struct vfsmount * mnt)
10508+{
10509+ __u32 mode;
10510+
10511+ if (unlikely(!dentry->d_inode))
10512+ return GR_FIND;
10513+
10514+ mode =
10515+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
10516+
10517+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
10518+ security_audit(GR_HIDDEN_ACL_MSG, "successful",
10519+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
10520+ return mode;
10521+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
10522+ security_alert(GR_HIDDEN_ACL_MSG, "denied",
10523+ gr_to_filename(dentry, mnt),
10524+ DEFAULTSECARGS);
10525+ return 0;
10526+ } else if (unlikely(!(mode & GR_FIND)))
10527+ return 0;
10528+
10529+ return GR_FIND;
10530+}
10531+
10532+__u32
10533+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
10534+ const int fmode)
10535+{
10536+ __u32 reqmode = GR_FIND;
10537+ __u32 mode;
10538+
10539+ if (unlikely(!dentry->d_inode))
10540+ return reqmode;
10541+
10542+ if (unlikely(fmode & O_APPEND))
10543+ reqmode |= GR_APPEND;
10544+ else if (unlikely(fmode & FMODE_WRITE))
10545+ reqmode |= GR_WRITE;
10546+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
10547+ reqmode |= GR_READ;
10548+
10549+ mode =
10550+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
10551+ mnt);
10552+
10553+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10554+ security_audit(GR_OPEN_ACL_MSG, "successful",
10555+ gr_to_filename(dentry, mnt),
10556+ reqmode & GR_READ ? " reading" : "",
10557+ reqmode & GR_WRITE ? " writing" :
10558+ reqmode & GR_APPEND ? " appending" : "",
10559+ DEFAULTSECARGS);
10560+ return reqmode;
10561+ } else
10562+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10563+ {
10564+ security_alert(GR_OPEN_ACL_MSG, "denied",
10565+ gr_to_filename(dentry, mnt),
10566+ reqmode & GR_READ ? " reading" : "",
10567+ reqmode & GR_WRITE ? " writing" : reqmode &
10568+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
10569+ return 0;
10570+ } else if (unlikely((mode & reqmode) != reqmode))
10571+ return 0;
10572+
10573+ return reqmode;
10574+}
10575+
10576+__u32
10577+gr_acl_handle_creat(const struct dentry * dentry,
10578+ const struct dentry * p_dentry,
10579+ const struct vfsmount * p_mnt, const int fmode,
10580+ const int imode)
10581+{
10582+ __u32 reqmode = GR_WRITE | GR_CREATE;
10583+ __u32 mode;
10584+
10585+ if (unlikely(fmode & O_APPEND))
10586+ reqmode |= GR_APPEND;
10587+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
10588+ reqmode |= GR_READ;
10589+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
10590+ reqmode |= GR_SETID;
10591+
10592+ mode =
10593+ gr_check_create(dentry, p_dentry, p_mnt,
10594+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
10595+
10596+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10597+ security_audit(GR_CREATE_ACL_MSG, "successful",
10598+ gr_to_filename(dentry, p_mnt),
10599+ reqmode & GR_READ ? " reading" : "",
10600+ reqmode & GR_WRITE ? " writing" :
10601+ reqmode & GR_APPEND ? " appending" : "",
10602+ DEFAULTSECARGS);
10603+ return reqmode;
10604+ } else
10605+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10606+ {
10607+ security_alert(GR_CREATE_ACL_MSG, "denied",
10608+ gr_to_filename(dentry, p_mnt),
10609+ reqmode & GR_READ ? " reading" : "",
10610+ reqmode & GR_WRITE ? " writing" : reqmode &
10611+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
10612+ return 0;
10613+ } else if (unlikely((mode & reqmode) != reqmode))
10614+ return 0;
10615+
10616+ return reqmode;
10617+}
10618+
10619+__u32
10620+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
10621+ const int fmode)
10622+{
10623+ __u32 mode, reqmode = GR_FIND;
10624+
10625+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
10626+ reqmode |= GR_EXEC;
10627+ if (fmode & S_IWOTH)
10628+ reqmode |= GR_WRITE;
10629+ if (fmode & S_IROTH)
10630+ reqmode |= GR_READ;
10631+
10632+ mode =
10633+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
10634+ mnt);
10635+
10636+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10637+ security_audit(GR_ACCESS_ACL_MSG, "successful",
10638+ gr_to_filename(dentry, mnt),
10639+ reqmode & GR_READ ? " reading" : "",
10640+ reqmode & GR_WRITE ? " writing" : "",
10641+ reqmode & GR_EXEC ? " executing" : "",
10642+ DEFAULTSECARGS);
10643+ return reqmode;
10644+ } else
10645+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10646+ {
10647+ security_alert(GR_ACCESS_ACL_MSG, "denied",
10648+ gr_to_filename(dentry, mnt),
10649+ reqmode & GR_READ ? " reading" : "",
10650+ reqmode & GR_WRITE ? " writing" : "",
10651+ reqmode & GR_EXEC ? " executing" : "",
10652+ DEFAULTSECARGS);
10653+ return 0;
10654+ } else if (unlikely((mode & reqmode) != reqmode))
10655+ return 0;
10656+
10657+ return reqmode;
10658+}
10659+
10660+#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
10661+{ \
10662+ __u32 mode; \
10663+ \
10664+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
10665+ \
10666+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
10667+ security_audit(fmt, "successful", \
10668+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
10669+ return mode; \
10670+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
10671+ security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
10672+ DEFAULTSECARGS); \
10673+ return 0; \
10674+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
10675+ return 0; \
10676+ \
10677+ return (reqmode); \
10678+}
10679+
10680+__u32
10681+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
10682+{
10683+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
10684+}
10685+
10686+__u32
10687+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
10688+{
10689+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
10690+}
10691+
10692+__u32
10693+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
10694+{
10695+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
10696+}
10697+
10698+__u32
10699+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
10700+{
10701+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
10702+}
10703+
10704+__u32
10705+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
10706+ mode_t mode)
10707+{
10708+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
10709+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
10710+ GR_FCHMOD_ACL_MSG);
10711+ } else {
10712+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
10713+ }
10714+}
10715+
10716+__u32
10717+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
10718+ mode_t mode)
10719+{
10720+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
10721+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
10722+ GR_CHMOD_ACL_MSG);
10723+ } else {
10724+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
10725+ }
10726+}
10727+
10728+__u32
10729+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
10730+{
10731+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
10732+}
10733+
10734+__u32
10735+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
10736+{
10737+ generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
10738+}
10739+
10740+__u32
10741+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
10742+{
10743+ generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
10744+ GR_UNIXCONNECT_ACL_MSG);
10745+}
10746+
10747+__u32
10748+gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
10749+ const ino_t ino)
10750+{
10751+ if (likely((unsigned long)(dentry->d_inode))) {
10752+ struct dentry d = *dentry;
10753+ struct inode inode = *(dentry->d_inode);
10754+
10755+ inode.i_ino = ino;
10756+ d.d_inode = &inode;
10757+
10758+ if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
10759+ return 0;
10760+ }
10761+
10762+ return 1;
10763+}
10764+
10765+__u32
10766+gr_acl_handle_link(const struct dentry * new_dentry,
10767+ const struct dentry * parent_dentry,
10768+ const struct vfsmount * parent_mnt,
10769+ const struct dentry * old_dentry,
10770+ const struct vfsmount * old_mnt, const char *to)
10771+{
10772+ __u32 needmode = GR_WRITE | GR_CREATE;
10773+ __u32 mode;
10774+
10775+ mode =
10776+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
10777+ old_mnt);
10778+
10779+ if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
10780+ security_audit(GR_LINK_ACL_MSG, "successful",
10781+ gr_to_filename(old_dentry, old_mnt), to,
10782+ DEFAULTSECARGS);
10783+ return mode;
10784+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
10785+ security_alert(GR_LINK_ACL_MSG, "denied",
10786+ gr_to_filename(old_dentry, old_mnt), to,
10787+ DEFAULTSECARGS);
10788+ return 0;
10789+ } else if (unlikely((mode & needmode) != needmode))
10790+ return 0;
10791+
10792+ return (GR_WRITE | GR_CREATE);
10793+}
10794+
10795+__u32
10796+gr_acl_handle_symlink(const struct dentry * new_dentry,
10797+ const struct dentry * parent_dentry,
10798+ const struct vfsmount * parent_mnt, const char *from)
10799+{
10800+ __u32 needmode = GR_WRITE | GR_CREATE;
10801+ __u32 mode;
10802+
10803+ mode =
10804+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
10805+ GR_CREATE | GR_AUDIT_CREATE |
10806+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
10807+
10808+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
10809+ security_audit(GR_SYMLINK_ACL_MSG, "successful",
10810+ from, gr_to_filename(new_dentry, parent_mnt),
10811+ DEFAULTSECARGS);
10812+ return mode;
10813+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
10814+ security_alert(GR_SYMLINK_ACL_MSG, "denied",
10815+ from, gr_to_filename(new_dentry, parent_mnt),
10816+ DEFAULTSECARGS);
10817+ return 0;
10818+ } else if (unlikely((mode & needmode) != needmode))
10819+ return 0;
10820+
10821+ return (GR_WRITE | GR_CREATE);
10822+}
10823+
10824+#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
10825+{ \
10826+ __u32 mode; \
10827+ \
10828+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
10829+ \
10830+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
10831+ security_audit(fmt, "successful", \
10832+ gr_to_filename(new_dentry, parent_mnt), \
10833+ DEFAULTSECARGS); \
10834+ return mode; \
10835+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
10836+ security_alert(fmt, "denied", \
10837+ gr_to_filename(new_dentry, parent_mnt), \
10838+ DEFAULTSECARGS); \
10839+ return 0; \
10840+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
10841+ return 0; \
10842+ \
10843+ return (reqmode); \
10844+}
10845+
10846+__u32
10847+gr_acl_handle_mknod(const struct dentry * new_dentry,
10848+ const struct dentry * parent_dentry,
10849+ const struct vfsmount * parent_mnt,
10850+ const int mode)
10851+{
10852+ __u32 reqmode = GR_WRITE | GR_CREATE;
10853+ if (unlikely(mode & (S_ISUID | S_ISGID)))
10854+ reqmode |= GR_SETID;
10855+
10856+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
10857+ reqmode, GR_MKNOD_ACL_MSG);
10858+}
10859+
10860+__u32
10861+gr_acl_handle_mkdir(const struct dentry *new_dentry,
10862+ const struct dentry *parent_dentry,
10863+ const struct vfsmount *parent_mnt)
10864+{
10865+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
10866+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
10867+}
10868+
10869+#define RENAME_CHECK_SUCCESS(old, new) \
10870+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
10871+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
10872+
10873+int
10874+gr_acl_handle_rename(struct dentry *new_dentry,
10875+ struct dentry *parent_dentry,
10876+ const struct vfsmount *parent_mnt,
10877+ struct dentry *old_dentry,
10878+ struct inode *old_parent_inode,
10879+ struct vfsmount *old_mnt, const char *newname)
10880+{
10881+ __u8 gr_replace = 1;
10882+ __u32 comp1, comp2;
10883+ int error = 0;
10884+
10885+ if (unlikely(!gr_acl_is_enabled()))
10886+ return 1;
10887+
10888+ if (!new_dentry->d_inode) {
10889+ gr_replace = 0;
10890+
10891+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
10892+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
10893+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
10894+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
10895+ GR_DELETE | GR_AUDIT_DELETE |
10896+ GR_AUDIT_READ | GR_AUDIT_WRITE |
10897+ GR_SUPPRESS, old_mnt);
10898+ } else {
10899+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
10900+ GR_CREATE | GR_DELETE |
10901+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
10902+ GR_AUDIT_READ | GR_AUDIT_WRITE |
10903+ GR_SUPPRESS, parent_mnt);
10904+ comp2 =
10905+ gr_search_file(old_dentry,
10906+ GR_READ | GR_WRITE | GR_AUDIT_READ |
10907+ GR_DELETE | GR_AUDIT_DELETE |
10908+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
10909+ }
10910+
10911+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
10912+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
10913+ security_audit(GR_RENAME_ACL_MSG, "successful",
10914+ gr_to_filename(old_dentry, old_mnt),
10915+ newname, DEFAULTSECARGS);
10916+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
10917+ && !(comp2 & GR_SUPPRESS)) {
10918+ security_alert(GR_RENAME_ACL_MSG, "denied",
10919+ gr_to_filename(old_dentry, old_mnt), newname,
10920+ DEFAULTSECARGS);
10921+ error = -EACCES;
10922+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
10923+ error = -EACCES;
10924+
10925+ if (error)
10926+ return error;
10927+
10928+ error = gr_handle_rename(old_parent_inode, parent_dentry->d_inode,
10929+ old_dentry, new_dentry, old_mnt, gr_replace);
10930+
10931+ return error;
10932+}
10933+
10934+void
10935+gr_acl_handle_exit(void)
10936+{
10937+ u16 id;
10938+ char *rolename;
10939+
10940+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
10941+ id = current->acl_role_id;
10942+ rolename = current->role->rolename;
10943+ gr_set_acls(1);
10944+ security_alert_good(GR_SPROLEL_ACL_MSG,
10945+ rolename, id, DEFAULTSECARGS);
10946+ }
10947+
10948+ if (current->exec_file) {
10949+ fput(current->exec_file);
10950+ current->exec_file = NULL;
10951+ }
10952+}
10953+
10954+int
10955+gr_acl_handle_procpidmem(const struct task_struct *task)
10956+{
10957+ if (unlikely(!gr_acl_is_enabled()))
10958+ return 0;
10959+
10960+ if (task->acl->mode & GR_PROTPROCFD)
10961+ return -EACCES;
10962+
10963+ return 0;
10964+}
474a6d91
AM
10965diff -urN linux-2.4.22.org/grsecurity/gracl_ip.c linux-2.4.22/grsecurity/gracl_ip.c
10966--- linux-2.4.22.org/grsecurity/gracl_ip.c 1970-01-01 01:00:00.000000000 +0100
10967+++ linux-2.4.22/grsecurity/gracl_ip.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
10968@@ -0,0 +1,235 @@
10969+/*
10970+ * grsecurity/gracl_ip.c
10971+ * Copyright Brad Spengler 2002, 2003
10972+ *
10973+ */
10974+
10975+#include <linux/kernel.h>
10976+#include <asm/uaccess.h>
10977+#include <asm/errno.h>
10978+#include <net/sock.h>
10979+#include <linux/file.h>
10980+#include <linux/fs.h>
10981+#include <linux/net.h>
10982+#include <linux/in.h>
10983+#include <linux/skbuff.h>
10984+#include <linux/ip.h>
10985+#include <linux/udp.h>
10986+#include <linux/smp_lock.h>
10987+#include <linux/types.h>
10988+#include <linux/sched.h>
10989+#include <linux/gracl.h>
10990+#include <linux/grsecurity.h>
10991+#include <linux/grinternal.h>
10992+
10993+#define GR_BIND 0x01
10994+#define GR_CONNECT 0x02
10995+
10996+static const char * gr_protocols[256] = {
10997+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
10998+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
10999+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
11000+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
11001+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
11002+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
11003+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
11004+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
11005+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
11006+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
11007+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
11008+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
11009+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
11010+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
11011+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
11012+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
11013+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
11014+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
11015+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
11016+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
11017+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
11018+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
11019+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
11020+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
11021+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
11022+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
11023+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
11024+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
11025+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
11026+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
11027+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
11028+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
11029+ };
11030+
11031+static const char * gr_socktypes[11] = {
11032+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
11033+ "unknown:7", "unknown:8", "unknown:9", "packet"
11034+ };
11035+
11036+static __inline__ const char *
11037+gr_proto_to_name(unsigned char proto)
11038+{
11039+ return gr_protocols[proto];
11040+}
11041+
11042+static __inline__ const char *
11043+gr_socktype_to_name(unsigned char type)
11044+{
11045+ return gr_socktypes[type];
11046+}
11047+
11048+int
11049+gr_search_socket(const int domain, const int type, const int protocol)
11050+{
11051+ struct acl_subject_label *curr;
11052+
11053+ if (unlikely(!gr_acl_is_enabled()))
11054+ goto exit;
11055+
11056+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
11057+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
11058+ goto exit; // let the kernel handle it
11059+
11060+ curr = current->acl;
11061+
11062+ if (!curr->ips)
11063+ goto exit;
11064+
11065+ if ((curr->ip_type & (1 << type)) &&
11066+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
11067+ goto exit;
11068+
11069+ if (curr->mode & GR_LEARN) {
11070+ /* we don't place acls on raw sockets , and sometimes
11071+ dgram/ip sockets are opened for ioctl and not
11072+ bind/connect, so we'll fake a bind learn log */
11073+ if (type == SOCK_RAW || type == SOCK_PACKET) {
11074+ __u32 fakeip = 0;
11075+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11076+ current->role->roletype, current->uid,
11077+ current->gid, current->exec_file ?
11078+ gr_to_filename(current->exec_file->f_dentry,
11079+ current->exec_file->f_vfsmnt) :
11080+ curr->filename, curr->filename,
11081+ NIPQUAD(fakeip), 0, type,
11082+ protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
11083+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
11084+ __u32 fakeip = 0;
11085+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11086+ current->role->roletype, current->uid,
11087+ current->gid, current->exec_file ?
11088+ gr_to_filename(current->exec_file->f_dentry,
11089+ current->exec_file->f_vfsmnt) :
11090+ curr->filename, curr->filename,
11091+ NIPQUAD(fakeip), 0, type,
11092+ protocol, GR_BIND, NIPQUAD(current->curr_ip));
11093+ }
11094+ /* we'll log when they use connect or bind */
11095+ goto exit;
11096+ }
11097+
11098+ security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
11099+ gr_proto_to_name(protocol), DEFAULTSECARGS);
11100+
11101+ return 0;
11102+ exit:
11103+ return 1;
11104+}
11105+
11106+static __inline__ int
11107+gr_search_connectbind(const int mode, const struct sock *sk,
11108+ const struct sockaddr_in *addr, const int type)
11109+{
11110+ struct acl_subject_label *curr;
11111+ struct acl_ip_label *ip;
11112+ unsigned long i;
11113+ __u32 ip_addr = 0;
11114+ __u16 ip_port = 0;
11115+
11116+ if (unlikely(!gr_acl_is_enabled() || sk->family != PF_INET))
11117+ return 1;
11118+
11119+ curr = current->acl;
11120+
11121+ if (!curr->ips)
11122+ return 1;
11123+
11124+ ip_addr = addr->sin_addr.s_addr;
11125+ ip_port = ntohs(addr->sin_port);
11126+
11127+ for (i = 0; i < curr->ip_num; i++) {
11128+ ip = *(curr->ips + i);
11129+ if ((ip->mode & mode) &&
11130+ (ip_port >= ip->low) &&
11131+ (ip_port <= ip->high) &&
11132+ ((ntohl(ip_addr) & ip->netmask) ==
11133+ (ntohl(ip->addr) & ip->netmask))
11134+ && (ip->
11135+ proto[sk->protocol / 32] & (1 << (sk->protocol % 32)))
11136+ && (ip->type & (1 << type)))
11137+ return 1;
11138+ }
11139+
11140+ if (curr->mode & GR_LEARN) {
11141+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11142+ current->role->roletype, current->uid,
11143+ current->gid, current->exec_file ?
11144+ gr_to_filename(current->exec_file->f_dentry,
11145+ current->exec_file->f_vfsmnt) :
11146+ curr->filename, curr->filename,
11147+ NIPQUAD(ip_addr), ip_port, type,
11148+ sk->protocol, mode, NIPQUAD(current->curr_ip));
11149+ return 1;
11150+ }
11151+
11152+ if (mode == GR_BIND)
11153+ security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11154+ gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11155+ DEFAULTSECARGS);
11156+ else if (mode == GR_CONNECT)
11157+ security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11158+ gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
11159+ DEFAULTSECARGS);
11160+
11161+ return 0;
11162+}
11163+
11164+int
11165+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
11166+{
11167+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
11168+}
11169+
11170+int
11171+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
11172+{
11173+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
11174+}
11175+
11176+int
11177+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
11178+{
11179+ if (addr)
11180+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
11181+ else {
11182+ struct sockaddr_in sin;
11183+
11184+ sin.sin_addr.s_addr = sk->daddr;
11185+ sin.sin_port = sk->dport;
11186+
11187+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11188+ }
11189+}
11190+
11191+int
11192+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
11193+{
11194+ struct sockaddr_in sin;
11195+
11196+ if (unlikely(skb->len < sizeof (struct udphdr)))
11197+ return 1; // skip this packet
11198+
11199+ sin.sin_addr.s_addr = skb->nh.iph->saddr;
11200+ sin.sin_port = skb->h.uh->source;
11201+
11202+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11203+}
474a6d91
AM
11204diff -urN linux-2.4.22.org/grsecurity/gracl_learn.c linux-2.4.22/grsecurity/gracl_learn.c
11205--- linux-2.4.22.org/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100
11206+++ linux-2.4.22/grsecurity/gracl_learn.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
11207@@ -0,0 +1,228 @@
11208+#include <linux/kernel.h>
11209+#include <linux/mm.h>
11210+#include <linux/sched.h>
11211+#include <linux/poll.h>
11212+#include <linux/smp_lock.h>
11213+#include <linux/string.h>
11214+#include <linux/file.h>
11215+#include <linux/types.h>
11216+#include <linux/vmalloc.h>
11217+#include <linux/grinternal.h>
11218+
11219+extern ssize_t write_grsec_handler(struct file * file, const char * buf,
11220+ size_t count, loff_t *ppos);
11221+extern int gr_acl_is_enabled(void);
11222+
11223+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
11224+static DECLARE_WAIT_QUEUE_HEAD(input_wait);
11225+static atomic_t learn_buffer_count = ATOMIC_INIT(0);
11226+static int gr_learn_attached;
11227+
11228+#define LEARN_BUFFER_SLOTS 256
11229+#define LEARN_BUFFER_SIZE 16384
11230+
11231+static spinlock_t learn_buffer_lock[LEARN_BUFFER_SLOTS] = { [0 ... (LEARN_BUFFER_SLOTS - 1)] = SPIN_LOCK_UNLOCKED };
11232+static char *learn_buffer[LEARN_BUFFER_SLOTS];
11233+static int learn_buffer_len[LEARN_BUFFER_SLOTS];
11234+
11235+static ssize_t
11236+read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
11237+{
11238+ DECLARE_WAITQUEUE(wait, current);
11239+ ssize_t retval = 0;
11240+ char *tmp;
11241+ unsigned int len;
11242+ int i;
11243+
11244+ add_wait_queue(&learn_wait, &wait);
11245+ set_current_state(TASK_INTERRUPTIBLE);
11246+ do {
11247+ if (atomic_read(&learn_buffer_count) > 1)
11248+ break;
11249+
11250+ if (file->f_flags & O_NONBLOCK) {
11251+ retval = -EAGAIN;
11252+ goto out;
11253+ }
11254+ if (signal_pending(current)) {
11255+ retval = -ERESTARTSYS;
11256+ goto out;
11257+ }
11258+
11259+ schedule();
11260+ } while (1);
11261+
11262+
11263+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11264+ spin_lock(&learn_buffer_lock[i]);
11265+ len = learn_buffer_len[i];
11266+ tmp = learn_buffer[i];
11267+ if (!len || !tmp) {
11268+ spin_unlock(&learn_buffer_lock[i]);
11269+ continue;
11270+ }
11271+ learn_buffer[i] = NULL;
11272+ learn_buffer_len[i] = 0;
11273+ spin_unlock(&learn_buffer_lock[i]);
11274+
11275+ if (count < ((i * LEARN_BUFFER_SIZE) + len)) {
11276+ retval = -EINVAL;
11277+ vfree(tmp);
11278+ goto out;
11279+ }
11280+ if (copy_to_user(buf + (i * LEARN_BUFFER_SIZE), tmp, len)) {
11281+ retval = -EFAULT;
11282+ vfree(tmp);
11283+ goto out;
11284+ }
11285+
11286+ retval += len;
11287+ vfree(tmp);
11288+ atomic_dec(&learn_buffer_count);
11289+ atomic_dec(&learn_buffer_count);
11290+ }
11291+
11292+ wake_up(&input_wait);
11293+out:
11294+ set_current_state(TASK_RUNNING);
11295+ remove_wait_queue(&learn_wait, &wait);
11296+ return retval;
11297+}
11298+
11299+static unsigned int
11300+poll_learn(struct file * file, poll_table * wait)
11301+{
11302+ poll_wait(file, &learn_wait, wait);
11303+
11304+ if (atomic_read(&learn_buffer_count) > 1)
11305+ return (POLLIN | POLLRDNORM);
11306+
11307+ return 0;
11308+}
11309+
11310+void
11311+gr_clear_learn_entries(void)
11312+{
11313+ int i;
11314+
11315+ atomic_set(&learn_buffer_count, 0);
11316+ wake_up(&input_wait);
11317+
11318+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11319+ if (learn_buffer_len[i]) {
11320+ vfree(learn_buffer[i]);
11321+ learn_buffer[i] = NULL;
11322+ learn_buffer_len[i] = 0;
11323+ }
11324+ }
11325+
11326+ return;
11327+}
11328+
11329+void
11330+gr_add_learn_entry(const char *fmt, ...)
11331+{
11332+ DECLARE_WAITQUEUE(wait, current);
11333+ va_list args;
11334+ char *tmpbuf;
11335+ char *buf;
11336+ int i;
11337+ unsigned int len;
11338+
11339+ if (!gr_learn_attached)
11340+ return;
11341+
11342+ tmpbuf = vmalloc(LEARN_BUFFER_SIZE);
11343+
11344+ if (tmpbuf == NULL)
11345+ return;
11346+
11347+ va_start(args, fmt);
11348+ len = vsnprintf(tmpbuf, LEARN_BUFFER_SIZE, fmt, args);
11349+ va_end(args);
11350+
11351+ if (len < 0)
11352+ len = LEARN_BUFFER_SIZE - 1;
11353+
11354+ buf = vmalloc(len + 1);
11355+
11356+ if (buf == NULL) {
11357+ vfree(tmpbuf);
11358+ return;
11359+ }
11360+
11361+ memcpy(buf, tmpbuf, len);
11362+ buf[len] = '\0';
11363+ vfree(tmpbuf);
11364+
11365+ add_wait_queue(&input_wait, &wait);
11366+
11367+ atomic_inc(&learn_buffer_count);
11368+ if (atomic_read(&learn_buffer_count) > ((2 * (LEARN_BUFFER_SLOTS - 1)) + 1)) {
11369+ /* don't sleep under the BKL */
11370+// if (unlikely(current->lock_depth >= 0)) {
11371+ remove_wait_queue(&input_wait, &wait);
11372+ atomic_dec(&learn_buffer_count);
11373+ vfree(buf);
11374+ return;
11375+// }
11376+// sleep_on(&input_wait);
11377+ }
11378+
11379+ if (!gr_acl_is_enabled()) {
11380+ remove_wait_queue(&input_wait, &wait);
11381+ atomic_dec(&learn_buffer_count);
11382+ vfree(buf);
11383+ return;
11384+ }
11385+
11386+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
11387+ spin_lock(&learn_buffer_lock[i]);
11388+
11389+ if (learn_buffer_len[i]) {
11390+ spin_unlock(&learn_buffer_lock[i]);
11391+ continue;
11392+ }
11393+
11394+ learn_buffer[i] = buf;
11395+
11396+ learn_buffer_len[i] = len + 1;
11397+
11398+ atomic_inc(&learn_buffer_count);
11399+ spin_unlock(&learn_buffer_lock[i]);
11400+ break;
11401+ }
11402+
11403+ remove_wait_queue(&input_wait, &wait);
11404+ wake_up_interruptible(&learn_wait);
11405+
11406+ return;
11407+}
11408+
11409+static int
11410+open_learn(struct inode *inode, struct file *file)
11411+{
11412+ if (file->f_mode & FMODE_READ && gr_learn_attached)
11413+ return -EBUSY;
11414+ else if (file->f_mode & FMODE_READ)
11415+ gr_learn_attached = 1;
11416+
11417+ return 0;
11418+}
11419+
11420+static int
11421+close_learn(struct inode *inode, struct file *file)
11422+{
11423+ if (file->f_mode & FMODE_READ)
11424+ gr_learn_attached = 0;
11425+
11426+ return 0;
11427+}
11428+
11429+struct file_operations grsec_fops = {
11430+ read: read_learn,
11431+ write: write_grsec_handler,
11432+ open: open_learn,
11433+ release: close_learn,
11434+ poll: poll_learn,
11435+};
474a6d91
AM
11436diff -urN linux-2.4.22.org/grsecurity/gracl_res.c linux-2.4.22/grsecurity/gracl_res.c
11437--- linux-2.4.22.org/grsecurity/gracl_res.c 1970-01-01 01:00:00.000000000 +0100
11438+++ linux-2.4.22/grsecurity/gracl_res.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
11439@@ -0,0 +1,45 @@
11440+/* resource handling routines (c) Brad Spengler 2002, 2003 */
11441+
11442+#include <linux/kernel.h>
11443+#include <linux/sched.h>
11444+#include <linux/gracl.h>
11445+#include <linux/grinternal.h>
11446+
11447+static const char *restab_log[11] = {
11448+ "RLIMIT_CPU",
11449+ "RLIMIT_FSIZE",
11450+ "RLIMIT_DATA",
11451+ "RLIMIT_STACK",
11452+ "RLIMIT_CORE",
11453+ "RLIMIT_RSS",
11454+ "RLIMIT_NPROC",
11455+ "RLIMIT_NOFILE",
11456+ "RLIMIT_MEMLOCK",
11457+ "RLIMIT_AS",
11458+ "RLIMIT_LOCKS"
11459+};
11460+
11461+__inline__ void
11462+gr_log_resource(const struct task_struct *task,
11463+ const int res, const unsigned long wanted)
11464+{
11465+ if (unlikely(res == RLIMIT_NPROC &&
11466+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
11467+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
11468+ return;
11469+
11470+ if (unlikely(wanted >= task->rlim[res].rlim_cur &&
11471+ task->rlim[res].rlim_cur != RLIM_INFINITY))
11472+ security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
11473+ task->rlim[res].rlim_cur,
11474+ gr_task_fullpath(task), task->comm,
11475+ task->pid, task->uid, task->euid,
11476+ task->gid, task->egid,
11477+ gr_parent_task_fullpath(task),
11478+ task->p_pptr->comm,
11479+ task->p_pptr->pid, task->p_pptr->uid,
11480+ task->p_pptr->euid, task->p_pptr->gid,
11481+ task->p_pptr->egid);
11482+
11483+ return;
11484+}
474a6d91
AM
11485diff -urN linux-2.4.22.org/grsecurity/gracl_segv.c linux-2.4.22/grsecurity/gracl_segv.c
11486--- linux-2.4.22.org/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100
11487+++ linux-2.4.22/grsecurity/gracl_segv.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
11488@@ -0,0 +1,327 @@
11489+/*
11490+ * grsecurity/gracl_segv.c
11491+ * Copyright Brad Spengler 2002, 2003
11492+ *
11493+ */
11494+
11495+#include <linux/kernel.h>
11496+#include <linux/mm.h>
11497+#include <asm/uaccess.h>
11498+#include <asm/errno.h>
11499+#include <asm/mman.h>
11500+#include <net/sock.h>
11501+#include <linux/file.h>
11502+#include <linux/fs.h>
11503+#include <linux/net.h>
11504+#include <linux/in.h>
11505+#include <linux/smp_lock.h>
11506+#include <linux/slab.h>
11507+#include <linux/types.h>
11508+#include <linux/sched.h>
11509+#include <linux/timer.h>
11510+#include <linux/gracl.h>
11511+#include <linux/grsecurity.h>
11512+#include <linux/grinternal.h>
11513+
11514+static struct crash_uid *uid_set;
11515+static unsigned short uid_used;
11516+static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
11517+extern rwlock_t gr_inode_lock;
11518+extern __inline__ struct acl_subject_label *lookup_acl_subj_label(const ino_t
11519+ inode,
11520+ const kdev_t
11521+ dev,
11522+ struct
11523+ acl_role_label
11524+ *role);
11525+
11526+int
11527+gr_init_uidset(void)
11528+{
11529+ uid_set =
11530+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
11531+ uid_used = 0;
11532+
11533+ return uid_set ? 1 : 0;
11534+}
11535+
11536+void
11537+gr_free_uidset(void)
11538+{
11539+ if (uid_set)
11540+ kfree(uid_set);
11541+
11542+ return;
11543+}
11544+
11545+int
11546+gr_find_uid(const uid_t uid)
11547+{
11548+ struct crash_uid *tmp = uid_set;
11549+ uid_t buid;
11550+ int low = 0, high = uid_used - 1, mid;
11551+
11552+ while (high >= low) {
11553+ mid = (low + high) >> 1;
11554+ buid = tmp[mid].uid;
11555+ if (buid == uid)
11556+ return mid;
11557+ if (buid > uid)
11558+ high = mid - 1;
11559+ if (buid < uid)
11560+ low = mid + 1;
11561+ }
11562+
11563+ return -1;
11564+}
11565+
11566+static __inline__ void
11567+gr_insertsort(void)
11568+{
11569+ unsigned short i, j;
11570+ struct crash_uid index;
11571+
11572+ for (i = 1; i < uid_used; i++) {
11573+ index = uid_set[i];
11574+ j = i;
11575+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
11576+ uid_set[j] = uid_set[j - 1];
11577+ j--;
11578+ }
11579+ uid_set[j] = index;
11580+ }
11581+
11582+ return;
11583+}
11584+
11585+static __inline__ void
11586+gr_insert_uid(const uid_t uid, const unsigned long expires)
11587+{
11588+ int loc;
11589+
11590+ if (uid_used == GR_UIDTABLE_MAX)
11591+ return;
11592+
11593+ loc = gr_find_uid(uid);
11594+
11595+ if (loc >= 0) {
11596+ uid_set[loc].expires = expires;
11597+ return;
11598+ }
11599+
11600+ uid_set[uid_used].uid = uid;
11601+ uid_set[uid_used].expires = expires;
11602+ uid_used++;
11603+
11604+ gr_insertsort();
11605+
11606+ return;
11607+}
11608+
11609+void
11610+gr_remove_uid(const unsigned short loc)
11611+{
11612+ unsigned short i;
11613+
11614+ for (i = loc + 1; i < uid_used; i++)
11615+ uid_set[i - i] = uid_set[i];
11616+
11617+ uid_used--;
11618+
11619+ return;
11620+}
11621+
11622+int
11623+gr_check_crash_uid(const uid_t uid)
11624+{
11625+ int loc;
11626+
11627+ if (unlikely(!gr_acl_is_enabled()))
11628+ return 0;
11629+
11630+ read_lock(&gr_uid_lock);
11631+ loc = gr_find_uid(uid);
11632+ read_unlock(&gr_uid_lock);
11633+
11634+ if (loc < 0)
11635+ return 0;
11636+
11637+ write_lock(&gr_uid_lock);
11638+ if (time_before_eq(uid_set[loc].expires, jiffies))
11639+ gr_remove_uid(loc);
11640+ else {
11641+ write_unlock(&gr_uid_lock);
11642+ return 1;
11643+ }
11644+
11645+ write_unlock(&gr_uid_lock);
11646+ return 0;
11647+}
11648+
11649+static __inline__ int
11650+proc_is_setxid(const struct task_struct *task)
11651+{
11652+ if (task->uid != task->euid || task->uid != task->suid ||
11653+ task->uid != task->fsuid)
11654+ return 1;
11655+ if (task->gid != task->egid || task->gid != task->sgid ||
11656+ task->gid != task->fsgid)
11657+ return 1;
11658+
11659+ return 0;
11660+}
11661+static __inline__ int
11662+gr_fake_force_sig(int sig, struct task_struct *t)
11663+{
11664+ unsigned long int flags;
11665+
11666+ spin_lock_irqsave(&t->sigmask_lock, flags);
11667+ if (t->sig == NULL) {
11668+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
11669+ return -ESRCH;
11670+ }
11671+
11672+ if (t->sig->action[sig - 1].sa.sa_handler == SIG_IGN)
11673+ t->sig->action[sig - 1].sa.sa_handler = SIG_DFL;
11674+ sigdelset(&t->blocked, sig);
11675+ recalc_sigpending(t);
11676+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
11677+
11678+ return send_sig_info(sig, (void *) 1L, t);
11679+}
11680+
11681+void
11682+gr_handle_crash(struct task_struct *task, const int sig)
11683+{
11684+ struct acl_subject_label *curr;
11685+ struct acl_subject_label *curr2;
11686+ struct task_struct *tsk;
11687+
11688+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
11689+ return;
11690+
11691+ if (unlikely(!gr_acl_is_enabled()))
11692+ return;
11693+
11694+ curr = task->acl;
11695+
11696+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
11697+ return;
11698+
11699+ if (time_before_eq(curr->expires, jiffies)) {
11700+ curr->expires = 0;
11701+ curr->crashes = 0;
11702+ }
11703+
11704+ curr->crashes++;
11705+
11706+ if (!curr->expires)
11707+ curr->expires = jiffies + curr->res[GR_CRASH_RES].rlim_max;
11708+
11709+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
11710+ time_after(curr->expires, jiffies)) {
11711+ if (task->uid && proc_is_setxid(task)) {
11712+ security_alert(GR_SEGVSTART_ACL_MSG,
11713+ gr_task_fullpath(task), task->comm,
11714+ task->pid, task->uid, task->euid,
11715+ task->gid, task->egid,
11716+ gr_parent_task_fullpath(task),
11717+ task->p_pptr->comm, task->p_pptr->pid,
11718+ task->p_pptr->uid, task->p_pptr->euid,
11719+ task->p_pptr->gid, task->p_pptr->egid,
11720+ task->uid,
11721+ curr->res[GR_CRASH_RES].rlim_max / HZ);
11722+ write_lock(&gr_uid_lock);
11723+ gr_insert_uid(task->uid, curr->expires);
11724+ write_unlock(&gr_uid_lock);
11725+ curr->expires = 0;
11726+ curr->crashes = 0;
11727+ read_lock(&tasklist_lock);
11728+ for_each_task(tsk) {
11729+ if (tsk != task && tsk->uid == task->uid)
11730+ gr_fake_force_sig(SIGKILL, tsk);
11731+ }
11732+ read_unlock(&tasklist_lock);
11733+ } else {
11734+ security_alert(GR_SEGVNOSUID_ACL_MSG,
11735+ gr_task_fullpath(task), task->comm,
11736+ task->pid, task->uid, task->euid,
11737+ task->gid, task->egid,
11738+ gr_parent_task_fullpath(task),
11739+ task->p_pptr->comm, task->p_pptr->pid,
11740+ task->p_pptr->uid, task->p_pptr->euid,
11741+ task->p_pptr->gid, task->p_pptr->egid,
11742+ kdevname(curr->device), curr->inode,
11743+ curr->res[GR_CRASH_RES].rlim_max / HZ);
11744+ read_lock(&tasklist_lock);
11745+ for_each_task(tsk) {
11746+ if (likely(tsk != task)) {
11747+ curr2 = tsk->acl;
11748+
11749+ if (curr2->device == curr->device &&
11750+ curr2->inode == curr->inode)
11751+ gr_fake_force_sig(SIGKILL, tsk);
11752+ }
11753+ }
11754+ read_unlock(&tasklist_lock);
11755+ }
11756+ }
11757+
11758+ return;
11759+}
11760+
11761+int
11762+gr_check_crash_exec(const struct file *filp)
11763+{
11764+ struct acl_subject_label *curr;
11765+
11766+ if (unlikely(!gr_acl_is_enabled()))
11767+ return 0;
11768+
11769+ read_lock(&gr_inode_lock);
11770+ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
11771+ filp->f_dentry->d_inode->i_dev,
11772+ current->role);
11773+ read_unlock(&gr_inode_lock);
11774+
11775+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
11776+ (!curr->crashes && !curr->expires))
11777+ return 0;
11778+
11779+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
11780+ time_after(curr->expires, jiffies))
11781+ return 1;
11782+ else if (time_before_eq(curr->expires, jiffies)) {
11783+ curr->crashes = 0;
11784+ curr->expires = 0;
11785+ }
11786+
11787+ return 0;
11788+}
11789+
11790+void
11791+gr_handle_alertkill(void)
11792+{
11793+ struct acl_subject_label *curracl;
11794+ __u32 curr_ip;
11795+ struct task_struct *task;
11796+
11797+ if (unlikely(!gr_acl_is_enabled()))
11798+ return;
11799+
11800+ curracl = current->acl;
11801+ curr_ip = current->curr_ip;
11802+
11803+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
11804+ (curr_ip != 0xffffffff)) {
11805+ read_lock(&tasklist_lock);
11806+ for_each_task(task) {
11807+ if (task->curr_ip == curr_ip)
11808+ gr_fake_force_sig(SIGKILL, task);
11809+ }
11810+ read_unlock(&tasklist_lock);
11811+ } else if (curracl->mode & GR_KILLPROC)
11812+ gr_fake_force_sig(SIGKILL, current);
11813+
11814+ return;
11815+}
474a6d91
AM
11816diff -urN linux-2.4.22.org/grsecurity/gracl_shm.c linux-2.4.22/grsecurity/gracl_shm.c
11817--- linux-2.4.22.org/grsecurity/gracl_shm.c 1970-01-01 01:00:00.000000000 +0100
11818+++ linux-2.4.22/grsecurity/gracl_shm.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
11819@@ -0,0 +1,36 @@
11820+/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
11821+
11822+#include <linux/kernel.h>
11823+#include <linux/mm.h>
11824+#include <linux/sched.h>
11825+#include <linux/file.h>
11826+#include <linux/ipc.h>
11827+#include <linux/gracl.h>
11828+#include <linux/grsecurity.h>
11829+#include <linux/grinternal.h>
11830+
11831+int
11832+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
11833+ const time_t shm_createtime, const uid_t cuid, const int shmid)
11834+{
11835+ struct task_struct *task;
11836+
11837+ if (!gr_acl_is_enabled())
11838+ return 1;
11839+
11840+ task = find_task_by_pid(shm_cprid);
11841+
11842+ if (unlikely(!task))
11843+ task = find_task_by_pid(shm_lapid);
11844+
11845+ if (unlikely(task && ((task->start_time < shm_createtime) ||
11846+ (task->pid == shm_lapid)) &&
11847+ (task->acl->mode & GR_PROTSHM) &&
11848+ (task->acl != current->acl))) {
11849+ security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
11850+ DEFAULTSECARGS);
11851+ return 0;
11852+ }
11853+
11854+ return 1;
11855+}
474a6d91
AM
11856diff -urN linux-2.4.22.org/grsecurity/grsec_chdir.c linux-2.4.22/grsecurity/grsec_chdir.c
11857--- linux-2.4.22.org/grsecurity/grsec_chdir.c 1970-01-01 01:00:00.000000000 +0100
11858+++ linux-2.4.22/grsecurity/grsec_chdir.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
11859@@ -0,0 +1,20 @@
11860+#include <linux/kernel.h>
11861+#include <linux/sched.h>
11862+#include <linux/fs.h>
11863+#include <linux/file.h>
11864+#include <linux/grsecurity.h>
11865+#include <linux/grinternal.h>
11866+
11867+void
11868+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
11869+{
11870+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
11871+ if ((grsec_enable_chdir && grsec_enable_group &&
11872+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
11873+ !grsec_enable_group)) {
11874+ security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
11875+ DEFAULTSECARGS);
11876+ }
11877+#endif
11878+ return;
11879+}
474a6d91
AM
11880diff -urN linux-2.4.22.org/grsecurity/grsec_chroot.c linux-2.4.22/grsecurity/grsec_chroot.c
11881--- linux-2.4.22.org/grsecurity/grsec_chroot.c 1970-01-01 01:00:00.000000000 +0100
11882+++ linux-2.4.22/grsecurity/grsec_chroot.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
11883@@ -0,0 +1,333 @@
11884+#include <linux/kernel.h>
11885+#include <linux/sched.h>
11886+#include <linux/file.h>
11887+#include <linux/fs.h>
11888+#include <linux/types.h>
11889+#include <linux/grinternal.h>
11890+
11891+int
11892+gr_handle_chroot_unix(const pid_t pid)
11893+{
11894+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
11895+ struct task_struct *p, **htable;
11896+
11897+ if (unlikely(!grsec_enable_chroot_unix))
11898+ return 1;
11899+
11900+ if (likely(!proc_is_chrooted(current)))
11901+ return 1;
11902+
11903+ read_lock(&tasklist_lock);
11904+
11905+ htable = &pidhash[pid_hashfn(pid)];
11906+
11907+ for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ;
11908+
11909+ if (unlikely(p && !have_same_root(current, p))) {
11910+ read_unlock(&tasklist_lock);
11911+ security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
11912+ return 0;
11913+ }
11914+ read_unlock(&tasklist_lock);
11915+#endif
11916+ return 1;
11917+}
11918+
11919+int
11920+gr_handle_chroot_nice(void)
11921+{
11922+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
11923+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
11924+ security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
11925+ return -EPERM;
11926+ }
11927+#endif
11928+ return 0;
11929+}
11930+
11931+int
11932+gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval)
11933+{
11934+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
11935+ if (grsec_enable_chroot_nice && (!have_same_root(p, current)
11936+ || (have_same_root(p, current)
11937+ && (niceval < task_nice(p))
11938+ && proc_is_chrooted(current)))) {
11939+ security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
11940+ DEFAULTSECARGS);
11941+ return -ESRCH;
11942+ }
11943+#endif
11944+ return 0;
11945+}
11946+
11947+int
11948+gr_handle_chroot_capset(const struct task_struct *target)
11949+{
11950+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11951+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
11952+ !have_same_root(current, target)) {
11953+ security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
11954+ DEFAULTSECARGS);
11955+ return 1;
11956+ }
11957+#endif
11958+ return 0;
11959+}
11960+
11961+int
11962+gr_handle_chroot_rawio(const struct inode *inode)
11963+{
11964+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11965+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
11966+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
11967+ return 1;
11968+#endif
11969+ return 0;
11970+}
11971+
11972+int
11973+gr_pid_is_chrooted(const struct task_struct *p)
11974+{
11975+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
11976+ if (!grsec_enable_chroot_findtask || (current->pid <= 1))
11977+ return 0;
11978+
11979+ if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
11980+ child_reaper && child_reaper->fs && child_reaper->fs->root &&
11981+ child_reaper->fs->root->d_inode && current && current->fs &&
11982+ current->fs->root && current->fs->root->d_inode) {
11983+ if (proc_is_chrooted(current) && !have_same_root(current, p))
11984+ return 1;
11985+ }
11986+#endif
11987+ return 0;
11988+}
11989+
11990+int
11991+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
11992+{
11993+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
11994+ if (!grsec_enable_chroot_fchdir)
11995+ return 1;
11996+
11997+ if (!proc_is_chrooted(current))
11998+ return 1;
11999+ else {
12000+ struct dentry *dentry = u_dentry;
12001+ struct vfsmount *mnt = u_mnt;
12002+ struct dentry *realroot;
12003+ struct vfsmount *realrootmnt;
12004+ struct dentry *currentroot;
12005+ struct vfsmount *currentmnt;
12006+
12007+ read_lock(&child_reaper->fs->lock);
12008+ realrootmnt = mntget(child_reaper->fs->rootmnt);
12009+ realroot = dget(child_reaper->fs->root);
12010+ read_unlock(&child_reaper->fs->lock);
12011+
12012+ read_lock(&current->fs->lock);
12013+ currentmnt = mntget(current->fs->rootmnt);
12014+ currentroot = dget(current->fs->root);
12015+ read_unlock(&current->fs->lock);
12016+
12017+ spin_lock(&dcache_lock);
12018+ for (;;) {
12019+ if (unlikely
12020+ ((dentry == realroot && mnt == realrootmnt)
12021+ || (dentry == currentroot && mnt == currentmnt)))
12022+ break;
12023+ if (unlikely
12024+ (dentry == mnt->mnt_root || IS_ROOT(dentry))) {
12025+ if (mnt->mnt_parent == mnt)
12026+ break;
12027+ dentry = mnt->mnt_mountpoint;
12028+ mnt = mnt->mnt_parent;
12029+ continue;
12030+ }
12031+ dentry = dentry->d_parent;
12032+ }
12033+ spin_unlock(&dcache_lock);
12034+
12035+ dput(currentroot);
12036+ mntput(currentmnt);
12037+
12038+ if (dentry == realroot && mnt == realrootmnt) {
12039+ /* ok, they're definitely trying to fchdir outside of the
12040+ chroot. */
12041+ dput(realroot);
12042+ mntput(realrootmnt);
12043+ security_alert(GR_CHROOT_FCHDIR_MSG,
12044+ gr_to_filename(u_dentry, u_mnt),
12045+ DEFAULTSECARGS);
12046+ return 0;
12047+ } else {
12048+ dput(realroot);
12049+ mntput(realrootmnt);
12050+ return 1;
12051+ }
12052+ }
12053+#endif
12054+ return 1;
12055+}
12056+
12057+int
12058+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12059+ const time_t shm_createtime)
12060+{
12061+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12062+ struct task_struct *p, **htable;
12063+
12064+ if (unlikely(!grsec_enable_chroot_shmat))
12065+ return 1;
12066+
12067+ if (likely(!proc_is_chrooted(current)))
12068+ return 1;
12069+
12070+ read_lock(&tasklist_lock);
12071+
12072+ htable = &pidhash[pid_hashfn(shm_cprid)];
12073+
12074+ for (p = *htable; p && p->pid != shm_cprid; p = p->pidhash_next) ;
12075+
12076+ if (unlikely(p && !have_same_root(current, p) &&
12077+ (p->start_time < shm_createtime))) {
12078+ read_unlock(&tasklist_lock);
12079+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12080+ return 0;
12081+ }
12082+
12083+ if (unlikely(!p)) {
12084+ htable = &pidhash[pid_hashfn(shm_lapid)];
12085+ for (p = *htable; p && p->pid != shm_lapid;
12086+ p = p->pidhash_next) ;
12087+
12088+ if (unlikely(p && !have_same_root(current, p))) {
12089+ read_unlock(&tasklist_lock);
12090+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12091+ return 0;
12092+ }
12093+ }
12094+
12095+ read_unlock(&tasklist_lock);
12096+#endif
12097+ return 1;
12098+}
12099+
12100+void
12101+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12102+{
12103+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12104+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
12105+ security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
12106+ DEFAULTSECARGS);
12107+#endif
12108+ return;
12109+}
12110+
12111+int
12112+gr_handle_chroot_mknod(const struct dentry *dentry,
12113+ const struct vfsmount *mnt, const int mode)
12114+{
12115+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12116+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) &&
12117+ proc_is_chrooted(current)) {
12118+ security_alert(GR_MKNOD_CHROOT_MSG,
12119+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12120+ return -EPERM;
12121+ }
12122+#endif
12123+ return 0;
12124+}
12125+
12126+int
12127+gr_handle_chroot_mount(const struct dentry *dentry,
12128+ const struct vfsmount *mnt, const char *dev_name)
12129+{
12130+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12131+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
12132+ security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
12133+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12134+ return -EPERM;
12135+ }
12136+#endif
12137+ return 0;
12138+}
12139+
12140+int
12141+gr_handle_chroot_pivot(void)
12142+{
12143+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12144+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
12145+ security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
12146+ return -EPERM;
12147+ }
12148+#endif
12149+ return 0;
12150+}
12151+
12152+int
12153+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
12154+{
12155+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12156+ if (grsec_enable_chroot_double && proc_is_chrooted(current)) {
12157+ security_alert(GR_CHROOT_CHROOT_MSG,
12158+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12159+ return -EPERM;
12160+ }
12161+#endif
12162+ return 0;
12163+}
12164+
12165+void
12166+gr_handle_chroot_caps(struct task_struct *task)
12167+{
12168+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12169+ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
12170+ task->cap_permitted =
12171+ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
12172+ task->cap_inheritable =
12173+ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
12174+ task->cap_effective =
12175+ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
12176+ }
12177+#endif
12178+ return;
12179+}
12180+
12181+int
12182+gr_handle_chroot_sysctl(const int op)
12183+{
12184+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12185+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
12186+ && (op & 002))
12187+ return -EACCES;
12188+#endif
12189+ return 0;
12190+}
12191+
12192+void
12193+gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
12194+{
12195+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12196+ if (grsec_enable_chroot_chdir)
12197+ set_fs_pwd(current->fs, mnt, dentry);
12198+#endif
12199+ return;
12200+}
12201+
12202+int
12203+gr_handle_chroot_chmod(const struct dentry *dentry,
12204+ const struct vfsmount *mnt, const int mode)
12205+{
12206+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12207+ if (grsec_enable_chroot_chmod &&
12208+ ((mode & S_ISUID) || (mode & S_ISGID)) &&
12209+ proc_is_chrooted(current)) {
12210+ security_alert(GR_CHMOD_CHROOT_MSG,
12211+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12212+ return -EPERM;
12213+ }
12214+#endif
12215+ return 0;
12216+}
474a6d91
AM
12217diff -urN linux-2.4.22.org/grsecurity/grsec_disabled.c linux-2.4.22/grsecurity/grsec_disabled.c
12218--- linux-2.4.22.org/grsecurity/grsec_disabled.c 1970-01-01 01:00:00.000000000 +0100
12219+++ linux-2.4.22/grsecurity/grsec_disabled.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
12220@@ -0,0 +1,380 @@
12221+/*
12222+ * when grsecurity is disabled, compile all external functions into nothing
12223+ */
12224+
12225+#include <linux/kernel.h>
12226+#include <linux/config.h>
12227+#include <linux/sched.h>
12228+#include <linux/file.h>
12229+#include <linux/fs.h>
12230+#include <linux/kdev_t.h>
12231+#include <linux/net.h>
12232+#include <linux/in.h>
12233+#include <linux/ip.h>
12234+#include <linux/skbuff.h>
12235+#include <linux/sysctl.h>
12236+
12237+#ifdef CONFIG_SYSCTL
12238+__u32
12239+gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
12240+{
12241+ return mode;
12242+}
12243+#endif
12244+
12245+int
12246+gr_acl_is_enabled(void)
12247+{
12248+ return 0;
12249+}
12250+
12251+int
12252+gr_handle_rawio(const struct inode *inode)
12253+{
12254+ return 0;
12255+}
12256+
12257+void
12258+gr_acl_handle_psacct(struct task_struct *task, const long code)
12259+{
12260+ return;
12261+}
12262+
12263+int
12264+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12265+{
12266+ return 0;
12267+}
12268+
12269+int
12270+gr_handle_mmap(const struct file *filp, const unsigned long prot)
12271+{
12272+ return 0;
12273+}
12274+
12275+int
12276+gr_handle_ptrace(struct task_struct *task, const long request)
12277+{
12278+ return 0;
12279+}
12280+
12281+void
12282+gr_learn_resource(const struct task_struct *task,
12283+ const int res, const unsigned long wanted)
12284+{
12285+ return;
12286+}
12287+
12288+int
12289+gr_set_acls(const int type)
12290+{
12291+ return 0;
12292+}
12293+
12294+int
12295+gr_check_hidden_task(const struct task_struct *tsk)
12296+{
12297+ return 0;
12298+}
12299+
12300+int
12301+gr_check_protected_task(const struct task_struct *task)
12302+{
12303+ return 0;
12304+}
12305+
12306+__inline__ void
12307+gr_copy_label(struct task_struct *tsk)
12308+{
12309+ return;
12310+}
12311+
12312+void
12313+gr_set_pax_flags(struct task_struct *task)
12314+{
12315+ return;
12316+}
12317+
12318+void
12319+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
12320+{
12321+ return;
12322+}
12323+
12324+void
12325+gr_handle_delete(const ino_t ino, const kdev_t dev)
12326+{
12327+ return;
12328+}
12329+
12330+void
12331+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
12332+{
12333+ return;
12334+}
12335+
12336+void
12337+gr_handle_crash(struct task_struct *task, const int sig)
12338+{
12339+ return;
12340+}
12341+
12342+int
12343+gr_check_crash_exec(const struct file *filp)
12344+{
12345+ return 0;
12346+}
12347+
12348+int
12349+gr_check_crash_uid(const uid_t uid)
12350+{
12351+ return 0;
12352+}
12353+
12354+int
12355+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
12356+ struct dentry *old_dentry,
12357+ struct dentry *new_dentry,
12358+ struct vfsmount *mnt, const __u8 replace)
12359+{
12360+ return 0;
12361+}
12362+
12363+int
12364+gr_search_socket(const int family, const int type, const int protocol)
12365+{
12366+ return 1;
12367+}
12368+
12369+int
12370+gr_search_connectbind(const int mode, const struct socket *sock,
12371+ const struct sockaddr_in *addr)
12372+{
12373+ return 1;
12374+}
12375+
12376+int
12377+gr_is_capable(const int cap)
12378+{
12379+ return 1;
12380+}
12381+
12382+void
12383+gr_handle_alertkill(void)
12384+{
12385+ return;
12386+}
12387+
12388+__u32
12389+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
12390+{
12391+ return 1;
12392+}
12393+
12394+__u32
12395+gr_acl_handle_hidden_file(const struct dentry * dentry,
12396+ const struct vfsmount * mnt)
12397+{
12398+ return 1;
12399+}
12400+
12401+__u32
12402+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12403+ const int fmode)
12404+{
12405+ return 1;
12406+}
12407+
12408+__u32
12409+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12410+{
12411+ return 1;
12412+}
12413+
12414+__u32
12415+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
12416+{
12417+ return 1;
12418+}
12419+
12420+int
12421+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
12422+ unsigned int *vm_flags)
12423+{
12424+ return 1;
12425+}
12426+
12427+__u32
12428+gr_acl_handle_truncate(const struct dentry * dentry,
12429+ const struct vfsmount * mnt)
12430+{
12431+ return 1;
12432+}
12433+
12434+__u32
12435+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
12436+{
12437+ return 1;
12438+}
12439+
12440+__u32
12441+gr_acl_handle_access(const struct dentry * dentry,
12442+ const struct vfsmount * mnt, const int fmode)
12443+{
12444+ return 1;
12445+}
12446+
12447+__u32
12448+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
12449+ mode_t mode)
12450+{
12451+ return 1;
12452+}
12453+
12454+__u32
12455+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
12456+ mode_t mode)
12457+{
12458+ return 1;
12459+}
12460+
12461+__u32
12462+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
12463+{
12464+ return 1;
12465+}
12466+
12467+void
12468+grsecurity_init(void)
12469+{
12470+ return;
12471+}
12472+
12473+__u32
12474+gr_acl_handle_mknod(const struct dentry * new_dentry,
12475+ const struct dentry * parent_dentry,
12476+ const struct vfsmount * parent_mnt,
12477+ const int mode)
12478+{
12479+ return 1;
12480+}
12481+
12482+__u32
12483+gr_acl_handle_mkdir(const struct dentry * new_dentry,
12484+ const struct dentry * parent_dentry,
12485+ const struct vfsmount * parent_mnt)
12486+{
12487+ return 1;
12488+}
12489+
12490+__u32
12491+gr_acl_handle_symlink(const struct dentry * new_dentry,
12492+ const struct dentry * parent_dentry,
12493+ const struct vfsmount * parent_mnt, const char *from)
12494+{
12495+ return 1;
12496+}
12497+
12498+__u32
12499+gr_acl_handle_link(const struct dentry * new_dentry,
12500+ const struct dentry * parent_dentry,
12501+ const struct vfsmount * parent_mnt,
12502+ const struct dentry * old_dentry,
12503+ const struct vfsmount * old_mnt, const char *to)
12504+{
12505+ return 1;
12506+}
12507+
12508+int
12509+gr_acl_handle_rename(const struct dentry *new_dentry,
12510+ const struct dentry *parent_dentry,
12511+ const struct vfsmount *parent_mnt,
12512+ const struct dentry *old_dentry,
12513+ const struct inode *old_parent_inode,
12514+ const struct vfsmount *old_mnt, const char *newname)
12515+{
12516+ return 1;
12517+}
12518+
12519+__u32
12520+gr_acl_handle_filldir(const struct dentry * dentry,
12521+ const struct vfsmount * mnt, const ino_t ino)
12522+{
12523+ return 1;
12524+}
12525+
12526+int
12527+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12528+ const time_t shm_createtime, const uid_t cuid, const int shmid)
12529+{
12530+ return 1;
12531+}
12532+
12533+int
12534+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
12535+{
12536+ return 1;
12537+}
12538+
12539+int
12540+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
12541+{
12542+ return 1;
12543+}
12544+
12545+__u32
12546+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
12547+{
12548+ return 1;
12549+}
12550+
12551+__u32
12552+gr_acl_handle_creat(const struct dentry * dentry,
12553+ const struct dentry * p_dentry,
12554+ const struct vfsmount * p_mnt, const int fmode,
12555+ const int imode)
12556+{
12557+ return 1;
12558+}
12559+
12560+void
12561+gr_acl_handle_exit(void)
12562+{
12563+ return;
12564+}
12565+
12566+int
12567+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
12568+{
12569+ return 1;
12570+}
12571+
12572+void
12573+gr_set_role_label(const uid_t uid, const gid_t gid)
12574+{
12575+ return;
12576+}
12577+
12578+int
12579+gr_acl_handle_procpidmem(const struct task_struct *task)
12580+{
12581+ return 0;
12582+}
12583+
12584+int
12585+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
12586+{
12587+ return 1;
12588+}
12589+
12590+int
12591+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
12592+{
12593+ return 1;
12594+}
12595+
12596+void
12597+gr_set_kernel_label(struct task_struct *task)
12598+{
12599+ return;
12600+}
474a6d91
AM
12601diff -urN linux-2.4.22.org/grsecurity/grsec_exec.c linux-2.4.22/grsecurity/grsec_exec.c
12602--- linux-2.4.22.org/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100
12603+++ linux-2.4.22/grsecurity/grsec_exec.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
12604@@ -0,0 +1,70 @@
12605+#include <linux/kernel.h>
12606+#include <linux/sched.h>
12607+#include <linux/file.h>
12608+#include <linux/fs.h>
12609+#include <linux/types.h>
12610+#include <linux/grdefs.h>
12611+#include <linux/grinternal.h>
12612+#include <linux/capability.h>
12613+
12614+#include <asm/uaccess.h>
12615+
12616+int
12617+gr_handle_nproc(void)
12618+{
12619+#ifdef CONFIG_GRKERNSEC_EXECVE
12620+ if (grsec_enable_execve && current->user &&
12621+ (atomic_read(&current->user->processes) >
12622+ current->rlim[RLIMIT_NPROC].rlim_cur) &&
12623+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
12624+ security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
12625+ return -EAGAIN;
12626+ }
12627+#endif
12628+ return 0;
12629+}
12630+
12631+void
12632+gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
12633+{
12634+#ifdef CONFIG_GRKERNSEC_EXECLOG
12635+ char grarg[64] = { 0 };
12636+ __u8 execlen = 0;
12637+ unsigned int i;
12638+
12639+ if (!((grsec_enable_execlog && grsec_enable_group &&
12640+ in_group_p(grsec_audit_gid))
12641+ || (grsec_enable_execlog && !grsec_enable_group)))
12642+ return;
12643+
12644+ if (unlikely(!argv))
12645+ goto log;
12646+
12647+ for (i = 0; i < bprm->argc && execlen < 62; i++) {
12648+ char *p;
12649+ __u8 len;
12650+
12651+ if (get_user(p, argv + i))
12652+ goto log;
12653+ if (!p)
12654+ goto log;
12655+ len = strnlen_user(p, 62 - execlen);
12656+ if (len > 62 - execlen)
12657+ len = 62 - execlen;
12658+ else if (len > 0)
12659+ len--;
12660+ if (copy_from_user(grarg + execlen, p, len))
12661+ goto log;
12662+ execlen += len;
12663+ *(grarg + execlen) = ' ';
12664+ *(grarg + execlen + 1) = '\0';
12665+ execlen++;
12666+ }
12667+
12668+ log:
12669+ security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
12670+ bprm->file->f_vfsmnt),
12671+ grarg, DEFAULTSECARGS);
12672+#endif
12673+ return;
12674+}
474a6d91
AM
12675diff -urN linux-2.4.22.org/grsecurity/grsec_fifo.c linux-2.4.22/grsecurity/grsec_fifo.c
12676--- linux-2.4.22.org/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100
12677+++ linux-2.4.22/grsecurity/grsec_fifo.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
12678@@ -0,0 +1,24 @@
12679+#include <linux/kernel.h>
12680+#include <linux/sched.h>
12681+#include <linux/fs.h>
12682+#include <linux/file.h>
12683+#include <linux/grinternal.h>
12684+
12685+int
12686+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
12687+ const struct dentry *dir, const int flag, const int acc_mode)
12688+{
12689+#ifdef CONFIG_GRKERNSEC_FIFO
12690+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
12691+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
12692+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
12693+ (current->fsuid != dentry->d_inode->i_uid)) {
12694+ if (!permission(dentry->d_inode, acc_mode))
12695+ security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
12696+ dentry->d_inode->i_uid,
12697+ dentry->d_inode->i_gid, DEFAULTSECARGS);
12698+ return -EACCES;
12699+ }
12700+#endif
12701+ return 0;
12702+}
474a6d91
AM
12703diff -urN linux-2.4.22.org/grsecurity/grsec_fork.c linux-2.4.22/grsecurity/grsec_fork.c
12704--- linux-2.4.22.org/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100
12705+++ linux-2.4.22/grsecurity/grsec_fork.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
12706@@ -0,0 +1,14 @@
12707+#include <linux/kernel.h>
12708+#include <linux/sched.h>
12709+#include <linux/grsecurity.h>
12710+#include <linux/grinternal.h>
12711+
12712+void
12713+gr_log_forkfail(const int retval)
12714+{
12715+#ifdef CONFIG_GRKERNSEC_FORKFAIL
12716+ if (grsec_enable_forkfail)
12717+ security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
12718+#endif
12719+ return;
12720+}
474a6d91
AM
12721diff -urN linux-2.4.22.org/grsecurity/grsec_init.c linux-2.4.22/grsecurity/grsec_init.c
12722--- linux-2.4.22.org/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100
12723+++ linux-2.4.22/grsecurity/grsec_init.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
12724@@ -0,0 +1,210 @@
12725+#include <linux/kernel.h>
12726+#include <linux/sched.h>
12727+#include <linux/mm.h>
12728+#include <linux/smp_lock.h>
12729+#include <linux/gracl.h>
12730+#include <linux/slab.h>
12731+
12732+int grsec_enable_link;
12733+int grsec_enable_dmesg;
12734+int grsec_enable_fifo;
12735+int grsec_enable_execve;
12736+int grsec_enable_execlog;
12737+int grsec_enable_signal;
12738+int grsec_enable_forkfail;
12739+int grsec_enable_time;
12740+int grsec_enable_group;
12741+int grsec_audit_gid;
12742+int grsec_enable_chdir;
12743+int grsec_enable_audit_ipc;
12744+int grsec_enable_mount;
12745+int grsec_enable_chroot_findtask;
12746+int grsec_enable_chroot_mount;
12747+int grsec_enable_chroot_shmat;
12748+int grsec_enable_chroot_fchdir;
12749+int grsec_enable_chroot_double;
12750+int grsec_enable_chroot_pivot;
12751+int grsec_enable_chroot_chdir;
12752+int grsec_enable_chroot_chmod;
12753+int grsec_enable_chroot_mknod;
12754+int grsec_enable_chroot_nice;
12755+int grsec_enable_chroot_execlog;
12756+int grsec_enable_chroot_caps;
12757+int grsec_enable_chroot_sysctl;
12758+int grsec_enable_chroot_unix;
12759+int grsec_enable_tpe;
12760+int grsec_tpe_gid;
12761+int grsec_enable_tpe_all;
12762+int grsec_enable_randpid;
12763+int grsec_enable_randid;
12764+int grsec_enable_randisn;
12765+int grsec_enable_randsrc;
12766+int grsec_enable_randrpc;
12767+int grsec_enable_socket_all;
12768+int grsec_socket_all_gid;
12769+int grsec_enable_socket_client;
12770+int grsec_socket_client_gid;
12771+int grsec_enable_socket_server;
12772+int grsec_socket_server_gid;
12773+int grsec_lock;
12774+
12775+spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
12776+unsigned long grsec_alert_wtime = 0;
12777+unsigned long grsec_alert_fyet = 0;
12778+
12779+spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
12780+unsigned long grsec_alertgood_wtime = 0;
12781+unsigned long grsec_alertgood_fyet = 0;
12782+
12783+spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
12784+
12785+char *gr_shared_page[4][NR_CPUS];
12786+extern struct gr_arg *gr_usermode;
12787+extern unsigned char *gr_system_salt;
12788+extern unsigned char *gr_system_sum;
12789+
12790+void
12791+grsecurity_init(void)
12792+{
12793+ int i, j;
12794+ /* create the per-cpu shared pages */
12795+
12796+ for (j = 0; j < 4; j++) {
12797+ for (i = 0; i < NR_CPUS; i++) {
12798+ gr_shared_page[j][i] = (char *) get_zeroed_page(GFP_KERNEL);
12799+ if (!gr_shared_page[j][i]) {
12800+ panic("Unable to allocate grsecurity shared page");
12801+ return;
12802+ }
12803+ }
12804+ }
12805+
12806+ /* allocate memory for authentication structure */
12807+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
12808+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
12809+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
12810+
12811+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
12812+ panic("Unable to allocate grsecurity authentication structure");
12813+ return;
12814+ }
12815+
12816+#ifndef CONFIG_GRKERNSEC_SYSCTL
12817+ grsec_lock = 1;
12818+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
12819+ grsec_enable_group = 1;
12820+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
12821+#endif
12822+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
12823+ grsec_enable_chdir = 1;
12824+#endif
12825+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12826+ grsec_enable_audit_ipc = 1;
12827+#endif
12828+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
12829+ grsec_enable_mount = 1;
12830+#endif
12831+#ifdef CONFIG_GRKERNSEC_LINK
12832+ grsec_enable_link = 1;
12833+#endif
12834+#ifdef CONFIG_GRKERNSEC_DMESG
12835+ grsec_enable_dmesg = 1;
12836+#endif
12837+#ifdef CONFIG_GRKERNSEC_FIFO
12838+ grsec_enable_fifo = 1;
12839+#endif
12840+#ifdef CONFIG_GRKERNSEC_EXECVE
12841+ grsec_enable_execve = 1;
12842+#endif
12843+#ifdef CONFIG_GRKERNSEC_EXECLOG
12844+ grsec_enable_execlog = 1;
12845+#endif
12846+#ifdef CONFIG_GRKERNSEC_SIGNAL
12847+ grsec_enable_signal = 1;
12848+#endif
12849+#ifdef CONFIG_GRKERNSEC_FORKFAIL
12850+ grsec_enable_forkfail = 1;
12851+#endif
12852+#ifdef CONFIG_GRKERNSEC_TIME
12853+ grsec_enable_time = 1;
12854+#endif
12855+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
12856+ grsec_enable_chroot_findtask = 1;
12857+#endif
12858+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12859+ grsec_enable_chroot_unix = 1;
12860+#endif
12861+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12862+ grsec_enable_chroot_mount = 1;
12863+#endif
12864+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
12865+ grsec_enable_chroot_fchdir = 1;
12866+#endif
12867+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12868+ grsec_enable_chroot_shmat = 1;
12869+#endif
12870+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12871+ grsec_enable_chroot_double = 1;
12872+#endif
12873+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12874+ grsec_enable_chroot_pivot = 1;
12875+#endif
12876+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12877+ grsec_enable_chroot_chdir = 1;
12878+#endif
12879+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12880+ grsec_enable_chroot_chmod = 1;
12881+#endif
12882+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12883+ grsec_enable_chroot_mknod = 1;
12884+#endif
12885+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12886+ grsec_enable_chroot_nice = 1;
12887+#endif
12888+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12889+ grsec_enable_chroot_execlog = 1;
12890+#endif
12891+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12892+ grsec_enable_chroot_caps = 1;
12893+#endif
12894+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12895+ grsec_enable_chroot_sysctl = 1;
12896+#endif
12897+#ifdef CONFIG_GRKERNSEC_TPE
12898+ grsec_enable_tpe = 1;
12899+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
12900+#ifdef CONFIG_GRKERNSEC_TPE_ALL
12901+ grsec_enable_tpe_all = 1;
12902+#endif
12903+#endif
12904+#ifdef CONFIG_GRKERNSEC_RANDPID
12905+ grsec_enable_randpid = 1;
12906+#endif
12907+#ifdef CONFIG_GRKERNSEC_RANDID
12908+ grsec_enable_randid = 1;
12909+#endif
12910+#ifdef CONFIG_GRKERNSEC_RANDISN
12911+ grsec_enable_randisn = 1;
12912+#endif
12913+#ifdef CONFIG_GRKERNSEC_RANDSRC
12914+ grsec_enable_randsrc = 1;
12915+#endif
12916+#ifdef CONFIG_GRKERNSEC_RANDRPC
12917+ grsec_enable_randrpc = 1;
12918+#endif
12919+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
12920+ grsec_enable_socket_all = 1;
12921+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
12922+#endif
12923+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
12924+ grsec_enable_socket_client = 1;
12925+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
12926+#endif
12927+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
12928+ grsec_enable_socket_server = 1;
12929+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
12930+#endif
12931+#endif
12932+
12933+ return;
12934+}
474a6d91
AM
12935diff -urN linux-2.4.22.org/grsecurity/grsec_ipc.c linux-2.4.22/grsecurity/grsec_ipc.c
12936--- linux-2.4.22.org/grsecurity/grsec_ipc.c 1970-01-01 01:00:00.000000000 +0100
12937+++ linux-2.4.22/grsecurity/grsec_ipc.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
12938@@ -0,0 +1,81 @@
12939+#include <linux/kernel.h>
12940+#include <linux/sched.h>
12941+#include <linux/types.h>
12942+#include <linux/ipc.h>
12943+#include <linux/grsecurity.h>
12944+#include <linux/grinternal.h>
12945+
12946+void
12947+gr_log_msgget(const int ret, const int msgflg)
12948+{
12949+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12950+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12951+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
12952+ !grsec_enable_group)) && (ret >= 0)
12953+ && (msgflg & IPC_CREAT))
12954+ security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
12955+#endif
12956+ return;
12957+}
12958+
12959+void
12960+gr_log_msgrm(const uid_t uid, const uid_t cuid)
12961+{
12962+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12963+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12964+ grsec_enable_audit_ipc) ||
12965+ (grsec_enable_audit_ipc && !grsec_enable_group))
12966+ security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
12967+#endif
12968+ return;
12969+}
12970+
12971+void
12972+gr_log_semget(const int err, const int semflg)
12973+{
12974+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12975+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12976+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
12977+ !grsec_enable_group)) && (err >= 0)
12978+ && (semflg & IPC_CREAT))
12979+ security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
12980+#endif
12981+ return;
12982+}
12983+
12984+void
12985+gr_log_semrm(const uid_t uid, const uid_t cuid)
12986+{
12987+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12988+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12989+ grsec_enable_audit_ipc) ||
12990+ (grsec_enable_audit_ipc && !grsec_enable_group))
12991+ security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
12992+#endif
12993+ return;
12994+}
12995+
12996+void
12997+gr_log_shmget(const int err, const int shmflg, const size_t size)
12998+{
12999+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13000+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13001+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13002+ !grsec_enable_group)) && (err >= 0)
13003+ && (shmflg & IPC_CREAT))
13004+ security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
13005+#endif
13006+ return;
13007+}
13008+
13009+void
13010+gr_log_shmrm(const uid_t uid, const uid_t cuid)
13011+{
13012+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13013+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13014+ grsec_enable_audit_ipc) ||
13015+ (grsec_enable_audit_ipc && !grsec_enable_group))
13016+ security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13017+#endif
13018+ return;
13019+}
474a6d91
AM
13020diff -urN linux-2.4.22.org/grsecurity/grsec_link.c linux-2.4.22/grsecurity/grsec_link.c
13021--- linux-2.4.22.org/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100
13022+++ linux-2.4.22/grsecurity/grsec_link.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13023@@ -0,0 +1,41 @@
13024+#include <linux/kernel.h>
13025+#include <linux/sched.h>
13026+#include <linux/fs.h>
13027+#include <linux/file.h>
13028+#include <linux/grinternal.h>
13029+
13030+int
13031+gr_handle_follow_link(const struct inode *parent,
13032+ const struct inode *inode,
13033+ const struct dentry *dentry, const struct vfsmount *mnt)
13034+{
13035+#ifdef CONFIG_GRKERNSEC_LINK
13036+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
13037+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
13038+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
13039+ security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
13040+ inode->i_uid, inode->i_gid, DEFAULTSECARGS);
13041+ return -EACCES;
13042+ }
13043+#endif
13044+ return 0;
13045+}
13046+
13047+int
13048+gr_handle_hardlink(const struct dentry *dentry,
13049+ const struct vfsmount *mnt,
13050+ struct inode *inode, const int mode, const char *to)
13051+{
13052+#ifdef CONFIG_GRKERNSEC_LINK
13053+ if (grsec_enable_link && current->fsuid != inode->i_uid &&
13054+ (!S_ISREG(mode) || (mode & S_ISUID) ||
13055+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
13056+ (permission(inode, MAY_READ | MAY_WRITE))) &&
13057+ !capable(CAP_FOWNER) && current->uid) {
13058+ security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
13059+ inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
13060+ return -EPERM;
13061+ }
13062+#endif
13063+ return 0;
13064+}
474a6d91
AM
13065diff -urN linux-2.4.22.org/grsecurity/grsec_mem.c linux-2.4.22/grsecurity/grsec_mem.c
13066--- linux-2.4.22.org/grsecurity/grsec_mem.c 1970-01-01 01:00:00.000000000 +0100
13067+++ linux-2.4.22/grsecurity/grsec_mem.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13068@@ -0,0 +1,54 @@
13069+#include <linux/kernel.h>
13070+#include <linux/sched.h>
13071+#include <linux/mm.h>
13072+#include <linux/grinternal.h>
13073+
13074+void
13075+gr_handle_ioperm(void)
13076+{
13077+ security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
13078+ return;
13079+}
13080+
13081+void
13082+gr_handle_iopl(void)
13083+{
13084+ security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
13085+ return;
13086+}
13087+
13088+void
13089+gr_handle_mem_write(void)
13090+{
13091+ security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
13092+ return;
13093+}
13094+
13095+void
13096+gr_handle_kmem_write(void)
13097+{
13098+ security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
13099+ return;
13100+}
13101+
13102+void
13103+gr_handle_open_port(void)
13104+{
13105+ security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
13106+ return;
13107+}
13108+
13109+int
13110+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
13111+{
13112+ if (offset < __pa(high_memory) &&
13113+ (pgprot_val(vma->vm_page_prot) & PROT_WRITE) &&
13114+ !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
13115+ !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
13116+ security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
13117+ return -EPERM;
13118+ } else if (offset < __pa(high_memory))
13119+ vma->vm_flags &= ~VM_MAYWRITE;
13120+
13121+ return 0;
13122+}
474a6d91
AM
13123diff -urN linux-2.4.22.org/grsecurity/grsec_mount.c linux-2.4.22/grsecurity/grsec_mount.c
13124--- linux-2.4.22.org/grsecurity/grsec_mount.c 1970-01-01 01:00:00.000000000 +0100
13125+++ linux-2.4.22/grsecurity/grsec_mount.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13126@@ -0,0 +1,34 @@
13127+#include <linux/kernel.h>
13128+#include <linux/sched.h>
13129+#include <linux/grsecurity.h>
13130+#include <linux/grinternal.h>
13131+
13132+void
13133+gr_log_remount(const char *devname, const int retval)
13134+{
13135+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13136+ if (grsec_enable_mount && (retval >= 0))
13137+ security_audit(GR_REMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13138+#endif
13139+ return;
13140+}
13141+
13142+void
13143+gr_log_unmount(const char *devname, const int retval)
13144+{
13145+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13146+ if (grsec_enable_mount && (retval >= 0))
13147+ security_audit(GR_UNMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
13148+#endif
13149+ return;
13150+}
13151+
13152+void
13153+gr_log_mount(const char *from, const char *to, const int retval)
13154+{
13155+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13156+ if (grsec_enable_mount && (retval >= 0))
13157+ security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
13158+#endif
13159+ return;
13160+}
474a6d91
AM
13161diff -urN linux-2.4.22.org/grsecurity/grsec_rand.c linux-2.4.22/grsecurity/grsec_rand.c
13162--- linux-2.4.22.org/grsecurity/grsec_rand.c 1970-01-01 01:00:00.000000000 +0100
13163+++ linux-2.4.22/grsecurity/grsec_rand.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13164@@ -0,0 +1,36 @@
13165+#include <linux/kernel.h>
13166+#include <linux/sched.h>
13167+#include <linux/smp_lock.h>
13168+#include <linux/grsecurity.h>
13169+#include <linux/grinternal.h>
13170+
13171+extern int last_pid;
13172+
13173+int
13174+gr_random_pid(spinlock_t * pid_lock)
13175+{
13176+#ifdef CONFIG_GRKERNSEC_RANDPID
13177+ struct task_struct *p;
13178+ int pid;
13179+
13180+ if (grsec_enable_randpid && current->fs->root) {
13181+ read_lock(&tasklist_lock);
13182+ spin_lock(pid_lock);
13183+
13184+ repeater:
13185+
13186+ pid = 1 + (get_random_long() % PID_MAX);
13187+
13188+ for_each_task(p) {
13189+ if (p->pid == pid || p->pgrp == pid ||
13190+ p->tgid == pid || p->session == pid)
13191+ goto repeater;
13192+ }
13193+ last_pid = pid;
13194+ spin_unlock(pid_lock);
13195+ read_unlock(&tasklist_lock);
13196+ return pid;
13197+ }
13198+#endif
13199+ return 0;
13200+}
474a6d91
AM
13201diff -urN linux-2.4.22.org/grsecurity/grsec_sig.c linux-2.4.22/grsecurity/grsec_sig.c
13202--- linux-2.4.22.org/grsecurity/grsec_sig.c 1970-01-01 01:00:00.000000000 +0100
13203+++ linux-2.4.22/grsecurity/grsec_sig.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13204@@ -0,0 +1,47 @@
13205+#include <linux/kernel.h>
13206+#include <linux/sched.h>
13207+#include <linux/grinternal.h>
13208+
13209+void
13210+gr_log_signal(const int sig, const struct task_struct *t)
13211+{
13212+#ifdef CONFIG_GRKERNSEC_SIGNAL
13213+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
13214+ (sig == SIGABRT) || (sig == SIGBUS))) {
13215+ if (t->pid == current->pid) {
13216+ security_alert_good(GR_UNISIGLOG_MSG, sig,
13217+ DEFAULTSECARGS);
13218+ } else {
13219+ security_alert_good(GR_DUALSIGLOG_MSG, sig,
13220+ gr_task_fullpath(t), t->comm,
13221+ t->pid, t->uid, t->euid, t->gid,
13222+ t->egid, gr_parent_task_fullpath(t),
13223+ t->p_pptr->comm,
13224+ t->p_pptr->pid, t->p_pptr->uid,
13225+ t->p_pptr->euid, t->p_pptr->gid,
13226+ t->p_pptr->egid, DEFAULTSECARGS);
13227+ }
13228+ }
13229+#endif
13230+ return;
13231+}
13232+
13233+int
13234+gr_handle_signal(const struct task_struct *p, const int sig)
13235+{
13236+#ifdef CONFIG_GRKERNSEC
13237+ if (current->pid > 1 && gr_check_protected_task(p)) {
13238+ security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath(p),
13239+ p->comm, p->pid, p->uid,
13240+ p->euid, p->gid, p->egid,
13241+ gr_parent_task_fullpath(p), p->p_pptr->comm,
13242+ p->p_pptr->pid, p->p_pptr->uid,
13243+ p->p_pptr->euid, p->p_pptr->gid,
13244+ p->p_pptr->egid, DEFAULTSECARGS);
13245+ return -EPERM;
13246+ } else if (gr_pid_is_chrooted(p)) {
13247+ return -EPERM;
13248+ }
13249+#endif
13250+ return 0;
13251+}
474a6d91
AM
13252diff -urN linux-2.4.22.org/grsecurity/grsec_sock.c linux-2.4.22/grsecurity/grsec_sock.c
13253--- linux-2.4.22.org/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100
13254+++ linux-2.4.22/grsecurity/grsec_sock.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13255@@ -0,0 +1,123 @@
13256+#include <linux/kernel.h>
13257+#include <linux/sched.h>
13258+#include <linux/file.h>
13259+#include <linux/net.h>
13260+#include <net/sock.h>
13261+#include <linux/grsecurity.h>
13262+#include <linux/grinternal.h>
13263+#include <linux/gracl.h>
13264+
13265+void
13266+gr_attach_curr_ip(const struct sock *sk)
13267+{
13268+#ifdef CONFIG_GRKERNSEC
13269+ struct task_struct *p;
13270+ unsigned int i;
13271+ struct inode *inode;
13272+ struct file *filp;
13273+ struct socket *connect_sock;
13274+
13275+ if (unlikely(sk->protocol != IPPROTO_TCP))
13276+ return;
13277+
13278+ read_lock(&tasklist_lock);
13279+ for_each_task(p) {
13280+ if (!p->used_connect)
13281+ continue;
13282+ task_lock(p);
13283+ if (unlikely(!p->files)) {
13284+ task_unlock(p);
13285+ continue;
13286+ }
13287+ read_lock(&p->files->file_lock);
13288+ for (i = 0; i < p->files->max_fds; i++) {
13289+ filp = fcheck_files(p->files, i);
13290+ if (likely(!filp))
13291+ continue;
13292+ inode = filp->f_dentry->d_inode;
13293+ if (likely(!inode || !inode->i_sock))
13294+ continue;
13295+ connect_sock = &inode->u.socket_i;
13296+ if (unlikely(!connect_sock ||
13297+ connect_sock->sk->protocol != IPPROTO_TCP))
13298+ continue;
13299+ if (unlikely(sk->rcv_saddr == connect_sock->sk->daddr &&
13300+ sk->daddr == connect_sock->sk->rcv_saddr &&
13301+ ntohs(sk->sport) ==
13302+ ntohs(connect_sock->sk->dport)
13303+ && ntohs(sk->dport) ==
13304+ ntohs(connect_sock->sk->sport))) {
13305+ current->curr_ip = p->curr_ip;
13306+ current->used_accept = 1;
13307+ read_unlock(&p->files->file_lock);
13308+ task_unlock(p);
13309+ read_unlock(&tasklist_lock);
13310+ return;
13311+ }
13312+ }
13313+ read_unlock(&p->files->file_lock);
13314+ task_unlock(p);
13315+ }
13316+ read_unlock(&tasklist_lock);
13317+
13318+ current->curr_ip = sk->daddr;
13319+ current->used_accept = 1;
13320+#endif
13321+ return;
13322+}
13323+
13324+int
13325+gr_handle_sock_all(const int family, const int type, const int protocol)
13326+{
13327+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13328+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
13329+ (family != AF_UNIX) && (family != AF_LOCAL)) {
13330+ security_alert(GR_SOCK_MSG, family, type, protocol,
13331+ DEFAULTSECARGS);
13332+ return -EACCES;
13333+ }
13334+#endif
13335+ return 0;
13336+}
13337+
13338+int
13339+gr_handle_sock_server(const struct sockaddr *sck)
13340+{
13341+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13342+ if (grsec_enable_socket_server &&
13343+ in_group_p(grsec_socket_server_gid) &&
13344+ sck && (sck->sa_family != AF_UNIX) &&
13345+ (sck->sa_family != AF_LOCAL)) {
13346+ security_alert(GR_BIND_MSG, DEFAULTSECARGS);
13347+ return -EACCES;
13348+ }
13349+#endif
13350+ return 0;
13351+}
13352+
13353+int
13354+gr_handle_sock_client(const struct sockaddr *sck)
13355+{
13356+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13357+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
13358+ sck && (sck->sa_family != AF_UNIX) &&
13359+ (sck->sa_family != AF_LOCAL)) {
13360+ security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
13361+ return -EACCES;
13362+ }
13363+#endif
13364+ return 0;
13365+}
13366+
13367+__u32
13368+gr_cap_rtnetlink(void)
13369+{
13370+#ifdef CONFIG_GRKERNSEC
13371+ if (!gr_acl_is_enabled())
13372+ return current->cap_effective;
13373+ else
13374+ return (current->cap_effective & ~(current->acl->cap_lower));
13375+#else
13376+ return current->cap_effective;
13377+#endif
13378+}
474a6d91
AM
13379diff -urN linux-2.4.22.org/grsecurity/grsec_sysctl.c linux-2.4.22/grsecurity/grsec_sysctl.c
13380--- linux-2.4.22.org/grsecurity/grsec_sysctl.c 1970-01-01 01:00:00.000000000 +0100
13381+++ linux-2.4.22/grsecurity/grsec_sysctl.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13382@@ -0,0 +1,16 @@
13383+#include <linux/kernel.h>
13384+#include <linux/sched.h>
13385+#include <linux/sysctl.h>
13386+#include <linux/grinternal.h>
13387+
13388+int
13389+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
13390+{
13391+#ifdef CONFIG_GRKERNSEC_SYSCTL
13392+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
13393+ security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
13394+ return -EACCES;
13395+ }
13396+#endif
13397+ return 0;
13398+}
474a6d91
AM
13399diff -urN linux-2.4.22.org/grsecurity/grsec_time.c linux-2.4.22/grsecurity/grsec_time.c
13400--- linux-2.4.22.org/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100
13401+++ linux-2.4.22/grsecurity/grsec_time.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13402@@ -0,0 +1,13 @@
13403+#include <linux/kernel.h>
13404+#include <linux/sched.h>
13405+#include <linux/grinternal.h>
13406+
13407+void
13408+gr_log_timechange(void)
13409+{
13410+#ifdef CONFIG_GRKERNSEC_TIME
13411+ if (grsec_enable_time)
13412+ security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
13413+#endif
13414+ return;
13415+}
474a6d91
AM
13416diff -urN linux-2.4.22.org/grsecurity/grsec_tpe.c linux-2.4.22/grsecurity/grsec_tpe.c
13417--- linux-2.4.22.org/grsecurity/grsec_tpe.c 1970-01-01 01:00:00.000000000 +0100
13418+++ linux-2.4.22/grsecurity/grsec_tpe.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13419@@ -0,0 +1,35 @@
13420+#include <linux/kernel.h>
13421+#include <linux/sched.h>
13422+#include <linux/file.h>
13423+#include <linux/fs.h>
13424+#include <linux/grinternal.h>
13425+
13426+extern int gr_acl_tpe_check(void);
13427+
13428+int
13429+gr_tpe_allow(const struct file *file)
13430+{
13431+#ifdef CONFIG_GRKERNSEC
13432+ struct inode *inode = file->f_dentry->d_parent->d_inode;
13433+
13434+ if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
13435+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
13436+ (inode->i_mode & S_IWOTH))))) {
13437+ security_alert(GR_EXEC_TPE_MSG,
13438+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
13439+ DEFAULTSECARGS);
13440+ return 0;
13441+ }
13442+#ifdef CONFIG_GRKERNSEC_TPE_ALL
13443+ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
13444+ ((inode->i_uid && (inode->i_uid != current->uid)) ||
13445+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
13446+ security_alert(GR_EXEC_TPE_MSG,
13447+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
13448+ DEFAULTSECARGS);
13449+ return 0;
13450+ }
13451+#endif
13452+#endif
13453+ return 1;
13454+}
474a6d91
AM
13455diff -urN linux-2.4.22.org/grsecurity/grsum.c linux-2.4.22/grsecurity/grsum.c
13456--- linux-2.4.22.org/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100
13457+++ linux-2.4.22/grsecurity/grsum.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13458@@ -0,0 +1,59 @@
13459+#include <linux/kernel.h>
13460+#include <linux/sched.h>
13461+#include <linux/mm.h>
13462+#include <asm/scatterlist.h>
13463+#include <linux/crypto.h>
13464+#include <linux/gracl.h>
13465+
13466+
13467+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
13468+#error "crypto and sha256 must be built into the kernel"
13469+#endif
13470+
13471+int
13472+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
13473+{
13474+ char *p;
13475+ struct crypto_tfm *tfm;
13476+ unsigned char temp_sum[GR_SHA_LEN];
13477+ struct scatterlist sg[2];
13478+ volatile int retval = 0;
13479+ volatile int dummy = 0;
13480+ unsigned int i;
13481+
13482+ tfm = crypto_alloc_tfm("sha256", 0);
13483+ if (tfm == NULL) {
13484+ /* should never happen, since sha256 should be built in */
13485+ return 1;
13486+ }
13487+
13488+ crypto_digest_init(tfm);
13489+
13490+ p = salt;
13491+ sg[0].page = virt_to_page(p);
13492+ sg[0].offset = ((long) p & ~PAGE_MASK);
13493+ sg[0].length = GR_SALT_LEN;
13494+
13495+ crypto_digest_update(tfm, sg, 1);
13496+
13497+ p = entry->pw;
13498+ sg[0].page = virt_to_page(p);
13499+ sg[0].offset = ((long) p & ~PAGE_MASK);
13500+ sg[0].length = strlen(entry->pw);
13501+
13502+ crypto_digest_update(tfm, sg, 1);
13503+
13504+ crypto_digest_final(tfm, temp_sum);
13505+
13506+ memset(entry->pw, 0, GR_PW_LEN);
13507+
13508+ for (i = 0; i < GR_SHA_LEN; i++)
13509+ if (sum[i] != temp_sum[i])
13510+ retval = 1;
13511+ else
13512+ dummy = 1; // waste a cycle
13513+
13514+ crypto_free_tfm(tfm);
13515+
13516+ return retval;
13517+}
474a6d91
AM
13518diff -urN linux-2.4.22.org/grsecurity/Makefile linux-2.4.22/grsecurity/Makefile
13519--- linux-2.4.22.org/grsecurity/Makefile 1970-01-01 01:00:00.000000000 +0100
13520+++ linux-2.4.22/grsecurity/Makefile 2003-11-22 22:14:08.000000000 +0100
13521@@ -0,0 +1,24 @@
13522+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
13523+# during 2001, 2002, and 2003 it has been completely redesigned by
13524+# Brad Spengler
13525+#
13526+# All code in this directory and various hooks inserted throughout the kernel
13527+# are copyright Brad Spengler, and released under the GPL, unless otherwise
13528+# noted (as in obsd_rand.c)
13529+
13530+O_TARGET := grsec.o
13531+
13532+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
13533+ grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
13534+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o
13535+
13536+ifeq ($(CONFIG_GRKERNSEC),y)
13537+obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
13538+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
13539+ gracl_learn.o
13540+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
13541+else
13542+obj-y += grsec_disabled.o
13543+endif
13544+
13545+include $(TOPDIR)/Rules.make
13546diff -urN linux-2.4.22.org/grsecurity/obsd_rand.c linux-2.4.22/grsecurity/obsd_rand.c
13547--- linux-2.4.22.org/grsecurity/obsd_rand.c 1970-01-01 01:00:00.000000000 +0100
13548+++ linux-2.4.22/grsecurity/obsd_rand.c 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13549@@ -0,0 +1,195 @@
13550+
13551+/*
13552+ * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
13553+ *
13554+ * Version 1.89, last modified 19-Sep-99
13555+ *
13556+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
13557+ * All rights reserved.
13558+ *
13559+ * Copyright 1998 Niels Provos <provos@citi.umich.edu>
13560+ * All rights reserved.
13561+ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
13562+ * such a mathematical system to generate more random (yet non-repeating)
13563+ * ids to solve the resolver/named problem. But Niels designed the
13564+ * actual system based on the constraints.
13565+ *
13566+ * Redistribution and use in source and binary forms, with or without
13567+ * modification, are permitted provided that the following conditions
13568+ * are met:
13569+ * 1. Redistributions of source code must retain the above copyright
13570+ * notice, this list of conditions and the following disclaimer,
13571+ * 2. Redistributions in binary form must reproduce the above copyright
13572+ * notice, this list of conditions and the following disclaimer in the
13573+ * documentation and/or other materials provided with the distribution.
13574+ * 3. All advertising materials mentioning features or use of this software
13575+ * must display the following acknowledgement:
13576+ * This product includes software developed by Niels Provos.
13577+ * 4. The name of the author may not be used to endorse or promote products
13578+ * derived from this software without specific prior written permission.
13579+ *
13580+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
13581+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
13582+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
13583+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
13584+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
13585+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
13586+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13587+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13588+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
13589+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13590+ */
13591+
13592+#include <linux/kernel.h>
13593+#include <linux/sched.h>
13594+#include <linux/timer.h>
13595+#include <linux/smp_lock.h>
13596+#include <linux/random.h>
13597+#include <linux/grsecurity.h>
13598+
13599+#define RU_OUT 180
13600+#define RU_MAX 30000
13601+#define RU_GEN 2
13602+#define RU_N 32749
13603+#define RU_AGEN 7
13604+#define RU_M 31104
13605+#define PFAC_N 3
13606+const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
13607+
13608+static __u16 ru_x;
13609+static __u16 ru_seed, ru_seed2;
13610+static __u16 ru_a, ru_b;
13611+static __u16 ru_g;
13612+static __u16 ru_counter = 0;
13613+static __u16 ru_msb = 0;
13614+static unsigned long ru_reseed = 0;
13615+static __u32 tmp;
13616+
13617+#define TCP_RNDISS_ROUNDS 15
13618+#define TCP_RNDISS_OUT 7200
13619+#define TCP_RNDISS_MAX 30000
13620+
13621+static __u8 tcp_rndiss_sbox[NR_CPUS][128];
13622+static __u16 tcp_rndiss_msb[NR_CPUS];
13623+static __u16 tcp_rndiss_cnt[NR_CPUS];
13624+static unsigned long tcp_rndiss_reseed[NR_CPUS];
13625+
13626+static __u16 pmod(__u16, __u16, __u16);
13627+static void ip_initid(void);
13628+__u16 ip_randomid(void);
13629+
13630+static __u16
13631+pmod(__u16 gen, __u16 exp, __u16 mod)
13632+{
13633+ __u16 s, t, u;
13634+
13635+ s = 1;
13636+ t = gen;
13637+ u = exp;
13638+
13639+ while (u) {
13640+ if (u & 1)
13641+ s = (s * t) % mod;
13642+ u >>= 1;
13643+ t = (t * t) % mod;
13644+ }
13645+ return (s);
13646+}
13647+
13648+static void
13649+ip_initid(void)
13650+{
13651+ __u16 j, i;
13652+ int noprime = 1;
13653+
13654+ ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
13655+
13656+ ru_seed = (tmp >> 16) & 0x7FFF;
13657+ ru_seed2 = get_random_long() & 0x7FFF;
13658+
13659+ ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
13660+ ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
13661+ while (ru_b % 3 == 0)
13662+ ru_b += 2;
13663+
13664+ j = (tmp = get_random_long()) % RU_N;
13665+ tmp = tmp >> 16;
13666+
13667+ while (noprime) {
13668+ for (i = 0; i < PFAC_N; i++)
13669+ if (j % pfacts[i] == 0)
13670+ break;
13671+
13672+ if (i >= PFAC_N)
13673+ noprime = 0;
13674+ else
13675+ j = (j + 1) % RU_N;
13676+ }
13677+
13678+ ru_g = pmod(RU_GEN, j, RU_N);
13679+ ru_counter = 0;
13680+
13681+ ru_reseed = xtime.tv_sec + RU_OUT;
13682+ ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
13683+}
13684+
13685+__u16
13686+ip_randomid(void)
13687+{
13688+ int i, n;
13689+
13690+ if (ru_counter >= RU_MAX || time_after(xtime.tv_sec, ru_reseed))
13691+ ip_initid();
13692+
13693+ if (!tmp)
13694+ tmp = get_random_long();
13695+
13696+ n = tmp & 0x3;
13697+ tmp = tmp >> 2;
13698+ if (ru_counter + n >= RU_MAX)
13699+ ip_initid();
13700+ for (i = 0; i <= n; i++)
13701+ ru_x = (ru_a * ru_x + ru_b) % RU_M;
13702+ ru_counter += i;
13703+
13704+ return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
13705+}
13706+
13707+__u16
13708+tcp_rndiss_encrypt(__u16 val)
13709+{
13710+ __u16 sum = 0, i;
13711+ int cpu = smp_processor_id();
13712+
13713+ for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
13714+ sum += 0x79b9;
13715+ val ^= ((__u16) tcp_rndiss_sbox[cpu][(val ^ sum) ^ 0x7f]) << 7;
13716+ val = ((val & 0xff) << 7) | (val >> 8);
13717+ }
13718+
13719+ return val;
13720+}
13721+
13722+static void
13723+tcp_rndiss_init(void)
13724+{
13725+ int cpu = smp_processor_id();
13726+
13727+ get_random_bytes(tcp_rndiss_sbox[cpu], sizeof (tcp_rndiss_sbox));
13728+ tcp_rndiss_reseed[cpu] = xtime.tv_sec + TCP_RNDISS_OUT;
13729+ tcp_rndiss_msb[cpu] = tcp_rndiss_msb[cpu] == 0x8000 ? 0 : 0x8000;
13730+ tcp_rndiss_cnt[cpu] = 0;
13731+}
13732+
13733+__u32
13734+ip_randomisn(void)
13735+{
13736+ int cpu = smp_processor_id();
13737+
13738+ if (tcp_rndiss_cnt[cpu] >= TCP_RNDISS_MAX ||
13739+ time_after(xtime.tv_sec, tcp_rndiss_reseed[cpu]))
13740+ tcp_rndiss_init();
13741+
13742+ return (((tcp_rndiss_encrypt(tcp_rndiss_cnt[cpu]++) |
13743+ tcp_rndiss_msb[cpu]) << 16) | (get_random_long() & 0x7fff));
13744+}
474a6d91
AM
13745diff -urN linux-2.4.22.org/include/asm-alpha/a.out.h linux-2.4.22/include/asm-alpha/a.out.h
13746--- linux-2.4.22.org/include/asm-alpha/a.out.h 2003-11-22 22:09:24.000000000 +0100
13747+++ linux-2.4.22/include/asm-alpha/a.out.h 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13748@@ -98,7 +98,7 @@
13749 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
13750 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
13751
13752-#define STACK_TOP \
13753+#define __STACK_TOP \
13754 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
13755
13756 #endif
474a6d91
AM
13757diff -urN linux-2.4.22.org/include/asm-alpha/elf.h linux-2.4.22/include/asm-alpha/elf.h
13758--- linux-2.4.22.org/include/asm-alpha/elf.h 2003-11-22 22:09:24.000000000 +0100
13759+++ linux-2.4.22/include/asm-alpha/elf.h 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13760@@ -41,6 +41,18 @@
13761
13762 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
13763
13764+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
13765+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
13766+
13767+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
13768+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
13769+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
13770+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
13771+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
13772+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
13773+#endif
13774+
13775+
13776 /* $0 is set by ld.so to a pointer to a function which might be
13777 registered using atexit. This provides a mean for the dynamic
13778 linker to call DT_FINI functions for shared libraries that have
474a6d91
AM
13779diff -urN linux-2.4.22.org/include/asm-alpha/mman.h linux-2.4.22/include/asm-alpha/mman.h
13780--- linux-2.4.22.org/include/asm-alpha/mman.h 2003-11-22 22:09:24.000000000 +0100
13781+++ linux-2.4.22/include/asm-alpha/mman.h 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13782@@ -24,6 +24,10 @@
13783 #define MAP_LOCKED 0x8000 /* lock the mapping */
13784 #define MAP_NORESERVE 0x10000 /* don't check for reservations */
13785
13786+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
13787+#define MAP_MIRROR 0x20000
13788+#endif
13789+
13790 #define MS_ASYNC 1 /* sync memory asynchronously */
13791 #define MS_SYNC 2 /* synchronous memory sync */
13792 #define MS_INVALIDATE 4 /* invalidate the caches */
474a6d91
AM
13793diff -urN linux-2.4.22.org/include/asm-alpha/pgtable.h linux-2.4.22/include/asm-alpha/pgtable.h
13794--- linux-2.4.22.org/include/asm-alpha/pgtable.h 2003-11-22 22:09:24.000000000 +0100
13795+++ linux-2.4.22/include/asm-alpha/pgtable.h 2003-11-22 22:14:08.000000000 +0100
8be839c4
JR
13796@@ -96,6 +96,17 @@
13797 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
13798 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
13799 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
13800+
13801+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
13802+#define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
13803+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
13804+#define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
13805+#else
13806+#define PAGE_SHARED_NOEXEC PAGE_SHARED
13807+#define PAGE_COPY_NOEXEC PAGE_COPY
13808+#define PAGE_READONLY_NOEXEC PAGE_READONLY
13809+#endif
13810+
13811 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
13812
13813 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
474a6d91
AM
13814diff -urN linux-2.4.22.org/include/asm-i386/a.out.h linux-2.4.22/include/asm-i386/a.out.h
13815--- linux-2.4.22.org/include/asm-i386/a.out.h 2003-11-22 22:09:22.000000000 +0100
13816+++ linux-2.4.22/include/asm-i386/a.out.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13817@@ -19,7 +19,11 @@
13818
13819 #ifdef __KERNEL__
13820
13821-#define STACK_TOP TASK_SIZE
13822+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
13823+#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
13824+#else
13825+#define __STACK_TOP TASK_SIZE
13826+#endif
13827
13828 #endif
13829
474a6d91
AM
13830diff -urN linux-2.4.22.org/include/asm-i386/desc.h linux-2.4.22/include/asm-i386/desc.h
13831--- linux-2.4.22.org/include/asm-i386/desc.h 2003-11-22 22:09:22.000000000 +0100
13832+++ linux-2.4.22/include/asm-i386/desc.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13833@@ -46,7 +46,8 @@
13834 };
13835
13836 extern struct desc_struct gdt_table[];
13837-extern struct desc_struct *idt, *gdt;
13838+extern struct desc_struct gdt_table2[];
13839+extern struct desc_struct *idt, *gdt, *gdt2;
13840
13841 struct Xgt_desc_struct {
13842 unsigned short size;
13843@@ -55,6 +56,7 @@
13844
13845 #define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
13846 #define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
13847+#define gdt_descr2 (*(struct Xgt_desc_struct *)((char *)&gdt2 - 2))
13848
13849 #define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3))
13850
13851@@ -67,6 +69,7 @@
13852 extern struct desc_struct default_ldt[];
13853 extern void set_intr_gate(unsigned int irq, void * addr);
13854 extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
13855+extern void __set_ldt_desc(unsigned int n, void *addr, unsigned int size);
13856 extern void set_tss_desc(unsigned int n, void *addr);
13857
13858 static inline void clear_LDT(void)
13859@@ -94,6 +97,21 @@
13860 __load_LDT(cpu);
13861 }
13862
13863+static inline void _load_LDT (struct mm_struct *mm)
13864+{
13865+ int cpu = smp_processor_id();
13866+ void *segments = mm->context.segments;
13867+ int count = LDT_ENTRIES;
13868+
13869+ if (!segments) {
13870+ segments = &default_ldt[0];
13871+ count = 5;
13872+ }
13873+
13874+ __set_ldt_desc(cpu, segments, count);
13875+ __load_LDT(cpu);
13876+}
13877+
13878 #endif /* !__ASSEMBLY__ */
13879
13880 #endif
474a6d91
AM
13881diff -urN linux-2.4.22.org/include/asm-i386/elf.h linux-2.4.22/include/asm-i386/elf.h
13882--- linux-2.4.22.org/include/asm-i386/elf.h 2003-11-22 22:09:22.000000000 +0100
13883+++ linux-2.4.22/include/asm-i386/elf.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13884@@ -55,7 +55,22 @@
13885 the loader. We need to make sure that it is out of the way of the program
13886 that it will "exec", and that there is sufficient room for the brk. */
13887
13888+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
13889+#define ELF_ET_DYN_BASE ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2)
13890+#else
13891 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
13892+#endif
13893+
13894+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
13895+#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL
13896+
13897+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
13898+#define PAX_DELTA_MMAP_LEN(tsk) 16
13899+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
13900+#define PAX_DELTA_EXEC_LEN(tsk) 16
13901+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
13902+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
13903+#endif
13904
13905 /* Wow, the "main" arch needs arch dependent functions too.. :) */
13906
474a6d91
AM
13907diff -urN linux-2.4.22.org/include/asm-i386/hw_irq.h linux-2.4.22/include/asm-i386/hw_irq.h
13908--- linux-2.4.22.org/include/asm-i386/hw_irq.h 2003-11-22 22:09:21.000000000 +0100
13909+++ linux-2.4.22/include/asm-i386/hw_irq.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13910@@ -128,6 +128,7 @@
13911 asmlinkage void x(void); \
13912 asmlinkage void call_##x(void); \
13913 __asm__( \
13914+"\n .text" \
13915 "\n"__ALIGN_STR"\n" \
13916 SYMBOL_NAME_STR(x) ":\n\t" \
13917 "pushl $"#v"-256\n\t" \
13918@@ -141,6 +142,7 @@
13919 asmlinkage void x(struct pt_regs * regs); \
13920 asmlinkage void call_##x(void); \
13921 __asm__( \
13922+"\n .text" \
13923 "\n"__ALIGN_STR"\n" \
13924 SYMBOL_NAME_STR(x) ":\n\t" \
13925 "pushl $"#v"-256\n\t" \
13926@@ -155,6 +157,7 @@
13927 #define BUILD_COMMON_IRQ() \
13928 asmlinkage void call_do_IRQ(void); \
13929 __asm__( \
13930+ "\n .text" \
13931 "\n" __ALIGN_STR"\n" \
13932 "common_interrupt:\n\t" \
13933 SAVE_ALL \
13934@@ -175,6 +178,7 @@
13935 #define BUILD_IRQ(nr) \
13936 asmlinkage void IRQ_NAME(nr); \
13937 __asm__( \
13938+"\n .text" \
13939 "\n"__ALIGN_STR"\n" \
13940 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
13941 "pushl $"#nr"-256\n\t" \
474a6d91
AM
13942diff -urN linux-2.4.22.org/include/asm-i386/mman.h linux-2.4.22/include/asm-i386/mman.h
13943--- linux-2.4.22.org/include/asm-i386/mman.h 2003-11-22 22:09:22.000000000 +0100
13944+++ linux-2.4.22/include/asm-i386/mman.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13945@@ -18,6 +18,10 @@
13946 #define MAP_LOCKED 0x2000 /* pages are locked */
13947 #define MAP_NORESERVE 0x4000 /* don't check for reservations */
13948
13949+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
13950+#define MAP_MIRROR 0x8000
13951+#endif
13952+
13953 #define MS_ASYNC 1 /* sync memory asynchronously */
13954 #define MS_INVALIDATE 2 /* invalidate the caches */
13955 #define MS_SYNC 4 /* synchronous memory sync */
474a6d91
AM
13956diff -urN linux-2.4.22.org/include/asm-i386/page.h linux-2.4.22/include/asm-i386/page.h
13957--- linux-2.4.22.org/include/asm-i386/page.h 2003-11-22 22:09:21.000000000 +0100
13958+++ linux-2.4.22/include/asm-i386/page.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13959@@ -78,7 +78,7 @@
13960 * and CONFIG_HIGHMEM64G options in the kernel configuration.
13961 */
13962
13963-#define __PAGE_OFFSET (0xC0000000)
13964+#include <asm/page_offset.h>
13965
13966 /*
13967 * This much address space is reserved for vmalloc() and iomap()
474a6d91
AM
13968diff -urN linux-2.4.22.org/include/asm-i386/page_offset.h linux-2.4.22/include/asm-i386/page_offset.h
13969--- linux-2.4.22.org/include/asm-i386/page_offset.h 1970-01-01 01:00:00.000000000 +0100
13970+++ linux-2.4.22/include/asm-i386/page_offset.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13971@@ -0,0 +1,2 @@
13972+#define __KERNEL_TEXT_OFFSET (0xC0400000)
13973+#define __PAGE_OFFSET (0xC0000000)
474a6d91
AM
13974diff -urN linux-2.4.22.org/include/asm-i386/pgtable.h linux-2.4.22/include/asm-i386/pgtable.h
13975--- linux-2.4.22.org/include/asm-i386/pgtable.h 2003-11-22 22:09:21.000000000 +0100
13976+++ linux-2.4.22/include/asm-i386/pgtable.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
13977@@ -205,6 +205,16 @@
13978 #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
13979 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
13980
13981+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
13982+#define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
13983+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
13984+#define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
13985+#else
13986+#define PAGE_SHARED_NOEXEC PAGE_SHARED
13987+#define PAGE_COPY_NOEXEC PAGE_COPY
13988+#define PAGE_READONLY_NOEXEC PAGE_READONLY
13989+#endif
13990+
13991 #define __PAGE_KERNEL \
13992 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
13993 #define __PAGE_KERNEL_NOCACHE \
13994@@ -237,18 +247,18 @@
13995 * This is the closest we can get..
13996 */
13997 #define __P000 PAGE_NONE
13998-#define __P001 PAGE_READONLY
13999-#define __P010 PAGE_COPY
14000-#define __P011 PAGE_COPY
14001+#define __P001 PAGE_READONLY_NOEXEC
14002+#define __P010 PAGE_COPY_NOEXEC
14003+#define __P011 PAGE_COPY_NOEXEC
14004 #define __P100 PAGE_READONLY
14005 #define __P101 PAGE_READONLY
14006 #define __P110 PAGE_COPY
14007 #define __P111 PAGE_COPY
14008
14009 #define __S000 PAGE_NONE
14010-#define __S001 PAGE_READONLY
14011-#define __S010 PAGE_SHARED
14012-#define __S011 PAGE_SHARED
14013+#define __S001 PAGE_READONLY_NOEXEC
14014+#define __S010 PAGE_SHARED_NOEXEC
14015+#define __S011 PAGE_SHARED_NOEXEC
14016 #define __S100 PAGE_READONLY
14017 #define __S101 PAGE_READONLY
14018 #define __S110 PAGE_SHARED
14019@@ -324,7 +334,7 @@
14020 ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
14021
14022 /* to find an entry in a page-table-directory. */
14023-#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14024+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
14025
14026 #define __pgd_offset(address) pgd_index(address)
14027
474a6d91
AM
14028diff -urN linux-2.4.22.org/include/asm-i386/processor.h linux-2.4.22/include/asm-i386/processor.h
14029--- linux-2.4.22.org/include/asm-i386/processor.h 2003-11-22 22:09:22.000000000 +0100
14030+++ linux-2.4.22/include/asm-i386/processor.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14031@@ -261,10 +261,19 @@
14032 */
14033 #define TASK_SIZE (PAGE_OFFSET)
14034
14035+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14036+#define SEGMEXEC_TASK_SIZE ((PAGE_OFFSET) / 2)
14037+#endif
14038+
14039 /* This decides where the kernel will search for a free chunk of vm
14040 * space during mmap's.
14041 */
14042+
14043+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
14044+#define TASK_UNMAPPED_BASE ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3)
14045+#else
14046 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
14047+#endif
14048
14049 /*
14050 * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
474a6d91
AM
14051diff -urN linux-2.4.22.org/include/asm-i386/system.h linux-2.4.22/include/asm-i386/system.h
14052--- linux-2.4.22.org/include/asm-i386/system.h 2003-11-22 22:09:22.000000000 +0100
14053+++ linux-2.4.22/include/asm-i386/system.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14054@@ -12,6 +12,8 @@
14055 struct task_struct; /* one of the stranger aspects of C forward declarations.. */
14056 extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
14057
14058+void pax_switch_segments(struct task_struct *);
14059+
14060 #define switch_to(prev,next,last) do { \
14061 asm volatile("pushl %%esi\n\t" \
14062 "pushl %%edi\n\t" \
474a6d91
AM
14063diff -urN linux-2.4.22.org/include/asm-parisc/a.out.h linux-2.4.22/include/asm-parisc/a.out.h
14064--- linux-2.4.22.org/include/asm-parisc/a.out.h 2003-11-22 22:09:51.000000000 +0100
14065+++ linux-2.4.22/include/asm-parisc/a.out.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14066@@ -22,7 +22,7 @@
14067 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
14068 * prumpf */
14069
14070-#define STACK_TOP TASK_SIZE
14071+#define __STACK_TOP TASK_SIZE
14072
14073 #endif
14074
474a6d91
AM
14075diff -urN linux-2.4.22.org/include/asm-parisc/elf.h linux-2.4.22/include/asm-parisc/elf.h
14076--- linux-2.4.22.org/include/asm-parisc/elf.h 2003-11-22 22:09:51.000000000 +0100
14077+++ linux-2.4.22/include/asm-parisc/elf.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14078@@ -135,6 +135,17 @@
14079
14080 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
14081
14082+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14083+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
14084+
14085+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
14086+#define PAX_DELTA_MMAP_LEN(tsk) 16
14087+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
14088+#define PAX_DELTA_EXEC_LEN(tsk) 16
14089+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
14090+#define PAX_DELTA_STACK_LEN(tsk) 16
14091+#endif
14092+
14093 /* This yields a mask that user programs can use to figure out what
14094 instruction set this CPU supports. This could be done in user space,
14095 but it's not easy, and we've already done it here. */
474a6d91
AM
14096diff -urN linux-2.4.22.org/include/asm-parisc/mman.h linux-2.4.22/include/asm-parisc/mman.h
14097--- linux-2.4.22.org/include/asm-parisc/mman.h 2003-11-22 22:09:51.000000000 +0100
14098+++ linux-2.4.22/include/asm-parisc/mman.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14099@@ -18,6 +18,10 @@
14100 #define MAP_NORESERVE 0x4000 /* don't check for reservations */
14101 #define MAP_GROWSDOWN 0x8000 /* stack-like segment */
14102
14103+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14104+#define MAP_MIRROR 0x0400
14105+#endif
14106+
14107 #define MS_SYNC 1 /* synchronous memory sync */
14108 #define MS_ASYNC 2 /* sync memory asynchronously */
14109 #define MS_INVALIDATE 4 /* invalidate the caches */
474a6d91
AM
14110diff -urN linux-2.4.22.org/include/asm-parisc/pgtable.h linux-2.4.22/include/asm-parisc/pgtable.h
14111--- linux-2.4.22.org/include/asm-parisc/pgtable.h 2003-11-22 22:09:50.000000000 +0100
14112+++ linux-2.4.22/include/asm-parisc/pgtable.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14113@@ -167,6 +167,17 @@
14114 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
14115 #define PAGE_COPY PAGE_EXECREAD
14116 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
14117+
14118+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14119+#define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
14120+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14121+#define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
14122+#else
14123+#define PAGE_SHARED_NOEXEC PAGE_SHARED
14124+#define PAGE_COPY_NOEXEC PAGE_COPY
14125+#define PAGE_READONLY_NOEXEC PAGE_READONLY
14126+#endif
14127+
14128 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
14129 #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
14130 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
474a6d91
AM
14131diff -urN linux-2.4.22.org/include/asm-ppc/a.out.h linux-2.4.22/include/asm-ppc/a.out.h
14132--- linux-2.4.22.org/include/asm-ppc/a.out.h 2003-11-22 22:09:28.000000000 +0100
14133+++ linux-2.4.22/include/asm-ppc/a.out.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14134@@ -2,7 +2,7 @@
14135 #define __PPC_A_OUT_H__
14136
14137 /* grabbed from the intel stuff */
14138-#define STACK_TOP TASK_SIZE
14139+#define __STACK_TOP TASK_SIZE
14140
14141
14142 struct exec
474a6d91
AM
14143diff -urN linux-2.4.22.org/include/asm-ppc/elf.h linux-2.4.22/include/asm-ppc/elf.h
14144--- linux-2.4.22.org/include/asm-ppc/elf.h 2003-11-22 22:09:28.000000000 +0100
14145+++ linux-2.4.22/include/asm-ppc/elf.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14146@@ -46,6 +46,17 @@
14147
14148 #define ELF_ET_DYN_BASE (0x08000000)
14149
14150+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14151+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000000UL
14152+
14153+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
14154+#define PAX_DELTA_MMAP_LEN(tsk) 15
14155+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
14156+#define PAX_DELTA_EXEC_LEN(tsk) 15
14157+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
14158+#define PAX_DELTA_STACK_LEN(tsk) 15
14159+#endif
14160+
14161 #define USE_ELF_CORE_DUMP
14162 #define ELF_EXEC_PAGESIZE 4096
14163
474a6d91
AM
14164diff -urN linux-2.4.22.org/include/asm-ppc/mman.h linux-2.4.22/include/asm-ppc/mman.h
14165--- linux-2.4.22.org/include/asm-ppc/mman.h 2003-11-22 22:09:28.000000000 +0100
14166+++ linux-2.4.22/include/asm-ppc/mman.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14167@@ -19,6 +19,10 @@
14168 #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
14169 #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
14170
14171+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14172+#define MAP_MIRROR 0x0200
14173+#endif
14174+
14175 #define MS_ASYNC 1 /* sync memory asynchronously */
14176 #define MS_INVALIDATE 2 /* invalidate the caches */
14177 #define MS_SYNC 4 /* synchronous memory sync */
474a6d91
AM
14178diff -urN linux-2.4.22.org/include/asm-ppc/pgtable.h linux-2.4.22/include/asm-ppc/pgtable.h
14179--- linux-2.4.22.org/include/asm-ppc/pgtable.h 2003-11-22 22:09:28.000000000 +0100
14180+++ linux-2.4.22/include/asm-ppc/pgtable.h 2003-11-22 22:14:09.000000000 +0100
14181@@ -386,6 +386,16 @@
8be839c4
JR
14182 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
14183 #define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
14184
14185+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14186+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
14187+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14188+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
14189+#else
14190+# define PAGE_SHARED_NOEXEC PAGE_SHARED
14191+# define PAGE_COPY_NOEXEC PAGE_COPY
14192+# define PAGE_READONLY_NOEXEC PAGE_READONLY
14193+#endif
14194+
14195 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
14196 #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_SHARED)
14197 #define PAGE_KERNEL_CI __pgprot(_PAGE_IO)
474a6d91 14198@@ -397,21 +407,21 @@
8be839c4
JR
14199 * This is the closest we can get..
14200 */
14201 #define __P000 PAGE_NONE
14202-#define __P001 PAGE_READONLY_X
14203-#define __P010 PAGE_COPY
14204-#define __P011 PAGE_COPY_X
14205-#define __P100 PAGE_READONLY
14206+#define __P001 PAGE_READONLY_NOEXEC
14207+#define __P010 PAGE_COPY_NOEXEC
14208+#define __P011 PAGE_COPY_NOEXEC
14209+#define __P100 PAGE_READONLY_X
14210 #define __P101 PAGE_READONLY_X
14211-#define __P110 PAGE_COPY
14212+#define __P110 PAGE_COPY_X
14213 #define __P111 PAGE_COPY_X
14214
14215 #define __S000 PAGE_NONE
14216-#define __S001 PAGE_READONLY_X
14217-#define __S010 PAGE_SHARED
14218-#define __S011 PAGE_SHARED_X
14219-#define __S100 PAGE_READONLY
14220+#define __S001 PAGE_READONLY_NOEXEC
14221+#define __S010 PAGE_SHARED_NOEXEC
14222+#define __S011 PAGE_SHARED_NOEXEC
14223+#define __S100 PAGE_READONLY_X
14224 #define __S101 PAGE_READONLY_X
14225-#define __S110 PAGE_SHARED
14226+#define __S110 PAGE_SHARED_X
14227 #define __S111 PAGE_SHARED_X
14228
14229 #ifndef __ASSEMBLY__
474a6d91
AM
14230diff -urN linux-2.4.22.org/include/asm-sparc/a.out.h linux-2.4.22/include/asm-sparc/a.out.h
14231--- linux-2.4.22.org/include/asm-sparc/a.out.h 2003-11-22 22:09:26.000000000 +0100
14232+++ linux-2.4.22/include/asm-sparc/a.out.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14233@@ -91,7 +91,7 @@
14234
14235 #include <asm/page.h>
14236
14237-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
14238+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
14239
14240 #endif /* __KERNEL__ */
14241
474a6d91
AM
14242diff -urN linux-2.4.22.org/include/asm-sparc/elf.h linux-2.4.22/include/asm-sparc/elf.h
14243--- linux-2.4.22.org/include/asm-sparc/elf.h 2003-11-22 22:09:26.000000000 +0100
14244+++ linux-2.4.22/include/asm-sparc/elf.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14245@@ -83,6 +83,18 @@
14246
14247 #define ELF_ET_DYN_BASE (0x08000000)
14248
14249+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14250+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
14251+
14252+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
14253+#define PAX_DELTA_MMAP_LEN(tsk) 16
14254+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
14255+#define PAX_DELTA_EXEC_LEN(tsk) 16
14256+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
14257+#define PAX_DELTA_STACK_LEN(tsk) 16
14258+#endif
14259+
14260+
14261 /* This yields a mask that user programs can use to figure out what
14262 instruction set this cpu supports. This can NOT be done in userspace
14263 on Sparc. */
474a6d91
AM
14264diff -urN linux-2.4.22.org/include/asm-sparc/mman.h linux-2.4.22/include/asm-sparc/mman.h
14265--- linux-2.4.22.org/include/asm-sparc/mman.h 2003-11-22 22:09:26.000000000 +0100
14266+++ linux-2.4.22/include/asm-sparc/mman.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14267@@ -24,6 +24,10 @@
14268 #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
14269 #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
14270
14271+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14272+#define MAP_MIRROR 0x0400
14273+#endif
14274+
14275 #define MS_ASYNC 1 /* sync memory asynchronously */
14276 #define MS_INVALIDATE 2 /* invalidate the caches */
14277 #define MS_SYNC 4 /* synchronous memory sync */
474a6d91
AM
14278diff -urN linux-2.4.22.org/include/asm-sparc/pgtable.h linux-2.4.22/include/asm-sparc/pgtable.h
14279--- linux-2.4.22.org/include/asm-sparc/pgtable.h 2003-11-22 22:09:26.000000000 +0100
14280+++ linux-2.4.22/include/asm-sparc/pgtable.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14281@@ -97,6 +97,13 @@
14282 BTFIXUPDEF_INT(page_shared)
14283 BTFIXUPDEF_INT(page_copy)
14284 BTFIXUPDEF_INT(page_readonly)
14285+
14286+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14287+BTFIXUPDEF_INT(page_shared_noexec)
14288+BTFIXUPDEF_INT(page_copy_noexec)
14289+BTFIXUPDEF_INT(page_readonly_noexec)
14290+#endif
14291+
14292 BTFIXUPDEF_INT(page_kernel)
14293
14294 #define PMD_SHIFT BTFIXUP_SIMM13(pmd_shift)
14295@@ -118,6 +125,16 @@
14296 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
14297 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
14298
14299+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14300+#define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec))
14301+#define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
14302+#define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
14303+#else
14304+#define PAGE_SHARED_NOEXEC PAGE_SHARED
14305+#define PAGE_COPY_NOEXEC PAGE_COPY
14306+#define PAGE_READONLY_NOEXEC PAGE_READONLY
14307+#endif
14308+
14309 extern unsigned long page_kernel;
14310
14311 #ifdef MODULE
474a6d91
AM
14312diff -urN linux-2.4.22.org/include/asm-sparc/pgtsrmmu.h linux-2.4.22/include/asm-sparc/pgtsrmmu.h
14313--- linux-2.4.22.org/include/asm-sparc/pgtsrmmu.h 2003-11-22 22:09:26.000000000 +0100
14314+++ linux-2.4.22/include/asm-sparc/pgtsrmmu.h 2003-11-22 22:14:09.000000000 +0100
14315@@ -76,6 +76,15 @@
8be839c4
JR
14316 SRMMU_EXEC | SRMMU_REF)
14317 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14318 SRMMU_EXEC | SRMMU_REF)
14319+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14320+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14321+ SRMMU_WRITE | SRMMU_REF)
14322+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14323+ SRMMU_REF)
14324+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
14325+ SRMMU_REF)
14326+#endif
14327+
14328 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
14329 SRMMU_DIRTY | SRMMU_REF)
14330
474a6d91
AM
14331diff -urN linux-2.4.22.org/include/asm-sparc/uaccess.h linux-2.4.22/include/asm-sparc/uaccess.h
14332--- linux-2.4.22.org/include/asm-sparc/uaccess.h 2003-11-22 22:09:26.000000000 +0100
14333+++ linux-2.4.22/include/asm-sparc/uaccess.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14334@@ -39,7 +39,7 @@
14335 * No one can read/write anything from userland in the kernel space by setting
14336 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
14337 */
14338-#define __user_ok(addr,size) ((addr) < STACK_TOP)
14339+#define __user_ok(addr,size) ((addr) < __STACK_TOP)
14340 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
14341 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
14342 #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
474a6d91
AM
14343diff -urN linux-2.4.22.org/include/asm-sparc64/a.out.h linux-2.4.22/include/asm-sparc64/a.out.h
14344--- linux-2.4.22.org/include/asm-sparc64/a.out.h 2003-11-22 22:09:29.000000000 +0100
14345+++ linux-2.4.22/include/asm-sparc64/a.out.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14346@@ -95,7 +95,7 @@
14347
14348 #ifdef __KERNEL__
14349
14350-#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14351+#define __STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
14352
14353 #endif
14354
474a6d91
AM
14355diff -urN linux-2.4.22.org/include/asm-sparc64/elf.h linux-2.4.22/include/asm-sparc64/elf.h
14356--- linux-2.4.22.org/include/asm-sparc64/elf.h 2003-11-22 22:09:28.000000000 +0100
14357+++ linux-2.4.22/include/asm-sparc64/elf.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14358@@ -82,6 +82,17 @@
14359 #define ELF_ET_DYN_BASE 0x0000010000000000UL
14360 #endif
14361
14362+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
14363+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 0x10000UL : 0x100000UL)
14364+
14365+#define PAX_DELTA_MMAP_LSB(tsk) (PAGE_SHIFT + 1)
14366+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14367+#define PAX_DELTA_EXEC_LSB(tsk) (PAGE_SHIFT + 1)
14368+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
14369+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
14370+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 15 : 29 )
14371+#endif
14372+
14373
14374 /* This yields a mask that user programs can use to figure out what
14375 instruction set this cpu supports. */
474a6d91
AM
14376diff -urN linux-2.4.22.org/include/asm-sparc64/mman.h linux-2.4.22/include/asm-sparc64/mman.h
14377--- linux-2.4.22.org/include/asm-sparc64/mman.h 2003-11-22 22:09:28.000000000 +0100
14378+++ linux-2.4.22/include/asm-sparc64/mman.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14379@@ -24,6 +24,10 @@
14380 #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
14381 #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
14382
14383+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
14384+#define MAP_MIRROR 0x0400
14385+#endif
14386+
14387 #define MS_ASYNC 1 /* sync memory asynchronously */
14388 #define MS_INVALIDATE 2 /* invalidate the caches */
14389 #define MS_SYNC 4 /* synchronous memory sync */
474a6d91
AM
14390diff -urN linux-2.4.22.org/include/asm-sparc64/pgtable.h linux-2.4.22/include/asm-sparc64/pgtable.h
14391--- linux-2.4.22.org/include/asm-sparc64/pgtable.h 2003-11-22 22:09:28.000000000 +0100
14392+++ linux-2.4.22/include/asm-sparc64/pgtable.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14393@@ -122,7 +122,8 @@
14394 #define _PAGE_G 0x0000000000000001 /* Global */
14395
14396 /* Here are the SpitFire software bits we use in the TTE's. */
14397-#define _PAGE_MODIFIED 0x0000000000000800 /* Modified Page (ie. dirty) */
14398+#define _PAGE_MODIFIED 0x0000000000001000 /* Modified Page (ie. dirty) */
14399+#define _PAGE_EXEC 0x0000000000000800 /* Executable SW bit */
14400 #define _PAGE_ACCESSED 0x0000000000000400 /* Accessed Page (ie. referenced) */
14401 #define _PAGE_READ 0x0000000000000200 /* Readable SW Bit */
14402 #define _PAGE_WRITE 0x0000000000000100 /* Writable SW Bit */
14403@@ -150,16 +151,30 @@
14404
14405 /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
14406 #define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14407- __ACCESS_BITS | _PAGE_WRITE)
14408+ __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
14409
14410 #define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14411- __ACCESS_BITS)
14412+ __ACCESS_BITS | _PAGE_EXEC)
14413
14414 #define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14415- __ACCESS_BITS)
14416+ __ACCESS_BITS | _PAGE_EXEC)
14417
14418 #define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14419- __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
14420+ __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \
14421+ _PAGE_EXEC)
14422+
14423+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
14424+#define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14425+ __ACCESS_BITS | _PAGE_WRITE)
14426+#define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14427+ __ACCESS_BITS)
14428+#define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
14429+ __ACCESS_BITS)
14430+#else
14431+#define PAGE_SHARED_NOEXEC PAGE_SHARED
14432+#define PAGE_COPY_NOEXEC PAGE_COPY
14433+#define PAGE_READONLY_NOEXEC PAGE_READONLY
14434+#endif
14435
14436 #define PAGE_INVALID __pgprot (0)
14437
14438@@ -170,18 +185,18 @@
14439 #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
14440
14441 #define __P000 PAGE_NONE
14442-#define __P001 PAGE_READONLY
14443-#define __P010 PAGE_COPY
14444-#define __P011 PAGE_COPY
14445+#define __P001 PAGE_READONLY_NOEXEC
14446+#define __P010 PAGE_COPY_NOEXEC
14447+#define __P011 PAGE_COPY_NOEXEC
14448 #define __P100 PAGE_READONLY
14449 #define __P101 PAGE_READONLY
14450 #define __P110 PAGE_COPY
14451 #define __P111 PAGE_COPY
14452
14453 #define __S000 PAGE_NONE
14454-#define __S001 PAGE_READONLY
14455-#define __S010 PAGE_SHARED
14456-#define __S011 PAGE_SHARED
14457+#define __S001 PAGE_READONLY_NOEXEC
14458+#define __S010 PAGE_SHARED_NOEXEC
14459+#define __S011 PAGE_SHARED_NOEXEC
14460 #define __S100 PAGE_READONLY
14461 #define __S101 PAGE_READONLY
14462 #define __S110 PAGE_SHARED
474a6d91
AM
14463diff -urN linux-2.4.22.org/include/linux/a.out.h linux-2.4.22/include/linux/a.out.h
14464--- linux-2.4.22.org/include/linux/a.out.h 2003-11-22 22:09:16.000000000 +0100
14465+++ linux-2.4.22/include/linux/a.out.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14466@@ -7,6 +7,16 @@
14467
14468 #include <asm/a.out.h>
14469
14470+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
14471+#define __DELTA_STACK (current->mm->delta_stack)
14472+#else
14473+#define __DELTA_STACK 0UL
14474+#endif
14475+
14476+#ifndef STACK_TOP
14477+#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
14478+#endif
14479+
14480 #endif /* __STRUCT_EXEC_OVERRIDE__ */
14481
14482 /* these go in the N_MACHTYPE field */
14483@@ -37,6 +47,14 @@
14484 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
14485 };
14486
14487+/* Constants for the N_FLAGS field */
14488+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
14489+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
14490+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
14491+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
14492+#define F_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */
14493+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
14494+
14495 #if !defined (N_MAGIC)
14496 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
14497 #endif
474a6d91
AM
14498diff -urN linux-2.4.22.org/include/linux/binfmts.h linux-2.4.22/include/linux/binfmts.h
14499--- linux-2.4.22.org/include/linux/binfmts.h 2003-11-22 22:09:16.000000000 +0100
14500+++ linux-2.4.22/include/linux/binfmts.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14501@@ -61,6 +61,8 @@
14502 extern int do_coredump(long signr, struct pt_regs * regs);
14503 extern void set_binfmt(struct linux_binfmt *new);
14504
14505+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
14506+void pax_report_insns(void *pc);
14507
14508 #if 0
14509 /* this went away now */
474a6d91
AM
14510diff -urN linux-2.4.22.org/include/linux/elf.h linux-2.4.22/include/linux/elf.h
14511--- linux-2.4.22.org/include/linux/elf.h 2003-11-22 22:09:15.000000000 +0100
14512+++ linux-2.4.22/include/linux/elf.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14513@@ -117,6 +117,8 @@
14514 #define DT_DEBUG 21
14515 #define DT_TEXTREL 22
14516 #define DT_JMPREL 23
14517+#define DT_FLAGS 30
14518+#define DF_TEXTREL 0x00000004
14519 #define DT_LOPROC 0x70000000
14520 #define DT_HIPROC 0x7fffffff
14521 #define DT_MIPS_RLD_VERSION 0x70000001
14522@@ -255,6 +257,13 @@
14523 #define R_MIPS_LOVENDOR 100
14524 #define R_MIPS_HIVENDOR 127
14525
14526+/* Constants for the e_flags field */
14527+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
14528+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
14529+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
14530+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
14531+#define EF_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */
14532+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
14533
14534 /*
14535 * Sparc ELF relocation types
14536@@ -550,6 +559,8 @@
14537 #define EI_VERSION 6
14538 #define EI_PAD 7
14539
14540+#define EI_PAX 14
14541+
14542 #define ELFMAG0 0x7f /* EI_MAG */
14543 #define ELFMAG1 'E'
14544 #define ELFMAG2 'L'
14545@@ -597,6 +608,7 @@
14546 #define elfhdr elf32_hdr
14547 #define elf_phdr elf32_phdr
14548 #define elf_note elf32_note
14549+#define elf_dyn Elf32_Dyn
14550
14551 #else
14552
14553@@ -604,6 +616,7 @@
14554 #define elfhdr elf64_hdr
14555 #define elf_phdr elf64_phdr
14556 #define elf_note elf64_note
14557+#define elf_dyn Elf64_Dyn
14558
14559 #endif
14560
474a6d91
AM
14561diff -urN linux-2.4.22.org/include/linux/fs.h linux-2.4.22/include/linux/fs.h
14562--- linux-2.4.22.org/include/linux/fs.h 2003-11-22 22:09:12.000000000 +0100
14563+++ linux-2.4.22/include/linux/fs.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14564@@ -1167,7 +1167,7 @@
14565
14566 asmlinkage long sys_open(const char *, int, int);
14567 asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */
14568-extern int do_truncate(struct dentry *, loff_t start);
14569+extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
14570
14571 extern struct file *filp_open(const char *, int, int);
14572 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
474a6d91
AM
14573diff -urN linux-2.4.22.org/include/linux/gracl.h linux-2.4.22/include/linux/gracl.h
14574--- linux-2.4.22.org/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100
14575+++ linux-2.4.22/include/linux/gracl.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14576@@ -0,0 +1,212 @@
14577+#ifndef GR_ACL_H
14578+#define GR_ACL_H
14579+#endif
14580+#include <linux/grdefs.h>
14581+#include <linux/resource.h>
14582+
14583+#include <asm/resource.h>
14584+
14585+/* * * * * * * * * * * * * * * * * * * * *
14586+ * grsecurity ACL System
14587+ * Main header file
14588+ * Purpose: define most gracl data structures
14589+ * * * * * * * * * * * * * * * * * * * * */
14590+
14591+/* Major status information */
14592+
14593+#define GR_VERSION "grsecurity 2.0"
14594+
14595+enum {
14596+
14597+ SHUTDOWN = 0,
14598+ ENABLE = 1,
14599+ SPROLE = 2,
14600+ RELOAD = 3,
14601+ SEGVMOD = 4,
14602+ STATUS = 5,
14603+ UNSPROLE = 6
14604+};
14605+
14606+/* Password setup definitions
14607+ * kernel/grhash.c */
14608+enum {
14609+ GR_PW_LEN = 128,
14610+ GR_SALT_LEN = 16,
14611+ GR_SHA_LEN = 32,
14612+};
14613+
14614+enum {
14615+ GR_SPROLE_LEN = 64,
14616+};
14617+
14618+/* Begin Data Structures */
14619+
14620+struct sprole_pw {
14621+ unsigned char *rolename;
14622+ unsigned char salt[GR_SALT_LEN];
14623+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
14624+};
14625+
14626+struct name_entry {
14627+ ino_t inode;
14628+ kdev_t device;
14629+ char *name;
14630+ __u16 len;
14631+};
14632+
14633+struct acl_role_db {
14634+ struct acl_role_label **r_hash;
14635+ __u32 r_size;
14636+};
14637+
14638+struct name_db {
14639+ struct name_entry **n_hash;
14640+ __u32 n_size;
14641+};
14642+
14643+struct crash_uid {
14644+ uid_t uid;
14645+ unsigned long expires;
14646+};
14647+
14648+/* Userspace Grsecurity ACL data structures */
14649+struct acl_subject_label {
14650+ char *filename;
14651+ ino_t inode;
14652+ kdev_t device;
14653+ __u32 mode;
14654+ __u32 cap_raise;
14655+ __u32 cap_lower;
14656+
14657+ struct rlimit res[RLIM_NLIMITS + 1];
14658+ __u16 resmask;
14659+
14660+ __u32 ip_proto[8];
14661+ __u32 ip_type;
14662+ struct acl_ip_label **ips;
14663+ __u32 ip_num;
14664+
14665+ __u32 crashes;
14666+ unsigned long expires;
14667+
14668+ struct acl_subject_label *parent_subject;
14669+ struct acl_object_label *proc_object;
14670+ struct acl_ip_label *ip_object;
14671+ struct acl_subject_label *prev;
14672+ struct acl_subject_label *next;
14673+
14674+ struct acl_object_label **obj_hash;
14675+ __u32 obj_hash_size;
14676+};
14677+
14678+struct role_allowed_ip {
14679+ __u32 addr;
14680+ __u32 netmask;
14681+
14682+ struct role_allowed_ip *prev;
14683+ struct role_allowed_ip *next;
14684+};
14685+
14686+struct role_transition {
14687+ char *rolename;
14688+
14689+ struct role_transition *prev;
14690+ struct role_transition *next;
14691+};
14692+
14693+struct acl_role_label {
14694+ char *rolename;
14695+ uid_t uidgid;
14696+ __u16 roletype;
14697+
14698+ __u16 auth_attempts;
14699+ unsigned long expires;
14700+
14701+ struct acl_subject_label *root_label;
14702+ struct acl_subject_label *proc_subject;
14703+
14704+ struct acl_role_label *prev;
14705+ struct acl_role_label *next;
14706+
14707+ struct role_transition *transitions;
14708+ struct role_allowed_ip *allowed_ips;
14709+ struct acl_subject_label **subj_hash;
14710+ __u32 subj_hash_size;
14711+};
14712+
14713+struct user_acl_role_db {
14714+ struct acl_role_label **r_table;
14715+ __u32 r_entries; /* number of entries in table */
14716+ __u32 s_entries; /* total number of subject acls */
14717+ __u32 i_entries; /* total number of ip acls */
14718+ __u32 o_entries; /* Total number of object acls */
14719+ __u32 a_entries; /* total number of allowed ips */
14720+ __u32 t_entries; /* total number of transitions */
14721+};
14722+
14723+struct acl_object_label {
14724+ char *filename;
14725+ ino_t inode;
14726+ kdev_t device;
14727+ __u32 mode;
14728+
14729+ struct acl_subject_label *nested;
14730+
14731+ /* next two structures not used */
14732+
14733+ struct acl_object_label *prev;
14734+ struct acl_object_label *next;
14735+};
14736+
14737+struct acl_ip_label {
14738+ __u32 addr;
14739+ __u32 netmask;
14740+ __u16 low, high;
14741+ __u8 mode;
14742+ __u32 type;
14743+ __u32 proto[8];
14744+
14745+ /* next two structures not used */
14746+
14747+ struct acl_ip_label *prev;
14748+ struct acl_ip_label *next;
14749+};
14750+
14751+struct gr_arg {
14752+ struct user_acl_role_db role_db;
14753+ unsigned char pw[GR_PW_LEN];
14754+ unsigned char salt[GR_SALT_LEN];
14755+ unsigned char sum[GR_SHA_LEN];
14756+ unsigned char sp_role[GR_SPROLE_LEN];
14757+ struct sprole_pw *sprole_pws;
14758+ __u16 num_sprole_pws;
14759+ kdev_t segv_device;
14760+ ino_t segv_inode;
14761+ uid_t segv_uid;
14762+ __u16 mode;
14763+};
14764+
14765+/* End Data Structures Section */
14766+
14767+/* Hash functions generated by empirical testing by Brad Spengler
14768+ Makes good use of the low bits of the inode. Generally 0-1 times
14769+ in loop for successful match. 0-3 for unsuccessful match.
14770+ Shift/add algorithm with modulus of table size and an XOR*/
14771+
14772+static __inline__ unsigned long
14773+rhash(const uid_t uid, const __u16 type, const unsigned long sz)
14774+{
14775+ return (((uid << type) + (uid ^ type)) % sz);
14776+}
14777+
14778+static __inline__ unsigned long
14779+fhash(const ino_t ino, const kdev_t dev, const unsigned long sz)
14780+{
14781+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
14782+}
14783+
14784+static __inline__ unsigned long
14785+nhash(const char *name, const __u16 len, const unsigned long sz)
14786+{
14787+ return full_name_hash(name, len) % sz;
14788+}
474a6d91
AM
14789diff -urN linux-2.4.22.org/include/linux/gralloc.h linux-2.4.22/include/linux/gralloc.h
14790--- linux-2.4.22.org/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100
14791+++ linux-2.4.22/include/linux/gralloc.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14792@@ -0,0 +1,8 @@
14793+#ifndef __GRALLOC_H
14794+#define __GRALLOC_H
14795+
14796+void acl_free_all(void);
14797+int acl_alloc_stack_init(unsigned long size);
14798+void *acl_alloc(unsigned long len);
14799+
14800+#endif
474a6d91
AM
14801diff -urN linux-2.4.22.org/include/linux/grdefs.h linux-2.4.22/include/linux/grdefs.h
14802--- linux-2.4.22.org/include/linux/grdefs.h 1970-01-01 01:00:00.000000000 +0100
14803+++ linux-2.4.22/include/linux/grdefs.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14804@@ -0,0 +1,104 @@
14805+#ifndef GRDEFS_H
14806+#define GRDEFS_H
14807+
14808+/* Begin grsecurity status declarations */
14809+
14810+enum {
14811+ GR_READY = 0x01,
14812+ GR_STATUS_INIT = 0x00 // disabled state
14813+};
14814+
14815+/* Begin ACL declarations */
14816+
14817+/* Role flags */
14818+
14819+enum {
14820+ GR_ROLE_USER = 0x0001,
14821+ GR_ROLE_GROUP = 0x0002,
14822+ GR_ROLE_DEFAULT = 0x0004,
14823+ GR_ROLE_SPECIAL = 0x0008,
14824+ GR_ROLE_AUTH = 0x0010,
14825+ GR_ROLE_NOPW = 0x0020,
14826+ GR_ROLE_GOD = 0x0040,
14827+ GR_ROLE_LEARN = 0x0080,
14828+ GR_ROLE_TPE = 0x0100
14829+};
14830+
14831+/* ACL Subject and Object mode flags */
14832+enum {
14833+ GR_DELETED = 0x00000080
14834+};
14835+
14836+/* ACL Object-only mode flags */
14837+enum {
14838+ GR_READ = 0x00000001,
14839+ GR_APPEND = 0x00000002,
14840+ GR_WRITE = 0x00000004,
14841+ GR_EXEC = 0x00000008,
14842+ GR_FIND = 0x00000010,
14843+ GR_INHERIT = 0x00000040,
14844+ GR_PTRACERD = 0x00000100,
14845+ GR_SETID = 0x00000200,
14846+ GR_CREATE = 0x00000400,
14847+ GR_DELETE = 0x00000800,
14848+ GR_AUDIT_READ = 0x00001000,
14849+ GR_AUDIT_APPEND = 0x00002000,
14850+ GR_AUDIT_WRITE = 0x0004000,
14851+ GR_AUDIT_EXEC = 0x00008000,
14852+ GR_AUDIT_FIND = 0x00010000,
14853+ GR_AUDIT_INHERIT = 0x00020000,
14854+ GR_AUDIT_SETID = 0x00400000,
14855+ GR_AUDIT_CREATE = 0x00800000,
14856+ GR_AUDIT_DELETE = 0x01000000,
14857+ GR_SUPPRESS = 0x02000000,
14858+ GR_NOLEARN = 0x04000000
14859+};
14860+
14861+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
14862+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
14863+ GR_AUDIT_CREATE | GR_AUDIT_DELETE)
14864+
14865+/* ACL subject-only mode flags */
14866+enum {
14867+ GR_KILL = 0x00000001,
14868+ GR_VIEW = 0x00000002,
14869+ GR_PROTECTED = 0x00000100,
14870+ GR_LEARN = 0x00000200,
14871+ GR_OVERRIDE = 0x00000400,
14872+ /* just a placeholder, this mode is only used in userspace */
14873+ GR_DUMMY = 0x00000800,
14874+
14875+ GR_PAXPAGE = 0x00001000,
14876+ GR_PAXSEGM = 0x00002000,
14877+ GR_PAXGCC = 0x00004000,
14878+ GR_PAXRANDMMAP = 0x00008000,
14879+ GR_PAXRANDEXEC = 0x00010000,
14880+ GR_PAXMPROTECT = 0x00020000,
14881+ GR_PROTSHM = 0x00040000,
14882+ GR_KILLPROC = 0x00080000,
14883+ GR_KILLIPPROC = 0x00100000,
14884+ /* just a placeholder, this mode is only used in userspace */
14885+ GR_NOTROJAN = 0x00200000,
14886+ GR_PROTPROCFD = 0x00400000,
14887+ GR_PROCACCT = 0x00800000
14888+};
14889+
14890+#define GR_CRASH_RES 11
14891+#define GR_UIDTABLE_MAX 500
14892+
14893+/* begin resource learning section */
14894+enum {
14895+ GR_RLIM_CPU_BUMP = 60,
14896+ GR_RLIM_FSIZE_BUMP = 50000,
14897+ GR_RLIM_DATA_BUMP = 10000,
14898+ GR_RLIM_STACK_BUMP = 1000,
14899+ GR_RLIM_CORE_BUMP = 10000,
14900+ GR_RLIM_RSS_BUMP = 500000,
14901+ GR_RLIM_NPROC_BUMP = 1,
14902+ GR_RLIM_NOFILE_BUMP = 5,
14903+ GR_RLIM_MEMLOCK_BUMP = 50000,
14904+ GR_RLIM_AS_BUMP = 500000,
14905+ GR_RLIM_LOCKS_BUMP = 2
14906+};
14907+
14908+#endif
474a6d91
AM
14909diff -urN linux-2.4.22.org/include/linux/grinternal.h linux-2.4.22/include/linux/grinternal.h
14910--- linux-2.4.22.org/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100
14911+++ linux-2.4.22/include/linux/grinternal.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
14912@@ -0,0 +1,193 @@
14913+#ifndef __GRINTERNAL_H
14914+#define __GRINTERNAL_H
14915+
14916+#ifdef CONFIG_GRKERNSEC
14917+
14918+#include <linux/grdefs.h>
14919+#include <linux/grmsg.h>
14920+
14921+extern void gr_add_learn_entry(const char *fmt, ...);
14922+extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
14923+ const struct vfsmount *mnt);
14924+extern __u32 gr_check_create(const struct dentry *new_dentry,
14925+ const struct dentry *parent,
14926+ const struct vfsmount *mnt, const __u32 mode);
14927+extern int gr_check_protected_task(const struct task_struct *task);
14928+extern __inline__ __u32 to_gr_audit(const __u32 reqmode);
14929+extern int gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14930+ struct dentry *old_dentry,
14931+ struct dentry *new_dentry,
14932+ struct vfsmount *mnt, const __u8 replace);
14933+extern int gr_set_acls(const int type);
14934+
14935+extern void gr_handle_alertkill(void);
14936+extern char *gr_to_filename(const struct dentry *dentry,
14937+ const struct vfsmount *mnt);
14938+extern char *gr_to_filename1(const struct dentry *dentry,
14939+ const struct vfsmount *mnt);
14940+extern char *gr_to_filename2(const struct dentry *dentry,
14941+ const struct vfsmount *mnt);
14942+extern char *gr_to_filename3(const struct dentry *dentry,
14943+ const struct vfsmount *mnt);
14944+
14945+extern int grsec_enable_link;
14946+extern int grsec_enable_fifo;
14947+extern int grsec_enable_execve;
14948+extern int grsec_enable_forkbomb;
14949+extern int grsec_forkbomb_gid;
14950+extern int grsec_forkbomb_sec;
14951+extern int grsec_forkbomb_max;
14952+extern int grsec_enable_execlog;
14953+extern int grsec_enable_signal;
14954+extern int grsec_enable_forkfail;
14955+extern int grsec_enable_time;
14956+extern int grsec_enable_chroot_shmat;
14957+extern int grsec_enable_chroot_findtask;
14958+extern int grsec_enable_chroot_mount;
14959+extern int grsec_enable_chroot_double;
14960+extern int grsec_enable_chroot_pivot;
14961+extern int grsec_enable_chroot_chdir;
14962+extern int grsec_enable_chroot_chmod;
14963+extern int grsec_enable_chroot_mknod;
14964+extern int grsec_enable_chroot_fchdir;
14965+extern int grsec_enable_chroot_nice;
14966+extern int grsec_enable_chroot_execlog;
14967+extern int grsec_enable_chroot_caps;
14968+extern int grsec_enable_chroot_sysctl;
14969+extern int grsec_enable_chroot_unix;
14970+extern int grsec_enable_tpe;
14971+extern int grsec_tpe_gid;
14972+extern int grsec_enable_tpe_all;
14973+extern int grsec_enable_sidcaps;
14974+extern int grsec_enable_randpid;
14975+extern int grsec_enable_socket_all;
14976+extern int grsec_socket_all_gid;
14977+extern int grsec_enable_socket_client;
14978+extern int grsec_socket_client_gid;
14979+extern int grsec_enable_socket_server;
14980+extern int grsec_socket_server_gid;
14981+extern int grsec_audit_gid;
14982+extern int grsec_enable_group;
14983+extern int grsec_enable_audit_ipc;
14984+extern int grsec_enable_mount;
14985+extern int grsec_enable_chdir;
14986+extern int grsec_lock;
14987+
14988+extern struct task_struct *child_reaper;
14989+
14990+extern spinlock_t grsec_alert_lock;
14991+extern unsigned long grsec_alert_wtime;
14992+extern unsigned long grsec_alert_fyet;
14993+
14994+extern spinlock_t grsec_alertgood_lock;
14995+extern unsigned long grsec_alertgood_wtime;
14996+extern unsigned long grsec_alertgood_fyet;
14997+
14998+extern spinlock_t grsec_audit_lock;
14999+
15000+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
15001+ gr_to_filename2(tsk->exec_file->f_dentry, \
15002+ tsk->exec_file->f_vfsmnt) : "/")
15003+
15004+#define gr_parent_task_fullpath(tsk) (tsk->p_pptr->exec_file ? \
15005+ gr_to_filename3(tsk->p_pptr->exec_file->f_dentry, \
15006+ tsk->p_pptr->exec_file->f_vfsmnt) : "/")
15007+
15008+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && \
15009+ ((tsk_a->fs->root->d_inode->i_dev != \
15010+ child_reaper->fs->root->d_inode->i_dev) || \
15011+ (tsk_a->fs->root->d_inode->i_ino != \
15012+ child_reaper->fs->root->d_inode->i_ino)))
15013+
15014+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_dev == \
15015+ tsk_b->fs->root->d_inode->i_dev) && \
15016+ (tsk_a->fs->root->d_inode->i_ino == \
15017+ tsk_b->fs->root->d_inode->i_ino))
15018+
15019+#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
15020+ current->pid, current->uid, \
15021+ current->euid, current->gid, current->egid, \
15022+ gr_parent_task_fullpath(current), \
15023+ current->p_pptr->comm, current->p_pptr->pid, \
15024+ current->p_pptr->uid, current->p_pptr->euid, \
15025+ current->p_pptr->gid, current->p_pptr->egid
15026+
15027+#define GR_CHROOT_CAPS ( \
15028+ CAP_TO_MASK(CAP_FOWNER) | \
15029+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
15030+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
15031+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
15032+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
15033+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
15034+ CAP_TO_MASK(CAP_IPC_OWNER))
15035+
15036+#define security_alert_good(normal_msg,args...) \
15037+({ \
15038+ spin_lock(&grsec_alertgood_lock); \
15039+ \
15040+ if (!grsec_alertgood_wtime || jiffies - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15041+ grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet = 0; \
15042+ if (current->curr_ip) \
15043+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15044+ else \
15045+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15046+ } else if((jiffies - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15047+ grsec_alertgood_fyet++; \
15048+ if (current->curr_ip) \
15049+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15050+ else \
15051+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15052+ } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15053+ grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet++; \
15054+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15055+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15056+ } \
15057+ \
15058+ spin_unlock(&grsec_alertgood_lock); \
15059+})
15060+
15061+#define security_alert(normal_msg,args...) \
15062+({ \
15063+ spin_lock(&grsec_alert_lock); \
15064+ \
15065+ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
15066+ grsec_alert_wtime = jiffies; grsec_alert_fyet = 0; \
15067+ if (current->curr_ip) \
15068+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15069+ else \
15070+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15071+ } else if((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
15072+ grsec_alert_fyet++; \
15073+ if (current->curr_ip) \
15074+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
15075+ else \
15076+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
15077+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
15078+ grsec_alert_wtime = jiffies; grsec_alert_fyet++; \
15079+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
15080+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
15081+ } \
15082+ \
15083+ gr_handle_alertkill(); \
15084+ spin_unlock(&grsec_alert_lock); \
15085+})
15086+
15087+#define security_audit(normal_msg,args...) \
15088+({ \
15089+ spin_lock(&grsec_audit_lock); \
15090+ if (current->curr_ip) \
15091+ printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
15092+ NIPQUAD(current->curr_ip) , ## args); \
15093+ else \
15094+ printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
15095+ spin_unlock(&grsec_audit_lock); \
15096+})
15097+
15098+#define security_learn(normal_msg,args...) \
15099+({ \
15100+ gr_add_learn_entry(normal_msg "\n", ## args); \
15101+})
15102+
15103+#endif
15104+
15105+#endif
474a6d91
AM
15106diff -urN linux-2.4.22.org/include/linux/grmsg.h linux-2.4.22/include/linux/grmsg.h
15107--- linux-2.4.22.org/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100
15108+++ linux-2.4.22/include/linux/grmsg.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
15109@@ -0,0 +1,104 @@
15110+#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d, parent %.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d"
15111+#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d"
15112+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
15113+#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
15114+#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
15115+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
15116+#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
15117+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
15118+#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
15119+#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
15120+#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
15121+#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
15122+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
15123+#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%u.%u.%u.%u"
15124+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
15125+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
15126+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
15127+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
15128+#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
15129+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
15130+#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
15131+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
15132+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
15133+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
15134+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
15135+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
15136+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
15137+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
15138+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
15139+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
15140+#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
15141+#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
15142+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
15143+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
15144+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution of [%.16s:%lu] for %lu seconds"
15145+#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
15146+#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
15147+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
15148+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
15149+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
15150+#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
15151+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
15152+#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
15153+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
15154+#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
15155+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
15156+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
15157+#define GR_INITF_ACL_MSG "init_variables() failed %s"
15158+#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader"
15159+#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
15160+#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
15161+#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
15162+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
15163+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
15164+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
15165+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
15166+#define GR_ENABLE_ACL_MSG "Loaded %s"
15167+#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
15168+#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
15169+#define GR_RELOAD_ACL_MSG "Reloaded %s"
15170+#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
15171+#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
15172+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
15173+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
15174+#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
15175+#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
15176+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
15177+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
15178+#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
15179+#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
15180+#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
15181+#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
15182+#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
15183+#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
15184+#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
15185+#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
15186+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
15187+#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
15188+#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
15189+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
15190+#define GR_TIME_MSG "time set by " DEFAULTSECMSG
15191+#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
15192+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
15193+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
15194+#define GR_SOCK_MSG "attempted socket(%d,%d,%d) by " DEFAULTSECMSG
15195+#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
15196+#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
15197+#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15198+#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
15199+#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%u.%u.%u.%u\t%u\t%u\t%u\t%u\t%u.%u.%u.%u"
15200+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
15201+#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
15202+#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
15203+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
15204+#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
15205+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
15206+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
15207+#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
15208+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
15209+#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
15210+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
15211+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
15212+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
15213+#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
474a6d91
AM
15214diff -urN linux-2.4.22.org/include/linux/grsecurity.h linux-2.4.22/include/linux/grsecurity.h
15215--- linux-2.4.22.org/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100
15216+++ linux-2.4.22/include/linux/grsecurity.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
15217@@ -0,0 +1,174 @@
15218+#ifndef GR_SECURITY_H
15219+#define GR_SECURITY_H
15220+
15221+extern int gr_pid_is_chrooted(const struct task_struct *p);
15222+extern int gr_handle_chroot_nice(void);
15223+extern int gr_handle_chroot_sysctl(const int op);
15224+extern int gr_handle_chroot_capset(const struct task_struct *target);
15225+extern int gr_handle_chroot_setpriority(const struct task_struct *p,
15226+ const int niceval);
15227+extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
15228+extern int gr_handle_chroot_chroot(const struct dentry *dentry,
15229+ const struct vfsmount *mnt);
15230+extern void gr_handle_chroot_caps(struct task_struct *task);
15231+extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
15232+extern int gr_handle_chroot_chmod(const struct dentry *dentry,
15233+ const struct vfsmount *mnt, const int mode);
15234+extern int gr_handle_chroot_mknod(const struct dentry *dentry,
15235+ const struct vfsmount *mnt, const int mode);
15236+extern int gr_handle_chroot_mount(const struct dentry *dentry,
15237+ const struct vfsmount *mnt,
15238+ const char *dev_name);
15239+extern int gr_handle_chroot_pivot(void);
15240+extern int gr_handle_chroot_unix(const pid_t pid);
15241+
15242+extern int gr_handle_rawio(const struct inode *inode);
15243+extern int gr_handle_nproc(void);
15244+
15245+extern void gr_handle_ioperm(void);
15246+extern void gr_handle_iopl(void);
15247+
15248+extern int gr_tpe_allow(const struct file *file);
15249+
15250+extern int gr_random_pid(spinlock_t * pid_lock);
15251+
15252+extern void gr_log_forkfail(const int retval);
15253+extern void gr_log_timechange(void);
15254+extern void gr_log_signal(const int sig, const struct task_struct *t);
15255+extern void gr_log_chdir(const struct dentry *dentry,
15256+ const struct vfsmount *mnt);
15257+extern void gr_log_chroot_exec(const struct dentry *dentry,
15258+ const struct vfsmount *mnt);
15259+extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
15260+extern void gr_log_remount(const char *devname, const int retval);
15261+extern void gr_log_unmount(const char *devname, const int retval);
15262+extern void gr_log_mount(const char *from, const char *to, const int retval);
15263+extern void gr_log_msgget(const int ret, const int msgflg);
15264+extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
15265+extern void gr_log_semget(const int err, const int semflg);
15266+extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
15267+extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
15268+extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
15269+
15270+extern int gr_handle_follow_link(const struct inode *parent,
15271+ const struct inode *inode,
15272+ const struct dentry *dentry,
15273+ const struct vfsmount *mnt);
15274+extern int gr_handle_fifo(const struct dentry *dentry,
15275+ const struct vfsmount *mnt,
15276+ const struct dentry *dir, const int flag,
15277+ const int acc_mode);
15278+extern int gr_handle_hardlink(const struct dentry *dentry,
15279+ const struct vfsmount *mnt,
15280+ struct inode *inode,
15281+ const int mode, const char *to);
15282+
15283+extern int gr_is_capable(const int cap);
15284+extern void gr_learn_resource(const struct task_struct *task, const int limit,
15285+ const unsigned long wanted);
15286+extern void gr_copy_label(struct task_struct *tsk);
15287+extern void gr_handle_crash(struct task_struct *task, const int sig);
15288+extern int gr_handle_signal(const struct task_struct *p, const int sig);
15289+extern int gr_check_crash_uid(const uid_t uid);
15290+extern int gr_check_protected_task(const struct task_struct *task);
15291+extern int gr_acl_handle_mmap(const struct file *file,
15292+ const unsigned long prot);
15293+extern int gr_acl_handle_mprotect(const struct file *file,
15294+ const unsigned long prot);
15295+extern int gr_check_hidden_task(const struct task_struct *tsk);
15296+extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
15297+ const struct vfsmount *mnt);
15298+extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
15299+ const struct vfsmount *mnt);
15300+extern __u32 gr_acl_handle_access(const struct dentry *dentry,
15301+ const struct vfsmount *mnt, const int fmode);
15302+extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
15303+ const struct vfsmount *mnt, mode_t mode);
15304+extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
15305+ const struct vfsmount *mnt, mode_t mode);
15306+extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
15307+ const struct vfsmount *mnt);
15308+extern int gr_handle_ptrace_exec(const struct dentry *dentry,
15309+ const struct vfsmount *mnt);
15310+extern int gr_handle_ptrace(struct task_struct *task, const long request);
15311+extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
15312+extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
15313+ const struct vfsmount *mnt);
15314+extern int gr_check_crash_exec(const struct file *filp);
15315+extern int gr_acl_is_enabled(void);
15316+extern void gr_set_kernel_label(struct task_struct *task);
15317+extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
15318+ const gid_t gid);
15319+extern void gr_set_proc_label(const struct dentry *dentry,
15320+ const struct vfsmount *mnt);
15321+extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
15322+ const struct vfsmount *mnt);
15323+extern __u32 gr_acl_handle_open(const struct dentry *dentry,
15324+ const struct vfsmount *mnt, const int fmode);
15325+extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
15326+ const struct dentry *p_dentry,
15327+ const struct vfsmount *p_mnt, const int fmode,
15328+ const int imode);
15329+extern void gr_handle_create(const struct dentry *dentry,
15330+ const struct vfsmount *mnt);
15331+extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
15332+ const struct dentry *parent_dentry,
15333+ const struct vfsmount *parent_mnt,
15334+ const int mode);
15335+extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
15336+ const struct dentry *parent_dentry,
15337+ const struct vfsmount *parent_mnt);
15338+extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
15339+ const struct vfsmount *mnt);
15340+extern void gr_handle_delete(const ino_t ino, const kdev_t dev);
15341+extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
15342+ const struct vfsmount *mnt);
15343+extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
15344+ const struct dentry *parent_dentry,
15345+ const struct vfsmount *parent_mnt,
15346+ const char *from);
15347+extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
15348+ const struct dentry *parent_dentry,
15349+ const struct vfsmount *parent_mnt,
15350+ const struct dentry *old_dentry,
15351+ const struct vfsmount *old_mnt, const char *to);
15352+extern int gr_acl_handle_rename(struct dentry *new_dentry,
15353+ struct dentry *parent_dentry,
15354+ const struct vfsmount *parent_mnt,
15355+ struct dentry *old_dentry,
15356+ struct inode *old_parent_inode,
15357+ struct vfsmount *old_mnt, const char *newname);
15358+extern __u32 gr_check_link(const struct dentry *new_dentry,
15359+ const struct dentry *parent_dentry,
15360+ const struct vfsmount *parent_mnt,
15361+ const struct dentry *old_dentry,
15362+ const struct vfsmount *old_mnt);
15363+extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
15364+ const struct vfsmount *mnt, const ino_t ino);
15365+extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
15366+ const struct vfsmount *mnt);
15367+extern void gr_set_pax_flags(struct task_struct *task);
15368+extern void gr_acl_handle_exit(void);
15369+extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
15370+extern int gr_acl_handle_procpidmem(const struct task_struct *task);
15371+extern __u32 gr_cap_rtnetlink(void);
15372+
15373+#ifdef CONFIG_GRKERNSEC
15374+extern void gr_handle_mem_write(void);
15375+extern void gr_handle_kmem_write(void);
15376+extern void gr_handle_open_port(void);
15377+extern int gr_handle_mem_mmap(const unsigned long offset,
15378+ struct vm_area_struct *vma);
15379+
15380+extern __u16 ip_randomid(void);
15381+extern __u32 ip_randomisn(void);
15382+extern unsigned long get_random_long(void);
15383+
15384+extern int grsec_enable_dmesg;
15385+extern int grsec_enable_randid;
15386+extern int grsec_enable_randisn;
15387+extern int grsec_enable_randsrc;
15388+extern int grsec_enable_randrpc;
15389+#endif
15390+
15391+#endif
474a6d91
AM
15392diff -urN linux-2.4.22.org/include/linux/kernel.h linux-2.4.22/include/linux/kernel.h
15393--- linux-2.4.22.org/include/linux/kernel.h 2003-11-22 22:09:15.000000000 +0100
15394+++ linux-2.4.22/include/linux/kernel.h 2003-11-22 22:14:09.000000000 +0100
8be839c4
JR
15395@@ -71,14 +71,17 @@
15396 extern long long simple_strtoll(const char *,char **,unsigned int);
15397 extern int sprintf(char * buf, const char * fmt, ...)
15398 __attribute__ ((format (printf, 2, 3)));
15399-extern int vsprintf(char *buf, const char *, va_list);
15400+extern int vsprintf(char *buf, const char *, va_list)
15401+ __attribute__ ((format (printf, 2, 0)));
15402 extern int snprintf(char * buf, size_t size, const char * fmt, ...)
15403 __attribute__ ((format (printf, 3, 4)));
15404-extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
15405+extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
15406+ __attribute__ ((format (printf, 3, 0)));
15407
15408 extern int sscanf(const char *, const char *, ...)
15409 __attribute__ ((format (scanf,2,3)));
15410-extern int vsscanf(const char *, const char *, va_list);
15411+extern int vsscanf(const char *, const char *, va_list)
15412+ __attribute__ ((format (scanf, 2, 0)));
15413
15414 extern void qsort(void *, size_t, size_t, int (*)(const void *,const void *));
15415
474a6d91
AM
15416diff -urN linux-2.4.22.org/include/linux/mm.h linux-2.4.22/include/linux/mm.h
15417--- linux-2.4.22.org/include/linux/mm.h 2003-11-22 22:09:12.000000000 +0100
15418+++ linux-2.4.22/include/linux/mm.h 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15419@@ -22,9 +22,13 @@
15420 extern struct list_head active_list;
15421 extern struct list_head inactive_list;
15422
15423+extern void gr_learn_resource(const struct task_struct * task, const int limit,
15424+ const unsigned long wanted);
15425+
15426 #include <asm/page.h>
15427 #include <asm/pgtable.h>
15428 #include <asm/atomic.h>
15429+#include <asm/mman.h>
15430
15431 /*
15432 * Linux kernel virtual memory manager primitives.
15433@@ -104,6 +108,33 @@
15434 #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
15435 #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
15436
15437+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
15438+#define VM_MIRROR 0x00100000 /* vma is mirroring another */
15439+#endif
15440+
15441+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
15442+#define VM_MAYNOTWRITE 0x00200000 /* vma cannot be granted VM_WRITE any more */
15443+#endif
15444+
15445+#ifdef ARCH_STACK_GROWSUP
15446+#define __VM_STACK_FLAGS 0x00000233
15447+#else
15448+#define __VM_STACK_FLAGS 0x00000133
15449+#endif
15450+
15451+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
15452+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
15453+#define VM_STACK_FLAGS (__VM_STACK_FLAGS | \
15454+ ((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15455+ ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
15456+#else
15457+#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_MAYEXEC | \
15458+ ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
15459+#endif
15460+#else
15461+#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_EXEC | VM_MAYEXEC)
15462+#endif
15463+
15464 #ifndef VM_STACK_FLAGS
15465 #define VM_STACK_FLAGS 0x00000177
15466 #endif
474a6d91 15467@@ -570,22 +601,50 @@
8be839c4
JR
15468 unsigned long prot, unsigned long flag,
15469 unsigned long pgoff);
15470
15471+extern int do_munmap(struct mm_struct *, unsigned long, size_t);
15472+
15473 static inline unsigned long do_mmap(struct file *file, unsigned long addr,
15474 unsigned long len, unsigned long prot,
15475 unsigned long flag, unsigned long offset)
15476 {
15477 unsigned long ret = -EINVAL;
15478+
15479+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
15480+ if ((current->flags & PF_PAX_SEGMEXEC) &&
15481+ (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
15482+ goto out;
15483+#endif
15484+
15485 if ((offset + PAGE_ALIGN(len)) < offset)
15486 goto out;
15487 if (!(offset & ~PAGE_MASK))
15488 ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag,
15489 offset >> PAGE_SHIFT);
15490+
15491+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
15492+#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE)
15493+ if ((current->flags & PF_PAX_SEGMEXEC) && !BAD_ADDR(ret) &&
15494+ (prot & PROT_EXEC) && ((flag & MAP_TYPE) == MAP_PRIVATE)
15495+
15496+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
15497+ && (!(current->flags & PF_PAX_MPROTECT) || (file && !(prot & PROT_WRITE)))
15498+#endif
15499+ )
15500+ {
15501+ unsigned long ret_m;
15502+ ret_m = do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flag | MAP_MIRROR | MAP_FIXED, ret);
15503+ if (BAD_ADDR(ret_m)) {
15504+ do_munmap(current->mm, ret, len);
15505+ ret = ret_m;
15506+ }
15507+ }
15508+#undef BAD_ADDR
15509+#endif
15510+
15511 out:
15512 return ret;
15513 }
15514
15515-extern int do_munmap(struct mm_struct *, unsigned long, size_t);
15516-
15517 extern unsigned long do_brk(unsigned long, unsigned long);
15518
15519 static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev)
474a6d91 15520@@ -598,6 +657,12 @@
8be839c4
JR
15521
15522 static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
15523 {
15524+
15525+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
15526+ if ((vma->vm_flags | vm_flags) & VM_MIRROR)
15527+ return 0;
15528+#endif
15529+
15530 if (!vma->vm_file && vma->vm_flags == vm_flags)
15531 return 1;
15532 else
474a6d91 15533@@ -651,7 +716,12 @@
8be839c4
JR
15534
15535 return gfp_mask;
15536 }
15537-
15538+
15539+/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
15540+extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
15541+extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
15542+ struct vm_area_struct **pprev);
15543+
15544 /* vma is the first one with address < vma->vm_end,
15545 * and even address < vma->vm_start. Have to extend vma. */
15546 static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
474a6d91 15547@@ -666,11 +736,51 @@
8be839c4
JR
15548 address &= PAGE_MASK;
15549 spin_lock(&vma->vm_mm->page_table_lock);
15550 grow = (vma->vm_start - address) >> PAGE_SHIFT;
15551+
15552+ gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address);
15553+ gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT);
15554+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT);
15555+
15556+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
15557+ if (vma->vm_flags & VM_MIRROR) {
15558+ struct vm_area_struct * vma_m;
15559+ unsigned long address_m;
15560+
15561+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
15562+ vma_m = find_vma(vma->vm_mm, address_m);
15563+ if (!vma_m || vma_m->vm_start != address_m || !(vma_m->vm_flags & VM_MIRROR) ||
15564+ vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start) {
15565+ spin_unlock(&vma->vm_mm->page_table_lock);
15566+ printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
15567+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
15568+ return -ENOMEM;
15569+ }
15570+
15571+ address_m = address + (unsigned long)vma->vm_private_data;
15572+ if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
15573+ ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
15574+ ((vma_m->vm_flags & VM_LOCKED) && ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
15575+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
15576+ spin_unlock(&vma->vm_mm->page_table_lock);
15577+ return -ENOMEM;
15578+ }
15579+
15580+ vma_m->vm_start = address_m;
15581+ vma_m->vm_pgoff -= grow;
15582+ vma_m->vm_mm->total_vm += grow;
15583+ if (vma_m->vm_flags & VM_LOCKED)
15584+ vma_m->vm_mm->locked_vm += grow;
15585+ } else
15586+#endif
15587+
15588 if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
15589- ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
15590+ ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
15591+ ((vma->vm_flags & VM_LOCKED) && ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
15592+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
15593 spin_unlock(&vma->vm_mm->page_table_lock);
15594 return -ENOMEM;
15595 }
15596+
15597 vma->vm_start = address;
15598 vma->vm_pgoff -= grow;
15599 vma->vm_mm->total_vm += grow;
474a6d91 15600@@ -680,11 +790,6 @@
8be839c4
JR
15601 return 0;
15602 }
15603
15604-/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
15605-extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
15606-extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
15607- struct vm_area_struct **pprev);
15608-
15609 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
15610 NULL if none. Assume start_addr < end_addr. */
15611 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
474a6d91
AM
15612diff -urN linux-2.4.22.org/include/linux/proc_fs.h linux-2.4.22/include/linux/proc_fs.h
15613--- linux-2.4.22.org/include/linux/proc_fs.h 2003-11-22 22:09:15.000000000 +0100
15614+++ linux-2.4.22/include/linux/proc_fs.h 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15615@@ -143,6 +143,9 @@
15616 extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
15617 struct proc_dir_entry *,kdev_t);
15618 extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
15619+#ifdef CONFIG_GRKERNSEC_PROC
15620+extern struct proc_dir_entry *proc_priv_mkdir(const char *, struct proc_dir_entry *);
15621+#endif
15622
15623 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
15624 mode_t mode, struct proc_dir_entry *base,
474a6d91
AM
15625diff -urN linux-2.4.22.org/include/linux/sched.h linux-2.4.22/include/linux/sched.h
15626--- linux-2.4.22.org/include/linux/sched.h 2003-11-22 22:09:12.000000000 +0100
15627+++ linux-2.4.22/include/linux/sched.h 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15628@@ -28,6 +28,9 @@
15629 #include <linux/securebits.h>
15630 #include <linux/fs_struct.h>
15631
15632+extern int gr_is_capable(const int cap);
15633+extern int gr_pid_is_chrooted(const struct task_struct *p);
15634+
15635 struct exec_domain;
15636
15637 /*
15638@@ -250,6 +253,20 @@
15639 unsigned long cpu_vm_mask;
15640 unsigned long swap_address;
15641
15642+#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
15643+ unsigned long call_dl_resolve;
15644+#endif
15645+
15646+#if defined(CONFIG_PPC32) && defined(CONFIG_GRKERNSEC_PAX_EMUSIGRT)
15647+ unsigned long call_syscall;
15648+#endif
15649+
15650+#ifdef CONFIG_GRKERNSEC_PAX_ASLR
15651+ unsigned long delta_mmap; /* PaX: randomized offset */
15652+ unsigned long delta_exec; /* PaX: randomized offset */
15653+ unsigned long delta_stack; /* PaX: randomized offset */
15654+#endif
15655+
15656 unsigned dumpable:1;
15657
15658 /* Architecture-specific MM context */
15659@@ -422,7 +439,7 @@
15660 int (*notifier)(void *priv);
15661 void *notifier_data;
15662 sigset_t *notifier_mask;
15663-
15664+
15665 /* Thread group tracking */
15666 u32 parent_exec_id;
15667 u32 self_exec_id;
15668@@ -433,6 +450,19 @@
15669
15670 /* journalling filesystem info */
15671 void *journal_info;
15672+
15673+#ifdef CONFIG_GRKERNSEC
15674+/* added by grsecurity's ACL system */
15675+ struct acl_subject_label *acl;
15676+ struct acl_role_label *role;
15677+ struct file *exec_file;
15678+ u32 curr_ip;
15679+ u16 acl_role_id;
15680+ u8 acl_sp_role:1;
15681+ u8 used_accept:1;
15682+ u8 used_connect:1;
15683+ u8 is_writable:1;
15684+#endif
15685 };
15686
15687 /*
474a6d91 15688@@ -453,6 +483,13 @@
8be839c4
JR
15689
15690 #define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */
15691
15692+#define PF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
15693+#define PF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
15694+#define PF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
15695+#define PF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
15696+#define PF_PAX_RANDEXEC 0x10000000 /* Randomize ET_EXEC base */
15697+#define PF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
15698+
15699 /*
15700 * Ptrace flags
15701 */
474a6d91 15702@@ -573,6 +610,8 @@
8be839c4
JR
15703 *p->pidhash_pprev = p->pidhash_next;
15704 }
15705
15706+#include <asm/current.h>
15707+
15708 static inline task_t *find_task_by_pid(int pid)
15709 {
15710 task_t *p, **htable = &pidhash[pid_hashfn(pid)];
474a6d91 15711@@ -580,6 +619,8 @@
8be839c4
JR
15712 for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
15713 ;
15714
15715+ if(gr_pid_is_chrooted(p)) p = NULL;
15716+
15717 return p;
15718 }
15719
15720@@ -588,8 +629,6 @@
8be839c4 15721 extern void free_uid(struct user_struct *);
474a6d91 15722 extern void switch_uid(struct user_struct *);
8be839c4
JR
15723
15724-#include <asm/current.h>
15725-
15726 extern unsigned long volatile jiffies;
15727 extern unsigned long itimer_ticks;
15728 extern unsigned long itimer_next;
15729@@ -756,7 +795,7 @@
15730 static inline int capable(int cap)
15731 {
15732 #if 1 /* ok now */
15733- if (cap_raised(current->cap_effective, cap))
15734+ if (cap_raised(current->cap_effective, cap) && gr_is_capable(cap))
15735 #else
15736 if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
15737 #endif
474a6d91
AM
15738diff -urN linux-2.4.22.org/include/linux/sysctl.h linux-2.4.22/include/linux/sysctl.h
15739--- linux-2.4.22.org/include/linux/sysctl.h 2003-11-22 22:09:11.000000000 +0100
15740+++ linux-2.4.22/include/linux/sysctl.h 2003-11-22 22:45:25.000000000 +0100
15741@@ -128,6 +128,7 @@
8be839c4
JR
15742 KERN_PPC_L3CR=57, /* l3cr register on PPC */
15743 KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
474a6d91
AM
15744 KERN_CORE_SETUID=59, /* int: set to allow core dumps of setuid apps */
15745+ KERN_GRSECURITY=68, /* grsecurity */
8be839c4
JR
15746 };
15747
15748
474a6d91
AM
15749diff -urN linux-2.4.22.org/include/net/inetpeer.h linux-2.4.22/include/net/inetpeer.h
15750--- linux-2.4.22.org/include/net/inetpeer.h 2003-11-22 22:09:27.000000000 +0100
15751+++ linux-2.4.22/include/net/inetpeer.h 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15752@@ -13,6 +13,7 @@
15753 #include <linux/init.h>
15754 #include <linux/sched.h>
15755 #include <linux/spinlock.h>
15756+
15757 #include <asm/atomic.h>
15758
15759 struct inet_peer
15760@@ -34,6 +35,11 @@
15761 /* can be called with or without local BH being disabled */
15762 struct inet_peer *inet_getpeer(__u32 daddr, int create);
15763
15764+#ifdef CONFIG_GRKERNSEC_RANDID
15765+extern int grsec_enable_randid;
15766+extern __u16 ip_randomid(void);
15767+#endif
15768+
15769 extern spinlock_t inet_peer_unused_lock;
15770 extern struct inet_peer *inet_peer_unused_head;
15771 extern struct inet_peer **inet_peer_unused_tailp;
15772@@ -58,7 +64,14 @@
15773 __u16 id;
15774
15775 spin_lock_bh(&inet_peer_idlock);
15776- id = p->ip_id_count++;
15777+
15778+#ifdef CONFIG_GRKERNSEC_RANDID
15779+ if(grsec_enable_randid)
15780+ id = htons(ip_randomid());
15781+ else
15782+#endif
15783+ id = p->ip_id_count++;
15784+
15785 spin_unlock_bh(&inet_peer_idlock);
15786 return id;
15787 }
474a6d91
AM
15788diff -urN linux-2.4.22.org/include/net/ip.h linux-2.4.22/include/net/ip.h
15789--- linux-2.4.22.org/include/net/ip.h 2003-11-22 22:09:27.000000000 +0100
15790+++ linux-2.4.22/include/net/ip.h 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15791@@ -64,6 +64,11 @@
15792 void (*destructor)(struct sock *);
15793 };
15794
15795+#ifdef CONFIG_GRKERNSEC_RANDID
15796+extern int grsec_enable_randid;
15797+extern __u16 ip_randomid(void);
15798+#endif
15799+
15800 extern struct ip_ra_chain *ip_ra_chain;
15801 extern rwlock_t ip_ra_lock;
15802
15803@@ -197,7 +202,13 @@
15804 * does not change, they drop every other packet in
15805 * a TCP stream using header compression.
15806 */
15807- iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
15808+
15809+#ifdef CONFIG_GRKERNSEC_RANDID
15810+ if(grsec_enable_randid)
15811+ iph->id = htons(ip_randomid());
15812+ else
15813+#endif
15814+ iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
15815 } else
15816 __ip_select_ident(iph, dst);
15817 }
474a6d91
AM
15818diff -urN linux-2.4.22.org/init/main.c linux-2.4.22/init/main.c
15819--- linux-2.4.22.org/init/main.c 2003-11-22 22:09:07.000000000 +0100
15820+++ linux-2.4.22/init/main.c 2003-11-22 22:14:10.000000000 +0100
15821@@ -28,6 +28,7 @@
8be839c4 15822 #include <linux/bootmem.h>
474a6d91 15823 #include <linux/file.h>
8be839c4
JR
15824 #include <linux/tty.h>
15825+#include <linux/grsecurity.h>
15826
15827 #include <asm/io.h>
15828 #include <asm/bugs.h>
474a6d91 15829@@ -113,6 +114,8 @@
8be839c4
JR
15830 extern void ipc_init(void);
15831 #endif
15832
15833+extern void grsecurity_init(void);
15834+
15835 /*
15836 * Boot command-line arguments
15837 */
474a6d91 15838@@ -568,6 +571,7 @@
8be839c4
JR
15839 do_basic_setup();
15840
15841 prepare_namespace();
15842+ grsecurity_init();
15843
15844 /*
15845 * Ok, we have completed the initial bootup, and
474a6d91
AM
15846diff -urN linux-2.4.22.org/ipc/msg.c linux-2.4.22/ipc/msg.c
15847--- linux-2.4.22.org/ipc/msg.c 2003-11-22 22:10:06.000000000 +0100
15848+++ linux-2.4.22/ipc/msg.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15849@@ -22,6 +22,7 @@
15850 #include <linux/init.h>
15851 #include <linux/proc_fs.h>
15852 #include <linux/list.h>
15853+#include <linux/grsecurity.h>
15854 #include <asm/uaccess.h>
15855 #include "util.h"
15856
15857@@ -326,6 +327,9 @@
15858 msg_unlock(id);
15859 }
15860 up(&msg_ids.sem);
15861+
15862+ gr_log_msgget(ret, msgflg);
15863+
15864 return ret;
15865 }
15866
15867@@ -560,6 +564,8 @@
15868 break;
15869 }
15870 case IPC_RMID:
15871+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
15872+
15873 freeque (msqid);
15874 break;
15875 }
474a6d91
AM
15876diff -urN linux-2.4.22.org/ipc/sem.c linux-2.4.22/ipc/sem.c
15877--- linux-2.4.22.org/ipc/sem.c 2003-11-22 22:10:06.000000000 +0100
15878+++ linux-2.4.22/ipc/sem.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15879@@ -63,6 +63,7 @@
15880 #include <linux/init.h>
15881 #include <linux/proc_fs.h>
15882 #include <linux/time.h>
15883+#include <linux/grsecurity.h>
15884 #include <asm/uaccess.h>
15885 #include "util.h"
15886
15887@@ -182,6 +183,9 @@
15888 }
15889
15890 up(&sem_ids.sem);
15891+
15892+ gr_log_semget(err, semflg);
15893+
15894 return err;
15895 }
15896
15897@@ -724,6 +728,8 @@
15898
15899 switch(cmd){
15900 case IPC_RMID:
15901+ gr_log_semrm(ipcp->uid, ipcp->cuid);
15902+
15903 freeary(semid);
15904 err = 0;
15905 break;
474a6d91
AM
15906diff -urN linux-2.4.22.org/ipc/shm.c linux-2.4.22/ipc/shm.c
15907--- linux-2.4.22.org/ipc/shm.c 2003-11-22 22:10:06.000000000 +0100
15908+++ linux-2.4.22/ipc/shm.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
15909@@ -23,6 +23,7 @@
15910 #include <linux/mman.h>
15911 #include <linux/proc_fs.h>
15912 #include <asm/uaccess.h>
15913+#include <linux/grsecurity.h>
15914
15915 #include "util.h"
15916
15917@@ -38,8 +39,21 @@
15918 time_t shm_ctim;
15919 pid_t shm_cprid;
15920 pid_t shm_lprid;
15921+
15922+#ifdef CONFIG_GRKERNSEC
15923+ time_t shm_createtime;
15924+ pid_t shm_lapid;
15925+#endif
15926 };
15927
15928+#ifdef CONFIG_GRKERNSEC
15929+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
15930+ const time_t shm_createtime, const uid_t cuid,
15931+ const int shmid);
15932+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
15933+ const time_t shm_createtime);
15934+#endif
15935+
15936 #define shm_flags shm_perm.mode
15937
15938 static struct file_operations shm_file_operations;
15939@@ -209,6 +223,9 @@
15940 shp->shm_lprid = 0;
15941 shp->shm_atim = shp->shm_dtim = 0;
15942 shp->shm_ctim = CURRENT_TIME;
15943+#ifdef CONFIG_GRKERNSEC
15944+ shp->shm_createtime = CURRENT_TIME;
15945+#endif
15946 shp->shm_segsz = size;
15947 shp->shm_nattch = 0;
15948 shp->id = shm_buildid(id,shp->shm_perm.seq);
15949@@ -254,6 +271,9 @@
15950 shm_unlock(id);
15951 }
15952 up(&shm_ids.sem);
15953+
15954+ gr_log_shmget(err, shmflg, size);
15955+
15956 return err;
15957 }
15958
15959@@ -509,6 +529,9 @@
15960 err=-EPERM;
15961 goto out_unlock_up;
15962 }
15963+
15964+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
15965+
15966 if (shp->shm_nattch){
15967 shp->shm_flags |= SHM_DEST;
15968 /* Do not find it any more */
15969@@ -622,9 +645,28 @@
15970 shm_unlock(shmid);
15971 return -EACCES;
15972 }
15973+
15974+#ifdef CONFIG_GRKERNSEC
15975+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
15976+ shp->shm_perm.cuid, shmid)) {
15977+ shm_unlock(shmid);
15978+ return -EACCES;
15979+ }
15980+
15981+ if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
15982+ shm_unlock(shmid);
15983+ return -EACCES;
15984+ }
15985+#endif
15986+
15987 file = shp->shm_file;
15988 size = file->f_dentry->d_inode->i_size;
15989 shp->shm_nattch++;
15990+
15991+#ifdef CONFIG_GRKERNSEC
15992+ shp->shm_lapid = current->pid;
15993+#endif
15994+
15995 shm_unlock(shmid);
15996
15997 down_write(&current->mm->mmap_sem);
474a6d91
AM
15998diff -urN linux-2.4.22.org/kernel/capability.c linux-2.4.22/kernel/capability.c
15999--- linux-2.4.22.org/kernel/capability.c 2003-11-22 22:09:08.000000000 +0100
16000+++ linux-2.4.22/kernel/capability.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16001@@ -7,6 +7,7 @@
16002
16003 #include <linux/mm.h>
16004 #include <asm/uaccess.h>
16005+#include <linux/grsecurity.h>
16006
16007 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
16008
16009@@ -170,6 +171,10 @@
16010 target = current;
16011 }
16012
16013+ if (gr_handle_chroot_capset(target)) {
16014+ error = -ESRCH;
16015+ goto out;
16016+ }
16017
16018 /* verify restrictions on target's new Inheritable set */
16019 if (!cap_issubset(inheritable,
474a6d91
AM
16020diff -urN linux-2.4.22.org/kernel/exit.c linux-2.4.22/kernel/exit.c
16021--- linux-2.4.22.org/kernel/exit.c 2003-11-22 22:09:07.000000000 +0100
16022+++ linux-2.4.22/kernel/exit.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16023@@ -7,6 +7,7 @@
16024 #include <linux/config.h>
16025 #include <linux/slab.h>
16026 #include <linux/interrupt.h>
16027+#include <linux/file.h>
16028 #include <linux/smp_lock.h>
16029 #include <linux/module.h>
16030 #include <linux/completion.h>
16031@@ -16,6 +17,7 @@
16032 #ifdef CONFIG_BSD_PROCESS_ACCT
16033 #include <linux/acct.h>
16034 #endif
16035+#include <linux/grsecurity.h>
16036
16037 #include <asm/uaccess.h>
16038 #include <asm/pgtable.h>
16039@@ -139,12 +141,21 @@
16040 {
16041 write_lock_irq(&tasklist_lock);
16042
16043+#ifdef CONFIG_GRKERNSEC
16044+ if (current->exec_file) {
16045+ fput(current->exec_file);
16046+ current->exec_file = NULL;
16047+ }
16048+#endif
16049+
16050 /* Reparent to init */
16051 REMOVE_LINKS(current);
16052 current->p_pptr = child_reaper;
16053 current->p_opptr = child_reaper;
16054 SET_LINKS(current);
16055
16056+ gr_set_kernel_label(current);
16057+
16058 /* Set the exit signal to SIGCHLD so we signal init on exit */
16059 current->exit_signal = SIGCHLD;
16060
16061@@ -485,6 +496,11 @@
16062 #ifdef CONFIG_BSD_PROCESS_ACCT
16063 acct_process(code);
16064 #endif
16065+#include <linux/grsecurity.h>
16066+
16067+ gr_acl_handle_psacct(tsk, code);
16068+ gr_acl_handle_exit();
16069+
16070 __exit_mm(tsk);
16071
16072 lock_kernel();
474a6d91
AM
16073diff -urN linux-2.4.22.org/kernel/fork.c linux-2.4.22/kernel/fork.c
16074--- linux-2.4.22.org/kernel/fork.c 2003-11-22 22:09:08.000000000 +0100
16075+++ linux-2.4.22/kernel/fork.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16076@@ -22,6 +22,7 @@
16077 #include <linux/namespace.h>
16078 #include <linux/personality.h>
16079 #include <linux/compiler.h>
16080+#include <linux/grsecurity.h>
16081
16082 #include <asm/pgtable.h>
16083 #include <asm/pgalloc.h>
16084@@ -94,6 +95,10 @@
16085 if (flags & CLONE_PID)
16086 return current->pid;
16087
16088+ pid = gr_random_pid(&lastpid_lock);
16089+ if (pid)
16090+ return pid;
16091+
16092 spin_lock(&lastpid_lock);
16093 beginpid = last_pid;
16094 if((++last_pid) & 0xffff8000) {
474a6d91 16095@@ -670,6 +675,9 @@
8be839c4
JR
16096 * friends to set the per-user process limit to something lower
16097 * than the amount of processes root is running. -- Rik
16098 */
16099+
16100+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes));
16101+
16102 if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
16103 && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
16104 goto bad_fork_free;
474a6d91 16105@@ -753,6 +761,7 @@
8be839c4
JR
16106 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
16107 if (retval)
16108 goto bad_fork_cleanup_namespace;
16109+ gr_copy_label(p);
16110 p->semundo = NULL;
16111
16112 /* Our parent execution domain becomes current domain
474a6d91 16113@@ -855,6 +864,9 @@
8be839c4
JR
16114 free_uid(p->user);
16115 bad_fork_free:
16116 free_task_struct(p);
16117+
16118+ gr_log_forkfail(retval);
16119+
16120 goto fork_out;
16121 }
16122
474a6d91
AM
16123diff -urN linux-2.4.22.org/kernel/ksyms.c linux-2.4.22/kernel/ksyms.c
16124--- linux-2.4.22.org/kernel/ksyms.c 2003-11-22 22:09:08.000000000 +0100
16125+++ linux-2.4.22/kernel/ksyms.c 2003-11-22 22:45:48.000000000 +0100
16126@@ -51,6 +51,7 @@
8be839c4
JR
16127 #include <linux/dnotify.h>
16128 #include <linux/crc32.h>
474a6d91 16129 #include <linux/firmware.h>
8be839c4
JR
16130+#include <linux/grsecurity.h>
16131 #include <asm/checksum.h>
16132
16133 #if defined(CONFIG_PROC_FS)
474a6d91 16134@@ -632,3 +633,9 @@
8be839c4
JR
16135 /* To match ksyms with System.map */
16136 extern const char _end[];
16137 EXPORT_SYMBOL(_end);
16138+
16139+/* grsecurity */
16140+EXPORT_SYMBOL(gr_is_capable);
16141+EXPORT_SYMBOL(gr_pid_is_chrooted);
16142+EXPORT_SYMBOL(gr_learn_resource);
16143+EXPORT_SYMBOL(gr_set_kernel_label);
474a6d91
AM
16144diff -urN linux-2.4.22.org/kernel/module.c linux-2.4.22/kernel/module.c
16145--- linux-2.4.22.org/kernel/module.c 2003-11-22 22:09:07.000000000 +0100
16146+++ linux-2.4.22/kernel/module.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16147@@ -900,6 +900,11 @@
16148 struct module *mod;
16149 int err;
16150
16151+#ifdef CONFIG_GRKERNSEC_HIDESYM
16152+ if (!capable(CAP_SYS_MODULE))
16153+ return -EPERM;
16154+#endif
16155+
16156 lock_kernel();
16157 if (name_user == NULL)
16158 mod = &kernel_module;
16159@@ -969,6 +974,11 @@
16160 int i;
16161 struct kernel_sym ksym;
16162
16163+#ifdef CONFIG_GRKERNSEC_HIDESYM
16164+ if (!capable(CAP_SYS_MODULE))
16165+ return 0;
16166+#endif
16167+
16168 lock_kernel();
16169 for (mod = module_list, i = 0; mod; mod = mod->next) {
16170 /* include the count for the module name! */
474a6d91
AM
16171diff -urN linux-2.4.22.org/kernel/printk.c linux-2.4.22/kernel/printk.c
16172--- linux-2.4.22.org/kernel/printk.c 2003-11-22 22:09:07.000000000 +0100
16173+++ linux-2.4.22/kernel/printk.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16174@@ -27,6 +27,7 @@
16175 #include <linux/interrupt.h> /* For in_interrupt() */
16176 #include <linux/config.h>
16177 #include <linux/delay.h>
16178+#include <linux/grsecurity.h>
16179
16180 #include <asm/uaccess.h>
16181
474a6d91 16182@@ -299,6 +300,11 @@
8be839c4
JR
16183
16184 asmlinkage long sys_syslog(int type, char * buf, int len)
16185 {
16186+#ifdef CONFIG_GRKERNSEC_DMESG
16187+ if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
16188+ return -EPERM;
16189+ else
16190+#endif
16191 if ((type != 3) && !capable(CAP_SYS_ADMIN))
16192 return -EPERM;
16193 return do_syslog(type, buf, len);
474a6d91
AM
16194diff -urN linux-2.4.22.org/kernel/sched.c linux-2.4.22/kernel/sched.c
16195--- linux-2.4.22.org/kernel/sched.c 2003-11-22 22:09:08.000000000 +0100
16196+++ linux-2.4.22/kernel/sched.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16197@@ -25,6 +25,7 @@
16198 #include <asm/mmu_context.h>
16199 #include <linux/kernel_stat.h>
16200 #include <linux/completion.h>
16201+#include <linux/grsecurity.h>
16202
16203 /*
16204 * Convert user-nice values [ -20 ... 0 ... 19 ]
16205@@ -1192,6 +1193,9 @@
16206 return -EPERM;
16207 if (increment < -40)
16208 increment = -40;
16209+
16210+ if (gr_handle_chroot_nice())
16211+ return -EPERM;
16212 }
16213 if (increment > 40)
16214 increment = 40;
474a6d91
AM
16215diff -urN linux-2.4.22.org/kernel/signal.c linux-2.4.22/kernel/signal.c
16216--- linux-2.4.22.org/kernel/signal.c 2003-11-22 22:09:08.000000000 +0100
16217+++ linux-2.4.22/kernel/signal.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16218@@ -13,6 +13,8 @@
16219 #include <linux/smp_lock.h>
16220 #include <linux/init.h>
16221 #include <linux/sched.h>
16222+#include <linux/fs.h>
16223+#include <linux/grsecurity.h>
16224
16225 #include <asm/uaccess.h>
16226
16227@@ -553,6 +555,8 @@
16228 if (!sig || !t->sig)
16229 goto out_nolock;
16230
16231+ gr_log_signal(sig, t);
16232+
16233 spin_lock_irqsave(&t->sigmask_lock, flags);
16234 handle_stop_signal(sig, t);
16235
16236@@ -602,6 +606,8 @@
16237 recalc_sigpending(t);
16238 spin_unlock_irqrestore(&t->sigmask_lock, flags);
16239
16240+ gr_handle_crash(t, sig);
16241+
16242 return send_sig_info(sig, info, t);
16243 }
16244
16245@@ -621,9 +627,13 @@
16246 read_lock(&tasklist_lock);
16247 for_each_task(p) {
16248 if (p->pgrp == pgrp && thread_group_leader(p)) {
16249- int err = send_sig_info(sig, info, p);
16250- if (retval)
16251- retval = err;
16252+ if (gr_handle_signal(p, sig))
16253+ retval = -EPERM;
16254+ else {
16255+ int err = send_sig_info(sig, info, p);
16256+ if (retval)
16257+ retval = err;
16258+ }
16259 }
16260 }
16261 read_unlock(&tasklist_lock);
16262@@ -674,7 +684,10 @@
16263 if (tg)
16264 p = tg;
16265 }
16266- error = send_sig_info(sig, info, p);
16267+ if (gr_handle_signal(p, sig))
16268+ error = -EPERM;
16269+ else
16270+ error = send_sig_info(sig, info, p);
16271 }
16272 read_unlock(&tasklist_lock);
16273 return error;
16274@@ -699,10 +712,14 @@
16275 read_lock(&tasklist_lock);
16276 for_each_task(p) {
16277 if (p->pid > 1 && p != current && thread_group_leader(p)) {
16278- int err = send_sig_info(sig, info, p);
16279- ++count;
16280- if (err != -EPERM)
16281- retval = err;
16282+ if (gr_handle_signal(p, sig))
16283+ retval = -EPERM;
16284+ else {
16285+ int err = send_sig_info(sig, info, p);
16286+ ++count;
16287+ if (err != -EPERM)
16288+ retval = err;
16289+ }
16290 }
16291 }
16292 read_unlock(&tasklist_lock);
474a6d91
AM
16293diff -urN linux-2.4.22.org/kernel/sys.c linux-2.4.22/kernel/sys.c
16294--- linux-2.4.22.org/kernel/sys.c 2003-11-22 22:09:07.000000000 +0100
16295+++ linux-2.4.22/kernel/sys.c 2003-11-22 22:14:10.000000000 +0100
8be839c4
JR
16296@@ -4,6 +4,7 @@
16297 * Copyright (C) 1991, 1992 Linus Torvalds
16298 */
16299
16300+#include <linux/config.h>
16301 #include <linux/module.h>
16302 #include <linux/mm.h>
16303 #include <linux/utsname.h>
16304@@ -14,6 +15,7 @@
16305 #include <linux/prctl.h>
16306 #include <linux/init.h>
16307 #include <linux/highuid.h>
16308+#include <linux/grsecurity.h>
16309
16310 #include <asm/uaccess.h>
16311 #include <asm/io.h>
16312@@ -239,6 +241,12 @@
16313 }
16314 if (error == -ESRCH)
16315 error = 0;
16316+
16317+ if (gr_handle_chroot_setpriority(p, niceval)) {
16318+ read_unlock(&tasklist_lock);
16319+ return -ESRCH;
16320+ }
16321+
16322 if (niceval < task_nice(p) && !capable(CAP_SYS_NICE))
16323 error = -EACCES;
16324 else
16325@@ -425,6 +433,9 @@
16326 if (rgid != (gid_t) -1 ||
16327 (egid != (gid_t) -1 && egid != old_rgid))
16328 current->sgid = new_egid;
16329+
16330+ gr_set_role_label(current, current->uid, new_rgid);
16331+
16332 current->fsgid = new_egid;
16333 current->egid = new_egid;
16334 current->gid = new_rgid;
16335@@ -447,6 +458,9 @@
16336 current->mm->dumpable=0;
16337 wmb();
16338 }
16339+
16340+ gr_set_role_label(current, current->uid, gid);
16341+
16342 current->gid = current->egid = current->sgid = current->fsgid = gid;
16343 }
16344 else if ((gid == current->gid) || (gid == current->sgid))
474a6d91 16345@@ -523,6 +537,9 @@
8be839c4
JR
16346 current->mm->dumpable = 0;
16347 wmb();
16348 }
16349+
16350+ gr_set_role_label(current, new_ruid, current->gid);
16351+
16352 current->uid = new_ruid;
474a6d91
AM
16353 return 0;
16354 }
16355@@ -617,6 +634,9 @@
8be839c4
JR
16356 } else if ((uid != current->uid) && (uid != new_suid))
16357 return -EPERM;
16358
16359+ if (gr_check_crash_uid(uid))
16360+ return -EPERM;
16361+
16362 if (old_euid != uid)
16363 {
16364 current->mm->dumpable = 0;
474a6d91 16365@@ -713,8 +733,10 @@
8be839c4
JR
16366 current->egid = egid;
16367 }
16368 current->fsgid = current->egid;
16369- if (rgid != (gid_t) -1)
16370+ if (rgid != (gid_t) -1) {
16371+ gr_set_role_label(current, current->uid, rgid);
16372 current->gid = rgid;
16373+ }
16374 if (sgid != (gid_t) -1)
16375 current->sgid = sgid;
16376 return 0;
474a6d91 16377@@ -1137,6 +1159,10 @@
8be839c4
JR
16378 if (new_rlim.rlim_cur > new_rlim.rlim_max)
16379 return -EINVAL;
16380 old_rlim = current->rlim + resource;
16381+
16382+ if (old_rlim->rlim_max < old_rlim->rlim_cur)
16383+ return -EINVAL;
16384+
16385 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
16386 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
16387 !capable(CAP_SYS_RESOURCE))
474a6d91
AM
16388diff -urN linux-2.4.22.org/kernel/sysctl.c linux-2.4.22/kernel/sysctl.c
16389--- linux-2.4.22.org/kernel/sysctl.c 2003-11-22 22:09:08.000000000 +0100
16390+++ linux-2.4.22/kernel/sysctl.c 2003-11-22 22:14:10.000000000 +0100
16391@@ -39,6 +39,15 @@
8be839c4
JR
16392 #endif
16393
16394 #if defined(CONFIG_SYSCTL)
16395+#include <linux/grsecurity.h>
16396+#include <linux/grinternal.h>
16397+
16398+extern int gr_proc_handler(ctl_table * table, int write, struct file * filp,
16399+ void * buffer, size_t * lenp);
16400+extern __u32 gr_handle_sysctl(const ctl_table * table, const void *oldval,
16401+ const void *newval);
16402+extern int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op);
16403+extern int gr_handle_chroot_sysctl(const int op);
16404
16405 /* External variables not in a header file. */
16406 extern int panic_timeout;
474a6d91 16407@@ -130,6 +139,8 @@
8be839c4
JR
16408 static ctl_table dev_table[];
16409 extern ctl_table random_table[];
16410
16411+static ctl_table grsecurity_table[];
16412+
16413 /* /proc declarations: */
16414
16415 #ifdef CONFIG_PROC_FS
474a6d91 16416@@ -278,8 +289,191 @@
8be839c4
JR
16417 {KERN_EXCEPTION_TRACE,"exception-trace",
16418 &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
16419 #endif
16420+#ifdef CONFIG_GRKERNSEC_SYSCTL
16421+ {KERN_GRSECURITY, "grsecurity", NULL, 0, 0500, grsecurity_table},
16422+#endif
16423+ {0}
16424+};
16425+
16426+#ifdef CONFIG_GRKERNSEC_SYSCTL
16427+enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
16428+GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
16429+GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
16430+GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
16431+GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
16432+GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
16433+GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
16434+GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
16435+GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
16436+GS_FINDTASK, GS_LOCK};
16437+
16438+static ctl_table grsecurity_table[] = {
16439+#ifdef CONFIG_GRKERNSEC_LINK
16440+ {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int),
16441+ 0600, NULL, &proc_dointvec},
16442+#endif
16443+#ifdef CONFIG_GRKERNSEC_FIFO
16444+ {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int),
16445+ 0600, NULL, &proc_dointvec},
16446+#endif
16447+#ifdef CONFIG_GRKERNSEC_EXECVE
16448+ {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int),
16449+ 0600, NULL, &proc_dointvec},
16450+#endif
16451+#ifdef CONFIG_GRKERNSEC_EXECLOG
16452+ {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int),
16453+ 0600, NULL, &proc_dointvec},
16454+#endif
16455+#ifdef CONFIG_GRKERNSEC_SIGNAL
16456+ {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int),
16457+ 0600, NULL, &proc_dointvec},
16458+#endif
16459+#ifdef CONFIG_GRKERNSEC_FORKFAIL
16460+ {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int),
16461+ 0600, NULL, &proc_dointvec},
16462+#endif
16463+#ifdef CONFIG_GRKERNSEC_TIME
16464+ {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int),
16465+ 0600, NULL, &proc_dointvec},
16466+#endif
16467+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16468+ {GS_CHROOT_SHMAT, "chroot_deny_shmat", &grsec_enable_chroot_shmat, sizeof (int),
16469+ 0600, NULL, &proc_dointvec},
16470+#endif
16471+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16472+ {GS_CHROOT_UNIX, "chroot_deny_unix", &grsec_enable_chroot_unix, sizeof(int),
16473+ 0600, NULL, &proc_dointvec},
16474+#endif
16475+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16476+ {GS_CHROOT_MNT, "chroot_deny_mount", &grsec_enable_chroot_mount, sizeof (int),
16477+ 0600, NULL, &proc_dointvec},
16478+#endif
16479+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16480+ {GS_CHROOT_FCHDIR, "chroot_deny_fchdir", &grsec_enable_chroot_fchdir, sizeof (int),
16481+ 0600, NULL, &proc_dointvec},
16482+#endif
16483+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16484+ {GS_CHROOT_DBL, "chroot_deny_chroot", &grsec_enable_chroot_double, sizeof (int),
16485+ 0600, NULL, &proc_dointvec},
16486+#endif
16487+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16488+ {GS_CHROOT_PVT, "chroot_deny_pivot", &grsec_enable_chroot_pivot, sizeof (int),
16489+ 0600, NULL, &proc_dointvec},
16490+#endif
16491+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16492+ {GS_CHROOT_CD, "chroot_enforce_chdir", &grsec_enable_chroot_chdir, sizeof (int),
16493+ 0600, NULL, &proc_dointvec},
16494+#endif
16495+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16496+ {GS_CHROOT_CM, "chroot_deny_chmod", &grsec_enable_chroot_chmod, sizeof (int),
16497+ 0600, NULL, &proc_dointvec},
16498+#endif
16499+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16500+ {GS_CHROOT_MK, "chroot_deny_mknod", &grsec_enable_chroot_mknod, sizeof (int),
16501+ 0600, NULL, &proc_dointvec},
16502+#endif
16503+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16504+ {GS_CHROOT_NI, "chroot_restrict_nice", &grsec_enable_chroot_nice, sizeof (int),
16505+ 0600, NULL, &proc_dointvec},
16506+#endif
16507+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16508+ {GS_CHROOT_EXECLOG, "chroot_execlog",
16509+ &grsec_enable_chroot_execlog, sizeof (int),
16510+ 0600, NULL, &proc_dointvec},
16511+#endif
16512+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16513+ {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int),
16514+ 0600, NULL, &proc_dointvec},
16515+#endif
16516+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16517+ {GS_CHROOT_SYSCTL, "chroot_deny_sysctl", &grsec_enable_chroot_sysctl, sizeof (int),
16518+ 0600, NULL, &proc_dointvec},
16519+#endif
16520+#ifdef CONFIG_GRKERNSEC_TPE
16521+ {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int),
16522+ 0600, NULL, &proc_dointvec},
16523+ {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int),
16524+ 0600, NULL, &proc_dointvec},
16525+#endif
16526+#ifdef CONFIG_GRKERNSEC_TPE_ALL
16527+ {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int),
16528+ 0600, NULL, &proc_dointvec},
16529+#endif
16530+#ifdef CONFIG_GRKERNSEC_RANDPID
16531+ {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int),
16532+ 0600, NULL, &proc_dointvec},
16533+#endif
16534+#ifdef CONFIG_GRKERNSEC_RANDID
16535+ {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int),
16536+ 0600, NULL, &proc_dointvec},
16537+#endif
16538+#ifdef CONFIG_GRKERNSEC_RANDSRC
16539+ {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int),
16540+ 0600, NULL, &proc_dointvec},
16541+#endif
16542+#ifdef CONFIG_GRKERNSEC_RANDISN
16543+ {GS_RANDISN, "rand_isns", &grsec_enable_randisn, sizeof (int),
16544+ 0600, NULL, &proc_dointvec},
16545+#endif
16546+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
16547+ {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int),
16548+ 0600, NULL, &proc_dointvec},
16549+ {GS_SOCKET_ALL_GID, "socket_all_gid",
16550+ &grsec_socket_all_gid, sizeof (int),
16551+ 0600, NULL, &proc_dointvec},
16552+#endif
16553+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16554+ {GS_SOCKET_CLIENT, "socket_client",
16555+ &grsec_enable_socket_client, sizeof (int),
16556+ 0600, NULL, &proc_dointvec},
16557+ {GS_SOCKET_CLIENT_GID, "socket_client_gid",
16558+ &grsec_socket_client_gid, sizeof (int),
16559+ 0600, NULL, &proc_dointvec},
16560+#endif
16561+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16562+ {GS_SOCKET_SERVER, "socket_server",
16563+ &grsec_enable_socket_server, sizeof (int),
16564+ 0600, NULL, &proc_dointvec},
16565+ {GS_SOCKET_SERVER_GID, "socket_server_gid",
16566+ &grsec_socket_server_gid, sizeof (int),
16567+ 0600, NULL, &proc_dointvec},
16568+#endif
16569+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
16570+ {GS_GROUP, "audit_group", &grsec_enable_group, sizeof (int),
16571+ 0600, NULL, &proc_dointvec},
16572+ {GS_GID, "audit_gid",
16573+ &grsec_audit_gid, sizeof (int),
16574+ 0600, NULL, &proc_dointvec},
16575+#endif
16576+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16577+ {GS_ACHDIR, "audit_chdir", &grsec_enable_chdir, sizeof (int),
16578+ 0600, NULL, &proc_dointvec},
16579+#endif
16580+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16581+ {GS_AMOUNT, "audit_mount", &grsec_enable_mount, sizeof (int),
16582+ 0600, NULL, &proc_dointvec},
16583+#endif
16584+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16585+ {GS_AIPC, "audit_ipc", &grsec_enable_audit_ipc, sizeof (int),
16586+ 0600, NULL, &proc_dointvec},
16587+#endif
16588+#ifdef CONFIG_GRKERNSEC_DMESG
16589+ {GS_AIPC, "dmesg", &grsec_enable_dmesg, sizeof (int),
16590+ 0600, NULL, &proc_dointvec},
16591+#endif
16592+#ifdef CONFIG_GRKERNSEC_RANDRPC
16593+ {GS_RANDRPC, "rand_rpc", &grsec_enable_randrpc, sizeof (int),
16594+ 0600, NULL, &proc_dointvec},
16595+#endif
16596+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16597+ {GS_FINDTASK, "chroot_findtask", &grsec_enable_chroot_findtask,
16598+ sizeof (int), 0600, NULL, &proc_dointvec},
16599+#endif
16600+ {GS_LOCK, "grsec_lock", &grsec_lock, sizeof (int), 0600, NULL,
16601+ &proc_dointvec},
16602 {0}
16603 };
16604+#endif
16605
16606 static ctl_table vm_table[] = {
474a6d91
AM
16607 {VM_GFP_DEBUG, "vm_gfp_debug",
16608@@ -432,6 +626,11 @@
8be839c4
JR
16609
16610 static inline int ctl_perm(ctl_table *table, int op)
16611 {
16612+ if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
16613+ return -EACCES;
16614+ if (gr_handle_chroot_sysctl(op))
16615+ return -EACCES;
16616+
16617 return test_perm(table->mode, op);
16618 }
16619
474a6d91 16620@@ -465,6 +664,10 @@
8be839c4
JR
16621 table = table->child;
16622 goto repeat;
16623 }
16624+
16625+ if (!gr_handle_sysctl(table, oldval, newval))
16626+ return -EACCES;
16627+
16628 error = do_sysctl_strategy(table, name, nlen,
16629 oldval, oldlenp,
16630 newval, newlen, context);
474a6d91
AM
16631diff -urN linux-2.4.22.org/kernel/time.c linux-2.4.22/kernel/time.c
16632--- linux-2.4.22.org/kernel/time.c 2003-11-22 22:09:07.000000000 +0100
16633+++ linux-2.4.22/kernel/time.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
16634@@ -27,6 +27,7 @@
16635 #include <linux/mm.h>
16636 #include <linux/timex.h>
16637 #include <linux/smp_lock.h>
16638+#include <linux/grsecurity.h>
16639
16640 #include <asm/uaccess.h>
16641
16642@@ -89,6 +90,9 @@
16643 time_maxerror = NTP_PHASE_LIMIT;
16644 time_esterror = NTP_PHASE_LIMIT;
16645 write_unlock_irq(&xtime_lock);
16646+
16647+ gr_log_timechange();
16648+
16649 return 0;
16650 }
16651
16652@@ -167,6 +171,8 @@
16653 * globally block out interrupts when it runs.
16654 */
16655 do_settimeofday(tv);
16656+
16657+ gr_log_timechange();
16658 }
16659 return 0;
16660 }
474a6d91
AM
16661diff -urN linux-2.4.22.org/kernel/timer.c linux-2.4.22/kernel/timer.c
16662--- linux-2.4.22.org/kernel/timer.c 2003-11-22 22:09:08.000000000 +0100
16663+++ linux-2.4.22/kernel/timer.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
16664@@ -565,6 +565,9 @@
16665
16666 psecs = (p->times.tms_utime += user);
16667 psecs += (p->times.tms_stime += system);
16668+
16669+ gr_learn_resource(p, RLIMIT_CPU, psecs / HZ);
16670+
16671 if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
16672 /* Send SIGXCPU every second.. */
16673 if (!(psecs % HZ))
474a6d91
AM
16674diff -urN linux-2.4.22.org/Makefile linux-2.4.22/Makefile
16675--- linux-2.4.22.org/Makefile 2003-11-22 22:13:00.000000000 +0100
16676+++ linux-2.4.22/Makefile 2003-11-22 22:14:06.000000000 +0100
16677@@ -134,9 +134,10 @@
16678
16679 CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
16680 NETWORKS =net/network.o
16681+GRSECURITY =grsecurity/grsec.o
16682
16683 LIBS =$(TOPDIR)/lib/lib.a
16684-SUBDIRS =kernel drivers mm fs net ipc lib crypto
16685+SUBDIRS =kernel drivers mm fs net ipc lib crypto grsecurity
16686
16687 DRIVERS-n :=
16688 DRIVERS-y :=
16689@@ -280,7 +281,7 @@
16690
16691 export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
16692
16693-export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
16694+export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS GRSECURITY
16695
16696 .S.s:
16697 $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
16698@@ -299,6 +300,7 @@
16699 $(CORE_FILES) \
16700 $(DRIVERS) \
16701 $(NETWORKS) \
16702+ $(GRSECURITY) \
16703 $(LIBS) \
16704 --end-group \
16705 -o vmlinux
16706diff -urN linux-2.4.22.org/mm/filemap.c linux-2.4.22/mm/filemap.c
16707--- linux-2.4.22.org/mm/filemap.c 2003-11-22 22:09:09.000000000 +0100
16708+++ linux-2.4.22/mm/filemap.c 2003-11-22 22:14:11.000000000 +0100
16709@@ -2316,6 +2316,12 @@
8be839c4
JR
16710 }
16711 if (!mapping->a_ops->readpage)
16712 return -ENOEXEC;
16713+
16714+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
16715+ if (current->flags & PF_PAX_PAGEEXEC)
16716+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
16717+#endif
16718+
16719 UPDATE_ATIME(inode);
16720 vma->vm_ops = &generic_file_vm_ops;
16721 return 0;
474a6d91 16722@@ -2600,6 +2606,7 @@
8be839c4
JR
16723 error = -EIO;
16724 rlim_rss = current->rlim ? current->rlim[RLIMIT_RSS].rlim_cur :
16725 LONG_MAX; /* default: see resource.h */
16726+ gr_learn_resource(current, RLIMIT_RSS, vma->vm_mm->rss + (end - start));
16727 if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
16728 return error;
16729
474a6d91 16730@@ -3083,6 +3090,7 @@
8be839c4
JR
16731 err = -EFBIG;
16732
16733 if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
16734+ gr_learn_resource(current, RLIMIT_FSIZE, pos);
16735 if (pos >= limit) {
16736 send_sig(SIGXFSZ, current, 0);
16737 goto out;
474a6d91 16738@@ -3118,6 +3126,7 @@
8be839c4
JR
16739 */
16740
16741 if (!S_ISBLK(inode->i_mode)) {
16742+ gr_learn_resource(current, RLIMIT_FSIZE, *count + (u32)pos);
16743 if (pos >= inode->i_sb->s_maxbytes)
16744 {
16745 if (*count || pos > inode->i_sb->s_maxbytes) {
474a6d91
AM
16746diff -urN linux-2.4.22.org/mm/memory.c linux-2.4.22/mm/memory.c
16747--- linux-2.4.22.org/mm/memory.c 2003-11-22 22:09:09.000000000 +0100
16748+++ linux-2.4.22/mm/memory.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
16749@@ -925,6 +925,65 @@
16750 establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
16751 }
16752
16753+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16754+/* PaX: if vma is mirrored, synchronize the mirror's PTE
16755+ *
16756+ * mm->page_table_lock is held on entry and is not released on exit or inside
16757+ * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
16758+ */
16759+static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
16760+ unsigned long address, pte_t *pte)
16761+{
16762+ unsigned long address_m;
16763+ struct vm_area_struct * vma_m = NULL;
16764+ pte_t * pte_m, entry_m;
16765+ struct page * page_m;
16766+
16767+ if (!(vma->vm_flags & VM_MIRROR))
16768+ return;
16769+
16770+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16771+ vma_m = find_vma(mm, address_m);
16772+ if (!vma_m || vma_m->vm_start != address_m)
16773+ return;
16774+
16775+ address_m = address + (unsigned long)vma->vm_private_data;
16776+
16777+ {
16778+ pgd_t *pgd_m;
16779+ pmd_t *pmd_m;
16780+
16781+ pgd_m = pgd_offset(mm, address_m);
16782+ pmd_m = pmd_offset(pgd_m, address_m);
16783+ pte_m = pte_offset(pmd_m, address_m);
16784+ }
16785+
16786+ if (pte_present(*pte_m)) {
16787+ flush_cache_page(vma_m, address_m);
16788+ flush_icache_page(vma_m, pte_page(*pte_m));
16789+ }
16790+ entry_m = ptep_get_and_clear(pte_m);
16791+ if (pte_present(entry_m))
16792+ flush_tlb_page(vma_m, address_m);
16793+
16794+ if (pte_none(entry_m)) {
16795+ ++mm->rss;
16796+ } else if (pte_present(entry_m)) {
16797+ page_cache_release(pte_page(entry_m));
16798+ } else {
16799+ free_swap_and_cache(pte_to_swp_entry(entry_m));
16800+ ++mm->rss;
16801+ }
16802+
16803+ page_m = pte_page(*pte);
16804+ page_cache_get(page_m);
16805+ entry_m = mk_pte(page_m, vma_m->vm_page_prot);
16806+ if (pte_write(*pte))
16807+ entry_m = pte_mkdirty(pte_mkwrite(entry_m));
16808+ establish_pte(vma_m, address_m, pte_m, entry_m);
16809+}
16810+#endif
16811+
16812 /*
16813 * This routine handles present pages, when users try to write
16814 * to a shared page. It is done by copying the page to a new address
16815@@ -988,6 +1047,11 @@
16816
16817 /* Free the old page.. */
16818 new_page = old_page;
16819+
16820+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16821+ pax_mirror_fault(mm, vma, address, page_table);
16822+#endif
16823+
16824 }
16825 spin_unlock(&mm->page_table_lock);
16826 page_cache_release(new_page);
16827@@ -1065,6 +1129,7 @@
16828
16829 do_expand:
16830 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
16831+ gr_learn_resource(current, RLIMIT_FSIZE, offset);
16832 if (limit != RLIM_INFINITY && offset > limit)
16833 goto out_sig;
16834 if (offset > inode->i_sb->s_maxbytes)
16835@@ -1178,6 +1243,11 @@
16836
16837 /* No need to invalidate - it was non-present before */
16838 update_mmu_cache(vma, address, pte);
16839+
16840+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16841+ pax_mirror_fault(mm, vma, address, page_table);
16842+#endif
16843+
16844 spin_unlock(&mm->page_table_lock);
16845 return ret;
16846 }
16847@@ -1223,6 +1293,11 @@
16848
16849 /* No need to invalidate - it was non-present before */
16850 update_mmu_cache(vma, addr, entry);
16851+
16852+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16853+ pax_mirror_fault(mm, vma, addr, page_table);
16854+#endif
16855+
16856 spin_unlock(&mm->page_table_lock);
16857 return 1; /* Minor fault */
16858
474a6d91 16859@@ -1304,6 +1379,11 @@
8be839c4
JR
16860
16861 /* no need to invalidate: a not-present page shouldn't be cached */
16862 update_mmu_cache(vma, address, entry);
16863+
16864+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16865+ pax_mirror_fault(mm, vma, address, page_table);
16866+#endif
16867+
16868 spin_unlock(&mm->page_table_lock);
16869 return 2; /* Major fault */
16870 }
474a6d91 16871@@ -1368,6 +1448,11 @@
8be839c4
JR
16872 pgd_t *pgd;
16873 pmd_t *pmd;
16874
16875+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16876+ unsigned long address_m = 0UL;
16877+ struct vm_area_struct * vma_m = NULL;
16878+#endif
16879+
16880 current->state = TASK_RUNNING;
16881 pgd = pgd_offset(mm, address);
16882
474a6d91 16883@@ -1376,6 +1461,47 @@
8be839c4
JR
16884 * and the SMP-safe atomic PTE updates.
16885 */
16886 spin_lock(&mm->page_table_lock);
16887+
16888+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16889+ if (vma->vm_flags & VM_MIRROR) {
16890+ pgd_t *pgd_m;
16891+ pmd_t *pmd_m;
16892+ pte_t *pte_m;
16893+
16894+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16895+ vma_m = find_vma(mm, address_m);
16896+
16897+ /* PaX: sanity checks */
16898+ if (!vma_m) {
16899+ spin_unlock(&mm->page_table_lock);
16900+ printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
16901+ address, vma, address_m, vma_m);
16902+ return 0;
16903+ } else if (!(vma_m->vm_flags & VM_MIRROR) ||
16904+ vma_m->vm_start != address_m ||
16905+ vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
16906+ {
16907+ spin_unlock(&mm->page_table_lock);
16908+ printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
16909+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
16910+ return 0;
16911+ }
16912+
16913+ address_m = address + (unsigned long)vma->vm_private_data;
16914+ pgd_m = pgd_offset(mm, address_m);
16915+ pmd_m = pmd_alloc(mm, pgd_m, address_m);
16916+ if (!pmd_m) {
16917+ spin_unlock(&mm->page_table_lock);
16918+ return -1;
16919+ }
16920+ pte_m = pte_alloc(mm, pmd_m, address_m);
16921+ if (!pte_m) {
16922+ spin_unlock(&mm->page_table_lock);
16923+ return -1;
16924+ }
16925+ }
16926+#endif
16927+
16928 pmd = pmd_alloc(mm, pgd, address);
16929
16930 if (pmd) {
474a6d91
AM
16931diff -urN linux-2.4.22.org/mm/mlock.c linux-2.4.22/mm/mlock.c
16932--- linux-2.4.22.org/mm/mlock.c 2003-11-22 22:09:09.000000000 +0100
16933+++ linux-2.4.22/mm/mlock.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
16934@@ -114,9 +114,35 @@
16935 return 0;
16936 }
16937
16938+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
16939+static int __mlock_fixup(struct vm_area_struct * vma,
16940+ unsigned long start, unsigned long end, unsigned int newflags);
16941 static int mlock_fixup(struct vm_area_struct * vma,
16942 unsigned long start, unsigned long end, unsigned int newflags)
16943 {
16944+ if (vma->vm_flags & VM_MIRROR) {
16945+ struct vm_area_struct * vma_m;
16946+ unsigned long start_m, end_m;
16947+
16948+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
16949+ vma_m = find_vma(vma->vm_mm, start_m);
16950+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
16951+ start_m = start + (unsigned long)vma->vm_private_data;
16952+ end_m = end + (unsigned long)vma->vm_private_data;
16953+ __mlock_fixup(vma_m, start_m, end_m, newflags);
16954+ } else
16955+ printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
16956+ }
16957+ return __mlock_fixup(vma, start, end, newflags);
16958+}
16959+
16960+static int __mlock_fixup(struct vm_area_struct * vma,
16961+ unsigned long start, unsigned long end, unsigned int newflags)
16962+#else
16963+static int mlock_fixup(struct vm_area_struct * vma,
16964+ unsigned long start, unsigned long end, unsigned int newflags)
16965+#endif
16966+{
16967 int pages, retval;
16968
16969 if (newflags == vma->vm_flags)
16970@@ -209,6 +235,7 @@
16971 lock_limit >>= PAGE_SHIFT;
16972
16973 /* check against resource limits */
16974+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
16975 if (locked > lock_limit)
16976 goto out;
16977
16978@@ -276,6 +303,7 @@
16979 lock_limit >>= PAGE_SHIFT;
16980
16981 ret = -ENOMEM;
16982+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm);
16983 if (current->mm->total_vm > lock_limit)
16984 goto out;
16985
474a6d91
AM
16986diff -urN linux-2.4.22.org/mm/mmap.c linux-2.4.22/mm/mmap.c
16987--- linux-2.4.22.org/mm/mmap.c 2003-11-22 22:09:09.000000000 +0100
16988+++ linux-2.4.22/mm/mmap.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
16989@@ -14,6 +14,8 @@
16990 #include <linux/file.h>
16991 #include <linux/fs.h>
16992 #include <linux/personality.h>
16993+#include <linux/random.h>
16994+#include <linux/grsecurity.h>
16995
16996 #include <asm/uaccess.h>
16997 #include <asm/pgalloc.h>
16998@@ -168,6 +170,7 @@
16999
17000 /* Check against rlimit.. */
17001 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
17002+ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data);
17003 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
17004 goto out;
17005
17006@@ -205,6 +208,11 @@
17007 _trans(prot, PROT_WRITE, VM_WRITE) |
17008 _trans(prot, PROT_EXEC, VM_EXEC);
17009 flag_bits =
17010+
17011+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17012+ _trans(flags, MAP_MIRROR, VM_MIRROR) |
17013+#endif
17014+
17015 _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
17016 _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
17017 _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
17018@@ -401,6 +409,28 @@
17019 int error;
17020 rb_node_t ** rb_link, * rb_parent;
17021
17022+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17023+ struct vm_area_struct * vma_m = NULL;
17024+
17025+ if (flags & MAP_MIRROR) {
17026+ /* PaX: sanity checks, to be removed when proved to be stable */
17027+ if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
17028+ return -EINVAL;
17029+
17030+ vma_m = find_vma(mm, pgoff);
17031+
17032+ if (!vma_m ||
17033+ vma_m->vm_start != pgoff ||
17034+ (vma_m->vm_flags & VM_MIRROR) ||
17035+ (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
17036+ return -EINVAL;
17037+
17038+ file = vma_m->vm_file;
17039+ pgoff = vma_m->vm_pgoff;
17040+ len = vma_m->vm_end - vma_m->vm_start;
17041+ }
17042+#endif
17043+
17044 if (file && (!file->f_op || !file->f_op->mmap))
17045 return -ENODEV;
17046
17047@@ -433,10 +463,32 @@
17048 */
17049 vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
17050
17051+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
17052+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
17053+
17054+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17055+ if (current->flags & PF_PAX_MPROTECT) {
17056+ if (!file || (prot & PROT_WRITE))
17057+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
17058+ else
17059+ vm_flags &= ~VM_MAYWRITE;
17060+
17061+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
17062+ if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
17063+ vma_m->vm_flags &= ~VM_MAYWRITE;
17064+#endif
17065+
17066+ }
17067+#endif
17068+
17069+ }
17070+#endif
17071+
17072 /* mlock MCL_FUTURE? */
17073 if (vm_flags & VM_LOCKED) {
17074 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
17075 locked += len;
17076+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
17077 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
17078 return -EAGAIN;
17079 }
17080@@ -481,6 +533,9 @@
17081 }
17082 }
17083
17084+ if (!gr_acl_handle_mmap(file, prot))
17085+ return -EACCES;
17086+
17087 /* Clear old maps */
17088 munmap_back:
17089 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
17090@@ -491,10 +546,16 @@
17091 }
17092
17093 /* Check against address space limit. */
17094+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17095+ if (!(vm_flags & VM_MIRROR)) {
17096+#endif
17097+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
17098 if ((mm->total_vm << PAGE_SHIFT) + len
17099 > current->rlim[RLIMIT_AS].rlim_cur)
17100 return -ENOMEM;
17101-
17102+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17103+ }
17104+#endif
17105 /* Private writable mapping? Check memory availability.. */
17106 if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
17107 !(flags & MAP_NORESERVE) &&
17108@@ -518,6 +579,13 @@
17109 vma->vm_start = addr;
17110 vma->vm_end = addr + len;
17111 vma->vm_flags = vm_flags;
17112+
17113+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17114+ if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
17115+ vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
17116+ else
17117+#endif
17118+
17119 vma->vm_page_prot = protection_map[vm_flags & 0x0f];
17120 vma->vm_ops = NULL;
17121 vma->vm_pgoff = pgoff;
17122@@ -546,6 +614,14 @@
17123 goto free_vma;
17124 }
17125
17126+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17127+ if (flags & MAP_MIRROR) {
17128+ vma_m->vm_flags |= VM_MIRROR;
17129+ vma_m->vm_private_data = (void *)(vma->vm_start - vma_m->vm_start);
17130+ vma->vm_private_data = (void *)(vma_m->vm_start - vma->vm_start);
17131+ }
17132+#endif
17133+
17134 /* Can addr have changed??
17135 *
17136 * Answer: Yes, several device drivers can do it in their
17137@@ -581,6 +657,9 @@
17138 atomic_inc(&file->f_dentry->d_inode->i_writecount);
17139
17140 out:
17141+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17142+ if (!(flags & MAP_MIRROR))
17143+#endif
17144 mm->total_vm += len >> PAGE_SHIFT;
17145 if (vm_flags & VM_LOCKED) {
17146 mm->locked_vm += len >> PAGE_SHIFT;
17147@@ -617,20 +696,49 @@
17148 {
17149 struct vm_area_struct *vma;
17150
17151+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17152+ if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE)
17153+ return -ENOMEM;
17154+ else
17155+#endif
17156+
17157 if (len > TASK_SIZE)
17158 return -ENOMEM;
17159
17160+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
17161+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
17162+#endif
17163+
17164 if (addr) {
17165 addr = PAGE_ALIGN(addr);
17166 vma = find_vma(current->mm, addr);
17167+
17168+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17169+ if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)
17170+ return -ENOMEM;
17171+#endif
17172+
17173 if (TASK_SIZE - len >= addr &&
17174 (!vma || addr + len <= vma->vm_start))
17175 return addr;
17176 }
17177 addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
17178
17179+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
17180+ /* PaX: randomize base address if requested */
17181+ if (current->flags & PF_PAX_RANDMMAP)
17182+ addr += current->mm->delta_mmap;
17183+#endif
17184+
17185 for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
17186 /* At this point: (!vma || addr < vma->vm_end). */
17187+
17188+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17189+ if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)
17190+ return -ENOMEM;
17191+ else
17192+#endif
17193+
17194 if (TASK_SIZE - len < addr)
17195 return -ENOMEM;
17196 if (!vma || addr + len <= vma->vm_start)
17197@@ -792,6 +900,9 @@
17198 struct vm_area_struct *mpnt;
17199 unsigned long end = addr + len;
17200
17201+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17202+ if (!(area->vm_flags & VM_MIRROR))
17203+#endif
17204 area->vm_mm->total_vm -= len >> PAGE_SHIFT;
17205 if (area->vm_flags & VM_LOCKED)
17206 area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
17207@@ -917,6 +1028,83 @@
17208 }
17209 }
17210
17211+static inline struct vm_area_struct *unmap_vma(struct mm_struct *mm,
17212+ unsigned long addr, size_t len, struct vm_area_struct *mpnt,
17213+ struct vm_area_struct *extra)
17214+{
17215+ unsigned long st, end, size;
17216+ struct file *file = NULL;
17217+
17218+ st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
17219+ end = addr+len;
17220+ end = end > mpnt->vm_end ? mpnt->vm_end : end;
17221+ size = end - st;
17222+
17223+ if (mpnt->vm_flags & VM_DENYWRITE &&
17224+ (st != mpnt->vm_start || end != mpnt->vm_end) &&
17225+ (file = mpnt->vm_file) != NULL) {
17226+ atomic_dec(&file->f_dentry->d_inode->i_writecount);
17227+ }
17228+ remove_shared_vm_struct(mpnt);
17229+ zap_page_range(mm, st, size);
17230+
17231+ /*
17232+ * Fix the mapping, and free the old area if it wasn't reused.
17233+ */
17234+ extra = unmap_fixup(mm, mpnt, st, size, extra);
17235+ if (file)
17236+ atomic_inc(&file->f_dentry->d_inode->i_writecount);
17237+ return extra;
17238+}
17239+
17240+static struct vm_area_struct *unmap_vma_list(struct mm_struct *mm,
17241+ unsigned long addr, size_t len, struct vm_area_struct *free,
17242+ struct vm_area_struct *extra, struct vm_area_struct *prev)
17243+{
17244+ struct vm_area_struct *mpnt;
17245+
17246+ /* Ok - we have the memory areas we should free on the 'free' list,
17247+ * so release them, and unmap the page range..
17248+ * If the one of the segments is only being partially unmapped,
17249+ * it will put new vm_area_struct(s) into the address space.
17250+ * In that case we have to be careful with VM_DENYWRITE.
17251+ */
17252+ while ((mpnt = free) != NULL) {
17253+ free = free->vm_next;
17254+ extra = unmap_vma(mm, addr, len, mpnt, extra);
17255+ }
17256+
17257+ free_pgtables(mm, prev, addr, addr+len);
17258+
17259+ return extra;
17260+}
17261+
17262+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17263+static struct vm_area_struct *unmap_vma_mirror_list(struct mm_struct *mm,
17264+ unsigned long addr, size_t len, struct vm_area_struct *free_m,
17265+ struct vm_area_struct *extra_m)
17266+{
17267+ struct vm_area_struct *mpnt, *prev;
17268+
17269+ while ((mpnt = free_m) != NULL) {
17270+ unsigned long addr_m, start, end;
17271+
17272+ free_m = free_m->vm_next;
17273+
17274+ addr_m = addr - (unsigned long)mpnt->vm_private_data;
17275+ start = addr_m < mpnt->vm_start ? mpnt->vm_start : addr_m;
17276+ end = addr_m+len;
17277+ end = end > mpnt->vm_end ? mpnt->vm_end : end;
17278+ find_vma_prev(mm, mpnt->vm_start, &prev);
17279+ extra_m = unmap_vma(mm, addr_m, len, mpnt, extra_m);
17280+
17281+ free_pgtables(mm, prev, start, end);
17282+ }
17283+
17284+ return extra_m;
17285+}
17286+#endif
17287+
17288 /* Munmap is split into 2 main parts -- this part which finds
17289 * what needs doing, and the areas themselves, which do the
17290 * work. This now handles partial unmappings.
17291@@ -926,6 +1114,10 @@
17292 {
17293 struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
17294
17295+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17296+ struct vm_area_struct *free_m, *extra_m;
17297+#endif
17298+
17299 if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr)
17300 return -EINVAL;
17301
17302@@ -958,60 +1150,69 @@
17303 if (!extra)
17304 return -ENOMEM;
17305
17306+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17307+ if (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) {
17308+ extra_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
17309+ if (!extra_m) {
17310+ kmem_cache_free(vm_area_cachep, extra);
17311+ return -ENOMEM;
17312+ }
17313+ } else
17314+ extra_m = NULL;
17315+
17316+ free_m = NULL;
17317+#endif
17318+
17319 npp = (prev ? &prev->vm_next : &mm->mmap);
17320 free = NULL;
17321 spin_lock(&mm->page_table_lock);
17322 for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) {
17323+ mm->map_count--;
17324 *npp = mpnt->vm_next;
17325 mpnt->vm_next = free;
17326 free = mpnt;
17327 rb_erase(&mpnt->vm_rb, &mm->mm_rb);
17328+
17329+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17330+ if (free->vm_flags & VM_MIRROR) {
17331+ struct vm_area_struct *mpnt_m, *prev_m, **npp_m;
17332+ unsigned long addr_m = free->vm_start + (unsigned long)free->vm_private_data;
17333+
17334+ mm->mmap_cache = NULL; /* Kill the cache. */
17335+ mpnt_m = find_vma_prev(mm, addr_m, &prev_m);
17336+ if (mpnt_m && mpnt_m->vm_start == addr_m && (mpnt_m->vm_flags & VM_MIRROR)) {
17337+ mm->map_count--;
17338+ npp_m = (prev_m ? &prev_m->vm_next : &mm->mmap);
17339+ *npp_m = mpnt_m->vm_next;
17340+ mpnt_m->vm_next = free_m;
17341+ free_m = mpnt_m;
17342+ rb_erase(&mpnt_m->vm_rb, &mm->mm_rb);
17343+ } else
17344+ printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, free->vm_start);
17345+ }
17346+#endif
17347+
17348 }
17349 mm->mmap_cache = NULL; /* Kill the cache. */
17350 spin_unlock(&mm->page_table_lock);
17351
17352- /* Ok - we have the memory areas we should free on the 'free' list,
17353- * so release them, and unmap the page range..
17354- * If the one of the segments is only being partially unmapped,
17355- * it will put new vm_area_struct(s) into the address space.
17356- * In that case we have to be careful with VM_DENYWRITE.
17357- */
17358- while ((mpnt = free) != NULL) {
17359- unsigned long st, end, size;
17360- struct file *file = NULL;
17361-
17362- free = free->vm_next;
17363+ extra = unmap_vma_list(mm, addr, len, free, extra, prev);
17364
17365- st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
17366- end = addr+len;
17367- end = end > mpnt->vm_end ? mpnt->vm_end : end;
17368- size = end - st;
17369-
17370- if (mpnt->vm_flags & VM_DENYWRITE &&
17371- (st != mpnt->vm_start || end != mpnt->vm_end) &&
17372- (file = mpnt->vm_file) != NULL) {
17373- atomic_dec(&file->f_dentry->d_inode->i_writecount);
17374- }
17375- remove_shared_vm_struct(mpnt);
17376- mm->map_count--;
17377-
17378- zap_page_range(mm, st, size);
17379+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17380+ extra_m = unmap_vma_mirror_list(mm, addr, len, free_m, extra_m);
17381+#endif
17382
17383- /*
17384- * Fix the mapping, and free the old area if it wasn't reused.
17385- */
17386- extra = unmap_fixup(mm, mpnt, st, size, extra);
17387- if (file)
17388- atomic_inc(&file->f_dentry->d_inode->i_writecount);
17389- }
17390 validate_mm(mm);
17391
17392+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17393+ if (extra_m)
17394+ kmem_cache_free(vm_area_cachep, extra_m);
17395+#endif
17396+
17397 /* Release the extra vma struct if it wasn't used */
17398 if (extra)
17399 kmem_cache_free(vm_area_cachep, extra);
17400
17401- free_pgtables(mm, prev, addr, addr+len);
17402-
17403 return 0;
17404 }
17405
17406@@ -1020,8 +1221,15 @@
17407 int ret;
17408 struct mm_struct *mm = current->mm;
17409
17410+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17411+ if ((current->flags & PF_PAX_SEGMEXEC) &&
17412+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
17413+ return -EINVAL;
17414+#endif
17415+
17416 down_write(&mm->mmap_sem);
17417 ret = do_munmap(mm, addr, len);
17418+
17419 up_write(&mm->mmap_sem);
17420 return ret;
17421 }
474a6d91 17422@@ -1051,6 +1259,7 @@
8be839c4
JR
17423 if (mm->def_flags & VM_LOCKED) {
17424 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
17425 locked += len;
17426+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
17427 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
17428 return -EAGAIN;
17429 }
474a6d91 17430@@ -1067,6 +1276,7 @@
8be839c4
JR
17431 }
17432
17433 /* Check against address space limits *after* clearing old maps... */
17434+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
17435 if ((mm->total_vm << PAGE_SHIFT) + len
17436 > current->rlim[RLIMIT_AS].rlim_cur)
17437 return -ENOMEM;
474a6d91 17438@@ -1079,6 +1289,17 @@
8be839c4
JR
17439
17440 flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
17441
17442+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
17443+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
17444+ flags &= ~VM_EXEC;
17445+
17446+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17447+ if (current->flags & PF_PAX_MPROTECT)
17448+ flags &= ~VM_MAYEXEC;
17449+#endif
17450+
17451+ }
17452+#endif
17453 /* Can we just expand an old anonymous mapping? */
17454 if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
17455 goto out;
474a6d91 17456@@ -1094,6 +1315,12 @@
8be839c4
JR
17457 vma->vm_start = addr;
17458 vma->vm_end = addr + len;
17459 vma->vm_flags = flags;
17460+
17461+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17462+ if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
17463+ vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
17464+ else
17465+#endif
17466 vma->vm_page_prot = protection_map[flags & 0x0f];
17467 vma->vm_ops = NULL;
17468 vma->vm_pgoff = 0;
474a6d91
AM
17469diff -urN linux-2.4.22.org/mm/mprotect.c linux-2.4.22/mm/mprotect.c
17470--- linux-2.4.22.org/mm/mprotect.c 2003-11-22 22:09:09.000000000 +0100
17471+++ linux-2.4.22/mm/mprotect.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
17472@@ -7,6 +7,12 @@
17473 #include <linux/smp_lock.h>
17474 #include <linux/shm.h>
17475 #include <linux/mman.h>
17476+#include <linux/grsecurity.h>
17477+
17478+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17479+#include <linux/elf.h>
17480+#include <linux/fs.h>
17481+#endif
17482
17483 #include <asm/uaccess.h>
17484 #include <asm/pgalloc.h>
17485@@ -236,9 +242,40 @@
17486 return 0;
17487 }
17488
17489+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17490+static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17491+ unsigned long start, unsigned long end, unsigned int newflags);
17492+
17493 static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17494 unsigned long start, unsigned long end, unsigned int newflags)
17495 {
17496+ if (vma->vm_flags & VM_MIRROR) {
17497+ struct vm_area_struct * vma_m, * prev_m;
17498+ unsigned long start_m, end_m;
17499+
17500+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
17501+ vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
17502+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
17503+ start_m = start + (unsigned long)vma->vm_private_data;
17504+ end_m = end + (unsigned long)vma->vm_private_data;
17505+ if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
17506+ __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
17507+ else
17508+ __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
17509+ } else
17510+ printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
17511+ }
17512+
17513+ return __mprotect_fixup(vma, pprev, start, end, newflags);
17514+}
17515+
17516+static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17517+ unsigned long start, unsigned long end, unsigned int newflags)
17518+#else
17519+static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
17520+ unsigned long start, unsigned long end, unsigned int newflags)
17521+#endif
17522+{
17523 pgprot_t newprot;
17524 int error;
17525
17526@@ -246,6 +283,12 @@
17527 *pprev = vma;
17528 return 0;
17529 }
17530+
17531+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
17532+ if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
17533+ newprot = protection_map[(newflags | VM_EXEC) & 0xf];
17534+ else
17535+#endif
17536 newprot = protection_map[newflags & 0xf];
17537 if (start == vma->vm_start) {
17538 if (end == vma->vm_end)
17539@@ -264,6 +307,68 @@
17540 return 0;
17541 }
17542
17543+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17544+/* PaX: non-PIC ELF libraries need relocations on their executable segments
17545+ * therefore we'll grant them VM_MAYWRITE once during their life.
17546+ *
17547+ * The checks favor ld-linux.so behaviour which operates on a per ELF segment
17548+ * basis because we want to allow the common case and not the special ones.
17549+ */
17550+static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
17551+{
17552+ struct elfhdr elf_h;
17553+ struct elf_phdr elf_p, p_dyn;
17554+ elf_dyn dyn;
17555+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
17556+
17557+#ifndef CONFIG_GRKERNSEC_PAX_NOELFRELOCS
17558+ if ((vma->vm_start != start) ||
17559+ !vma->vm_file ||
17560+ !(vma->vm_flags & VM_MAYEXEC) ||
17561+ (vma->vm_flags & VM_MAYNOTWRITE))
17562+#endif
17563+
17564+ return;
17565+
17566+ if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
17567+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
17568+
17569+#ifdef CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
17570+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
17571+#else
17572+ elf_h.e_type != ET_DYN ||
17573+#endif
17574+
17575+ !elf_check_arch(&elf_h) ||
17576+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
17577+ elf_h.e_phnum > j)
17578+ return;
17579+
17580+ for (i = 0UL; i < elf_h.e_phnum; i++) {
17581+ if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
17582+ return;
17583+ if (elf_p.p_type == PT_DYNAMIC) {
17584+ p_dyn = elf_p;
17585+ j = i;
17586+ }
17587+ }
17588+ if (elf_h.e_phnum <= j)
17589+ return;
17590+
17591+ i = 0UL;
17592+ do {
17593+ if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
17594+ return;
17595+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
17596+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
17597+ return;
17598+ }
17599+ i++;
17600+ } while (dyn.d_tag != DT_NULL);
17601+ return;
17602+}
17603+#endif
17604+
17605 long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
17606 unsigned long prot)
17607 {
17608@@ -289,6 +394,16 @@
17609 if (!vma || vma->vm_start > start)
17610 goto out;
17611
17612+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
17613+ error = -EACCES;
17614+ goto out;
17615+ }
17616+
17617+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17618+ if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
17619+ pax_handle_maywrite(vma, start);
17620+#endif
17621+
17622 for (nstart = start ; ; ) {
17623 unsigned int newflags;
17624 int last = 0;
17625@@ -306,6 +421,13 @@
17626 if (error < 0)
17627 goto out;
17628 }
17629+
17630+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
17631+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
17632+ if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
17633+ newflags &= ~VM_MAYWRITE;
17634+#endif
17635+
17636 if (vma->vm_end > end) {
17637 error = mprotect_fixup(vma, &prev, nstart, end, newflags);
17638 goto out;
474a6d91
AM
17639diff -urN linux-2.4.22.org/mm/mremap.c linux-2.4.22/mm/mremap.c
17640--- linux-2.4.22.org/mm/mremap.c 2003-11-22 22:09:09.000000000 +0100
17641+++ linux-2.4.22/mm/mremap.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
17642@@ -193,7 +193,9 @@
17643 }
17644
17645 do_munmap(current->mm, addr, old_len);
17646-
17647+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17648+ if (!(new_vma->vm_flags & VM_MIRROR))
17649+#endif
17650 current->mm->total_vm += new_len >> PAGE_SHIFT;
17651 if (vm_locked) {
17652 current->mm->locked_vm += new_len >> PAGE_SHIFT;
17653@@ -232,6 +234,13 @@
17654 old_len = PAGE_ALIGN(old_len);
17655 new_len = PAGE_ALIGN(new_len);
17656
17657+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17658+ if ((current->flags & PF_PAX_SEGMEXEC) &&
17659+ (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
17660+ old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len))
17661+ goto out;
17662+#endif
17663+
17664 /* new_addr is only valid if MREMAP_FIXED is specified */
17665 if (flags & MREMAP_FIXED) {
17666 if (new_addr & ~PAGE_MASK)
17667@@ -242,6 +251,12 @@
17668 if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
17669 goto out;
17670
17671+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
17672+ if ((current->flags & PF_PAX_SEGMEXEC) &&
17673+ (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len))
17674+ goto out;
17675+#endif
17676+
17677 /* Check if the location we're moving into overlaps the
17678 * old location at all, and fail if it does.
17679 */
17680@@ -272,6 +287,13 @@
17681 vma = find_vma(current->mm, addr);
17682 if (!vma || vma->vm_start > addr)
17683 goto out;
17684+
17685+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17686+ if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
17687+ (vma->vm_flags & VM_MIRROR))
17688+ return -EINVAL;
17689+#endif
17690+
17691 /* We can't remap across vm area boundaries */
17692 if (old_len > vma->vm_end - addr)
17693 goto out;
17694@@ -283,13 +305,22 @@
17695 unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
17696 locked += new_len - old_len;
17697 ret = -EAGAIN;
17698+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
17699 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
17700 goto out;
17701 }
17702 ret = -ENOMEM;
17703+
17704+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17705+ if (!(vma->vm_flags & VM_MIRROR)) {
17706+#endif
17707+ gr_learn_resource(current, RLIMIT_AS, (current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len));
17708 if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
17709 > current->rlim[RLIMIT_AS].rlim_cur)
17710 goto out;
17711+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17712+ }
17713+#endif
17714 /* Private writable mapping? Check memory availability.. */
17715 if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
17716 !(flags & MAP_NORESERVE) &&
17717@@ -311,6 +342,9 @@
17718 spin_lock(&vma->vm_mm->page_table_lock);
17719 vma->vm_end = addr + new_len;
17720 spin_unlock(&vma->vm_mm->page_table_lock);
17721+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
17722+ if (!(vma->vm_flags & VM_MIRROR))
17723+#endif
17724 current->mm->total_vm += pages;
17725 if (vma->vm_flags & VM_LOCKED) {
17726 current->mm->locked_vm += pages;
474a6d91
AM
17727diff -urN linux-2.4.22.org/net/ipv4/af_inet.c linux-2.4.22/net/ipv4/af_inet.c
17728--- linux-2.4.22.org/net/ipv4/af_inet.c 2003-11-22 22:10:02.000000000 +0100
17729+++ linux-2.4.22/net/ipv4/af_inet.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
17730@@ -83,6 +83,7 @@
17731 #include <linux/init.h>
17732 #include <linux/poll.h>
17733 #include <linux/netfilter_ipv4.h>
17734+#include <linux/grsecurity.h>
17735
17736 #include <asm/uaccess.h>
17737 #include <asm/system.h>
17738@@ -374,7 +375,12 @@
17739 else
17740 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
17741
17742- sk->protinfo.af_inet.id = 0;
17743+#ifdef CONFIG_GRKERNSEC_RANDID
17744+ if(grsec_enable_randid)
17745+ sk->protinfo.af_inet.id = htons(ip_randomid());
17746+ else
17747+#endif
17748+ sk->protinfo.af_inet.id = 0;
17749
17750 sock_init_data(sock,sk);
17751
474a6d91
AM
17752diff -urN linux-2.4.22.org/net/ipv4/icmp.c linux-2.4.22/net/ipv4/icmp.c
17753--- linux-2.4.22.org/net/ipv4/icmp.c 2003-11-22 22:09:53.000000000 +0100
17754+++ linux-2.4.22/net/ipv4/icmp.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
17755@@ -87,6 +87,8 @@
17756 #include <linux/errno.h>
17757 #include <linux/timer.h>
17758 #include <linux/init.h>
17759+#include <linux/grsecurity.h>
17760+
17761 #include <asm/system.h>
17762 #include <asm/uaccess.h>
17763 #include <net/checksum.h>
474a6d91 17764@@ -723,6 +725,7 @@
8be839c4
JR
17765
17766 icmp_param.data.icmph=*skb->h.icmph;
17767 icmp_param.data.icmph.type=ICMP_ECHOREPLY;
17768+
17769 icmp_param.skb=skb;
17770 icmp_param.offset=0;
17771 icmp_param.data_len=skb->len;
474a6d91
AM
17772diff -urN linux-2.4.22.org/net/ipv4/ip_output.c linux-2.4.22/net/ipv4/ip_output.c
17773--- linux-2.4.22.org/net/ipv4/ip_output.c 2003-11-22 22:10:02.000000000 +0100
17774+++ linux-2.4.22/net/ipv4/ip_output.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
17775@@ -77,6 +77,7 @@
17776 #include <linux/netfilter_ipv4.h>
17777 #include <linux/mroute.h>
17778 #include <linux/netlink.h>
17779+#include <linux/grsecurity.h>
17780
17781 /*
17782 * Shall we try to damage output packets if routing dev changes?
17783@@ -514,7 +515,13 @@
17784 * Begin outputting the bytes.
17785 */
17786
17787- id = sk->protinfo.af_inet.id++;
17788+#ifdef CONFIG_GRKERNSEC_RANDID
17789+ if(grsec_enable_randid) {
17790+ id = htons(ip_randomid());
17791+ sk->protinfo.af_inet.id = htons(ip_randomid());
17792+ } else
17793+#endif
17794+ id = sk->protinfo.af_inet.id++;
17795
17796 do {
17797 char *data;
474a6d91
AM
17798diff -urN linux-2.4.22.org/net/ipv4/netfilter/Config.in linux-2.4.22/net/ipv4/netfilter/Config.in
17799--- linux-2.4.22.org/net/ipv4/netfilter/Config.in 2003-11-22 22:10:02.000000000 +0100
17800+++ linux-2.4.22/net/ipv4/netfilter/Config.in 2003-11-22 22:14:11.000000000 +0100
17801@@ -69,6 +69,7 @@
8be839c4
JR
17802 dep_tristate ' TTL match support' CONFIG_IP_NF_MATCH_TTL $CONFIG_IP_NF_IPTABLES
17803 dep_tristate ' address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES
17804 dep_tristate ' tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES
17805+ dep_tristate ' stealth match support' CONFIG_IP_NF_MATCH_STEALTH $CONFIG_IP_NF_IPTABLES
17806 dep_tristate ' realm match support' CONFIG_IP_NF_MATCH_REALM $CONFIG_IP_NF_IPTABLES
17807 if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
17808 dep_tristate ' Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES
474a6d91
AM
17809diff -urN linux-2.4.22.org/net/ipv4/netfilter/ipt_stealth.c linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c
17810--- linux-2.4.22.org/net/ipv4/netfilter/ipt_stealth.c 1970-01-01 01:00:00.000000000 +0100
17811+++ linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
17812@@ -0,0 +1,109 @@
17813+/* Kernel module to add stealth support.
17814+ *
17815+ * Copyright (C) 2002 Brad Spengler <spender@grsecurity.net>
17816+ *
17817+ */
17818+
17819+#include <linux/kernel.h>
17820+#include <linux/module.h>
17821+#include <linux/skbuff.h>
17822+#include <linux/net.h>
17823+#include <linux/sched.h>
17824+#include <linux/inet.h>
17825+#include <linux/stddef.h>
17826+
17827+#include <net/ip.h>
17828+#include <net/sock.h>
17829+#include <net/tcp.h>
17830+#include <net/udp.h>
17831+#include <net/route.h>
17832+#include <net/inet_common.h>
17833+
17834+#include <linux/netfilter_ipv4/ip_tables.h>
17835+
17836+MODULE_LICENSE("GPL");
17837+
17838+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
17839+
17840+static int
17841+match(const struct sk_buff *skb,
17842+ const struct net_device *in,
17843+ const struct net_device *out,
17844+ const void *matchinfo,
17845+ int offset,
17846+ const void *hdr,
17847+ u_int16_t datalen,
17848+ int *hotdrop)
17849+{
17850+ struct iphdr *ip = skb->nh.iph;
17851+ struct tcphdr *th = (struct tcphdr *) hdr;
17852+ struct udphdr *uh = (struct udphdr *) hdr;
17853+ struct sock *sk = NULL;
17854+
17855+ if (!ip || !hdr || offset) return 0;
17856+
17857+ switch(ip->protocol) {
17858+ case IPPROTO_TCP:
17859+ if (datalen < sizeof(struct tcphdr)) {
17860+ *hotdrop = 1;
17861+ return 0;
17862+ }
17863+ if (!(th->syn && !th->ack)) return 0;
17864+ sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th->dest), ((struct rtable*)skb->dst)->rt_iif);
17865+ break;
17866+ case IPPROTO_UDP:
17867+ if (datalen < sizeof(struct udphdr)) {
17868+ *hotdrop = 1;
17869+ return 0;
17870+ }
17871+ sk = udp_v4_lookup(ip->saddr, uh->source, ip->daddr, uh->dest, skb->dev->ifindex);
17872+ break;
17873+ default:
17874+ return 0;
17875+ }
17876+
17877+ if(!sk) // port is being listened on, match this
17878+ return 1;
17879+ else {
17880+ sock_put(sk);
17881+ return 0;
17882+ }
17883+}
17884+
17885+/* Called when user tries to insert an entry of this type. */
17886+static int
17887+checkentry(const char *tablename,
17888+ const struct ipt_ip *ip,
17889+ void *matchinfo,
17890+ unsigned int matchsize,
17891+ unsigned int hook_mask)
17892+{
17893+ if (matchsize != IPT_ALIGN(0))
17894+ return 0;
17895+
17896+ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
17897+ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
17898+ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
17899+ return 1;
17900+
17901+ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
17902+
17903+ return 0;
17904+}
17905+
17906+
17907+static struct ipt_match stealth_match
17908+= { { NULL, NULL }, "stealth", &match, &checkentry, NULL, THIS_MODULE };
17909+
17910+static int __init init(void)
17911+{
17912+ return ipt_register_match(&stealth_match);
17913+}
17914+
17915+static void __exit fini(void)
17916+{
17917+ ipt_unregister_match(&stealth_match);
17918+}
17919+
17920+module_init(init);
17921+module_exit(fini);
474a6d91
AM
17922diff -urN linux-2.4.22.org/net/ipv4/netfilter/Makefile linux-2.4.22/net/ipv4/netfilter/Makefile
17923--- linux-2.4.22.org/net/ipv4/netfilter/Makefile 2003-11-22 22:10:02.000000000 +0100
17924+++ linux-2.4.22/net/ipv4/netfilter/Makefile 2003-11-22 22:14:11.000000000 +0100
17925@@ -176,6 +176,7 @@
17926 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
17927 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
17928 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
17929+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
17930
17931 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
17932
17933diff -urN linux-2.4.22.org/net/ipv4/tcp_ipv4.c linux-2.4.22/net/ipv4/tcp_ipv4.c
17934--- linux-2.4.22.org/net/ipv4/tcp_ipv4.c 2003-11-22 22:09:53.000000000 +0100
17935+++ linux-2.4.22/net/ipv4/tcp_ipv4.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
17936@@ -67,6 +67,7 @@
17937 #include <linux/inet.h>
17938 #include <linux/stddef.h>
17939 #include <linux/ipsec.h>
17940+#include <linux/grsecurity.h>
17941
17942 extern int sysctl_ip_dynaddr;
17943 extern int sysctl_ip_default_ttl;
474a6d91 17944@@ -223,9 +224,18 @@
8be839c4
JR
17945
17946 spin_lock(&tcp_portalloc_lock);
17947 rover = tcp_port_rover;
17948- do { rover++;
17949- if ((rover < low) || (rover > high))
17950- rover = low;
17951+ do {
17952+#ifdef CONFIG_GRKERNSEC_RANDSRC
17953+ if (grsec_enable_randsrc && (high > low)) {
17954+ rover = low + (get_random_long() % (high - low));
17955+ } else
17956+#endif
17957+ {
17958+ rover++;
17959+ if ((rover < low) || (rover > high))
17960+ rover = low;
17961+ }
17962+
17963 head = &tcp_bhash[tcp_bhashfn(rover)];
17964 spin_lock(&head->lock);
17965 for (tb = head->chain; tb; tb = tb->next)
474a6d91 17966@@ -548,6 +558,11 @@
8be839c4
JR
17967
17968 static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
17969 {
17970+#ifdef CONFIG_GRKERNSEC_RANDISN
17971+ if (likely(grsec_enable_randisn))
17972+ return ip_randomisn();
17973+ else
17974+#endif
17975 return secure_tcp_sequence_number(skb->nh.iph->daddr,
17976 skb->nh.iph->saddr,
17977 skb->h.th->dest,
474a6d91 17978@@ -683,9 +698,16 @@
8be839c4
JR
17979 rover = tcp_port_rover;
17980
17981 do {
17982- rover++;
17983- if ((rover < low) || (rover > high))
17984- rover = low;
17985+#ifdef CONFIG_GRKERNSEC_RANDSRC
17986+ if(grsec_enable_randsrc && (high > low)) {
17987+ rover = low + (get_random_long() % (high - low));
17988+ } else
17989+#endif
17990+ {
17991+ rover++;
17992+ if ((rover < low) || (rover > high))
17993+ rover = low;
17994+ }
17995 head = &tcp_bhash[tcp_bhashfn(rover)];
17996 spin_lock(&head->lock);
17997
474a6d91 17998@@ -846,11 +868,22 @@
8be839c4
JR
17999 if (err)
18000 goto failure;
18001
18002- if (!tp->write_seq)
18003+ if (!tp->write_seq) {
18004+#ifdef CONFIG_GRKERNSEC_RANDISN
18005+ if (likely(grsec_enable_randisn))
18006+ tp->write_seq = ip_randomisn();
18007+ else
18008+#endif
18009 tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
18010 sk->sport, usin->sin_port);
18011+ }
18012
18013- sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18014+#ifdef CONFIG_GRKERNSEC_RANDID
18015+ if(grsec_enable_randid)
18016+ sk->protinfo.af_inet.id = htons(ip_randomid());
18017+ else
18018+#endif
18019+ sk->protinfo.af_inet.id = tp->write_seq^jiffies;
18020
18021 err = tcp_connect(sk);
18022 if (err)
474a6d91 18023@@ -1572,7 +1605,13 @@
8be839c4
JR
18024 newtp->ext_header_len = 0;
18025 if (newsk->protinfo.af_inet.opt)
18026 newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen;
18027- newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18028+
18029+#ifdef CONFIG_GRKERNSEC_RANDID
18030+ if(grsec_enable_randid)
18031+ newsk->protinfo.af_inet.id = htons(ip_randomid());
18032+ else
18033+#endif
18034+ newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
18035
18036 tcp_sync_mss(newsk, dst->pmtu);
18037 newtp->advmss = dst->advmss;
474a6d91
AM
18038diff -urN linux-2.4.22.org/net/ipv4/udp.c linux-2.4.22/net/ipv4/udp.c
18039--- linux-2.4.22.org/net/ipv4/udp.c 2003-11-22 22:09:53.000000000 +0100
18040+++ linux-2.4.22/net/ipv4/udp.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
18041@@ -91,6 +91,7 @@
18042 #include <net/ipv6.h>
18043 #include <net/protocol.h>
18044 #include <linux/skbuff.h>
18045+#include <linux/grsecurity.h>
18046 #include <net/sock.h>
18047 #include <net/udp.h>
18048 #include <net/icmp.h>
18049@@ -98,6 +99,11 @@
18050 #include <net/inet_common.h>
18051 #include <net/checksum.h>
18052
18053+extern int gr_search_udp_recvmsg(const struct sock *sk,
18054+ const struct sk_buff *skb);
18055+extern int gr_search_udp_sendmsg(const struct sock *sk,
18056+ const struct sockaddr_in *addr);
18057+
18058 /*
18059 * Snmp MIB for the UDP layer
18060 */
474a6d91 18061@@ -480,9 +486,16 @@
8be839c4
JR
18062 ufh.uh.dest = usin->sin_port;
18063 if (ufh.uh.dest == 0)
18064 return -EINVAL;
18065+
18066+ if (!gr_search_udp_sendmsg(sk, usin))
18067+ return -EPERM;
18068 } else {
18069 if (sk->state != TCP_ESTABLISHED)
18070 return -EDESTADDRREQ;
18071+
18072+ if (!gr_search_udp_sendmsg(sk, NULL))
18073+ return -EPERM;
18074+
18075 ufh.daddr = sk->daddr;
18076 ufh.uh.dest = sk->dport;
18077 /* Open fast path for connected socket.
474a6d91 18078@@ -490,6 +503,7 @@
8be839c4
JR
18079 */
18080 connected = 1;
18081 }
18082+
18083 ipc.addr = sk->saddr;
18084 ufh.uh.source = sk->sport;
18085
474a6d91 18086@@ -661,6 +675,11 @@
8be839c4
JR
18087 if (!skb)
18088 goto out;
18089
18090+ if (!gr_search_udp_recvmsg(sk, skb)) {
18091+ err = -EPERM;
18092+ goto out_free;
18093+ }
18094+
18095 copied = skb->len - sizeof(struct udphdr);
18096 if (copied > len) {
18097 copied = len;
474a6d91 18098@@ -765,7 +784,13 @@
8be839c4
JR
18099 sk->daddr = rt->rt_dst;
18100 sk->dport = usin->sin_port;
18101 sk->state = TCP_ESTABLISHED;
18102- sk->protinfo.af_inet.id = jiffies;
18103+
18104+#ifdef CONFIG_GRKERNSEC_RANDID
18105+ if(grsec_enable_randid)
18106+ sk->protinfo.af_inet.id = htons(ip_randomid());
18107+ else
18108+#endif
18109+ sk->protinfo.af_inet.id = jiffies;
18110
18111 sk_dst_set(sk, &rt->u.dst);
18112 return(0);
474a6d91
AM
18113diff -urN linux-2.4.22.org/net/netlink/af_netlink.c linux-2.4.22/net/netlink/af_netlink.c
18114--- linux-2.4.22.org/net/netlink/af_netlink.c 2003-11-22 22:10:04.000000000 +0100
18115+++ linux-2.4.22/net/netlink/af_netlink.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
18116@@ -40,6 +40,7 @@
18117 #include <linux/proc_fs.h>
18118 #include <linux/smp_lock.h>
18119 #include <linux/notifier.h>
18120+#include <linux/grsecurity.h>
18121 #include <net/sock.h>
18122 #include <net/scm.h>
18123
18124@@ -625,7 +626,8 @@
18125 check them, when this message will be delivered
18126 to corresponding kernel module. --ANK (980802)
18127 */
18128- NETLINK_CB(skb).eff_cap = current->cap_effective;
18129+
18130+ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
18131
18132 err = -EFAULT;
18133 if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
474a6d91
AM
18134diff -urN linux-2.4.22.org/net/netsyms.c linux-2.4.22/net/netsyms.c
18135--- linux-2.4.22.org/net/netsyms.c 2003-11-22 22:10:06.000000000 +0100
18136+++ linux-2.4.22/net/netsyms.c 2003-11-22 22:14:11.000000000 +0100
18137@@ -25,6 +25,7 @@
8be839c4
JR
18138 #include <net/checksum.h>
18139 #include <linux/etherdevice.h>
18140 #include <net/route.h>
18141+#include <linux/grsecurity.h>
18142 #ifdef CONFIG_HIPPI
18143 #include <linux/hippidevice.h>
18144 #endif
f6c0171e 18145@@ -614,6 +615,49 @@
8be839c4
JR
18146
18147 EXPORT_SYMBOL(softnet_data);
18148
18149+#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
18150+#if !defined (CONFIG_IPV6_MODULE) && !defined (CONFIG_KHTTPD) && !defined (CONFIG_KHTTPD_MODULE)
18151+EXPORT_SYMBOL(tcp_v4_lookup_listener);
18152+#endif
18153+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
8be839c4
JR
18154+EXPORT_SYMBOL(udp_v4_lookup);
18155+#endif
8be839c4
JR
18156+
18157+#if defined(CONFIG_GRKERNSEC_RANDID)
18158+EXPORT_SYMBOL(ip_randomid);
18159+#endif
18160+#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
18161+EXPORT_SYMBOL(get_random_long);
18162+#endif
18163+#ifdef CONFIG_GRKERNSEC_RANDISN
18164+EXPORT_SYMBOL(ip_randomisn);
18165+EXPORT_SYMBOL(grsec_enable_randisn);
18166+#endif
18167+#ifdef CONFIG_GRKERNSEC_RANDID
18168+EXPORT_SYMBOL(grsec_enable_randid);
18169+#endif
18170+#ifdef CONFIG_GRKERNSEC_RANDSRC
18171+EXPORT_SYMBOL(grsec_enable_randsrc);
18172+#endif
18173+#ifdef CONFIG_GRKERNSEC_RANDRPC
18174+EXPORT_SYMBOL(grsec_enable_randrpc);
18175+#endif
18176+
18177+EXPORT_SYMBOL(gr_cap_rtnetlink);
18178+
18179+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
18180+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
18181+
18182+EXPORT_SYMBOL(gr_search_udp_recvmsg);
18183+EXPORT_SYMBOL(gr_search_udp_sendmsg);
18184+
18185+#ifdef CONFIG_UNIX_MODULE
18186+EXPORT_SYMBOL(gr_acl_handle_unix);
18187+EXPORT_SYMBOL(gr_acl_handle_mknod);
18188+EXPORT_SYMBOL(gr_handle_chroot_unix);
18189+EXPORT_SYMBOL(gr_handle_create);
18190+#endif
18191+
18192 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
18193 #include <net/iw_handler.h>
18194 EXPORT_SYMBOL(wireless_send_event);
474a6d91
AM
18195diff -urN linux-2.4.22.org/net/socket.c linux-2.4.22/net/socket.c
18196--- linux-2.4.22.org/net/socket.c 2003-11-22 22:09:53.000000000 +0100
18197+++ linux-2.4.22/net/socket.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
18198@@ -85,6 +85,18 @@
18199 #include <net/scm.h>
18200 #include <linux/netfilter.h>
18201
18202+extern void gr_attach_curr_ip(const struct sock *sk);
18203+extern int gr_handle_sock_all(const int family, const int type,
18204+ const int protocol);
18205+extern int gr_handle_sock_server(const struct sockaddr *sck);
18206+extern int gr_handle_sock_client(const struct sockaddr *sck);
18207+extern int gr_search_connect(const struct socket * sock,
18208+ const struct sockaddr_in * addr);
18209+extern int gr_search_bind(const struct socket * sock,
18210+ const struct sockaddr_in * addr);
18211+extern int gr_search_socket(const int domain, const int type,
18212+ const int protocol);
18213+
18214 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
18215 static ssize_t sock_read(struct file *file, char *buf,
18216 size_t size, loff_t *ppos);
18217@@ -699,6 +711,7 @@
18218
18219 int sock_close(struct inode *inode, struct file *filp)
18220 {
18221+ struct socket *sock;
18222 /*
18223 * It was possible the inode is NULL we were
18224 * closing an unfinished socket.
18225@@ -709,8 +722,21 @@
18226 printk(KERN_DEBUG "sock_close: NULL inode\n");
18227 return 0;
18228 }
18229+ sock = socki_lookup(inode);
18230+
18231 sock_fasync(-1, filp, 0);
18232+
18233+#ifdef CONFIG_GRKERNSEC
18234+ if (unlikely(current->used_accept && sock->sk &&
18235+ (sock->sk->protocol == IPPROTO_TCP) &&
18236+ (sock->sk->daddr == current->curr_ip))) {
18237+ current->used_accept = 0;
18238+ current->curr_ip = 0;
18239+ }
18240+#endif
18241+
18242 sock_release(socki_lookup(inode));
18243+
18244 return 0;
18245 }
18246
18247@@ -903,6 +929,16 @@
18248 int retval;
18249 struct socket *sock;
18250
18251+ if(!gr_search_socket(family, type, protocol)) {
18252+ retval = -EACCES;
18253+ goto out;
18254+ }
18255+
18256+ if (gr_handle_sock_all(family, type, protocol)) {
18257+ retval = -EACCES;
18258+ goto out;
18259+ }
18260+
18261 retval = sock_create(family, type, protocol, &sock);
18262 if (retval < 0)
18263 goto out;
18264@@ -998,12 +1034,26 @@
18265 {
18266 struct socket *sock;
18267 char address[MAX_SOCK_ADDR];
18268+ struct sockaddr * sck;
18269 int err;
18270
18271 if((sock = sockfd_lookup(fd,&err))!=NULL)
18272 {
18273- if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
18274+ if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
18275+ sck = (struct sockaddr *) address;
18276+
18277+ if(!gr_search_bind(sock, (struct sockaddr_in *) sck)) {
18278+ sockfd_put(sock);
18279+ return -EACCES;
18280+ }
18281+
18282+ if (gr_handle_sock_server(sck)) {
18283+ sockfd_put(sock);
18284+ return -EACCES;
18285+ }
18286+
18287 err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
18288+ }
18289 sockfd_put(sock);
18290 }
18291 return err;
18292@@ -1079,6 +1129,8 @@
18293 if ((err = sock_map_fd(newsock)) < 0)
18294 goto out_release;
18295
18296+ gr_attach_curr_ip(newsock->sk);
18297+
18298 out_put:
18299 sockfd_put(sock);
18300 out:
18301@@ -1106,6 +1158,7 @@
18302 {
18303 struct socket *sock;
18304 char address[MAX_SOCK_ADDR];
18305+ struct sockaddr * sck;
18306 int err;
18307
18308 sock = sockfd_lookup(fd, &err);
18309@@ -1114,6 +1167,24 @@
18310 err = move_addr_to_kernel(uservaddr, addrlen, address);
18311 if (err < 0)
18312 goto out_put;
18313+
18314+ sck = (struct sockaddr *) address;
18315+
18316+ if (!gr_search_connect(sock, (struct sockaddr_in *) sck)) {
18317+ err = -EACCES;
18318+ goto out_put;
18319+ }
18320+
18321+ if (gr_handle_sock_client(sck)) {
18322+ err = -EACCES;
18323+ goto out_put;
18324+ }
18325+
18326+#ifdef CONFIG_GRKERNSEC
18327+ if (sock->sk->protocol == IPPROTO_TCP)
18328+ current->used_connect = 1;
18329+#endif
18330+
18331 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
18332 sock->file->f_flags);
18333 out_put:
18334@@ -1333,6 +1404,14 @@
18335 err=sock->ops->shutdown(sock, how);
18336 sockfd_put(sock);
18337 }
18338+
18339+#ifdef CONFIG_GRKERNSEC
18340+ if (likely(!err && current->used_accept)) {
18341+ current->used_accept = 0;
18342+ current->curr_ip = 0;
18343+ }
18344+#endif
18345+
18346 return err;
18347 }
18348
474a6d91
AM
18349diff -urN linux-2.4.22.org/net/sunrpc/xprt.c linux-2.4.22/net/sunrpc/xprt.c
18350--- linux-2.4.22.org/net/sunrpc/xprt.c 2003-11-22 22:10:03.000000000 +0100
18351+++ linux-2.4.22/net/sunrpc/xprt.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
18352@@ -59,6 +59,7 @@
18353 #include <linux/unistd.h>
18354 #include <linux/sunrpc/clnt.h>
18355 #include <linux/file.h>
18356+#include <linux/grsecurity.h>
18357
18358 #include <net/sock.h>
18359 #include <net/checksum.h>
474a6d91 18360@@ -1297,6 +1298,12 @@
8be839c4
JR
18361 }
18362 ret = xid++;
18363 spin_unlock(&xid_lock);
18364+
18365+#ifdef CONFIG_GRKERNSEC_RANDRPC
18366+ if (grsec_enable_randrpc)
18367+ ret = (u32) get_random_long();
18368+#endif
18369+
18370 return ret;
18371 }
18372
474a6d91
AM
18373diff -urN linux-2.4.22.org/net/unix/af_unix.c linux-2.4.22/net/unix/af_unix.c
18374--- linux-2.4.22.org/net/unix/af_unix.c 2003-11-22 22:09:53.000000000 +0100
18375+++ linux-2.4.22/net/unix/af_unix.c 2003-11-22 22:14:11.000000000 +0100
8be839c4
JR
18376@@ -109,6 +109,7 @@
18377 #include <linux/poll.h>
18378 #include <linux/smp_lock.h>
18379 #include <linux/rtnetlink.h>
18380+#include <linux/grsecurity.h>
18381
18382 #include <asm/checksum.h>
18383
18384@@ -599,6 +600,11 @@
18385 if (err)
18386 goto put_fail;
18387
18388+ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
18389+ err = -EACCES;
18390+ goto put_fail;
18391+ }
18392+
18393 err = -ECONNREFUSED;
18394 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
18395 goto put_fail;
18396@@ -622,6 +628,13 @@
18397 if (u) {
18398 struct dentry *dentry;
18399 dentry = u->protinfo.af_unix.dentry;
18400+
18401+ if (!gr_handle_chroot_unix(u->peercred.pid)) {
18402+ err = -EPERM;
18403+ sock_put(u);
18404+ goto fail;
18405+ }
18406+
18407 if (dentry)
18408 UPDATE_ATIME(dentry->d_inode);
18409 } else
18410@@ -720,9 +733,19 @@
18411 * All right, let's create it.
18412 */
18413 mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask);
18414+
18415+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
18416+ err = -EACCES;
18417+ goto out_mknod_dput;
18418+ }
18419+
18420 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
18421+
18422 if (err)
18423 goto out_mknod_dput;
18424+
18425+ gr_handle_create(dentry, nd.mnt);
18426+
18427 up(&nd.dentry->d_inode->i_sem);
18428 dput(nd.dentry);
18429 nd.dentry = dentry;
18430@@ -740,6 +763,10 @@
18431 goto out_unlock;
18432 }
18433
18434+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
18435+ sk->peercred.pid = current->pid;
18436+#endif
18437+
18438 list = &unix_socket_table[addr->hash];
18439 } else {
18440 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
18441@@ -866,6 +893,9 @@
18442 int st;
18443 int err;
18444 long timeo;
18445+#ifdef CONFIG_GRKERNSEC
18446+ struct task_struct *p, **htable;
18447+#endif
18448
18449 err = unix_mkname(sunaddr, addr_len, &hash);
18450 if (err < 0)
18451@@ -989,6 +1019,17 @@
18452 /* Set credentials */
18453 sk->peercred = other->peercred;
18454
18455+#ifdef CONFIG_GRKERNSEC
18456+ read_lock(&tasklist_lock);
18457+ htable = &pidhash[pid_hashfn(other->peercred.pid)];
18458+ for (p = *htable; p && p->pid != other->peercred.pid; p = p->pidhash_next);
18459+ if (p) {
18460+ p->curr_ip = current->curr_ip;
18461+ p->used_accept = 1;
18462+ }
18463+ read_unlock(&tasklist_lock);
18464+#endif
18465+
18466 sock_hold(newsk);
18467 unix_peer(sk)=newsk;
18468 sock->state=SS_CONNECTED;
This page took 4.926019 seconds and 4 git commands to generate.