]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-grsec.patch
- update for cset 20040707_...
[packages/kernel.git] / kernel-grsec.patch
CommitLineData
1db5cd70
PS
1diff -uNr linux-2.6.7-rc1.orig/arch/alpha/kernel/osf_sys.c linux-2.6.7-rc1/arch/alpha/kernel/osf_sys.c
2--- linux-2.6.7-rc1.orig/arch/alpha/kernel/osf_sys.c 2004-05-23 07:53:28.000000000 +0200
3+++ linux-2.6.7-rc1/arch/alpha/kernel/osf_sys.c 2004-05-25 14:33:57.642597320 +0200
4@@ -37,6 +37,7 @@
5 #include <linux/namei.h>
6 #include <linux/uio.h>
7 #include <linux/vfs.h>
8+#include <linux/grsecurity.h>
9
10 #include <asm/fpu.h>
11 #include <asm/io.h>
12@@ -189,6 +190,13 @@
13 if (!file)
14 goto out;
15 }
16+
17+ if (gr_handle_mmap(file, prot)) {
18+ fput(file);
19+ ret = -EACCES;
20+ goto out;
21+ }
22+
23 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
24 down_write(&current->mm->mmap_sem);
25 ret = do_mmap(file, addr, len, prot, flags, off);
26diff -uNr linux-2.6.7-rc1.orig/arch/alpha/kernel/ptrace.c linux-2.6.7-rc1/arch/alpha/kernel/ptrace.c
27--- linux-2.6.7-rc1.orig/arch/alpha/kernel/ptrace.c 2004-05-23 07:54:43.000000000 +0200
28+++ linux-2.6.7-rc1/arch/alpha/kernel/ptrace.c 2004-05-25 14:33:57.658594888 +0200
29@@ -14,6 +14,7 @@
30 #include <linux/user.h>
31 #include <linux/slab.h>
32 #include <linux/security.h>
33+#include <linux/grsecurity.h>
34
35 #include <asm/uaccess.h>
36 #include <asm/pgtable.h>
37@@ -288,6 +289,9 @@
38 if (!child)
39 goto out_notsk;
40
41+ if (gr_handle_ptrace(child, request))
42+ goto out;
43+
44 if (request == PTRACE_ATTACH) {
45 ret = ptrace_attach(child);
46 goto out;
47diff -uNr linux-2.6.7-rc1.orig/arch/i386/Kconfig linux-2.6.7-rc1/arch/i386/Kconfig
48--- linux-2.6.7-rc1.orig/arch/i386/Kconfig 2004-05-25 14:25:41.000000000 +0200
49+++ linux-2.6.7-rc1/arch/i386/Kconfig 2004-05-25 14:33:57.669593216 +0200
50@@ -394,7 +394,7 @@
51
52 config X86_ALIGNMENT_16
53 bool
54- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
55+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
56 default y
57
58 config X86_GOOD_APIC
1db5cd70
PS
59diff -uNr linux-2.6.7-rc1.orig/arch/i386/kernel/ioport.c linux-2.6.7-rc1/arch/i386/kernel/ioport.c
60--- linux-2.6.7-rc1.orig/arch/i386/kernel/ioport.c 2004-05-23 07:54:16.000000000 +0200
61+++ linux-2.6.7-rc1/arch/i386/kernel/ioport.c 2004-05-25 14:33:57.726584552 +0200
62@@ -15,6 +15,7 @@
63 #include <linux/stddef.h>
64 #include <linux/slab.h>
65 #include <linux/thread_info.h>
66+#include <linux/grsecurity.h>
67
68 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
69 static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
70@@ -62,9 +63,16 @@
71
72 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
73 return -EINVAL;
74+#ifdef CONFIG_GRKERNSEC_IO
75+ if (turn_on) {
76+ gr_handle_ioperm();
77+#else
78 if (turn_on && !capable(CAP_SYS_RAWIO))
79+#endif
80 return -EPERM;
81-
82+#ifdef CONFIG_GRKERNSEC_IO
83+ }
84+#endif
85 /*
86 * If it's the first ioperm() call in this thread's lifetime, set the
87 * IO bitmap up. ioperm() is much less timing critical than clone(),
88@@ -115,8 +123,13 @@
89 return -EINVAL;
90 /* Trying to gain more privileges? */
91 if (level > old) {
92+#ifdef CONFIG_GRKERNSEC_IO
93+ gr_handle_iopl();
94+ return -EPERM;
95+#else
96 if (!capable(CAP_SYS_RAWIO))
97 return -EPERM;
98+#endif
99 }
100 regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
101 /* Make sure we return the long way (not sysenter) */
1db5cd70
PS
102diff -uNr linux-2.6.7-rc1.orig/arch/i386/kernel/ptrace.c linux-2.6.7-rc1/arch/i386/kernel/ptrace.c
103--- linux-2.6.7-rc1.orig/arch/i386/kernel/ptrace.c 2004-05-23 07:53:47.000000000 +0200
104+++ linux-2.6.7-rc1/arch/i386/kernel/ptrace.c 2004-05-25 14:33:57.759579536 +0200
105@@ -15,6 +15,7 @@
106 #include <linux/user.h>
107 #include <linux/security.h>
108 #include <linux/audit.h>
109+#include <linux/grsecurity.h>
110
111 #include <asm/uaccess.h>
112 #include <asm/pgtable.h>
113@@ -263,6 +264,9 @@
114 if (pid == 1) /* you may not mess with init */
115 goto out_tsk;
116
117+ if (gr_handle_ptrace(child, request))
118+ goto out_tsk;
119+
120 if (request == PTRACE_ATTACH) {
121 ret = ptrace_attach(child);
122 goto out_tsk;
123@@ -341,6 +345,17 @@
124 if(addr == (long) &dummy->u_debugreg[5]) break;
125 if(addr < (long) &dummy->u_debugreg[4] &&
126 ((unsigned long) data) >= TASK_SIZE-3) break;
127+
128+#ifdef CONFIG_GRKERNSEC
129+ if(addr >= (long) &dummy->u_debugreg[0] &&
130+ addr <= (long) &dummy->u_debugreg[3]){
131+ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
132+ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
133+ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
134+ if((type & 1) && (data & align))
135+ break;
136+ }
137+#endif
138
139 if(addr == (long) &dummy->u_debugreg[7]) {
140 data &= ~DR_CONTROL_RESERVED;
1db5cd70
PS
141diff -uNr linux-2.6.7-rc1.orig/arch/i386/kernel/sys_i386.c linux-2.6.7-rc1/arch/i386/kernel/sys_i386.c
142--- linux-2.6.7-rc1.orig/arch/i386/kernel/sys_i386.c 2004-05-23 07:55:01.000000000 +0200
143+++ linux-2.6.7-rc1/arch/i386/kernel/sys_i386.c 2004-05-25 14:33:57.766578472 +0200
144@@ -19,6 +19,7 @@
145 #include <linux/mman.h>
146 #include <linux/file.h>
147 #include <linux/utsname.h>
148+#include <linux/grsecurity.h>
149
150 #include <asm/uaccess.h>
151 #include <asm/ipc.h>
152@@ -56,8 +57,14 @@
153 goto out;
154 }
155
156+ if (gr_handle_mmap(file, prot)) {
157+ fput(file);
158+ error = -EACCES;
159+ goto out;
160+ }
161+
162 down_write(&current->mm->mmap_sem);
163- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
164+ error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
165 up_write(&current->mm->mmap_sem);
166
167 if (file)
1db5cd70
PS
168diff -uNr linux-2.6.7-rc1.orig/arch/i386/kernel/traps.c linux-2.6.7-rc1/arch/i386/kernel/traps.c
169--- linux-2.6.7-rc1.orig/arch/i386/kernel/traps.c 2004-05-23 07:53:46.000000000 +0200
170+++ linux-2.6.7-rc1/arch/i386/kernel/traps.c 2004-05-25 14:33:57.779576496 +0200
78638fc5 171@@ -122,13 +117,15 @@
1db5cd70
PS
172 unsigned long ebp)
173 {
174 unsigned long addr;
175+ int i = kstack_depth_to_print;
176
177- while (!kstack_end(stack)) {
178+ while (i && !kstack_end(stack)) {
179 addr = *stack++;
78638fc5
AM
180 if (__kernel_text_address(addr)) {
181 printk(" [<%08lx>]", addr);
182 print_symbol(" %s", addr);
183 printk("\n");
1db5cd70
PS
184+ --i;
185 }
186 }
187 }
1db5cd70
PS
188diff -uNr linux-2.6.7-rc1.orig/arch/ia64/kernel/ptrace.c linux-2.6.7-rc1/arch/ia64/kernel/ptrace.c
189--- linux-2.6.7-rc1.orig/arch/ia64/kernel/ptrace.c 2004-05-23 07:55:02.000000000 +0200
190+++ linux-2.6.7-rc1/arch/ia64/kernel/ptrace.c 2004-05-25 14:33:57.842566920 +0200
191@@ -17,6 +17,7 @@
192 #include <linux/smp_lock.h>
193 #include <linux/user.h>
194 #include <linux/security.h>
195+#include <linux/grsecurity.h>
196
197 #include <asm/pgtable.h>
198 #include <asm/processor.h>
199@@ -1314,6 +1315,9 @@
200 if (pid == 1) /* no messing around with init! */
201 goto out_tsk;
202
203+ if (gr_handle_ptrace(child, request))
204+ goto out_tsk;
205+
206 if (request == PTRACE_ATTACH) {
207 ret = ptrace_attach(child);
208 goto out_tsk;
209diff -uNr linux-2.6.7-rc1.orig/arch/ia64/kernel/sys_ia64.c linux-2.6.7-rc1/arch/ia64/kernel/sys_ia64.c
210--- linux-2.6.7-rc1.orig/arch/ia64/kernel/sys_ia64.c 2004-05-23 07:54:21.000000000 +0200
211+++ linux-2.6.7-rc1/arch/ia64/kernel/sys_ia64.c 2004-05-25 14:33:57.858564488 +0200
212@@ -18,6 +18,7 @@
213 #include <linux/syscalls.h>
214 #include <linux/highuid.h>
215 #include <linux/hugetlb.h>
216+#include <linux/grsecurity.h>
217
218 #include <asm/shmparam.h>
219 #include <asm/uaccess.h>
220@@ -222,6 +223,11 @@
221 goto out;
222 }
223
224+ if (gr_handle_mmap(file, prot)) {
225+ addr = -EACCES;
226+ goto out;
227+ }
228+
229 down_write(&current->mm->mmap_sem);
230 addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
231 up_write(&current->mm->mmap_sem);
232diff -uNr linux-2.6.7-rc1.orig/arch/ppc/kernel/ptrace.c linux-2.6.7-rc1/arch/ppc/kernel/ptrace.c
233--- linux-2.6.7-rc1.orig/arch/ppc/kernel/ptrace.c 2004-05-23 07:53:47.000000000 +0200
234+++ linux-2.6.7-rc1/arch/ppc/kernel/ptrace.c 2004-05-25 14:33:57.867563120 +0200
235@@ -26,6 +26,7 @@
236 #include <linux/ptrace.h>
237 #include <linux/user.h>
238 #include <linux/security.h>
239+#include <linux/grsecurity.h>
240
241 #include <asm/uaccess.h>
242 #include <asm/page.h>
243@@ -202,6 +203,9 @@
244 if (pid == 1) /* you may not mess with init */
245 goto out_tsk;
246
247+ if (gr_handle_ptrace(child, request))
248+ goto out_tsk;
249+
250 if (request == PTRACE_ATTACH) {
251 ret = ptrace_attach(child);
252 goto out_tsk;
253diff -uNr linux-2.6.7-rc1.orig/arch/ppc/kernel/syscalls.c linux-2.6.7-rc1/arch/ppc/kernel/syscalls.c
254--- linux-2.6.7-rc1.orig/arch/ppc/kernel/syscalls.c 2004-05-23 07:54:44.000000000 +0200
255+++ linux-2.6.7-rc1/arch/ppc/kernel/syscalls.c 2004-05-25 14:33:57.884560536 +0200
256@@ -36,6 +36,7 @@
257 #include <linux/utsname.h>
258 #include <linux/file.h>
259 #include <linux/unistd.h>
260+#include <linux/grsecurity.h>
261
262 #include <asm/uaccess.h>
263 #include <asm/ipc.h>
d7e01d2a 264@@ -171,8 +172,14 @@
1db5cd70
PS
265 goto out;
266 }
267
268+ if (gr_handle_mmap(file, prot)) {
269+ fput(file);
270+ ret = -EACCES;
271+ goto out;
272+ }
273+
274 down_write(&current->mm->mmap_sem);
275- ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
276+ ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
277 up_write(&current->mm->mmap_sem);
278 if (file)
279 fput(file);
1db5cd70
PS
280diff -uNr linux-2.6.7-rc1.orig/arch/sparc/kernel/ptrace.c linux-2.6.7-rc1/arch/sparc/kernel/ptrace.c
281--- linux-2.6.7-rc1.orig/arch/sparc/kernel/ptrace.c 2004-05-23 07:55:02.000000000 +0200
282+++ linux-2.6.7-rc1/arch/sparc/kernel/ptrace.c 2004-05-25 14:33:57.923554608 +0200
283@@ -18,6 +18,7 @@
284 #include <linux/smp.h>
285 #include <linux/smp_lock.h>
286 #include <linux/security.h>
287+#include <linux/grsecurity.h>
288
289 #include <asm/pgtable.h>
290 #include <asm/system.h>
291@@ -320,6 +321,11 @@
292 goto out;
293 }
294
295+ if (gr_handle_ptrace(child, request)) {
296+ pt_error_return(regs, EPERM);
297+ goto out_tsk;
298+ }
299+
300 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
301 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
302 if (ptrace_attach(child)) {
303diff -uNr linux-2.6.7-rc1.orig/arch/sparc/kernel/sys_sparc.c linux-2.6.7-rc1/arch/sparc/kernel/sys_sparc.c
304--- linux-2.6.7-rc1.orig/arch/sparc/kernel/sys_sparc.c 2004-05-23 07:53:57.000000000 +0200
305+++ linux-2.6.7-rc1/arch/sparc/kernel/sys_sparc.c 2004-05-25 14:33:57.932553240 +0200
306@@ -21,6 +21,7 @@
307 #include <linux/utsname.h>
308 #include <linux/smp.h>
309 #include <linux/smp_lock.h>
310+#include <linux/grsecurity.h>
311
312 #include <asm/uaccess.h>
313 #include <asm/ipc.h>
314@@ -242,6 +243,12 @@
315 if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
316 goto out_putf;
317
318+ if (gr_handle_mmap(file, prot)) {
319+ fput(file);
320+ retval = -EACCES;
321+ goto out;
322+ }
323+
324 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
325
326 down_write(&current->mm->mmap_sem);
1db5cd70
PS
327diff -uNr linux-2.6.7-rc1.orig/arch/sparc64/kernel/ptrace.c linux-2.6.7-rc1/arch/sparc64/kernel/ptrace.c
328--- linux-2.6.7-rc1.orig/arch/sparc64/kernel/ptrace.c 2004-05-23 07:55:02.000000000 +0200
329+++ linux-2.6.7-rc1/arch/sparc64/kernel/ptrace.c 2004-05-25 14:33:57.944551416 +0200
330@@ -19,6 +19,7 @@
331 #include <linux/smp.h>
332 #include <linux/smp_lock.h>
333 #include <linux/security.h>
334+#include <linux/grsecurity.h>
335
336 #include <asm/asi.h>
337 #include <asm/pgtable.h>
338@@ -169,6 +170,11 @@
339 goto out;
340 }
341
342+ if (gr_handle_ptrace(child, (long)request)) {
343+ pt_error_return(regs, EPERM);
344+ goto out_tsk;
345+ }
346+
347 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
348 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
349 if (ptrace_attach(child)) {
1db5cd70
PS
350diff -uNr linux-2.6.7-rc1.orig/arch/sparc64/kernel/sys_sparc.c linux-2.6.7-rc1/arch/sparc64/kernel/sys_sparc.c
351--- linux-2.6.7-rc1.orig/arch/sparc64/kernel/sys_sparc.c 2004-05-23 07:54:19.000000000 +0200
352+++ linux-2.6.7-rc1/arch/sparc64/kernel/sys_sparc.c 2004-05-25 14:33:57.955549744 +0200
353@@ -25,6 +25,7 @@
354 #include <linux/syscalls.h>
355 #include <linux/ipc.h>
356 #include <linux/personality.h>
357+#include <linux/grsecurity.h>
358
359 #include <asm/uaccess.h>
360 #include <asm/ipc.h>
d7e01d2a 361@@ -316,6 +317,12 @@
1db5cd70
PS
362 if (!file)
363 goto out;
364 }
365+
366+ if (gr_handle_mmap(file, prot)) {
367+ retval = -EACCES;
368+ goto out_putf;
369+ }
370+
371 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
372 len = PAGE_ALIGN(len);
373 retval = -EINVAL;
1db5cd70
PS
374diff -uNr linux-2.6.7-rc1.orig/arch/x86_64/kernel/ptrace.c linux-2.6.7-rc1/arch/x86_64/kernel/ptrace.c
375--- linux-2.6.7-rc1.orig/arch/x86_64/kernel/ptrace.c 2004-05-23 07:53:56.000000000 +0200
376+++ linux-2.6.7-rc1/arch/x86_64/kernel/ptrace.c 2004-05-25 14:37:46.397821240 +0200
377@@ -17,6 +17,7 @@
378 #include <linux/user.h>
379 #include <linux/security.h>
380 #include <linux/audit.h>
381+#include <linux/grsecurity.h>
382
383 #include <asm/uaccess.h>
384 #include <asm/pgtable.h>
385@@ -213,6 +214,9 @@
386 if (pid == 1) /* you may not mess with init */
387 goto out_tsk;
388
389+ if (gr_handle_ptrace(child, request))
390+ goto out_tsk;
391+
392 if (request == PTRACE_ATTACH) {
393 ret = ptrace_attach(child);
394 goto out_tsk;
395diff -uNr linux-2.6.7-rc1.orig/drivers/char/keyboard.c linux-2.6.7-rc1/drivers/char/keyboard.c
396--- linux-2.6.7-rc1.orig/drivers/char/keyboard.c 2004-05-25 14:25:39.000000000 +0200
397+++ linux-2.6.7-rc1/drivers/char/keyboard.c 2004-05-25 14:33:58.033537888 +0200
398@@ -606,6 +606,16 @@
399 kbd->kbdmode == VC_MEDIUMRAW) &&
400 value != KVAL(K_SAK))
401 return; /* SAK is allowed even in raw mode */
402+
403+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
404+ {
405+ void *func = fn_handler[value];
406+ if (func == fn_show_state || func == fn_show_ptregs ||
407+ func == fn_show_mem)
408+ return;
409+ }
410+#endif
411+
412 fn_handler[value](vc, regs);
413 }
414
415diff -uNr linux-2.6.7-rc1.orig/drivers/char/mem.c linux-2.6.7-rc1/drivers/char/mem.c
416--- linux-2.6.7-rc1.orig/drivers/char/mem.c 2004-05-23 07:54:18.000000000 +0200
417+++ linux-2.6.7-rc1/drivers/char/mem.c 2004-05-25 14:33:58.061533632 +0200
418@@ -23,6 +23,7 @@
419 #include <linux/devfs_fs_kernel.h>
420 #include <linux/ptrace.h>
421 #include <linux/device.h>
422+#include <linux/grsecurity.h>
423
424 #include <asm/uaccess.h>
425 #include <asm/io.h>
426@@ -39,6 +40,10 @@
427 extern void tapechar_init(void);
428 #endif
429
430+#ifdef CONFIG_GRKERNSEC
431+extern struct file_operations grsec_fops;
432+#endif
433+
434 /*
435 * Architectures vary in how they handle caching for addresses
436 * outside of main memory.
437@@ -191,6 +196,12 @@
438
439 if (!valid_phys_addr_range(p, &count))
440 return -EFAULT;
441+
442+#ifdef CONFIG_GRKERNSEC_KMEM
443+ gr_handle_mem_write();
444+ return -EPERM;
445+#endif
446+
447 return do_write_mem(__va(p), p, buf, count, ppos);
448 }
449
450@@ -205,6 +216,11 @@
451 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
452 #endif
453
454+#ifdef CONFIG_GRKERNSEC_KMEM
455+ if (gr_handle_mem_mmap(offset, vma))
456+ return -EPERM;
457+#endif
458+
459 /* Don't try to swap out physical pages.. */
460 vma->vm_flags |= VM_RESERVED;
461
462@@ -298,6 +314,11 @@
463 ssize_t written;
464 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
465
466+#ifdef CONFIG_GRKERNSEC_KMEM
467+ gr_handle_kmem_write();
468+ return -EPERM;
469+#endif
470+
471 if (p < (unsigned long) high_memory) {
472
473 wrote = count;
474@@ -573,6 +594,16 @@
475
476 static int open_port(struct inode * inode, struct file * filp)
477 {
478+#ifdef CONFIG_GRKERNSEC_KMEM
479+ gr_handle_open_port();
480+ return -EPERM;
481+#endif
482+
483+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
484+}
485+
486+static int open_mem(struct inode * inode, struct file * filp)
487+{
488 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
489 }
490
491@@ -581,7 +612,6 @@
492 #define full_lseek null_lseek
493 #define write_zero write_null
494 #define read_full read_zero
495-#define open_mem open_port
496 #define open_kmem open_mem
497
498 static struct file_operations mem_fops = {
499@@ -679,6 +709,11 @@
500 case 9:
501 filp->f_op = &urandom_fops;
502 break;
503+#ifdef CONFIG_GRKERNSEC
504+ case 10:
505+ filp->f_op = &grsec_fops;
506+ break;
507+#endif
508 case 11:
509 filp->f_op = &kmsg_fops;
510 break;
511@@ -710,6 +745,9 @@
512 {7, "full", S_IRUGO | S_IWUGO, &full_fops},
513 {8, "random", S_IRUGO | S_IWUSR, &random_fops},
514 {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
515+#ifdef CONFIG_GRKERNSEC
516+ {10,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
517+#endif
518 {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops},
519 };
520
521diff -uNr linux-2.6.7-rc1.orig/drivers/char/random.c linux-2.6.7-rc1/drivers/char/random.c
522--- linux-2.6.7-rc1.orig/drivers/char/random.c 2004-05-23 07:53:33.000000000 +0200
523+++ linux-2.6.7-rc1/drivers/char/random.c 2004-05-25 14:33:58.081530592 +0200
524@@ -263,9 +263,15 @@
525 /*
526 * Configuration information
527 */
528+#ifdef CONFIG_GRKERNSEC_RANDNET
529+#define DEFAULT_POOL_SIZE 1024
530+#define SECONDARY_POOL_SIZE 256
531+#define BATCH_ENTROPY_SIZE 512
532+#else
533 #define DEFAULT_POOL_SIZE 512
534 #define SECONDARY_POOL_SIZE 128
535 #define BATCH_ENTROPY_SIZE 256
536+#endif
537 #define USE_SHA
538
539 /*
540@@ -2380,6 +2386,29 @@
541 return halfMD4Transform(hash, keyptr->secret);
542 }
543
544+#ifdef CONFIG_GRKERNSEC
545+/* the following function is provided by PaX under the GPL */
546+unsigned long get_random_long(void)
547+{
548+ static time_t rekey_time;
549+ static __u32 secret[12];
550+ time_t t;
551+
552+ /*
553+ * Pick a random secret every REKEY_INTERVAL seconds
554+ */
555+ t = get_seconds();
556+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
557+ rekey_time = t;
558+ get_random_bytes(secret, sizeof(secret));
559+ }
560+
561+ secret[1] = halfMD4Transform(secret+8, secret);
562+ secret[0] = halfMD4Transform(secret+8, secret);
563+ return *(unsigned long *)secret;
564+}
565+#endif
566+
567 #ifdef CONFIG_SYN_COOKIES
568 /*
569 * Secure SYN cookie computation. This is the algorithm worked out by
570diff -uNr linux-2.6.7-rc1.orig/drivers/char/vt_ioctl.c linux-2.6.7-rc1/drivers/char/vt_ioctl.c
571--- linux-2.6.7-rc1.orig/drivers/char/vt_ioctl.c 2004-05-23 07:54:28.000000000 +0200
572+++ linux-2.6.7-rc1/drivers/char/vt_ioctl.c 2004-05-25 14:33:58.164517976 +0200
573@@ -96,6 +96,12 @@
574 case KDSKBENT:
575 if (!perm)
576 return -EPERM;
577+
578+#ifdef CONFIG_GRKERNSEC
579+ if (!capable(CAP_SYS_TTY_CONFIG))
580+ return -EPERM;
581+#endif
582+
583 if (!i && v == K_NOSUCHMAP) {
584 /* disallocate map */
585 key_map = key_maps[s];
586@@ -232,6 +238,13 @@
587 goto reterr;
588 }
589
590+#ifdef CONFIG_GRKERNSEC
591+ if (!capable(CAP_SYS_TTY_CONFIG)) {
592+ return -EPERM;
593+ goto reterr;
594+ }
595+#endif
596+
597 q = func_table[i];
598 first_free = funcbufptr + (funcbufsize - funcbufleft);
599 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
600diff -uNr linux-2.6.7-rc1.orig/drivers/pci/proc.c linux-2.6.7-rc1/drivers/pci/proc.c
601--- linux-2.6.7-rc1.orig/drivers/pci/proc.c 2004-05-23 07:54:21.000000000 +0200
602+++ linux-2.6.7-rc1/drivers/pci/proc.c 2004-05-25 14:33:58.199512656 +0200
603@@ -565,7 +565,15 @@
604
605 static void legacy_proc_init(void)
606 {
607+#ifdef CONFIG_GRKERNSEC_PROC_ADD
608+#ifdef CONFIG_GRKERNSEC_PROC_USER
609+ struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
610+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
611+ struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
612+#endif
613+#else
614 struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
615+#endif
616 if (entry)
617 entry->proc_fops = &proc_pci_operations;
618 }
619@@ -594,7 +602,15 @@
620 {
621 struct proc_dir_entry *entry;
622 struct pci_dev *dev = NULL;
623+#ifdef CONFIG_GRKERNSEC_PROC_ADD
624+#ifdef CONFIG_GRKERNSEC_PROC_USER
625+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
626+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
627+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
628+#endif
629+#else
630 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
631+#endif
632 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
633 if (entry)
634 entry->proc_fops = &proc_bus_pci_dev_operations;
1db5cd70
PS
635diff -uNr linux-2.6.7-rc1.orig/fs/binfmt_aout.c linux-2.6.7-rc1/fs/binfmt_aout.c
636--- linux-2.6.7-rc1.orig/fs/binfmt_aout.c 2004-05-23 07:53:46.000000000 +0200
637+++ linux-2.6.7-rc1/fs/binfmt_aout.c 2004-05-25 14:33:58.437476480 +0200
638@@ -24,6 +24,7 @@
639 #include <linux/binfmts.h>
640 #include <linux/personality.h>
641 #include <linux/init.h>
642+#include <linux/grsecurity.h>
643
644 #include <asm/system.h>
645 #include <asm/uaccess.h>
646@@ -118,10 +119,12 @@
647 /* If the size of the dump file exceeds the rlimit, then see what would happen
648 if we wrote the stack, but not the data area. */
649 #ifdef __sparc__
650+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
651 if ((dump.u_dsize+dump.u_ssize) >
652 current->rlim[RLIMIT_CORE].rlim_cur)
653 dump.u_dsize = 0;
654 #else
655+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
656 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
657 current->rlim[RLIMIT_CORE].rlim_cur)
658 dump.u_dsize = 0;
659@@ -129,10 +132,12 @@
660
661 /* Make sure we have enough room to write the stack and data areas. */
662 #ifdef __sparc__
663+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
664 if ((dump.u_ssize) >
665 current->rlim[RLIMIT_CORE].rlim_cur)
666 dump.u_ssize = 0;
667 #else
668+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
669 if ((dump.u_ssize+1) * PAGE_SIZE >
670 current->rlim[RLIMIT_CORE].rlim_cur)
671 dump.u_ssize = 0;
672@@ -281,6 +286,8 @@
673 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
674 if (rlim >= RLIM_INFINITY)
675 rlim = ~0;
676+
677+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
678 if (ex.a_data + ex.a_bss > rlim)
679 return -ENOMEM;
680
681@@ -399,7 +406,7 @@
682
683 down_write(&current->mm->mmap_sem);
684 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
685- PROT_READ | PROT_WRITE | PROT_EXEC,
686+ PROT_READ | PROT_WRITE,
687 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
688 fd_offset + ex.a_text);
689 up_write(&current->mm->mmap_sem);
690diff -uNr linux-2.6.7-rc1.orig/fs/binfmt_elf.c linux-2.6.7-rc1/fs/binfmt_elf.c
691--- linux-2.6.7-rc1.orig/fs/binfmt_elf.c 2004-05-23 07:54:09.000000000 +0200
692+++ linux-2.6.7-rc1/fs/binfmt_elf.c 2004-05-25 14:33:58.457473440 +0200
6a84f544 693@@ -37,6 +37,8 @@
1db5cd70
PS
694 #include <linux/pagemap.h>
695 #include <linux/security.h>
696 #include <linux/syscalls.h>
697+#include <linux/random.h>
698+#include <linux/grsecurity.h>
699
700 #include <asm/uaccess.h>
701 #include <asm/param.h>
6a84f544 702@@ -85,6 +87,7 @@
1db5cd70
PS
703
704 static int set_brk(unsigned long start, unsigned long end)
705 {
706+ current->mm->start_brk = current->mm->brk = end;
707 start = ELF_PAGEALIGN(start);
708 end = ELF_PAGEALIGN(end);
709 if (end > start) {
6a84f544 710@@ -92,7 +95,6 @@
1db5cd70
PS
711 if (BAD_ADDR(addr))
712 return addr;
1db5cd70
PS
713 }
714- current->mm->start_brk = current->mm->brk = end;
715 return 0;
716 }
717
6a84f544 718@@ -1098,8 +1100,11 @@
1db5cd70
PS
719 #undef DUMP_SEEK
720
721 #define DUMP_WRITE(addr, nr) \
722+ do { \
723+ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
724 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
725- goto end_coredump;
726+ goto end_coredump; \
727+ } while (0);
728 #define DUMP_SEEK(off) \
729 if (!dump_seek(file, (off))) \
730 goto end_coredump;
731diff -uNr linux-2.6.7-rc1.orig/fs/binfmt_misc.c linux-2.6.7-rc1/fs/binfmt_misc.c
732--- linux-2.6.7-rc1.orig/fs/binfmt_misc.c 2004-05-23 07:53:57.000000000 +0200
733+++ linux-2.6.7-rc1/fs/binfmt_misc.c 2004-05-25 14:33:58.467471920 +0200
734@@ -108,9 +108,11 @@
735 int retval;
736
737 retval = -ENOEXEC;
738- if (!enabled)
739+ if (!enabled || bprm->misc)
740 goto _ret;
741
742+ bprm->misc++;
743+
744 /* to keep locking time low, we copy the interpreter string */
745 read_lock(&entries_lock);
746 fmt = check_file(bprm);
747diff -uNr linux-2.6.7-rc1.orig/fs/buffer.c linux-2.6.7-rc1/fs/buffer.c
748--- linux-2.6.7-rc1.orig/fs/buffer.c 2004-05-23 07:54:21.000000000 +0200
749+++ linux-2.6.7-rc1/fs/buffer.c 2004-05-25 14:33:58.488468728 +0200
750@@ -37,6 +37,7 @@
751 #include <linux/bio.h>
752 #include <linux/notifier.h>
753 #include <linux/cpu.h>
754+#include <linux/grsecurity.h>
755 #include <asm/bitops.h>
756
757 static void invalidate_bh_lrus(void);
758@@ -2231,6 +2232,9 @@
759 int err;
760
761 err = -EFBIG;
762+
763+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
764+
765 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
766 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
767 send_sig(SIGXFSZ, current, 0);
1db5cd70
PS
768diff -uNr linux-2.6.7-rc1.orig/fs/exec.c linux-2.6.7-rc1/fs/exec.c
769--- linux-2.6.7-rc1.orig/fs/exec.c 2004-05-23 07:53:57.000000000 +0200
770+++ linux-2.6.7-rc1/fs/exec.c 2004-05-25 14:33:58.597452160 +0200
771@@ -46,6 +46,8 @@
772 #include <linux/security.h>
773 #include <linux/syscalls.h>
774 #include <linux/rmap.h>
775+#include <linux/random.h>
776+#include <linux/grsecurity.h>
777
778 #include <asm/uaccess.h>
779 #include <asm/pgalloc.h>
780@@ -904,6 +906,9 @@
781 if (retval)
782 return retval;
783
784+ if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
785+ return -EACCES;
786+
787 memset(bprm->buf,0,BINPRM_BUF_SIZE);
788 return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
789 }
790@@ -933,6 +938,7 @@
791 task_lock(current);
792 unsafe = unsafe_exec(current);
793 security_bprm_apply_creds(bprm, unsafe);
794+ gr_handle_chroot_caps(current);
795 task_unlock(current);
796 }
797
ee78bb96
PS
798@@ -1073,6 +1079,11 @@
799 struct file *file;
800 int retval;
801 int i;
802+#ifdef CONFIG_GRKERNSEC
803+ struct file *old_exec_file;
804+ struct acl_subject_label *old_acl;
805+ struct rlimit old_rlim[RLIM_NLIMITS];
806+#endif
807
808 sched_balance_exec();
809
810@@ -1082,6 +1093,20 @@
1db5cd70
PS
811 if (IS_ERR(file))
812 return retval;
813
814+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
815+
816+ if (gr_handle_nproc()) {
817+ allow_write_access(file);
818+ fput(file);
819+ return -EAGAIN;
820+ }
821+
822+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
823+ allow_write_access(file);
824+ fput(file);
825+ return -EACCES;
826+ }
827+
828 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
829 memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
830
ee78bb96 831@@ -1089,6 +1114,7 @@
1db5cd70
PS
832 bprm.filename = filename;
833 bprm.interp = filename;
834 bprm.sh_bang = 0;
835+ bprm.misc = 0;
836 bprm.loader = 0;
837 bprm.exec = 0;
838 bprm.security = NULL;
ee78bb96 839@@ -1117,11 +1143,26 @@
1db5cd70
PS
840 if (retval < 0)
841 goto out;
842
843+ if (!gr_tpe_allow(file)) {
844+ retval = -EACCES;
845+ goto out;
846+ }
847+
848+ if (gr_check_crash_exec(file)) {
849+ retval = -EACCES;
850+ goto out;
851+ }
852+
853 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
854 if (retval < 0)
855 goto out;
856
857 bprm.exec = bprm.p;
858+
859+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
860+
861+ gr_handle_exec_args(&bprm, argv);
862+
863 retval = copy_strings(bprm.envc, envp, &bprm);
864 if (retval < 0)
865 goto out;
ee78bb96 866@@ -1130,8 +1171,22 @@
1db5cd70
PS
867 if (retval < 0)
868 goto out;
869
870+#ifdef CONFIG_GRKERNSEC
871+ old_acl = current->acl;
872+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
873+ old_exec_file = current->exec_file;
874+ get_file(file);
875+ current->exec_file = file;
876+#endif
877+
878+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
879+
880 retval = search_binary_handler(&bprm,regs);
881 if (retval >= 0) {
882+#ifdef CONFIG_GRKERNSEC
883+ if (old_exec_file)
884+ fput(old_exec_file);
885+#endif
886 free_arg_pages(&bprm);
887
888 /* execve success */
ee78bb96 889@@ -1139,6 +1194,13 @@
1db5cd70
PS
890 return retval;
891 }
892
893+#ifdef CONFIG_GRKERNSEC
894+ current->acl = old_acl;
895+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
896+ fput(current->exec_file);
897+ current->exec_file = old_exec_file;
898+#endif
899+
900 out:
901 /* Something went wrong, return the inode and free the argument pages*/
902 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
ee78bb96 903@@ -1365,6 +1427,7 @@
1db5cd70
PS
904 current->signal->group_exit_code = exit_code;
905 coredump_wait(mm);
906
907+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
908 if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
909 goto fail_unlock;
910
ee78bb96 911@@ -1384,7 +1447,7 @@
1db5cd70
PS
912 goto close_fail;
913 if (!file->f_op->write)
914 goto close_fail;
915- if (do_truncate(file->f_dentry, 0) != 0)
916+ if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
917 goto close_fail;
918
919 retval = binfmt->core_dump(signr, regs, file);
920diff -uNr linux-2.6.7-rc1.orig/fs/fcntl.c linux-2.6.7-rc1/fs/fcntl.c
921--- linux-2.6.7-rc1.orig/fs/fcntl.c 2004-05-23 07:54:22.000000000 +0200
922+++ linux-2.6.7-rc1/fs/fcntl.c 2004-05-25 14:33:58.632446840 +0200
923@@ -14,6 +14,7 @@
924 #include <linux/module.h>
925 #include <linux/security.h>
926 #include <linux/ptrace.h>
927+#include <linux/grsecurity.h>
928
929 #include <asm/poll.h>
930 #include <asm/siginfo.h>
931@@ -86,6 +87,9 @@
932 int error;
933
934 error = -EINVAL;
935+
936+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
937+
938 if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
939 goto out;
940
941@@ -105,6 +109,9 @@
942 }
943
944 error = -EMFILE;
945+
946+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
947+
948 if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
949 goto out;
950
951@@ -154,6 +161,8 @@
952 struct file * file, *tofree;
953 struct files_struct * files = current->files;
954
955+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
956+
957 spin_lock(&files->file_lock);
958 if (!(file = fcheck(oldfd)))
959 goto out_unlock;
960@@ -493,13 +502,15 @@
961 if (pid > 0) {
962 p = find_task_by_pid(pid);
963 if (p) {
964- send_sigio_to_task(p, fown, fd, band);
965+ if (!gr_check_protected_task(p))
966+ send_sigio_to_task(p, fown, fd, band);
967 }
968 } else {
969 struct list_head *l;
970 struct pid *pidptr;
971 for_each_task_pid(-pid, PIDTYPE_PGID, p, l, pidptr) {
972- send_sigio_to_task(p, fown, fd, band);
973+ if (!gr_check_protected_task(p) && !gr_pid_is_chrooted(p))
974+ send_sigio_to_task(p, fown, fd, band);
975 }
976 }
977 read_unlock(&tasklist_lock);
978diff -uNr linux-2.6.7-rc1.orig/fs/Kconfig linux-2.6.7-rc1/fs/Kconfig
979--- linux-2.6.7-rc1.orig/fs/Kconfig 2004-05-25 14:25:42.000000000 +0200
980+++ linux-2.6.7-rc1/fs/Kconfig 2004-05-25 14:33:58.318494568 +0200
981@@ -816,6 +816,7 @@
982
983 config PROC_KCORE
984 bool
985+ depends on !GRKERNSEC_PROC_ADD
986 default y if !ARM
987
988 config SYSFS
66e3021a
PS
989diff -uNr linux-2.6.6/fs/dcache.c linux-2.6.6.grsec/fs/dcache.c
990--- linux-2.6.6/fs/dcache.c 2004-05-13 16:55:46.446490696 +0200
991+++ linux-2.6.6.grsec/fs/dcache.c 2004-05-13 16:52:25.000000000 +0200
992@@ -1263,7 +1263,7 @@
993 *
994 * "buflen" should be positive. Caller holds the dcache_lock.
995 */
996-static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
997+char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
998 struct dentry *root, struct vfsmount *rootmnt,
999 char *buffer, int buflen)
1000 {
1db5cd70
PS
1001diff -uNr linux-2.6.7-rc1.orig/fs/namei.c linux-2.6.7-rc1/fs/namei.c
1002--- linux-2.6.7-rc1.orig/fs/namei.c 2004-05-23 07:53:57.000000000 +0200
1003+++ linux-2.6.7-rc1/fs/namei.c 2004-05-25 14:33:58.669441216 +0200
1004@@ -27,6 +27,7 @@
1005 #include <linux/security.h>
1006 #include <linux/mount.h>
1007 #include <linux/audit.h>
1008+#include <linux/grsecurity.h>
1009 #include <asm/namei.h>
1010 #include <asm/uaccess.h>
1011
1012@@ -413,6 +414,13 @@
1013 err = security_inode_follow_link(dentry, nd);
1014 if (err)
1015 goto loop;
1016+
1017+ if (gr_handle_follow_link(dentry->d_parent->d_inode,
1018+ dentry->d_inode, dentry, nd->mnt)) {
1019+ err = -EACCES;
1020+ goto loop;
1021+ }
1022+
1023 current->link_count++;
1024 current->total_link_count++;
1025 touch_atime(nd->mnt, dentry);
1026@@ -764,6 +772,10 @@
1027 break;
1028 }
1029 return_base:
1030+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
1031+ path_release(nd);
1032+ return -ENOENT;
1033+ }
1034 return 0;
1035 out_dput:
1036 dput(next.dentry);
1037@@ -1225,7 +1237,7 @@
1038 if (!error) {
1039 DQUOT_INIT(inode);
1040
1041- error = do_truncate(dentry, 0);
1042+ error = do_truncate(dentry, 0, nd->mnt);
1043 }
1044 put_write_access(inode);
1045 if (error)
1046@@ -1276,6 +1288,17 @@
1047 error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
1048 if (error)
1049 return error;
1050+
1051+ if (gr_handle_rawio(nd->dentry->d_inode)) {
1052+ error = -EPERM;
1053+ goto exit;
1054+ }
1055+
1056+ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
1057+ error = -EACCES;
1058+ goto exit;
1059+ }
1060+
1061 goto ok;
1062 }
1063
1064@@ -1309,9 +1332,19 @@
1065
1066 /* Negative dentry, just create the file */
1067 if (!dentry->d_inode) {
1068+ if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
1069+ error = -EACCES;
1070+ up(&dir->d_inode->i_sem);
1071+ goto exit_dput;
1072+ }
1073+
1074 if (!IS_POSIXACL(dir->d_inode))
1075 mode &= ~current->fs->umask;
1076 error = vfs_create(dir->d_inode, dentry, mode, nd);
1077+
1078+ if (!error)
1079+ gr_handle_create(dentry, nd->mnt);
1080+
1081 up(&dir->d_inode->i_sem);
1082 dput(nd->dentry);
1083 nd->dentry = dentry;
1084@@ -1326,6 +1359,25 @@
1085 /*
1086 * It already exists.
1087 */
1088+
1089+ if (gr_handle_rawio(dentry->d_inode)) {
1090+ error = -EPERM;
1091+ up(&dir->d_inode->i_sem);
1092+ goto exit_dput;
1093+ }
1094+
1095+ if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
1096+ up(&dir->d_inode->i_sem);
1097+ error = -EACCES;
1098+ goto exit_dput;
1099+ }
1100+
1101+ if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
1102+ up(&dir->d_inode->i_sem);
1103+ error = -EACCES;
1104+ goto exit_dput;
1105+ }
1106+
1107 up(&dir->d_inode->i_sem);
1108
1109 error = -EEXIST;
1110@@ -1379,6 +1431,13 @@
1111 error = security_inode_follow_link(dentry, nd);
1112 if (error)
1113 goto exit_dput;
1114+
1115+ if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
1116+ dentry, nd->mnt)) {
1117+ error = -EACCES;
1118+ goto exit_dput;
1119+ }
1120+
1121 touch_atime(nd->mnt, dentry);
1122 error = dentry->d_inode->i_op->follow_link(dentry, nd);
1123 dput(dentry);
1124@@ -1486,6 +1545,22 @@
1125 if (!IS_POSIXACL(nd.dentry->d_inode))
1126 mode &= ~current->fs->umask;
1127 if (!IS_ERR(dentry)) {
1128+ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
1129+ error = -EPERM;
1130+ dput(dentry);
1131+ up(&nd.dentry->d_inode->i_sem);
1132+ path_release(&nd);
1133+ goto out;
1134+ }
1135+
1136+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
1137+ error = -EACCES;
1138+ dput(dentry);
1139+ up(&nd.dentry->d_inode->i_sem);
1140+ path_release(&nd);
1141+ goto out;
1142+ }
1143+
1144 switch (mode & S_IFMT) {
1145 case 0: case S_IFREG:
1146 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
1147@@ -1503,6 +1578,10 @@
1148 default:
1149 error = -EINVAL;
1150 }
1151+
1152+ if (!error)
1153+ gr_handle_create(dentry, nd.mnt);
1154+
1155 dput(dentry);
1156 }
1157 up(&nd.dentry->d_inode->i_sem);
1158@@ -1554,9 +1633,19 @@
1159 dentry = lookup_create(&nd, 1);
1160 error = PTR_ERR(dentry);
1161 if (!IS_ERR(dentry)) {
1162+ error = 0;
1163 if (!IS_POSIXACL(nd.dentry->d_inode))
1164 mode &= ~current->fs->umask;
1165- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
1166+
1167+ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
1168+ error = -EACCES;
1169+
1170+ if (!error)
1171+ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
1172+
1173+ if (!error)
1174+ gr_handle_create(dentry, nd.mnt);
1175+
1176 dput(dentry);
1177 }
1178 up(&nd.dentry->d_inode->i_sem);
1179@@ -1640,6 +1729,8 @@
1180 char * name;
1181 struct dentry *dentry;
1182 struct nameidata nd;
1183+ ino_t saved_ino = 0;
1184+ dev_t saved_dev = 0;
1185
1186 name = getname(pathname);
1187 if(IS_ERR(name))
1188@@ -1664,7 +1755,21 @@
1189 dentry = lookup_hash(&nd.last, nd.dentry);
1190 error = PTR_ERR(dentry);
1191 if (!IS_ERR(dentry)) {
1192- error = vfs_rmdir(nd.dentry->d_inode, dentry);
1193+ error = 0;
1194+ if (dentry->d_inode) {
1195+ if (dentry->d_inode->i_nlink <= 1) {
1196+ saved_ino = dentry->d_inode->i_ino;
1197+ saved_dev = dentry->d_inode->i_sb->s_dev;
1198+ }
1199+
1200+ if (!gr_acl_handle_rmdir(dentry, nd.mnt))
1201+ error = -EACCES;
1202+ }
1203+
1204+ if (!error)
1205+ error = vfs_rmdir(nd.dentry->d_inode, dentry);
1206+ if (!error && (saved_dev || saved_ino))
1207+ gr_handle_delete(saved_ino, saved_dev);
1208 dput(dentry);
1209 }
1210 up(&nd.dentry->d_inode->i_sem);
1211@@ -1718,6 +1823,8 @@
1212 struct dentry *dentry;
1213 struct nameidata nd;
1214 struct inode *inode = NULL;
1215+ ino_t saved_ino = 0;
1216+ dev_t saved_dev = 0;
1217
1218 name = getname(pathname);
1219 if(IS_ERR(name))
1220@@ -1733,13 +1840,26 @@
1221 dentry = lookup_hash(&nd.last, nd.dentry);
1222 error = PTR_ERR(dentry);
1223 if (!IS_ERR(dentry)) {
1224+ error = 0;
1225 /* Why not before? Because we want correct error value */
1226 if (nd.last.name[nd.last.len])
1227 goto slashes;
1228 inode = dentry->d_inode;
1229- if (inode)
1230+ if (inode) {
1231+ if (inode->i_nlink <= 1) {
1232+ saved_ino = inode->i_ino;
1233+ saved_dev = inode->i_sb->s_dev;
1234+ }
1235+
1236+ if (!gr_acl_handle_unlink(dentry, nd.mnt))
1237+ error = -EACCES;
1238+
1239 atomic_inc(&inode->i_count);
1240- error = vfs_unlink(nd.dentry->d_inode, dentry);
1241+ }
1242+ if (!error)
1243+ error = vfs_unlink(nd.dentry->d_inode, dentry);
1244+ if (!error && (saved_ino || saved_dev))
1245+ gr_handle_delete(saved_ino, saved_dev);
1246 exit2:
1247 dput(dentry);
1248 }
1249@@ -1803,7 +1923,15 @@
1250 dentry = lookup_create(&nd, 0);
1251 error = PTR_ERR(dentry);
1252 if (!IS_ERR(dentry)) {
1253- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
1254+ error = 0;
1255+ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
1256+ error = -EACCES;
1257+
1258+ if (!error)
1259+ error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
1260+
1261+ if (!error)
1262+ gr_handle_create(dentry, nd.mnt);
1263 dput(dentry);
1264 }
1265 up(&nd.dentry->d_inode->i_sem);
1266@@ -1887,7 +2015,20 @@
1267 new_dentry = lookup_create(&nd, 0);
1268 error = PTR_ERR(new_dentry);
1269 if (!IS_ERR(new_dentry)) {
1270- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1271+ error = 0;
1272+ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
1273+ old_nd.dentry->d_inode,
1274+ old_nd.dentry->d_inode->i_mode, to))
1275+ error = -EPERM;
1276+ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
1277+ old_nd.dentry, old_nd.mnt, to))
1278+ error = -EACCES;
1279+ if (!error)
1280+ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1281+
1282+ if (!error)
1283+ gr_handle_create(new_dentry, nd.mnt);
1284+
1285 dput(new_dentry);
1286 }
1287 up(&nd.dentry->d_inode->i_sem);
1288@@ -2109,8 +2250,16 @@
1289 if (new_dentry == trap)
1290 goto exit5;
1291
1292- error = vfs_rename(old_dir->d_inode, old_dentry,
1293+ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
1294+ old_dentry, old_dir->d_inode, oldnd.mnt,
1295+ newname);
1296+
1297+ if (!error)
1298+ error = vfs_rename(old_dir->d_inode, old_dentry,
1299 new_dir->d_inode, new_dentry);
1300+ if (!error)
1301+ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
1302+ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
1303 exit5:
1304 dput(new_dentry);
1305 exit4:
1306diff -uNr linux-2.6.7-rc1.orig/fs/namespace.c linux-2.6.7-rc1/fs/namespace.c
1307--- linux-2.6.7-rc1.orig/fs/namespace.c 2004-05-23 07:54:22.000000000 +0200
1308+++ linux-2.6.7-rc1/fs/namespace.c 2004-05-25 14:33:58.726432552 +0200
1309@@ -21,6 +21,8 @@
1310 #include <linux/namei.h>
1311 #include <linux/security.h>
1312 #include <linux/mount.h>
1313+#include <linux/sched.h>
1314+#include <linux/grsecurity.h>
1315 #include <asm/uaccess.h>
1316 #include <asm/unistd.h>
1317
1318@@ -402,6 +404,8 @@
1319 lock_kernel();
1320 retval = do_remount_sb(sb, MS_RDONLY, 0, 0);
1321 unlock_kernel();
1322+
1323+ gr_log_remount(mnt->mnt_devname, retval);
1324 }
1325 up_write(&sb->s_umount);
1326 return retval;
1327@@ -430,6 +434,9 @@
1328 if (retval)
1329 security_sb_umount_busy(mnt);
1330 up_write(&current->namespace->sem);
1331+
1332+ gr_log_unmount(mnt->mnt_devname, retval);
1333+
1334 return retval;
1335 }
1336
1337@@ -852,6 +859,11 @@
1338 if (retval)
1339 goto dput_out;
1340
1341+ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
1342+ retval = -EPERM;
1343+ goto dput_out;
1344+ }
1345+
1346 if (flags & MS_REMOUNT)
1347 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
1348 data_page);
1349@@ -864,6 +876,9 @@
1350 dev_name, data_page);
1351 dput_out:
1352 path_release(&nd);
1353+
1354+ gr_log_mount(dev_name, dir_name, retval);
1355+
1356 return retval;
1357 }
1358
1359@@ -1086,6 +1101,9 @@
1360 if (!capable(CAP_SYS_ADMIN))
1361 return -EPERM;
1362
1363+ if (gr_handle_chroot_pivot())
1364+ return -EPERM;
1365+
1366 lock_kernel();
1367
1368 error = __user_walk(new_root, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
1369diff -uNr linux-2.6.7-rc1.orig/fs/open.c linux-2.6.7-rc1/fs/open.c
1370--- linux-2.6.7-rc1.orig/fs/open.c 2004-05-23 07:53:32.000000000 +0200
1371+++ linux-2.6.7-rc1/fs/open.c 2004-05-25 14:33:58.770425864 +0200
1372@@ -22,6 +22,7 @@
1373 #include <asm/uaccess.h>
1374 #include <linux/fs.h>
1375 #include <linux/pagemap.h>
1376+#include <linux/grsecurity.h>
1377
1378 #include <asm/unistd.h>
1379
1380@@ -191,7 +192,7 @@
1381 return error;
1382 }
1383
1384-int do_truncate(struct dentry *dentry, loff_t length)
1385+int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
1386 {
1387 int err;
1388 struct iattr newattrs;
1389@@ -200,6 +201,9 @@
1390 if (length < 0)
1391 return -EINVAL;
1392
1393+ if (!gr_acl_handle_truncate(dentry, mnt))
1394+ return -EACCES;
1395+
1396 newattrs.ia_size = length;
1397 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
1398 down(&dentry->d_inode->i_sem);
1399@@ -260,7 +264,7 @@
1400 error = locks_verify_truncate(inode, NULL, length);
1401 if (!error) {
1402 DQUOT_INIT(inode);
1403- error = do_truncate(nd.dentry, length);
1404+ error = do_truncate(nd.dentry, length, nd.mnt);
1405 }
1406 put_write_access(inode);
1407
1408@@ -312,7 +316,7 @@
1409
1410 error = locks_verify_truncate(inode, file, length);
1411 if (!error)
1412- error = do_truncate(dentry, length);
1413+ error = do_truncate(dentry, length, file->f_vfsmnt);
1414 out_putf:
1415 fput(file);
1416 out:
1417@@ -391,6 +395,11 @@
1418 (error = permission(inode,MAY_WRITE,&nd)) != 0)
1419 goto dput_and_out;
1420 }
1421+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
1422+ error = -EACCES;
1423+ goto dput_and_out;
1424+ }
1425+
1426 down(&inode->i_sem);
1427 error = notify_change(nd.dentry, &newattrs);
1428 up(&inode->i_sem);
1429@@ -444,6 +453,12 @@
1430 (error = permission(inode,MAY_WRITE,&nd)) != 0)
1431 goto dput_and_out;
1432 }
1433+
1434+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
1435+ error = -EACCES;
1436+ goto dput_and_out;
1437+ }
1438+
1439 down(&inode->i_sem);
1440 error = notify_change(nd.dentry, &newattrs);
1441 up(&inode->i_sem);
1442@@ -505,6 +520,10 @@
1443 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1444 && !special_file(nd.dentry->d_inode->i_mode))
1445 res = -EROFS;
1446+
1447+ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
1448+ res = -EACCES;
1449+
1450 path_release(&nd);
1451 }
1452
1453@@ -528,6 +547,8 @@
1454 if (error)
1455 goto dput_and_out;
1456
1457+ gr_log_chdir(nd.dentry, nd.mnt);
1458+
1459 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1460
1461 dput_and_out:
1462@@ -558,6 +579,13 @@
1463 goto out_putf;
1464
1465 error = permission(inode, MAY_EXEC, NULL);
1466+
1467+ if (!error && !gr_chroot_fchdir(dentry, mnt))
1468+ error = -EPERM;
1469+
1470+ if (!error)
1471+ gr_log_chdir(dentry, mnt);
1472+
1473 if (!error)
1474 set_fs_pwd(current->fs, mnt, dentry);
1475 out_putf:
1476@@ -583,8 +611,16 @@
1477 if (!capable(CAP_SYS_CHROOT))
1478 goto dput_and_out;
1479
1480+ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
1481+ goto dput_and_out;
1482+
1483 set_fs_root(current->fs, nd.mnt, nd.dentry);
1484 set_fs_altroot();
1485+
1486+ gr_handle_chroot_caps(current);
1487+
1488+ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
1489+
1490 error = 0;
1491 dput_and_out:
1492 path_release(&nd);
1493@@ -613,9 +649,22 @@
1494 err = -EPERM;
1495 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1496 goto out_putf;
1497+
1498+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
1499+ err = -EACCES;
1500+ goto out_putf;
1501+ }
1502+
1503 down(&inode->i_sem);
1504 if (mode == (mode_t) -1)
1505 mode = inode->i_mode;
1506+
1507+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
1508+ err = -EPERM;
1509+ up(&inode->i_sem);
1510+ goto out_putf;
1511+ }
1512+
1513 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
1514 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1515 err = notify_change(dentry, &newattrs);
1516@@ -647,9 +696,21 @@
1517 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1518 goto dput_and_out;
1519
1520+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
1521+ error = -EACCES;
1522+ goto dput_and_out;
1523+ }
1524+
1525 down(&inode->i_sem);
1526 if (mode == (mode_t) -1)
1527 mode = inode->i_mode;
1528+
1529+ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
1530+ error = -EACCES;
1531+ up(&inode->i_sem);
1532+ goto dput_and_out;
1533+ }
1534+
1535 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
1536 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1537 error = notify_change(nd.dentry, &newattrs);
1538@@ -661,7 +722,7 @@
1539 return error;
1540 }
1541
1542-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
1543+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
1544 {
1545 struct inode * inode;
1546 int error;
1547@@ -678,6 +739,12 @@
1548 error = -EPERM;
1549 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1550 goto out;
1551+
1552+ if (!gr_acl_handle_chown(dentry, mnt)) {
1553+ error = -EACCES;
1554+ goto out;
1555+ }
1556+
1557 newattrs.ia_valid = ATTR_CTIME;
1558 if (user != (uid_t) -1) {
1559 newattrs.ia_valid |= ATTR_UID;
1560@@ -703,7 +770,7 @@
1561
1562 error = user_path_walk(filename, &nd);
1563 if (!error) {
1564- error = chown_common(nd.dentry, user, group);
1565+ error = chown_common(nd.dentry, user, group, nd.mnt);
1566 path_release(&nd);
1567 }
1568 return error;
1569@@ -716,7 +783,7 @@
1570
1571 error = user_path_walk_link(filename, &nd);
1572 if (!error) {
1573- error = chown_common(nd.dentry, user, group);
1574+ error = chown_common(nd.dentry, user, group, nd.mnt);
1575 path_release(&nd);
1576 }
1577 return error;
1578@@ -730,7 +797,8 @@
1579
1580 file = fget(fd);
1581 if (file) {
1582- error = chown_common(file->f_dentry, user, group);
1583+ error = chown_common(file->f_dentry, user,
1584+ group, file->f_vfsmnt);
1585 fput(file);
1586 }
1587 return error;
1588@@ -852,6 +920,7 @@
1589 * N.B. For clone tasks sharing a files structure, this test
1590 * will limit the total number of files that can be opened.
1591 */
1592+ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
1593 if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
1594 goto out;
1595
1596diff -uNr linux-2.6.7-rc1.orig/fs/proc/array.c linux-2.6.7-rc1/fs/proc/array.c
1597--- linux-2.6.7-rc1.orig/fs/proc/array.c 2004-05-23 07:54:21.000000000 +0200
1598+++ linux-2.6.7-rc1/fs/proc/array.c 2004-05-25 14:33:58.797421760 +0200
dbb7f4ea 1599@@ -323,6 +323,12 @@
1db5cd70
PS
1600
1601 wchan = get_wchan(task);
1602
dbb7f4ea 1603+#if defined(CONFIG_GRKERNSEC_PROC_MEMMAP) || defined(CONFIG_GRKERNSEC_HIDESYM)
1db5cd70
PS
1604+ wchan = 0;
1605+ eip =0;
1606+ esp =0;
1607+#endif
1608+
1609 sigemptyset(&sigign);
1610 sigemptyset(&sigcatch);
1611 read_lock(&tasklist_lock);
dbb7f4ea 1612@@ -424,3 +430,14 @@
1db5cd70
PS
1613 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
1614 size, resident, shared, text, lib, data, 0);
1615 }
1616+
1617+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
1618+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
1619+{
1620+ int len;
1621+
1622+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
1623+ return len;
1624+}
1625+#endif
1626+
1627diff -uNr linux-2.6.7-rc1.orig/fs/proc/base.c linux-2.6.7-rc1/fs/proc/base.c
1628--- linux-2.6.7-rc1.orig/fs/proc/base.c 2004-05-23 07:54:21.000000000 +0200
1629+++ linux-2.6.7-rc1/fs/proc/base.c 2004-05-25 14:33:58.811419632 +0200
1630@@ -32,6 +32,7 @@
1631 #include <linux/mount.h>
1632 #include <linux/security.h>
1633 #include <linux/ptrace.h>
1634+#include <linux/grsecurity.h>
1635
1636 /*
1637 * For hysterical raisins we keep the same inumbers as in the old procfs.
1638@@ -67,6 +68,9 @@
1639 PROC_TGID_ATTR_EXEC,
1640 PROC_TGID_ATTR_FSCREATE,
1641 #endif
1642+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
1643+ PROC_TGID_IPADDR,
1644+#endif
1645 PROC_TGID_FD_DIR,
1646 PROC_TID_INO,
1647 PROC_TID_STATUS,
1648@@ -117,6 +121,9 @@
1649 E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
1650 E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
1651 E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
1652+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
1653+ E(PROC_TGID_IPADDR, "ipaddr", S_IFREG|S_IRUSR),
1654+#endif
1655 #ifdef CONFIG_SECURITY
1656 E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
1657 #endif
1658@@ -181,6 +188,9 @@
1659 int proc_pid_status(struct task_struct*,char*);
1660 int proc_pid_statm(struct task_struct*,char*);
1661 int proc_pid_cpu(struct task_struct*,char*);
1662+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
1663+int proc_pid_ipaddr(struct task_struct*,char*);
1664+#endif
1665
1666 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
1667 {
1668@@ -277,7 +287,7 @@
1669 (task == current || \
1670 (task->parent == current && \
1671 (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED && \
1672- security_ptrace(current,task) == 0))
1673+ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
1674
1675 static int may_ptrace_attach(struct task_struct *task)
1676 {
1677@@ -292,13 +302,15 @@
1678 (current->uid != task->uid) ||
1679 (current->gid != task->egid) ||
1680 (current->gid != task->sgid) ||
1681- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
1682+ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
1683 goto out;
1684 rmb();
1685- if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
1686+ if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
1687 goto out;
1688 if (security_ptrace(current, task))
1689 goto out;
1690+ if (gr_handle_proc_ptrace(task))
1691+ goto out;
1692
1693 retval = 1;
1694 out:
1695@@ -445,9 +457,22 @@
1696
1697 static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
1698 {
1699+ int ret;
1700+ struct task_struct *task;
1701+
1702 if (vfs_permission(inode, mask) != 0)
1703 return -EACCES;
1704- return proc_check_root(inode);
1705+ ret = proc_check_root(inode);
1706+
1707+ if (ret)
1708+ return ret;
1709+
1710+ task = proc_task(inode);
1711+
1712+ if (!task)
1713+ return 0;
1714+
1715+ return gr_acl_handle_procpidmem(task);
1716 }
1717
1718 extern struct seq_operations proc_pid_maps_op;
1719@@ -954,6 +979,9 @@
1720 inode->i_uid = task->euid;
1721 inode->i_gid = task->egid;
1722 }
1723+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
1724+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
1725+#endif
1726 security_task_to_inode(task, inode);
1727
1728 out:
1729@@ -982,7 +1010,9 @@
1730 if (pid_alive(task)) {
1731 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
1732 inode->i_uid = task->euid;
1733+#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
1734 inode->i_gid = task->egid;
1735+#endif
1736 } else {
1737 inode->i_uid = 0;
1738 inode->i_gid = 0;
1739@@ -1318,6 +1348,12 @@
1740 inode->i_fop = &proc_info_file_operations;
1741 ei->op.proc_read = proc_pid_status;
1742 break;
1743+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
1744+ case PROC_TGID_IPADDR:
1745+ inode->i_fop = &proc_info_file_operations;
1746+ ei->op.proc_read = proc_pid_ipaddr;
1747+ break;
1748+#endif
1749 case PROC_TID_STAT:
1750 case PROC_TGID_STAT:
1751 inode->i_fop = &proc_info_file_operations;
1752@@ -1567,6 +1603,22 @@
1753 if (!task)
1754 goto out;
1755
1756+ if (gr_check_hidden_task(task)) {
1757+ put_task_struct(task);
1758+ goto out;
1759+ }
1760+
1761+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
1762+ if (current->uid && (task->uid != current->uid)
1763+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
1764+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
1765+#endif
1766+ ) {
1767+ put_task_struct(task);
1768+ goto out;
1769+ }
1770+#endif
1771+
1772 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
1773
1774
1775@@ -1574,7 +1626,15 @@
1776 put_task_struct(task);
1777 goto out;
1778 }
1779+
1780+#ifdef CONFIG_GRKERNSEC_PROC_USER
1781+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
1782+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
1783+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
1784+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
1785+#else
1786 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
1787+#endif
1788 inode->i_op = &proc_tgid_base_inode_operations;
1789 inode->i_fop = &proc_tgid_base_operations;
1790 inode->i_nlink = 3;
1791@@ -1658,6 +1718,9 @@
1792 static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
1793 {
1794 struct task_struct *p;
1795+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
1796+ struct task_struct *tmp = current;
1797+#endif
1798 int nr_tgids = 0;
1799
1800 index--;
1801@@ -1678,6 +1741,18 @@
1802 int tgid = p->pid;
1803 if (!pid_alive(p))
1804 continue;
1805+ if (gr_pid_is_chrooted(p))
1806+ continue;
1807+ if (gr_check_hidden_task(p))
1808+ continue;
1809+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
1810+ if (tmp->uid && (p->uid != tmp->uid)
1811+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
1812+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
1813+#endif
1814+ )
1815+ continue;
1816+#endif
1817 if (--index >= 0)
1818 continue;
1819 tgids[nr_tgids] = tgid;
1820diff -uNr linux-2.6.7-rc1.orig/fs/proc/inode.c linux-2.6.7-rc1/fs/proc/inode.c
1821--- linux-2.6.7-rc1.orig/fs/proc/inode.c 2004-05-23 07:54:43.000000000 +0200
1822+++ linux-2.6.7-rc1/fs/proc/inode.c 2004-05-25 14:33:58.814419176 +0200
1823@@ -209,7 +209,11 @@
1824 if (de->mode) {
1825 inode->i_mode = de->mode;
1826 inode->i_uid = de->uid;
1827+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
1828+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
1829+#else
1830 inode->i_gid = de->gid;
1831+#endif
1832 }
1833 if (de->size)
1834 inode->i_size = de->size;
1835diff -uNr linux-2.6.7-rc1.orig/fs/proc/proc_misc.c linux-2.6.7-rc1/fs/proc/proc_misc.c
1836--- linux-2.6.7-rc1.orig/fs/proc/proc_misc.c 2004-05-23 07:53:35.000000000 +0200
1837+++ linux-2.6.7-rc1/fs/proc/proc_misc.c 2004-05-25 14:33:58.817418720 +0200
1838@@ -654,6 +654,8 @@
1839 void __init proc_misc_init(void)
1840 {
1841 struct proc_dir_entry *entry;
1842+ int gr_mode = 0;
1843+
1844 static struct {
1845 char *name;
1846 int (*read_proc)(char*,char**,off_t,int,int*,void*);
1847@@ -668,9 +670,13 @@
1848 #ifdef CONFIG_STRAM_PROC
1849 {"stram", stram_read_proc},
1850 #endif
1851+#ifndef CONFIG_GRKERNSEC_PROC_ADD
1852 {"devices", devices_read_proc},
1853+#endif
1854 {"filesystems", filesystems_read_proc},
1855+#ifndef CONFIG_GRKERNSEC_PROC_ADD
1856 {"cmdline", cmdline_read_proc},
1857+#endif
962c3f72 1858 {"locks", locks_read_proc},
1859 {"execdomains", execdomains_read_proc},
1860 {NULL,}
1db5cd70
PS
1861@@ -681,24 +687,39 @@
1862 for (p = simple_ones; p->name; p++)
1863 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
1864
1865+#ifdef CONFIG_GRKERNSEC_PROC_USER
1866+ gr_mode = S_IRUSR;
1867+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
1868+ gr_mode = S_IRUSR | S_IRGRP;
1869+#endif
1870+#ifdef CONFIG_GRKERNSEC_PROC_ADD
1871+ create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
1872+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
1873+#endif
1874+
1875 proc_symlink("mounts", NULL, "self/mounts");
1876
1877 /* And now for trickier ones */
1878 entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
1879 if (entry)
1880 entry->proc_fops = &proc_kmsg_operations;
1881+#ifdef CONFIG_GRKERNSEC_PROC_ADD
1882+ create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
1883+ create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
1884+#else
1885 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
1886+ create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
1887+#endif
1888 create_seq_entry("partitions", 0, &proc_partitions_operations);
1889 create_seq_entry("stat", 0, &proc_stat_operations);
1890 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
1891- create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
1892 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
1893 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
1894 create_seq_entry("diskstats", 0, &proc_diskstats_operations);
1895 #ifdef CONFIG_MODULES
1896- create_seq_entry("modules", 0, &proc_modules_operations);
1897+ create_seq_entry("modules", gr_mode, &proc_modules_operations);
1898 #endif
1899-#ifdef CONFIG_PROC_KCORE
1900+#if defined(CONFIG_PROC_KCORE)
1901 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
1902 if (proc_root_kcore) {
1903 proc_root_kcore->proc_fops = &proc_kcore_operations;
1904diff -uNr linux-2.6.7-rc1.orig/fs/proc/root.c linux-2.6.7-rc1/fs/proc/root.c
1905--- linux-2.6.7-rc1.orig/fs/proc/root.c 2004-05-23 07:54:29.000000000 +0200
1906+++ linux-2.6.7-rc1/fs/proc/root.c 2004-05-25 14:33:58.819418416 +0200
1907@@ -52,13 +52,26 @@
1908 return;
1909 }
1910 proc_misc_init();
1911+
1912+#ifdef CONFIG_GRKERNSEC_PROC_USER
7d1735ed 1913+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
1db5cd70 1914+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7d1735ed 1915+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
1db5cd70 1916+#else
7d1735ed 1917 proc_net = proc_mkdir("net", NULL);
1db5cd70
PS
1918+#endif
1919 #ifdef CONFIG_SYSVIPC
7d1735ed 1920 proc_mkdir("sysvipc", NULL);
1db5cd70
PS
1921 #endif
1922 #ifdef CONFIG_SYSCTL
1923+#ifdef CONFIG_GRKERNSEC_PROC_USER
7d1735ed 1924+ proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR, NULL);
1db5cd70 1925+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7d1735ed 1926+ proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
1db5cd70 1927+#else
7d1735ed 1928 proc_sys_root = proc_mkdir("sys", NULL);
1db5cd70
PS
1929 #endif
1930+#endif
1931 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
7d1735ed 1932 proc_mkdir("sys/fs", NULL);
1933 proc_mkdir("sys/fs/binfmt_misc", NULL);
1db5cd70
PS
1934@@ -74,7 +87,15 @@
1935 #ifdef CONFIG_PROC_DEVICETREE
1936 proc_device_tree_init();
1937 #endif
1938+#ifdef CONFIG_GRKERNSEC_PROC_ADD
1939+#ifdef CONFIG_GRKERNSEC_PROC_USER
7d1735ed 1940+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
1db5cd70 1941+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7d1735ed 1942+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
1db5cd70
PS
1943+#endif
1944+#else
7d1735ed 1945 proc_bus = proc_mkdir("bus", NULL);
1db5cd70
PS
1946+#endif
1947 }
1948
1949 static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
1db5cd70
PS
1950diff -uNr linux-2.6.7-rc1.orig/fs/readdir.c linux-2.6.7-rc1/fs/readdir.c
1951--- linux-2.6.7-rc1.orig/fs/readdir.c 2004-05-23 07:54:17.000000000 +0200
1952+++ linux-2.6.7-rc1/fs/readdir.c 2004-05-25 14:33:58.841415072 +0200
1953@@ -15,6 +15,8 @@
1954 #include <linux/dirent.h>
1955 #include <linux/security.h>
1956 #include <linux/unistd.h>
1957+#include <linux/namei.h>
1958+#include <linux/grsecurity.h>
1959
1960 #include <asm/uaccess.h>
1961
1962@@ -65,6 +67,7 @@
1963 struct readdir_callback {
1964 struct old_linux_dirent __user * dirent;
1965 int result;
1966+ struct nameidata nd;
1967 };
1968
1969 static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
1970@@ -75,6 +78,10 @@
1971
1972 if (buf->result)
1973 return -EINVAL;
1974+
1975+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
1976+ return 0;
1977+
1978 buf->result++;
1979 dirent = buf->dirent;
1980 if (!access_ok(VERIFY_WRITE, (unsigned long)dirent,
1981@@ -107,6 +114,9 @@
1982 buf.result = 0;
1983 buf.dirent = dirent;
1984
1985+ buf.nd.dentry = file->f_dentry;
1986+ buf.nd.mnt = file->f_vfsmnt;
1987+
1988 error = vfs_readdir(file, fillonedir, &buf);
1989 if (error >= 0)
1990 error = buf.result;
1991@@ -134,6 +144,7 @@
1992 struct linux_dirent __user * previous;
1993 int count;
1994 int error;
1995+ struct nameidata nd;
1996 };
1997
1998 static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
1999@@ -146,6 +157,10 @@
2000 buf->error = -EINVAL; /* only used if we fail.. */
2001 if (reclen > buf->count)
2002 return -EINVAL;
2003+
2004+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
2005+ return 0;
2006+
2007 dirent = buf->previous;
2008 if (dirent) {
2009 if (__put_user(offset, &dirent->d_off))
2010@@ -193,6 +208,9 @@
2011 buf.count = count;
2012 buf.error = 0;
2013
2014+ buf.nd.dentry = file->f_dentry;
2015+ buf.nd.mnt = file->f_vfsmnt;
2016+
2017 error = vfs_readdir(file, filldir, &buf);
2018 if (error < 0)
2019 goto out_putf;
2020@@ -218,6 +236,7 @@
2021 struct linux_dirent64 __user * previous;
2022 int count;
2023 int error;
2024+ struct nameidata nd;
2025 };
2026
2027 static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
2028@@ -230,6 +249,10 @@
2029 buf->error = -EINVAL; /* only used if we fail.. */
2030 if (reclen > buf->count)
2031 return -EINVAL;
2032+
2033+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
2034+ return 0;
2035+
2036 dirent = buf->previous;
2037 if (dirent) {
2038 if (__put_user(offset, &dirent->d_off))
2039@@ -279,6 +302,9 @@
2040 buf.count = count;
2041 buf.error = 0;
2042
2043+ buf.nd.mnt = file->f_vfsmnt;
2044+ buf.nd.dentry = file->f_dentry;
2045+
2046 error = vfs_readdir(file, filldir64, &buf);
2047 if (error < 0)
2048 goto out_putf;
2049diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_alloc.c linux-2.6.7-rc1/grsecurity/gracl_alloc.c
2050--- linux-2.6.7-rc1.orig/grsecurity/gracl_alloc.c 1970-01-01 01:00:00.000000000 +0100
2051+++ linux-2.6.7-rc1/grsecurity/gracl_alloc.c 2004-05-25 14:33:58.907405040 +0200
2052@@ -0,0 +1,93 @@
2053+/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
2054+
2055+#include <linux/kernel.h>
2056+#include <linux/mm.h>
2057+#include <linux/slab.h>
2058+#include <linux/vmalloc.h>
2059+#include <linux/gracl.h>
2060+#include <linux/grsecurity.h>
2061+
2062+static unsigned long alloc_stack_next = 1;
2063+static unsigned long alloc_stack_size = 1;
2064+static void **alloc_stack;
2065+
2066+static __inline__ int
2067+alloc_pop(void)
2068+{
2069+ if (alloc_stack_next == 1)
2070+ return 0;
2071+
2072+ kfree(alloc_stack[alloc_stack_next - 2]);
2073+
2074+ alloc_stack_next--;
2075+
2076+ return 1;
2077+}
2078+
2079+static __inline__ void
2080+alloc_push(void *buf)
2081+{
2082+ if (alloc_stack_next >= alloc_stack_size)
2083+ BUG();
2084+
2085+ alloc_stack[alloc_stack_next - 1] = buf;
2086+
2087+ alloc_stack_next++;
2088+
2089+ return;
2090+}
2091+
2092+void *
2093+acl_alloc(unsigned long len)
2094+{
2095+ void *ret;
2096+
2097+ if (len > PAGE_SIZE)
2098+ BUG();
2099+
2100+ ret = kmalloc(len, GFP_KERNEL);
2101+
2102+ if (ret)
2103+ alloc_push(ret);
2104+
2105+ return ret;
2106+}
2107+
2108+void
2109+acl_free_all(void)
2110+{
2111+ if (gr_acl_is_enabled() || !alloc_stack)
2112+ return;
2113+
2114+ while (alloc_pop()) ;
2115+
2116+ if (alloc_stack) {
2117+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
2118+ kfree(alloc_stack);
2119+ else
2120+ vfree(alloc_stack);
2121+ }
2122+
2123+ alloc_stack = NULL;
2124+ alloc_stack_size = 1;
2125+ alloc_stack_next = 1;
2126+
2127+ return;
2128+}
2129+
2130+int
2131+acl_alloc_stack_init(unsigned long size)
2132+{
2133+ if ((size * sizeof (void *)) <= PAGE_SIZE)
2134+ alloc_stack =
2135+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
2136+ else
2137+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
2138+
2139+ alloc_stack_size = size;
2140+
2141+ if (!alloc_stack)
2142+ return 0;
2143+ else
2144+ return 1;
2145+}
2146diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl.c linux-2.6.7-rc1/grsecurity/gracl.c
2147--- linux-2.6.7-rc1.orig/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100
2148+++ linux-2.6.7-rc1/grsecurity/gracl.c 2004-05-25 14:33:58.905405344 +0200
6a84f544 2149@@ -0,0 +1,3311 @@
1db5cd70
PS
2150+/*
2151+ * grsecurity/gracl.c
2152+ * Copyright Brad Spengler 2001, 2002, 2003
2153+ *
2154+ */
2155+
2156+#include <linux/kernel.h>
2157+#include <linux/module.h>
2158+#include <linux/sched.h>
2159+#include <linux/mm.h>
2160+#include <linux/file.h>
2161+#include <linux/fs.h>
2162+#include <linux/namei.h>
2163+#include <linux/mount.h>
2164+#include <linux/tty.h>
2165+#include <linux/proc_fs.h>
2166+#include <linux/smp_lock.h>
2167+#include <linux/slab.h>
2168+#include <linux/vmalloc.h>
2169+#include <linux/types.h>
2170+#include <linux/capability.h>
2171+#include <linux/sysctl.h>
2172+#include <linux/ptrace.h>
2173+#include <linux/gracl.h>
2174+#include <linux/gralloc.h>
2175+#include <linux/grsecurity.h>
2176+#include <linux/grinternal.h>
2177+#include <linux/percpu.h>
2178+
2179+#include <asm/uaccess.h>
2180+#include <asm/errno.h>
2181+#include <asm/mman.h>
2182+
2183+static struct acl_role_db acl_role_set;
2184+static struct acl_role_label *role_list_head;
2185+static struct name_db name_set;
2186+static struct name_db inodev_set;
2187+
2188+/* for keeping track of userspace pointers used for subjects, so we
2189+ can share references in the kernel as well
2190+*/
2191+static struct acl_subj_map_db subj_map_set;
2192+
2193+static struct acl_role_label *default_role;
2194+
2195+static u16 acl_sp_role_value;
2196+
2197+extern char *gr_shared_page[4];
2198+static DECLARE_MUTEX(gr_dev_sem);
2199+rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
2200+
2201+struct gr_arg *gr_usermode;
2202+
2203+static unsigned long gr_status = GR_STATUS_INIT;
2204+
2205+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
2206+extern void gr_clear_learn_entries(void);
2207+
2208+#ifdef CONFIG_GRKERNSEC_RESLOG
2209+extern void gr_log_resource(const struct task_struct *task,
2210+ const int res, const unsigned long wanted, const int gt);
2211+#endif
2212+
2213+extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
2214+ struct dentry *root, struct vfsmount *rootmnt,
2215+ char *buffer, int buflen);
2216+
2217+unsigned char *gr_system_salt;
2218+unsigned char *gr_system_sum;
2219+
2220+static struct sprole_pw **acl_special_roles = NULL;
2221+static __u16 num_sprole_pws = 0;
2222+
2223+static struct acl_role_label *kernel_role = NULL;
2224+
2225+/* The following are used to keep a place held in the hash table when we move
2226+ entries around. They can be replaced during insert. */
2227+
2228+static struct acl_subject_label *deleted_subject;
2229+static struct acl_object_label *deleted_object;
2230+static struct name_entry *deleted_inodev;
2231+
2232+/* for keeping track of the last and final allocated subjects, since
2233+ nested subject parsing is tricky
2234+*/
2235+static struct acl_subject_label *s_last = NULL;
2236+static struct acl_subject_label *s_final = NULL;
2237+
2238+static unsigned int gr_auth_attempts = 0;
2239+static unsigned long gr_auth_expires = 0UL;
2240+
2241+extern int gr_init_uidset(void);
2242+extern void gr_free_uidset(void);
2243+extern void gr_remove_uid(uid_t uid);
2244+extern int gr_find_uid(uid_t uid);
2245+
2246+__inline__ int
2247+gr_acl_is_enabled(void)
2248+{
2249+ return (gr_status & GR_READY);
2250+}
2251+
2252+__inline__ int
2253+gr_acl_tpe_check(void)
2254+{
2255+ if (unlikely(!(gr_status & GR_READY)))
2256+ return 0;
2257+ if (current->role->roletype & GR_ROLE_TPE)
2258+ return 1;
2259+ else
2260+ return 0;
2261+}
2262+
2263+int
2264+gr_handle_rawio(const struct inode *inode)
2265+{
2266+ if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
2267+ ((gr_status & GR_READY)
2268+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
2269+ || (grsec_enable_chroot_caps && proc_is_chrooted(current))
2270+#endif
2271+ ))
2272+ return 1;
2273+ return 0;
2274+}
2275+
2276+
2277+static __inline__ int
2278+gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
2279+{
2280+ int i;
2281+ unsigned long *l1;
2282+ unsigned long *l2;
2283+ unsigned char *c1;
2284+ unsigned char *c2;
2285+ int num_longs;
2286+
2287+ if (likely(lena != lenb))
2288+ return 0;
2289+
2290+ l1 = (unsigned long *)a;
2291+ l2 = (unsigned long *)b;
2292+
2293+ num_longs = lena / sizeof(unsigned long);
2294+
2295+ for (i = num_longs; i--; l1++, l2++) {
2296+ if (unlikely(*l1 != *l2))
2297+ return 0;
2298+ }
2299+
2300+ c1 = (unsigned char *) l1;
2301+ c2 = (unsigned char *) l2;
2302+
2303+ i = lena - (num_longs * sizeof(unsigned long));
2304+
2305+ for (; i--; c1++, c2++) {
2306+ if (unlikely(*c1 != *c2))
2307+ return 0;
2308+ }
2309+
2310+ return 1;
2311+}
2312+
2313+static __inline__ char *
2314+__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
2315+ char *buf, int buflen)
2316+{
2317+ char *res;
2318+ struct dentry *our_dentry;
2319+ struct vfsmount *our_mount;
2320+ struct vfsmount *rootmnt;
2321+ struct dentry *root;
2322+
2323+ our_dentry = (struct dentry *) dentry;
2324+ our_mount = (struct vfsmount *) vfsmnt;
2325+
2326+ read_lock(&child_reaper->fs->lock);
2327+ rootmnt = mntget(child_reaper->fs->rootmnt);
2328+ root = dget(child_reaper->fs->root);
2329+ read_unlock(&child_reaper->fs->lock);
2330+
2331+ res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
2332+ if (unlikely(IS_ERR(res)))
2333+ res = strcpy(buf, "<path too long>");
2334+ dput(root);
2335+ mntput(rootmnt);
2336+ return res;
2337+}
2338+
2339+char *
2340+gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
2341+{
2342+ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
2343+ PAGE_SIZE);
2344+}
2345+
2346+static __inline__ char *
2347+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
2348+ char *buf, int buflen)
2349+{
2350+ char *res;
2351+ struct dentry *our_dentry;
2352+ struct vfsmount *our_mount;
2353+ struct vfsmount *rootmnt;
2354+ struct dentry *root;
2355+
2356+ our_dentry = (struct dentry *) dentry;
2357+ our_mount = (struct vfsmount *) vfsmnt;
2358+
2359+ read_lock(&child_reaper->fs->lock);
2360+ rootmnt = mntget(child_reaper->fs->rootmnt);
2361+ root = dget(child_reaper->fs->root);
2362+ read_unlock(&child_reaper->fs->lock);
2363+
2364+ spin_lock(&dcache_lock);
2365+ res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
2366+ spin_unlock(&dcache_lock);
2367+ if (unlikely(IS_ERR(res)))
2368+ res = strcpy(buf, "<path too long>");
2369+ dput(root);
2370+ mntput(rootmnt);
2371+ return res;
2372+}
2373+
2374+char *
2375+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
2376+{
2377+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
2378+ PAGE_SIZE);
2379+}
2380+
2381+char *
2382+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
2383+{
2384+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
2385+ PAGE_SIZE);
2386+}
2387+
2388+char *
2389+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
2390+{
2391+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
2392+ PAGE_SIZE);
2393+}
2394+
2395+char *
2396+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
2397+{
2398+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
2399+ PAGE_SIZE);
2400+}
2401+
2402+__inline__ __u32
2403+to_gr_audit(const __u32 reqmode)
2404+{
2405+ __u32 retmode = 0;
2406+
2407+ retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
2408+ retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
2409+ retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
2410+ retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
2411+ retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
2412+ retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
2413+ retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
2414+ retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
2415+ retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
2416+
2417+ return retmode;
2418+}
2419+
2420+__inline__ struct acl_subject_label *
2421+lookup_subject_map(const struct acl_subject_label *userp)
2422+{
2423+ unsigned long index = shash(userp, subj_map_set.s_size);
2424+ struct subject_map *match;
2425+ __u8 i = 0;
2426+
2427+ match = subj_map_set.s_hash[index];
2428+
2429+ while (match && match->user != userp) {
2430+ index = (index + (1 << i)) % subj_map_set.s_size;
2431+ match = subj_map_set.s_hash[index];
2432+ i = (i + 1) % 32;
2433+ }
2434+
2435+ if (match)
2436+ return match->kernel;
2437+ else
2438+ return NULL;
2439+}
2440+
2441+static void
2442+insert_subj_map_entry(struct subject_map *subjmap)
2443+{
2444+ unsigned long index = shash(subjmap->user, subj_map_set.s_size);
2445+ struct subject_map **curr;
2446+ __u8 i = 0;
2447+
2448+ curr = &subj_map_set.s_hash[index];
2449+
2450+ while (*curr) {
2451+ index = (index + (1 << i)) % subj_map_set.s_size;
2452+ curr = &subj_map_set.s_hash[index];
2453+ i = (i + 1) % 32;
2454+ }
2455+
2456+ *curr = subjmap;
2457+
2458+ return;
2459+}
2460+
2461+__inline__ struct acl_role_label *
2462+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
2463+ const gid_t gid)
2464+{
2465+ unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
2466+ struct acl_role_label *match;
2467+ struct role_allowed_ip *ipp;
2468+ __u8 i = 0;
2469+
2470+ match = acl_role_set.r_hash[index];
2471+
2472+ while (match
2473+ && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
2474+ index = (index + (1 << i)) % acl_role_set.r_size;
2475+ match = acl_role_set.r_hash[index];
2476+ i = (i + 1) % 32;
2477+ }
2478+
2479+ if (match == NULL) {
2480+ try_group:
2481+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
2482+ match = acl_role_set.r_hash[index];
2483+ i = 0;
2484+
2485+ while (match && (match->uidgid != gid
2486+ || !(match->roletype & GR_ROLE_GROUP))) {
2487+ index = (index + (1 << i)) % acl_role_set.r_size;
2488+ match = acl_role_set.r_hash[index];
2489+ i = (i + 1) % 32;
2490+ }
2491+
2492+ if (match == NULL)
2493+ match = default_role;
2494+ if (match->allowed_ips == NULL)
2495+ return match;
2496+ else {
2497+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
2498+ if (likely
2499+ ((task->curr_ip & ipp->netmask) ==
2500+ (ipp->addr & ipp->netmask)))
2501+ return match;
2502+ }
2503+ match = default_role;
2504+ }
2505+ } else if (match->allowed_ips == NULL) {
2506+ return match;
2507+ } else {
2508+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
2509+ if (likely
2510+ ((task->curr_ip & ipp->netmask) ==
2511+ (ipp->addr & ipp->netmask)))
2512+ return match;
2513+ }
2514+ goto try_group;
2515+ }
2516+
2517+ return match;
2518+}
2519+
2520+__inline__ struct acl_subject_label *
2521+lookup_acl_subj_label(const ino_t ino, const dev_t dev,
2522+ const struct acl_role_label *role)
2523+{
2524+ unsigned long subj_size = role->subj_hash_size;
2525+ struct acl_subject_label **s_hash = role->subj_hash;
2526+ unsigned long index = fhash(ino, dev, subj_size);
2527+ struct acl_subject_label *match;
2528+ __u8 i = 0;
2529+
2530+ match = s_hash[index];
2531+
2532+ while (match && (match->inode != ino || match->device != dev ||
2533+ (match->mode & GR_DELETED))) {
2534+ index = (index + (1 << i)) % subj_size;
2535+ match = s_hash[index];
2536+ i = (i + 1) % 32;
2537+ }
2538+
2539+ if (match && (match != deleted_subject) && !(match->mode & GR_DELETED))
2540+ return match;
2541+ else
2542+ return NULL;
2543+}
2544+
2545+static __inline__ struct acl_object_label *
2546+lookup_acl_obj_label(const ino_t ino, const dev_t dev,
2547+ const struct acl_subject_label *subj)
2548+{
2549+ unsigned long obj_size = subj->obj_hash_size;
2550+ struct acl_object_label **o_hash = subj->obj_hash;
2551+ unsigned long index = fhash(ino, dev, obj_size);
2552+ struct acl_object_label *match;
2553+ __u8 i = 0;
2554+
2555+ match = o_hash[index];
2556+
2557+ while (match && (match->inode != ino || match->device != dev ||
2558+ (match->mode & GR_DELETED))) {
2559+ index = (index + (1 << i)) % obj_size;
2560+ match = o_hash[index];
2561+ i = (i + 1) % 32;
2562+ }
2563+
2564+ if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
2565+ return match;
2566+ else
2567+ return NULL;
2568+}
2569+
2570+static __inline__ struct acl_object_label *
2571+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
2572+ const struct acl_subject_label *subj)
2573+{
2574+ unsigned long obj_size = subj->obj_hash_size;
2575+ struct acl_object_label **o_hash = subj->obj_hash;
2576+ unsigned long index = fhash(ino, dev, obj_size);
2577+ struct acl_object_label *match;
2578+ __u8 i = 0;
2579+
2580+ match = o_hash[index];
2581+
2582+ while (match && (match->inode != ino || match->device != dev ||
2583+ !(match->mode & GR_DELETED))) {
2584+ index = (index + (1 << i)) % obj_size;
2585+ match = o_hash[index];
2586+ i = (i + 1) % 32;
2587+ }
2588+
2589+ if (match && (match != deleted_object) && (match->mode & GR_DELETED))
2590+ return match;
2591+
2592+ i = 0;
2593+ index = fhash(ino, dev, obj_size);
2594+ match = o_hash[index];
2595+
2596+ while (match && (match->inode != ino || match->device != dev ||
2597+ (match->mode & GR_DELETED))) {
2598+ index = (index + (1 << i)) % obj_size;
2599+ match = o_hash[index];
2600+ i = (i + 1) % 32;
2601+ }
2602+
2603+ if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
2604+ return match;
2605+ else
2606+ return NULL;
2607+}
2608+
2609+static __inline__ struct name_entry *
2610+lookup_name_entry(const char *name)
2611+{
2612+ __u16 len = strlen(name);
2613+ unsigned long index = nhash(name, len, name_set.n_size);
2614+ struct name_entry *match;
2615+ __u8 i = 0;
2616+
2617+ match = name_set.n_hash[index];
2618+
2619+ while (match && !gr_streq(match->name, name, match->len, len)) {
2620+ index = (index + (1 << i)) % name_set.n_size;
2621+ match = name_set.n_hash[index];
2622+ i = (i + 1) % 32;
2623+ }
2624+
2625+ return match;
2626+}
2627+
2628+static __inline__ struct name_entry *
2629+lookup_inodev_entry(const ino_t ino, const dev_t dev)
2630+{
2631+ unsigned long index = fhash(ino, dev, inodev_set.n_size);
2632+ struct name_entry *match;
2633+ __u8 i = 0;
2634+
2635+ match = inodev_set.n_hash[index];
2636+
2637+ while (match && (match->inode != ino || match->device != dev)) {
2638+ index = (index + (1 << i)) % inodev_set.n_size;
2639+ match = inodev_set.n_hash[index];
2640+ i = (i + 1) % 32;
2641+ }
2642+
2643+ if (match && (match != deleted_inodev))
2644+ return match;
2645+ else
2646+ return NULL;
2647+}
2648+
2649+static void
2650+insert_inodev_entry(struct name_entry *nentry)
2651+{
2652+ unsigned long index = fhash(nentry->inode, nentry->device,
2653+ inodev_set.n_size);
2654+ struct name_entry **curr;
2655+ __u8 i = 0;
2656+
2657+ curr = &inodev_set.n_hash[index];
2658+
2659+ while (*curr && *curr != deleted_inodev) {
2660+ index = (index + (1 << i)) % inodev_set.n_size;
2661+ curr = &inodev_set.n_hash[index];
2662+ i = (i + 1) % 32;
2663+ }
2664+
2665+ *curr = nentry;
2666+
2667+ return;
2668+}
2669+
2670+static void
2671+insert_acl_role_label(struct acl_role_label *role)
2672+{
2673+ unsigned long index =
2674+ rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
2675+ struct acl_role_label **curr;
2676+ __u8 i = 0;
2677+
2678+ curr = &acl_role_set.r_hash[index];
2679+
2680+ while (*curr) {
2681+ index = (index + (1 << i)) % acl_role_set.r_size;
2682+ curr = &acl_role_set.r_hash[index];
2683+ i = (i + 1) % 32;
2684+ }
2685+
2686+ *curr = role;
2687+
2688+ return;
2689+}
2690+
2691+static int
2692+insert_name_entry(char *name, const ino_t inode, const dev_t device)
2693+{
2694+ struct name_entry **curr;
2695+ __u8 i = 0;
2696+ __u16 len = strlen(name);
2697+ unsigned long index = nhash(name, len, name_set.n_size);
2698+
2699+ curr = &name_set.n_hash[index];
2700+
2701+ while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
2702+ index = (index + (1 << i)) % name_set.n_size;
2703+ curr = &name_set.n_hash[index];
2704+ i = (i + 1) % 32;
2705+ }
2706+
2707+ if (!(*curr)) {
2708+ struct name_entry *nentry =
2709+ acl_alloc(sizeof (struct name_entry));
2710+ if (!nentry)
2711+ return 0;
2712+ nentry->name = name;
2713+ nentry->inode = inode;
2714+ nentry->device = device;
2715+ nentry->len = len;
2716+ *curr = nentry;
2717+ /* insert us into the table searchable by inode/dev */
2718+ insert_inodev_entry(nentry);
2719+ }
2720+
2721+ return 1;
2722+}
2723+
2724+static void
2725+insert_acl_obj_label(struct acl_object_label *obj,
2726+ struct acl_subject_label *subj)
2727+{
2728+ unsigned long index =
2729+ fhash(obj->inode, obj->device, subj->obj_hash_size);
2730+ struct acl_object_label **curr;
2731+ __u8 i = 0;
2732+
2733+ curr = &subj->obj_hash[index];
2734+
2735+ while (*curr && *curr != deleted_object) {
2736+ index = (index + (1 << i)) % subj->obj_hash_size;
2737+ curr = &subj->obj_hash[index];
2738+ i = (i + 1) % 32;
2739+ }
2740+
2741+ *curr = obj;
2742+
2743+ return;
2744+}
2745+
2746+static void
2747+insert_acl_subj_label(struct acl_subject_label *obj,
2748+ struct acl_role_label *role)
2749+{
2750+ unsigned long subj_size = role->subj_hash_size;
2751+ struct acl_subject_label **s_hash = role->subj_hash;
2752+ unsigned long index = fhash(obj->inode, obj->device, subj_size);
2753+ struct acl_subject_label **curr;
2754+ __u8 i = 0;
2755+
2756+ curr = &s_hash[index];
2757+
2758+ while (*curr && *curr != deleted_subject) {
2759+ index = (index + (1 << i)) % subj_size;
2760+ curr = &s_hash[index];
2761+ i = (i + 1) % 32;
2762+ }
2763+
2764+ *curr = obj;
2765+
2766+ return;
2767+}
2768+
2769+static void **
2770+create_table(__u32 * len)
2771+{
2772+ unsigned long table_sizes[] = {
2773+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
2774+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
2775+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
2776+ 268435399, 536870909, 1073741789, 2147483647
2777+ };
2778+ void *newtable = NULL;
2779+ unsigned int pwr = 0;
2780+
2781+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
2782+ table_sizes[pwr] <= (2 * (*len)))
2783+ pwr++;
2784+
2785+ if (table_sizes[pwr] <= (2 * (*len)))
2786+ return newtable;
2787+
2788+ if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
2789+ newtable =
2790+ kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
2791+ else
2792+ newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
2793+
2794+ *len = table_sizes[pwr];
2795+
2796+ return newtable;
2797+}
2798+
2799+static int
2800+init_variables(const unsigned long acl_obj_size,
2801+ const unsigned long acl_glob_size,
2802+ const unsigned long acl_subj_size,
2803+ const unsigned long acl_ip_size,
2804+ const unsigned long acl_role_size,
2805+ const unsigned long allowed_ip_size,
2806+ const unsigned long acl_trans_size,
2807+ const __u16 num_sprole_pws)
2808+{
2809+ unsigned long stacksize;
2810+
2811+ subj_map_set.s_size = acl_subj_size;
2812+ acl_role_set.r_size = acl_role_size;
2813+ name_set.n_size = (acl_obj_size + acl_subj_size);
2814+ inodev_set.n_size = (acl_obj_size + acl_subj_size);
2815+
2816+ if (!gr_init_uidset())
2817+ return 1;
2818+
2819+ /* set up the stack that holds allocation info */
2820+
2821+ stacksize = (3 * acl_obj_size) + (3 * acl_role_size) +
2822+ (6 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
2823+ allowed_ip_size + (2 * num_sprole_pws) + (2 * acl_glob_size) + 5;
2824+
2825+ if (!acl_alloc_stack_init(stacksize))
2826+ return 1;
2827+
2828+ /* create our empty, fake deleted acls */
2829+ deleted_subject =
2830+ (struct acl_subject_label *)
2831+ acl_alloc(sizeof (struct acl_subject_label));
2832+ deleted_object =
2833+ (struct acl_object_label *)
2834+ acl_alloc(sizeof (struct acl_object_label));
2835+ deleted_inodev =
2836+ (struct name_entry *) acl_alloc(sizeof (struct name_entry));
2837+
2838+ if (!deleted_subject || !deleted_object || !deleted_inodev)
2839+ return 1;
2840+
2841+ memset(deleted_subject, 0, sizeof (struct acl_subject_label));
2842+ memset(deleted_object, 0, sizeof (struct acl_object_label));
2843+ memset(deleted_inodev, 0, sizeof (struct name_entry));
2844+
2845+ /* We only want 50% full tables for now */
2846+
2847+ subj_map_set.s_hash =
2848+ (struct subject_map **) create_table(&subj_map_set.s_size);
2849+ acl_role_set.r_hash =
2850+ (struct acl_role_label **) create_table(&acl_role_set.r_size);
2851+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
2852+ inodev_set.n_hash =
2853+ (struct name_entry **) create_table(&inodev_set.n_size);
2854+
2855+ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
2856+ !name_set.n_hash || !inodev_set.n_hash)
2857+ return 1;
2858+
2859+ memset(subj_map_set.s_hash, 0,
2860+ sizeof(struct subject_map *) * subj_map_set.s_size);
2861+ memset(acl_role_set.r_hash, 0,
2862+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
2863+ memset(name_set.n_hash, 0,
2864+ sizeof (struct name_entry *) * name_set.n_size);
2865+ memset(inodev_set.n_hash, 0,
2866+ sizeof (struct name_entry *) * inodev_set.n_size);
2867+
2868+ return 0;
2869+}
2870+
2871+/* free information not needed after startup
2872+ currently contains user->kernel pointer mappings for subjects
2873+*/
2874+
2875+static void
2876+free_init_variables(void)
2877+{
2878+ __u32 i;
2879+
2880+ if (subj_map_set.s_hash) {
2881+ for (i = 0; i < subj_map_set.s_size; i++) {
2882+ if (subj_map_set.s_hash[i]) {
2883+ kfree(subj_map_set.s_hash[i]);
2884+ subj_map_set.s_hash[i] = NULL;
2885+ }
2886+ }
2887+
2888+ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
2889+ PAGE_SIZE)
2890+ kfree(subj_map_set.s_hash);
2891+ else
2892+ vfree(subj_map_set.s_hash);
2893+ }
2894+
2895+ return;
2896+}
2897+
2898+static void
2899+free_variables(void)
2900+{
2901+ struct acl_subject_label *s;
2902+ struct acl_role_label *r;
2903+ struct task_struct *task, *task2;
2904+
2905+ gr_clear_learn_entries();
2906+
2907+ read_lock(&tasklist_lock);
2908+ for_each_process(task) {
2909+ task2 = task;
2910+ do {
2911+ task2->acl_sp_role = 0;
2912+ task2->acl_role_id = 0;
2913+ task2->acl = NULL;
2914+ task2->role = NULL;
2915+ } while ((task2 = next_thread(task2)) != task);
2916+ }
2917+ read_unlock(&tasklist_lock);
2918+
2919+ /* free all object hash tables */
2920+
2921+ if (role_list_head) {
2922+ for (r = role_list_head; r; r = r->next) {
2923+ if (!r->subj_hash)
2924+ break;
2925+ for (s = r->hash->first; s; s = s->next) {
2926+ if (!s->obj_hash)
2927+ break;
2928+ if ((s->obj_hash_size *
2929+ sizeof (struct acl_object_label *)) <=
2930+ PAGE_SIZE)
2931+ kfree(s->obj_hash);
2932+ else
2933+ vfree(s->obj_hash);
2934+ }
2935+ if ((r->subj_hash_size *
2936+ sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
2937+ kfree(r->subj_hash);
2938+ else
2939+ vfree(r->subj_hash);
2940+ }
2941+ }
2942+
2943+ acl_free_all();
2944+
2945+ if (acl_role_set.r_hash) {
2946+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
2947+ PAGE_SIZE)
2948+ kfree(acl_role_set.r_hash);
2949+ else
2950+ vfree(acl_role_set.r_hash);
2951+ }
2952+ if (name_set.n_hash) {
2953+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
2954+ PAGE_SIZE)
2955+ kfree(name_set.n_hash);
2956+ else
2957+ vfree(name_set.n_hash);
2958+ }
2959+
2960+ if (inodev_set.n_hash) {
2961+ if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
2962+ PAGE_SIZE)
2963+ kfree(inodev_set.n_hash);
2964+ else
2965+ vfree(inodev_set.n_hash);
2966+ }
2967+
2968+ gr_free_uidset();
2969+
2970+ memset(&name_set, 0, sizeof (struct name_db));
2971+ memset(&inodev_set, 0, sizeof (struct name_db));
2972+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
2973+ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
2974+
2975+ role_list_head = NULL;
2976+ default_role = NULL;
2977+
2978+ return;
2979+}
2980+
2981+static __u32
2982+count_user_objs(struct acl_object_label *userp)
2983+{
2984+ struct acl_object_label o_tmp;
2985+ __u32 num = 0;
2986+
2987+ while (userp) {
2988+ if (copy_from_user(&o_tmp, userp,
2989+ sizeof (struct acl_object_label)))
2990+ break;
2991+
2992+ userp = o_tmp.prev;
2993+ num++;
2994+ }
2995+
2996+ return num;
2997+}
2998+
2999+static struct acl_subject_label *
3000+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
3001+
3002+static int
3003+copy_user_glob(struct acl_object_label *obj)
3004+{
3005+ struct acl_object_label *g_tmp, **guser, *glast = NULL;
3006+ unsigned int len;
3007+ char *tmp;
3008+
3009+ if (obj->globbed == NULL)
3010+ return 0;
3011+
3012+ guser = &obj->globbed;
3013+ while (*guser) {
3014+ g_tmp = (struct acl_object_label *)
3015+ acl_alloc(sizeof (struct acl_object_label));
3016+ if (g_tmp == NULL)
3017+ return -ENOMEM;
3018+
3019+ if (copy_from_user(g_tmp, *guser,
3020+ sizeof (struct acl_object_label)))
3021+ return -EFAULT;
3022+
3023+ len = strnlen_user(g_tmp->filename, PATH_MAX);
3024+
3025+ if (!len || len >= PATH_MAX)
3026+ return -EINVAL;
3027+
3028+ if ((tmp = (char *) acl_alloc(len)) == NULL)
3029+ return -ENOMEM;
3030+
3031+ if (copy_from_user(tmp, g_tmp->filename, len))
3032+ return -EFAULT;
3033+
3034+ g_tmp->filename = tmp;
3035+
3036+ if (glast)
3037+ glast->next = g_tmp;
3038+ g_tmp->prev = glast;
3039+ *guser = g_tmp;
3040+ glast = g_tmp;
3041+ guser = &((*guser)->next);
3042+ }
3043+
3044+ return 0;
3045+}
3046+
3047+static int
3048+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
3049+ struct acl_role_label *role)
3050+{
3051+ struct acl_object_label *o_tmp;
3052+ unsigned int len;
3053+ int ret;
3054+ char *tmp;
3055+
3056+ while (userp) {
3057+ if ((o_tmp = (struct acl_object_label *)
3058+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
3059+ return -ENOMEM;
3060+
3061+ if (copy_from_user(o_tmp, userp,
3062+ sizeof (struct acl_object_label)))
3063+ return -EFAULT;
3064+
3065+ userp = o_tmp->prev;
3066+
3067+ len = strnlen_user(o_tmp->filename, PATH_MAX);
3068+
3069+ if (!len || len >= PATH_MAX)
3070+ return -EINVAL;
3071+
3072+ if ((tmp = (char *) acl_alloc(len)) == NULL)
3073+ return -ENOMEM;
3074+
3075+ if (copy_from_user(tmp, o_tmp->filename, len))
3076+ return -EFAULT;
3077+
3078+ o_tmp->filename = tmp;
3079+
3080+ insert_acl_obj_label(o_tmp, subj);
3081+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
3082+ o_tmp->device))
3083+ return -ENOMEM;
3084+
3085+ ret = copy_user_glob(o_tmp);
3086+ if (ret)
3087+ return ret;
3088+
3089+ if (o_tmp->nested) {
3090+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
3091+ if (IS_ERR(o_tmp->nested))
3092+ return PTR_ERR(o_tmp->nested);
3093+
3094+ s_final = o_tmp->nested;
3095+ }
3096+ }
3097+
3098+ return 0;
3099+}
3100+
3101+static __u32
3102+count_user_subjs(struct acl_subject_label *userp)
3103+{
3104+ struct acl_subject_label s_tmp;
3105+ __u32 num = 0;
3106+
3107+ while (userp) {
3108+ if (copy_from_user(&s_tmp, userp,
3109+ sizeof (struct acl_subject_label)))
3110+ break;
3111+
3112+ userp = s_tmp.prev;
3113+ /* do not count nested subjects against this count, since
3114+ they are not included in the hash table, but are
3115+ attached to objects. We have already counted
3116+ the subjects in userspace for the allocation
3117+ stack
3118+ */
3119+ if (!(s_tmp.mode & GR_NESTED))
3120+ num++;
3121+ }
3122+
3123+ return num;
3124+}
3125+
3126+static int
3127+copy_user_allowedips(struct acl_role_label *rolep)
3128+{
3129+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
3130+
3131+ ruserip = rolep->allowed_ips;
3132+
3133+ while (ruserip) {
3134+ rlast = rtmp;
3135+
3136+ if ((rtmp = (struct role_allowed_ip *)
3137+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
3138+ return -ENOMEM;
3139+
3140+ if (copy_from_user(rtmp, ruserip,
3141+ sizeof (struct role_allowed_ip)))
3142+ return -EFAULT;
3143+
3144+ ruserip = rtmp->prev;
3145+
3146+ if (!rlast) {
3147+ rtmp->prev = NULL;
3148+ rolep->allowed_ips = rtmp;
3149+ } else {
3150+ rlast->next = rtmp;
3151+ rtmp->prev = rlast;
3152+ }
3153+
3154+ if (!ruserip)
3155+ rtmp->next = NULL;
3156+ }
3157+
3158+ return 0;
3159+}
3160+
3161+static int
3162+copy_user_transitions(struct acl_role_label *rolep)
3163+{
3164+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
3165+ unsigned int len;
3166+ char *tmp;
3167+
3168+ rusertp = rolep->transitions;
3169+
3170+ while (rusertp) {
3171+ rlast = rtmp;
3172+
3173+ if ((rtmp = (struct role_transition *)
3174+ acl_alloc(sizeof (struct role_transition))) == NULL)
3175+ return -ENOMEM;
3176+
3177+ if (copy_from_user(rtmp, rusertp,
3178+ sizeof (struct role_transition)))
3179+ return -EFAULT;
3180+
3181+ rusertp = rtmp->prev;
3182+
3183+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
3184+
3185+ if (!len || len >= GR_SPROLE_LEN)
3186+ return -EINVAL;
3187+
3188+ if ((tmp = (char *) acl_alloc(len)) == NULL)
3189+ return -ENOMEM;
3190+
3191+ if (copy_from_user(tmp, rtmp->rolename, len))
3192+ return -EFAULT;
3193+
3194+ rtmp->rolename = tmp;
3195+
3196+ if (!rlast) {
3197+ rtmp->prev = NULL;
3198+ rolep->transitions = rtmp;
3199+ } else {
3200+ rlast->next = rtmp;
3201+ rtmp->prev = rlast;
3202+ }
3203+
3204+ if (!rusertp)
3205+ rtmp->next = NULL;
3206+ }
3207+
3208+ return 0;
3209+}
3210+
3211+static struct acl_subject_label *
3212+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
3213+{
3214+ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
3215+ unsigned int len;
3216+ char *tmp;
3217+ __u32 num_objs;
3218+ struct acl_ip_label **i_tmp, *i_utmp2;
3219+ struct gr_hash_struct ghash;
3220+ struct subject_map *subjmap;
3221+ unsigned long i_num;
3222+ int err;
3223+
3224+ s_tmp = lookup_subject_map(userp);
3225+
3226+ /* we've already copied this subject into the kernel, just return
3227+ the reference to it, and don't copy it over again
3228+ */
3229+ if (s_tmp)
3230+ return(s_tmp);
3231+
3232+
3233+ if ((s_tmp = (struct acl_subject_label *)
3234+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
3235+ return ERR_PTR(-ENOMEM);
3236+
3237+ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
3238+ if (subjmap == NULL)
3239+ return ERR_PTR(-ENOMEM);
3240+
3241+ subjmap->user = userp;
3242+ subjmap->kernel = s_tmp;
3243+ insert_subj_map_entry(subjmap);
3244+
3245+ if (copy_from_user(s_tmp, userp,
3246+ sizeof (struct acl_subject_label)))
3247+ return ERR_PTR(-EFAULT);
3248+
3249+ if (!s_last) {
3250+ s_tmp->prev = NULL;
3251+ role->hash->first = s_tmp;
3252+ } else {
3253+ s_last->next = s_tmp;
3254+ s_tmp->prev = s_last;
3255+ }
3256+
3257+ s_last = s_tmp;
3258+
3259+ len = strnlen_user(s_tmp->filename, PATH_MAX);
3260+
3261+ if (!len || len >= PATH_MAX)
3262+ return ERR_PTR(-EINVAL);
3263+
3264+ if ((tmp = (char *) acl_alloc(len)) == NULL)
3265+ return ERR_PTR(-ENOMEM);
3266+
3267+ if (copy_from_user(tmp, s_tmp->filename, len))
3268+ return ERR_PTR(-EFAULT);
3269+
3270+ s_tmp->filename = tmp;
3271+
3272+ if (!strcmp(s_tmp->filename, "/"))
3273+ role->root_label = s_tmp;
3274+
3275+ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
3276+ return ERR_PTR(-EFAULT);
3277+
3278+ /* copy user and group transition tables */
3279+
3280+ if (s_tmp->user_trans_num) {
3281+ uid_t *uidlist;
3282+
3283+ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
3284+ if (uidlist == NULL)
3285+ return ERR_PTR(-ENOMEM);
3286+ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
3287+ return ERR_PTR(-EFAULT);
3288+
3289+ s_tmp->user_transitions = uidlist;
3290+ }
3291+
3292+ if (s_tmp->group_trans_num) {
3293+ gid_t *gidlist;
3294+
3295+ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
3296+ if (gidlist == NULL)
3297+ return ERR_PTR(-ENOMEM);
3298+ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
3299+ return ERR_PTR(-EFAULT);
3300+
3301+ s_tmp->group_transitions = gidlist;
3302+ }
3303+
3304+ /* set up object hash table */
3305+ num_objs = count_user_objs(ghash.first);
3306+
3307+ s_tmp->obj_hash_size = num_objs;
3308+ s_tmp->obj_hash =
3309+ (struct acl_object_label **)
3310+ create_table(&(s_tmp->obj_hash_size));
3311+
3312+ if (!s_tmp->obj_hash)
3313+ return ERR_PTR(-ENOMEM);
3314+
3315+ memset(s_tmp->obj_hash, 0,
3316+ s_tmp->obj_hash_size *
3317+ sizeof (struct acl_object_label *));
3318+
3319+ /* copy before adding in objects, since a nested
3320+ acl could be found and be the final subject
3321+ copied
3322+ */
3323+
3324+ s_final = s_tmp;
3325+
3326+ /* add in objects */
3327+ err = copy_user_objs(ghash.first, s_tmp, role);
3328+
3329+ if (err)
3330+ return ERR_PTR(err);
3331+
3332+ /* set pointer for parent subject */
3333+ if (s_tmp->parent_subject) {
3334+ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
3335+
3336+ if (IS_ERR(s_tmp2))
3337+ return s_tmp2;
3338+
3339+ s_tmp->parent_subject = s_tmp2;
3340+ }
3341+
3342+ /* add in ip acls */
3343+
3344+ if (!s_tmp->ip_num) {
3345+ s_tmp->ips = NULL;
3346+ goto insert;
3347+ }
3348+
3349+ i_tmp =
3350+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
3351+ sizeof (struct
3352+ acl_ip_label *));
3353+
3354+ if (!i_tmp)
3355+ return ERR_PTR(-ENOMEM);
3356+
3357+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
3358+ *(i_tmp + i_num) =
3359+ (struct acl_ip_label *)
3360+ acl_alloc(sizeof (struct acl_ip_label));
3361+ if (!*(i_tmp + i_num))
3362+ return ERR_PTR(-ENOMEM);
3363+
3364+ if (copy_from_user
3365+ (&i_utmp2, s_tmp->ips + i_num,
3366+ sizeof (struct acl_ip_label *)))
3367+ return ERR_PTR(-EFAULT);
3368+
3369+ if (copy_from_user
3370+ (*(i_tmp + i_num), i_utmp2,
3371+ sizeof (struct acl_ip_label)))
3372+ return ERR_PTR(-EFAULT);
3373+ }
3374+
3375+ s_tmp->ips = i_tmp;
3376+
3377+insert:
3378+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
3379+ s_tmp->device))
3380+ return ERR_PTR(-ENOMEM);
3381+
3382+ return s_tmp;
3383+}
3384+
3385+static int
3386+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
3387+{
3388+ struct acl_subject_label s_pre;
3389+ struct acl_subject_label * ret;
3390+ int err;
3391+
3392+ while (userp) {
3393+ if (copy_from_user(&s_pre, userp,
3394+ sizeof (struct acl_subject_label)))
3395+ return -EFAULT;
3396+
3397+ /* do not add nested subjects here, add
3398+ while parsing objects
3399+ */
3400+
3401+ if (s_pre.mode & GR_NESTED) {
3402+ userp = s_pre.prev;
3403+ continue;
3404+ }
3405+
3406+ ret = do_copy_user_subj(userp, role);
3407+
3408+ err = PTR_ERR(ret);
3409+ if (IS_ERR(ret))
3410+ return err;
3411+
3412+ insert_acl_subj_label(ret, role);
3413+
3414+ userp = s_pre.prev;
3415+ }
3416+
3417+ s_final->next = NULL;
3418+
3419+ return 0;
3420+}
3421+
3422+static int
3423+copy_user_acl(struct gr_arg *arg)
3424+{
3425+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
3426+ struct sprole_pw *sptmp;
3427+ struct gr_hash_struct *ghash;
3428+ unsigned long r_num;
3429+ unsigned int len;
3430+ char *tmp;
3431+ int err = 0;
3432+ __u16 i;
3433+ __u32 num_subjs;
3434+
3435+ /* we need a default and kernel role */
3436+ if (arg->role_db.r_entries < 2)
3437+ return -EINVAL;
3438+
3439+ /* copy special role authentication info from userspace */
3440+
3441+ num_sprole_pws = arg->num_sprole_pws;
3442+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
3443+
3444+ if (!acl_special_roles) {
3445+ err = -ENOMEM;
3446+ goto cleanup;
3447+ }
3448+
3449+ for (i = 0; i < num_sprole_pws; i++) {
3450+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
3451+ if (!sptmp) {
3452+ err = -ENOMEM;
3453+ goto cleanup;
3454+ }
3455+ if (copy_from_user(sptmp, arg->sprole_pws + i,
3456+ sizeof (struct sprole_pw))) {
3457+ err = -EFAULT;
3458+ goto cleanup;
3459+ }
3460+
3461+ len =
3462+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
3463+
3464+ if (!len || len >= GR_SPROLE_LEN) {
3465+ err = -EINVAL;
3466+ goto cleanup;
3467+ }
3468+
3469+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
3470+ err = -ENOMEM;
3471+ goto cleanup;
3472+ }
3473+
3474+ if (copy_from_user(tmp, sptmp->rolename, len)) {
3475+ err = -EFAULT;
3476+ goto cleanup;
3477+ }
3478+
3479+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
3480+ printk(KERN_ALERT "Copying special role %s\n", tmp);
3481+#endif
3482+ sptmp->rolename = tmp;
3483+ acl_special_roles[i] = sptmp;
3484+ }
3485+
3486+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
3487+
3488+ for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
3489+ r_last = r_tmp;
3490+
3491+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
3492+
3493+ if (!r_tmp) {
3494+ err = -ENOMEM;
3495+ goto cleanup;
3496+ }
3497+
3498+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
3499+ sizeof (struct acl_role_label *))) {
3500+ err = -EFAULT;
3501+ goto cleanup;
3502+ }
3503+
3504+ if (copy_from_user(r_tmp, r_utmp2,
3505+ sizeof (struct acl_role_label))) {
3506+ err = -EFAULT;
3507+ goto cleanup;
3508+ }
3509+
3510+ if (!r_last) {
3511+ r_tmp->prev = NULL;
3512+ role_list_head = r_tmp;
3513+ } else {
3514+ r_last->next = r_tmp;
3515+ r_tmp->prev = r_last;
3516+ }
3517+
3518+ if (r_num == (arg->role_db.r_entries - 1))
3519+ r_tmp->next = NULL;
3520+
3521+ len = strnlen_user(r_tmp->rolename, PATH_MAX);
3522+
3523+ if (!len || len >= PATH_MAX) {
3524+ err = -EINVAL;
3525+ goto cleanup;
3526+ }
3527+
3528+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
3529+ err = -ENOMEM;
3530+ goto cleanup;
3531+ }
3532+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
3533+ err = -EFAULT;
3534+ goto cleanup;
3535+ }
3536+ r_tmp->rolename = tmp;
3537+
3538+ if (!strcmp(r_tmp->rolename, "default")
3539+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
3540+ default_role = r_tmp;
3541+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
3542+ kernel_role = r_tmp;
3543+ }
3544+
3545+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
3546+ err = -ENOMEM;
3547+ goto cleanup;
3548+ }
3549+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
3550+ err = -EFAULT;
3551+ goto cleanup;
3552+ }
3553+
3554+ r_tmp->hash = ghash;
3555+
3556+ num_subjs = count_user_subjs(r_tmp->hash->first);
3557+
3558+ r_tmp->subj_hash_size = num_subjs;
3559+ r_tmp->subj_hash =
3560+ (struct acl_subject_label **)
3561+ create_table(&(r_tmp->subj_hash_size));
3562+
3563+ if (!r_tmp->subj_hash) {
3564+ err = -ENOMEM;
3565+ goto cleanup;
3566+ }
3567+
3568+ err = copy_user_allowedips(r_tmp);
3569+ if (err)
3570+ goto cleanup;
3571+
3572+ err = copy_user_transitions(r_tmp);
3573+ if (err)
3574+ goto cleanup;
3575+
3576+ memset(r_tmp->subj_hash, 0,
3577+ r_tmp->subj_hash_size *
3578+ sizeof (struct acl_subject_label *));
3579+
3580+ s_last = NULL;
3581+
3582+ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
3583+
3584+ if (err)
3585+ goto cleanup;
3586+
3587+ insert_acl_role_label(r_tmp);
3588+ }
3589+
3590+ goto return_err;
3591+ cleanup:
3592+ free_variables();
3593+ return_err:
3594+ return err;
3595+
3596+}
3597+
3598+static int
3599+gracl_init(struct gr_arg *args)
3600+{
3601+ int error = 0;
3602+
3603+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
3604+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
3605+
3606+ if (init_variables(args->role_db.o_entries, args->role_db.g_entries,
3607+ args->role_db.s_entries, args->role_db.i_entries,
3608+ args->role_db.r_entries, args->role_db.a_entries,
3609+ args->role_db.t_entries, args->num_sprole_pws)) {
3610+ security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
3611+ error = -ENOMEM;
3612+ free_variables();
3613+ goto out;
3614+ }
3615+
3616+ error = copy_user_acl(args);
3617+ free_init_variables();
3618+ if (error) {
3619+ free_variables();
3620+ goto out;
3621+ }
3622+
3623+ if ((error = gr_set_acls(0))) {
3624+ free_variables();
3625+ goto out;
3626+ }
3627+
3628+ gr_status |= GR_READY;
3629+ out:
3630+ return error;
3631+}
3632+
3633+static int
3634+glob_match(char *pattern, char *string)
3635+{
3636+ char *p1, *p2;
3637+
3638+ p1 = pattern;
3639+ p2 = string;
3640+
3641+ while (*p1 != '\0' && *p2 != '\0' && *p1 != '*') {
3642+ if (*p1 == *p2 || *p1 == '?') {
3643+ p1++;
3644+ p2++;
3645+ } else
3646+ break;
3647+ }
3648+ if (*p1 == '*') {
3649+ p1++;
3650+ while (*p2 != '\0') {
3651+ if (!glob_match(p1, p2))
3652+ return 0;
3653+ else
3654+ p2++;
3655+ }
3656+ }
3657+
3658+ if (*p2 == '\0' && *p1 == '*')
3659+ while (*p1 == '*')
3660+ p1++;
3661+
3662+ if (*p1 == '\0' && *p2 == '\0')
3663+ return 0;
3664+ else
3665+ return 1;
3666+}
3667+
3668+static struct acl_object_label *
3669+chk_glob_label(struct acl_object_label *globbed,
3670+ struct dentry *dentry, struct vfsmount *mnt, char **path)
3671+{
3672+ struct acl_object_label *tmp;
3673+
3674+ if (*path == NULL)
3675+ *path = gr_to_filename_nolock(dentry, mnt);
3676+
3677+ tmp = globbed;
3678+
3679+ while (tmp) {
3680+ if (!glob_match(tmp->filename, *path))
3681+ return tmp;
3682+ tmp = tmp->next;
3683+ }
3684+
3685+ return NULL;
3686+}
3687+
3688+static __inline__ struct acl_object_label *
3689+full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
3690+ struct dentry *curr_dentry,
3691+ const struct acl_subject_label *subj, char **path)
3692+{
3693+ struct acl_subject_label *tmpsubj;
3694+ struct acl_object_label *retval;
3695+ struct acl_object_label *retval2;
3696+
3697+ tmpsubj = (struct acl_subject_label *) subj;
3698+ read_lock(&gr_inode_lock);
3699+ do {
3700+ retval = lookup_acl_obj_label(curr_dentry->d_inode->i_ino,
3701+ curr_dentry->d_inode->i_sb->s_dev, tmpsubj);
3702+ if (retval) {
3703+ if (retval->globbed) {
3704+ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
3705+ (struct vfsmount *)orig_mnt, path);
3706+ if (retval2)
3707+ retval = retval2;
3708+ }
3709+ break;
3710+ }
3711+ } while ((tmpsubj = tmpsubj->parent_subject));
3712+ read_unlock(&gr_inode_lock);
3713+
3714+ return retval;
3715+}
3716+
3717+static struct acl_object_label *
3718+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
3719+ const struct acl_subject_label *subj)
3720+{
3721+ struct dentry *dentry = (struct dentry *) l_dentry;
3722+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
3723+ struct dentry *root;
3724+ struct vfsmount *rootmnt;
3725+ struct acl_object_label *retval;
3726+ char *path = NULL;
3727+
3728+ read_lock(&child_reaper->fs->lock);
3729+ rootmnt = mntget(child_reaper->fs->rootmnt);
3730+ root = dget(child_reaper->fs->root);
3731+ read_unlock(&child_reaper->fs->lock);
3732+ spin_lock(&dcache_lock);
3733+
3734+ for (;;) {
3735+ if (dentry == root && mnt == rootmnt)
3736+ break;
3737+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
3738+ if (mnt->mnt_parent == mnt)
3739+ break;
3740+
3741+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
3742+ if (retval != NULL)
3743+ goto out;
3744+
3745+ dentry = mnt->mnt_mountpoint;
3746+ mnt = mnt->mnt_parent;
3747+ continue;
3748+ }
3749+
3750+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
3751+ if (retval != NULL)
3752+ goto out;
3753+
3754+ dentry = dentry->d_parent;
3755+ }
3756+
3757+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
3758+
3759+ if (retval == NULL)
3760+ retval = full_lookup(l_dentry, l_mnt, root, subj, &path);
3761+out:
3762+ spin_unlock(&dcache_lock);
3763+ dput(root);
3764+ mntput(rootmnt);
3765+
3766+ return retval;
3767+}
3768+
3769+static struct acl_object_label *
3770+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
3771+ const struct acl_subject_label *subj, char *path)
3772+{
3773+ struct dentry *dentry = (struct dentry *) l_dentry;
3774+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
3775+ struct dentry *root;
3776+ struct vfsmount *rootmnt;
3777+ struct acl_object_label *retval;
3778+
3779+ read_lock(&child_reaper->fs->lock);
3780+ rootmnt = mntget(child_reaper->fs->rootmnt);
3781+ root = dget(child_reaper->fs->root);
3782+ read_unlock(&child_reaper->fs->lock);
3783+ spin_lock(&dcache_lock);
3784+
3785+ for (;;) {
3786+ if (dentry == root && mnt == rootmnt)
3787+ break;
3788+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
3789+ if (mnt->mnt_parent == mnt)
3790+ break;
3791+
3792+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
3793+ if (retval != NULL)
3794+ goto out;
3795+
3796+ dentry = mnt->mnt_mountpoint;
3797+ mnt = mnt->mnt_parent;
3798+ continue;
3799+ }
3800+
3801+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
3802+ if (retval != NULL)
3803+ goto out;
3804+
3805+ dentry = dentry->d_parent;
3806+ }
3807+
3808+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
3809+
3810+ if (retval == NULL)
3811+ retval = full_lookup(l_dentry, l_mnt, root, subj, &path);
3812+out:
3813+ spin_unlock(&dcache_lock);
3814+ dput(root);
3815+ mntput(rootmnt);
3816+
3817+ return retval;
3818+}
3819+
3820+static struct acl_subject_label *
3821+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
3822+ const struct acl_role_label *role)
3823+{
3824+ struct dentry *dentry = (struct dentry *) l_dentry;
3825+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
3826+ struct dentry *root;
3827+ struct vfsmount *rootmnt;
3828+ struct acl_subject_label *retval;
3829+
3830+ read_lock(&child_reaper->fs->lock);
3831+ rootmnt = mntget(child_reaper->fs->rootmnt);
3832+ root = dget(child_reaper->fs->root);
3833+ read_unlock(&child_reaper->fs->lock);
3834+ spin_lock(&dcache_lock);
3835+
3836+ for (;;) {
3837+ if (unlikely(dentry == root && mnt == rootmnt))
3838+ break;
3839+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
3840+ if (mnt->mnt_parent == mnt)
3841+ break;
3842+
3843+ read_lock(&gr_inode_lock);
3844+ retval =
3845+ lookup_acl_subj_label(dentry->d_inode->i_ino,
3846+ dentry->d_inode->i_sb->s_dev, role);
3847+ read_unlock(&gr_inode_lock);
3848+ if (unlikely(retval != NULL))
3849+ goto out;
3850+
3851+ dentry = mnt->mnt_mountpoint;
3852+ mnt = mnt->mnt_parent;
3853+ continue;
3854+ }
3855+
3856+ read_lock(&gr_inode_lock);
3857+ retval =
3858+ lookup_acl_subj_label(dentry->d_inode->i_ino,
3859+ dentry->d_inode->i_sb->s_dev, role);
3860+ read_unlock(&gr_inode_lock);
3861+ if (unlikely(retval != NULL))
3862+ goto out;
3863+
3864+ dentry = dentry->d_parent;
3865+ }
3866+
3867+ read_lock(&gr_inode_lock);
3868+ retval =
3869+ lookup_acl_subj_label(dentry->d_inode->i_ino,
3870+ dentry->d_inode->i_sb->s_dev, role);
3871+ read_unlock(&gr_inode_lock);
3872+
3873+ if (unlikely(retval == NULL)) {
3874+ read_lock(&gr_inode_lock);
3875+ retval =
3876+ lookup_acl_subj_label(root->d_inode->i_ino,
3877+ root->d_inode->i_sb->s_dev, role);
3878+ read_unlock(&gr_inode_lock);
3879+ }
3880+ out:
3881+ spin_unlock(&dcache_lock);
3882+ dput(root);
3883+ mntput(rootmnt);
3884+
3885+ return retval;
3886+}
3887+
3888+static __inline__ void
3889+gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
3890+ const struct task_struct *task, const char *pathname,
3891+ const __u32 mode)
3892+{
3893+ security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
3894+ uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
3895+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
3896+ 1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
3897+
3898+ return;
3899+}
3900+
3901+__u32
3902+gr_check_link(const struct dentry * new_dentry,
3903+ const struct dentry * parent_dentry,
3904+ const struct vfsmount * parent_mnt,
3905+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
3906+{
3907+ struct acl_object_label *obj;
3908+ __u32 oldmode, newmode;
3909+
3910+ if (unlikely(!(gr_status & GR_READY)))
3911+ return (GR_WRITE | GR_CREATE);
3912+
3913+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
3914+ oldmode = obj->mode;
3915+
3916+ if (current->acl->mode & GR_LEARN)
3917+ oldmode |= (GR_WRITE | GR_CREATE);
3918+ newmode =
3919+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
3920+ oldmode | GR_CREATE | GR_AUDIT_CREATE |
3921+ GR_AUDIT_WRITE | GR_SUPPRESS);
3922+
3923+ if ((newmode & oldmode) == oldmode)
3924+ return newmode;
3925+ else if (current->acl->mode & GR_LEARN) {
3926+ gr_log_learn(current->role, current->uid, current->gid,
3927+ current, gr_to_filename(old_dentry, old_mnt), oldmode);
3928+ return (GR_WRITE | GR_CREATE);
3929+ } else if (newmode & GR_SUPPRESS)
3930+ return GR_SUPPRESS;
3931+ else
3932+ return 0;
3933+}
3934+
3935+__u32
3936+gr_search_file(const struct dentry * dentry, const __u32 mode,
3937+ const struct vfsmount * mnt)
3938+{
3939+ __u32 retval = mode;
3940+ struct acl_subject_label *curracl;
3941+ struct acl_object_label *currobj;
3942+
3943+ if (unlikely(!(gr_status & GR_READY)))
3944+ return (mode & ~GR_AUDITS);
3945+
3946+ curracl = current->acl;
3947+
3948+ currobj = chk_obj_label(dentry, mnt, curracl);
3949+ retval = currobj->mode & mode;
3950+
3951+ if (unlikely
3952+ ((curracl->mode & GR_LEARN) && !(mode & GR_NOPTRACE)
3953+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
3954+ __u32 new_mode = mode;
3955+
3956+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
3957+
3958+ retval = new_mode;
3959+
3960+ if (!(mode & GR_NOLEARN))
3961+ gr_log_learn(current->role, current->uid, current->gid,
3962+ current, gr_to_filename(dentry, mnt), new_mode);
3963+ }
3964+
3965+ return retval;
3966+}
3967+
3968+__u32
3969+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
3970+ const struct vfsmount * mnt, const __u32 mode)
3971+{
3972+ struct name_entry *match;
3973+ struct acl_object_label *matchpo;
3974+ struct acl_subject_label *curracl;
3975+ char *path;
3976+ __u32 retval;
3977+
3978+ if (unlikely(!(gr_status & GR_READY)))
3979+ return (mode & ~GR_AUDITS);
3980+
3981+ preempt_disable();
3982+ path = gr_to_filename(new_dentry, mnt);
3983+ match = lookup_name_entry(path);
3984+
3985+ if (!match)
3986+ goto check_parent;
3987+
3988+ curracl = current->acl;
3989+
3990+ read_lock(&gr_inode_lock);
3991+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
3992+ read_unlock(&gr_inode_lock);
3993+
3994+ if (matchpo) {
3995+ if ((matchpo->mode & mode) !=
3996+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
3997+ && curracl->mode & GR_LEARN) {
3998+ __u32 new_mode = mode;
3999+
4000+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
4001+
4002+ gr_log_learn(current->role, current->uid, current->gid,
4003+ current, gr_to_filename(new_dentry, mnt), new_mode);
4004+
4005+ preempt_enable();
4006+ return new_mode;
4007+ }
4008+ preempt_enable();
4009+ return (matchpo->mode & mode);
4010+ }
4011+
4012+ check_parent:
4013+ curracl = current->acl;
4014+
4015+ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
4016+ retval = matchpo->mode & mode;
4017+
4018+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
4019+ && (curracl->mode & GR_LEARN)) {
4020+ __u32 new_mode = mode;
4021+
4022+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
4023+
4024+ gr_log_learn(current->role, current->uid, current->gid,
4025+ current, gr_to_filename(new_dentry, mnt), new_mode);
4026+ preempt_enable();
4027+ return new_mode;
4028+ }
4029+
4030+ preempt_enable();
4031+ return retval;
4032+}
4033+
4034+int
4035+gr_check_hidden_task(const struct task_struct *task)
4036+{
4037+ if (unlikely(!(gr_status & GR_READY)))
4038+ return 0;
4039+
4040+ if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
4041+ return 1;
4042+
4043+ return 0;
4044+}
4045+
4046+int
4047+gr_check_protected_task(const struct task_struct *task)
4048+{
4049+ if (unlikely(!(gr_status & GR_READY) || !task))
4050+ return 0;
4051+
4052+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
4053+ return 1;
4054+
4055+ return 0;
4056+}
4057+
4058+__inline__ void
4059+gr_copy_label(struct task_struct *tsk)
4060+{
4061+ tsk->used_accept = 0;
4062+ tsk->acl_sp_role = 0;
4063+ tsk->acl_role_id = current->acl_role_id;
4064+ tsk->acl = current->acl;
4065+ tsk->role = current->role;
4066+ tsk->curr_ip = current->curr_ip;
4067+ if (current->exec_file)
4068+ get_file(current->exec_file);
4069+ tsk->exec_file = current->exec_file;
4070+ tsk->is_writable = current->is_writable;
4071+ if (unlikely(current->used_accept))
4072+ current->curr_ip = 0;
4073+
4074+ return;
4075+}
4076+
4077+static __inline__ void
4078+gr_set_proc_res(void)
4079+{
4080+ struct acl_subject_label *proc;
4081+ unsigned short i;
4082+
4083+ proc = current->acl;
4084+
4085+ if (proc->mode & GR_LEARN)
4086+ return;
4087+
4088+ for (i = 0; i < RLIM_NLIMITS; i++) {
4089+ if (!(proc->resmask & (1 << i)))
4090+ continue;
4091+
4092+ current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
4093+ current->rlim[i].rlim_max = proc->res[i].rlim_max;
4094+ }
4095+
4096+ return;
4097+}
4098+
4099+static __inline__ void
4100+do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
4101+{
4102+ task->role = lookup_acl_role_label(task, uid, gid);
4103+
4104+ return;
4105+}
4106+
4107+int
4108+gr_check_user_change(int real, int effective, int fs)
4109+{
4110+ unsigned int i;
4111+ __u16 num;
4112+ uid_t *uidlist;
4113+ int curuid;
4114+ int realok = 0;
4115+ int effectiveok = 0;
4116+ int fsok = 0;
4117+
4118+ if (unlikely(!(gr_status & GR_READY)))
4119+ return 0;
4120+
4121+ num = current->acl->user_trans_num;
4122+ uidlist = current->acl->user_transitions;
4123+
4124+ if (uidlist == NULL)
4125+ return 0;
4126+
4127+ if (real == -1)
4128+ realok = 1;
4129+ if (effective == -1)
4130+ effectiveok = 1;
4131+ if (fs == -1)
4132+ fsok = 1;
4133+
4134+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
4135+ for (i = 0; i < num; i++) {
4136+ curuid = (int)uidlist[i];
4137+ if (real == curuid)
4138+ realok = 1;
4139+ if (effective == curuid)
4140+ effectiveok = 1;
4141+ if (fs == curuid)
4142+ fsok = 1;
4143+ }
4144+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
4145+ for (i = 0; i < num; i++) {
4146+ curuid = (int)uidlist[i];
4147+ if (real == curuid)
4148+ break;
4149+ if (effective == curuid)
4150+ break;
4151+ if (fs == curuid)
4152+ break;
4153+ }
4154+ /* not in deny list */
4155+ if (i == num) {
4156+ realok = 1;
4157+ effectiveok = 1;
4158+ fsok = 1;
4159+ }
4160+ }
4161+
4162+ if (realok && effectiveok && fsok)
4163+ return 0;
4164+ else {
4165+ security_alert(GR_USRCHANGE_ACL_MSG,
4166+ realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
4167+ return 1;
4168+ }
4169+}
4170+
4171+int
4172+gr_check_group_change(int real, int effective, int fs)
4173+{
4174+ unsigned int i;
4175+ __u16 num;
4176+ gid_t *gidlist;
4177+ int curgid;
4178+ int realok = 0;
4179+ int effectiveok = 0;
4180+ int fsok = 0;
4181+
4182+ if (unlikely(!(gr_status & GR_READY)))
4183+ return 0;
4184+
4185+ num = current->acl->group_trans_num;
4186+ gidlist = current->acl->group_transitions;
4187+
4188+ if (gidlist == NULL)
4189+ return 0;
4190+
4191+ if (real == -1)
4192+ realok = 1;
4193+ if (effective == -1)
4194+ effectiveok = 1;
4195+ if (fs == -1)
4196+ fsok = 1;
4197+
4198+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
4199+ for (i = 0; i < num; i++) {
4200+ curgid = (int)gidlist[i];
4201+ if (real == curgid)
4202+ realok = 1;
4203+ if (effective == curgid)
4204+ effectiveok = 1;
4205+ if (fs == curgid)
4206+ fsok = 1;
4207+ }
4208+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
4209+ for (i = 0; i < num; i++) {
4210+ curgid = (int)gidlist[i];
4211+ if (real == curgid)
4212+ break;
4213+ if (effective == curgid)
4214+ break;
4215+ if (fs == curgid)
4216+ break;
4217+ }
4218+ /* not in deny list */
4219+ if (i == num) {
4220+ realok = 1;
4221+ effectiveok = 1;
4222+ fsok = 1;
4223+ }
4224+ }
4225+
4226+ if (realok && effectiveok && fsok)
4227+ return 0;
4228+ else {
4229+ security_alert(GR_GRPCHANGE_ACL_MSG,
4230+ realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
4231+ return 1;
4232+ }
4233+}
4234+
4235+void
4236+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
4237+{
4238+ struct acl_object_label *obj;
4239+ struct file *filp;
4240+
4241+ if (unlikely(!(gr_status & GR_READY)))
4242+ return;
4243+
4244+ filp = task->exec_file;
4245+
4246+ /* kernel process, we'll give them the kernel role */
4247+ if (unlikely(!filp)) {
4248+ task->role = kernel_role;
4249+ task->acl = kernel_role->root_label;
4250+ return;
4251+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
4252+ do_set_role_label(task, uid, gid);
4253+
4254+ task->acl =
4255+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
4256+
4257+ task->is_writable = 0;
4258+
4259+ /* ignore additional mmap checks for processes that are writable
4260+ by the default ACL */
4261+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
4262+ if (unlikely(obj->mode & GR_WRITE))
4263+ task->is_writable = 1;
4264+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
4265+ if (unlikely(obj->mode & GR_WRITE))
4266+ task->is_writable = 1;
4267+
4268+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
4269+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
4270+#endif
4271+
4272+ gr_set_proc_res();
4273+
4274+ return;
4275+}
4276+
4277+void
4278+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
4279+{
4280+ struct acl_subject_label *newacl;
4281+ struct acl_object_label *obj;
4282+ __u32 retmode;
4283+
4284+ if (unlikely(!(gr_status & GR_READY)))
4285+ return;
4286+
4287+ newacl = chk_subj_label(dentry, mnt, current->role);
4288+
4289+ obj = chk_obj_label(dentry, mnt, current->acl);
4290+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
4291+
4292+ if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
4293+ if (obj->nested)
4294+ current->acl = obj->nested;
4295+ else
4296+ current->acl = newacl;
4297+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
4298+ security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
4299+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
4300+
4301+ current->is_writable = 0;
4302+
4303+ /* ignore additional mmap checks for processes that are writable
4304+ by the default ACL */
4305+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
4306+ if (unlikely(obj->mode & GR_WRITE))
4307+ current->is_writable = 1;
4308+ obj = chk_obj_label(dentry, mnt, current->role->root_label);
4309+ if (unlikely(obj->mode & GR_WRITE))
4310+ current->is_writable = 1;
4311+
4312+ gr_set_proc_res();
4313+
4314+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
4315+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
4316+#endif
4317+ return;
4318+}
4319+
4320+static __inline__ void
4321+do_handle_delete(const ino_t ino, const dev_t dev)
4322+{
4323+ struct acl_object_label *matchpo;
4324+ struct acl_subject_label *matchps;
4325+ struct acl_subject_label *i;
4326+ struct acl_role_label *role;
4327+
4328+ for (role = role_list_head; role; role = role->next) {
4329+ for (i = role->hash->first; i; i = i->next) {
4330+ if (unlikely((i->mode & GR_NESTED) &&
4331+ (i->inode == ino) &&
4332+ (i->device == dev)))
4333+ i->mode |= GR_DELETED;
4334+ if (unlikely((matchpo =
4335+ lookup_acl_obj_label(ino, dev, i)) != NULL))
4336+ matchpo->mode |= GR_DELETED;
4337+ }
4338+
4339+ if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
4340+ matchps->mode |= GR_DELETED;
4341+ }
4342+
4343+ return;
4344+}
4345+
4346+void
4347+gr_handle_delete(const ino_t ino, const dev_t dev)
4348+{
4349+ if (unlikely(!(gr_status & GR_READY)))
4350+ return;
4351+
4352+ write_lock(&gr_inode_lock);
4353+ if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
4354+ do_handle_delete(ino, dev);
4355+ write_unlock(&gr_inode_lock);
4356+
4357+ return;
4358+}
4359+
4360+static __inline__ void
4361+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
4362+ const ino_t newinode, const dev_t newdevice,
4363+ struct acl_subject_label *subj)
4364+{
4365+ unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
4366+ struct acl_object_label **match;
4367+ struct acl_object_label *tmp;
4368+ __u8 i = 0;
4369+
4370+ match = &subj->obj_hash[index];
4371+
4372+ while (*match && ((*match)->inode != oldinode ||
4373+ (*match)->device != olddevice ||
4374+ !((*match)->mode & GR_DELETED))) {
4375+ index = (index + (1 << i)) % subj->obj_hash_size;
4376+ match = &subj->obj_hash[index];
4377+ i = (i + 1) % 32;
4378+ }
4379+
4380+ if (*match && ((*match) != deleted_object)
4381+ && ((*match)->inode == oldinode)
4382+ && ((*match)->device == olddevice)
4383+ && ((*match)->mode & GR_DELETED)) {
4384+ tmp = *match;
4385+ tmp->inode = newinode;
4386+ tmp->device = newdevice;
4387+ tmp->mode &= ~GR_DELETED;
4388+
4389+ *match = deleted_object;
4390+
4391+ insert_acl_obj_label(tmp, subj);
4392+ }
4393+
4394+ return;
4395+}
4396+
4397+static __inline__ void
4398+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
4399+ const ino_t newinode, const dev_t newdevice,
4400+ struct acl_role_label *role)
4401+{
4402+ struct acl_subject_label **s_hash = role->subj_hash;
4403+ unsigned long subj_size = role->subj_hash_size;
4404+ unsigned long index = fhash(oldinode, olddevice, subj_size);
4405+ struct acl_subject_label **match;
4406+ struct acl_subject_label *tmp;
4407+ __u8 i = 0;
4408+
4409+ match = &s_hash[index];
4410+
4411+ while (*match && ((*match)->inode != oldinode ||
4412+ (*match)->device != olddevice ||
4413+ !((*match)->mode & GR_DELETED))) {
4414+ index = (index + (1 << i)) % subj_size;
4415+ i = (i + 1) % 32;
4416+ match = &s_hash[index];
4417+ }
4418+
4419+ if (*match && (*match != deleted_subject)
4420+ && ((*match)->inode == oldinode)
4421+ && ((*match)->device == olddevice)
4422+ && ((*match)->mode & GR_DELETED)) {
4423+ tmp = *match;
4424+
4425+ tmp->inode = newinode;
4426+ tmp->device = newdevice;
4427+ tmp->mode &= ~GR_DELETED;
4428+
4429+ *match = deleted_subject;
4430+
4431+ insert_acl_subj_label(tmp, role);
4432+ }
4433+
4434+ return;
4435+}
4436+
4437+static __inline__ void
4438+update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
4439+ const ino_t newinode, const dev_t newdevice)
4440+{
4441+ unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
4442+ struct name_entry **match;
4443+ struct name_entry *tmp;
4444+ __u8 i = 0;
4445+
4446+ match = &inodev_set.n_hash[index];
4447+
4448+ while (*match
4449+ && ((*match)->inode != oldinode
4450+ || (*match)->device != olddevice)) {
4451+ index = (index + (1 << i)) % inodev_set.n_size;
4452+ i = (i + 1) % 32;
4453+ match = &inodev_set.n_hash[index];
4454+ }
4455+
4456+ if (*match && (*match != deleted_inodev)
4457+ && ((*match)->inode == oldinode)
4458+ && ((*match)->device == olddevice)) {
4459+ tmp = *match;
4460+
4461+ tmp->inode = newinode;
4462+ tmp->device = newdevice;
4463+
4464+ *match = deleted_inodev;
4465+
4466+ insert_inodev_entry(tmp);
4467+ }
4468+
4469+ return;
4470+}
4471+
4472+static __inline__ void
4473+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
4474+ const struct vfsmount *mnt)
4475+{
4476+ struct acl_subject_label *i;
4477+ struct acl_role_label *role;
4478+
4479+ for (role = role_list_head; role; role = role->next) {
4480+ update_acl_subj_label(matchn->inode, matchn->device,
4481+ dentry->d_inode->i_ino,
4482+ dentry->d_inode->i_sb->s_dev, role);
4483+
4484+ for (i = role->hash->first; i; i = i->next) {
4485+ if (unlikely((i->mode & GR_NESTED) &&
4486+ (i->inode == dentry->d_inode->i_ino) &&
4487+ (i->device == dentry->d_inode->i_sb->s_dev))) {
4488+ i->inode = dentry->d_inode->i_ino;
4489+ i->device = dentry->d_inode->i_sb->s_dev;
4490+ }
4491+ update_acl_obj_label(matchn->inode, matchn->device,
4492+ dentry->d_inode->i_ino,
4493+ dentry->d_inode->i_sb->s_dev, i);
4494+ }
4495+ }
4496+
4497+ update_inodev_entry(matchn->inode, matchn->device,
4498+ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
4499+
4500+ return;
4501+}
4502+
4503+void
4504+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
4505+{
4506+ struct name_entry *matchn;
4507+
4508+ if (unlikely(!(gr_status & GR_READY)))
4509+ return;
4510+
4511+ preempt_disable();
4512+ matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
4513+ preempt_enable();
4514+
4515+ if (unlikely((unsigned long)matchn)) {
4516+ write_lock(&gr_inode_lock);
4517+ do_handle_create(matchn, dentry, mnt);
4518+ write_unlock(&gr_inode_lock);
4519+ }
4520+
4521+ return;
4522+}
4523+
4524+void
4525+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
4526+ struct dentry *old_dentry,
4527+ struct dentry *new_dentry,
4528+ struct vfsmount *mnt, const __u8 replace)
4529+{
4530+ struct name_entry *matchn;
4531+
4532+ if (unlikely(!(gr_status & GR_READY)))
4533+ return;
4534+
4535+ preempt_disable();
4536+ matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
4537+ preempt_enable();
4538+
4539+ /* we wouldn't have to check d_inode if it weren't for
4540+ NFS silly-renaming
4541+ */
4542+
4543+ write_lock(&gr_inode_lock);
4544+ if (unlikely(replace && new_dentry->d_inode)) {
4545+ if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
4546+ new_dentry->d_inode->i_sb->s_dev) &&
4547+ (old_dentry->d_inode->i_nlink <= 1)))
4548+ do_handle_delete(new_dentry->d_inode->i_ino,
4549+ new_dentry->d_inode->i_sb->s_dev);
4550+ }
4551+
4552+ if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
4553+ old_dentry->d_inode->i_sb->s_dev) &&
4554+ (old_dentry->d_inode->i_nlink <= 1)))
4555+ do_handle_delete(old_dentry->d_inode->i_ino,
4556+ old_dentry->d_inode->i_sb->s_dev);
4557+
4558+ if (unlikely((unsigned long)matchn))
4559+ do_handle_create(matchn, old_dentry, mnt);
4560+ write_unlock(&gr_inode_lock);
4561+
4562+ return;
4563+}
4564+
4565+static int
4566+lookup_special_role_auth(const char *rolename, unsigned char **salt,
4567+ unsigned char **sum)
4568+{
4569+ struct acl_role_label *r;
4570+ struct role_transition *trans;
4571+ __u16 i;
4572+ int found = 0;
4573+
4574+ /* check transition table */
4575+
4576+ for (trans = current->role->transitions; trans; trans = trans->next) {
4577+ if (!strcmp(rolename, trans->rolename)) {
4578+ found = 1;
4579+ break;
4580+ }
4581+ }
4582+
4583+ if (!found)
4584+ return 0;
4585+
4586+ /* handle special roles that do not require authentication */
4587+
4588+ for (r = role_list_head; r; r = r->next) {
4589+ if (!strcmp(rolename, r->rolename)
4590+ && (r->roletype & GR_ROLE_NOPW)) {
4591+ *salt = NULL;
4592+ *sum = NULL;
4593+ return 1;
4594+ }
4595+ }
4596+
4597+ for (i = 0; i < num_sprole_pws; i++) {
4598+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
4599+ *salt = acl_special_roles[i]->salt;
4600+ *sum = acl_special_roles[i]->sum;
4601+ return 1;
4602+ }
4603+ }
4604+
4605+ return 0;
4606+}
4607+
4608+static void
4609+assign_special_role(char *rolename)
4610+{
4611+ struct acl_object_label *obj;
4612+ struct acl_role_label *r;
4613+ struct acl_role_label *assigned = NULL;
4614+ struct task_struct *tsk;
4615+ struct file *filp;
4616+
4617+ for (r = role_list_head; r; r = r->next)
4618+ if (!strcmp(rolename, r->rolename) &&
4619+ (r->roletype & GR_ROLE_SPECIAL))
4620+ assigned = r;
4621+
4622+ if (!assigned)
4623+ return;
4624+
4625+ tsk = current->parent;
4626+ filp = tsk->exec_file;
4627+
4628+ if (tsk && filp) {
4629+ tsk->is_writable = 0;
4630+
4631+ acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
4632+ tsk->acl_sp_role = 1;
4633+ tsk->acl_role_id = acl_sp_role_value;
4634+ tsk->role = assigned;
4635+ tsk->acl =
4636+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
4637+
4638+ /* ignore additional mmap checks for processes that are writable
4639+ by the default ACL */
4640+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
4641+ if (unlikely(obj->mode & GR_WRITE))
4642+ tsk->is_writable = 1;
4643+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
4644+ if (unlikely(obj->mode & GR_WRITE))
4645+ tsk->is_writable = 1;
4646+
4647+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
4648+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
4649+#endif
4650+ }
4651+
4652+ return;
4653+}
4654+
4655+ssize_t
4656+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
4657+{
4658+ struct gr_arg *arg;
4659+ unsigned char *sprole_salt;
4660+ unsigned char *sprole_sum;
4661+ int error = sizeof (struct gr_arg);
4662+ int error2 = 0;
4663+
4664+ down(&gr_dev_sem);
4665+
4666+ arg = (struct gr_arg *) buf;
4667+
4668+ if (count != sizeof (struct gr_arg)) {
4669+ security_alert_good(GR_DEV_ACL_MSG, count,
4670+ (int) sizeof (struct gr_arg));
4671+ error = -EINVAL;
4672+ goto out;
4673+ }
4674+
4675+ if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
4676+ && time_before_eq(gr_auth_expires, get_seconds())) {
4677+ gr_auth_expires = 0;
4678+ gr_auth_attempts = 0;
4679+ }
4680+
4681+ if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
4682+ error = -EFAULT;
4683+ goto out;
4684+ }
4685+
4686+ if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, get_seconds())) {
4687+ error = -EBUSY;
4688+ goto out;
4689+ }
4690+
4691+ /* if non-root trying to do anything other than use a special role,
4692+ do not attempt authentication, do not count towards authentication
4693+ locking
4694+ */
4695+
4696+ if (gr_usermode->mode != SPROLE && current->uid) {
4697+ error = -EPERM;
4698+ goto out;
4699+ }
4700+
4701+ /* ensure pw and special role name are null terminated */
4702+
4703+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
4704+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
4705+
4706+ /* Okay.
4707+ * We have our enough of the argument structure..(we have yet
4708+ * to copy_from_user the tables themselves) . Copy the tables
4709+ * only if we need them, i.e. for loading operations. */
4710+
4711+ switch (gr_usermode->mode) {
4712+ case STATUS:
4713+ if (gr_status & GR_READY)
4714+ error = 1;
4715+ else
4716+ error = 2;
4717+ goto out;
4718+ case SHUTDOWN:
4719+ if ((gr_status & GR_READY)
4720+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
4721+ gr_status &= ~GR_READY;
4722+ security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
4723+ free_variables();
4724+ memset(gr_usermode, 0, sizeof (struct gr_arg));
4725+ memset(gr_system_salt, 0, GR_SALT_LEN);
4726+ memset(gr_system_sum, 0, GR_SHA_LEN);
4727+ } else if (gr_status & GR_READY) {
4728+ security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
4729+ error = -EPERM;
4730+ } else {
4731+ security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
4732+ error = -EAGAIN;
4733+ }
4734+ break;
4735+ case ENABLE:
4736+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
4737+ security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
4738+ else {
4739+ if (gr_status & GR_READY)
4740+ error = -EAGAIN;
4741+ else
4742+ error = error2;
4743+ security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
4744+ DEFAULTSECARGS);
4745+ }
4746+ break;
4747+ case RELOAD:
4748+ if (!(gr_status & GR_READY)) {
4749+ security_alert_good(GR_RELOADI_ACL_MSG);
4750+ error = -EAGAIN;
4751+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
4752+ lock_kernel();
4753+ gr_status &= ~GR_READY;
4754+ free_variables();
4755+ if (!(error2 = gracl_init(gr_usermode))) {
4756+ unlock_kernel();
4757+ security_alert_good(GR_RELOAD_ACL_MSG,
4758+ GR_VERSION);
4759+ } else {
4760+ unlock_kernel();
4761+ error = error2;
4762+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
4763+ DEFAULTSECARGS);
4764+ }
4765+ } else {
4766+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
4767+ DEFAULTSECARGS);
4768+ error = -EPERM;
4769+ }
4770+ break;
4771+ case SEGVMOD:
4772+ if (unlikely(!(gr_status & GR_READY))) {
4773+ security_alert_good(GR_SEGVMODI_ACL_MSG,
4774+ DEFAULTSECARGS);
4775+ error = -EAGAIN;
4776+ break;
4777+ }
4778+
4779+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
4780+ security_alert_good(GR_SEGVMODS_ACL_MSG,
4781+ DEFAULTSECARGS);
4782+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
4783+ struct acl_subject_label *segvacl;
4784+ segvacl =
4785+ lookup_acl_subj_label(gr_usermode->segv_inode,
4786+ gr_usermode->segv_device,
4787+ current->role);
4788+ if (segvacl) {
4789+ segvacl->crashes = 0;
4790+ segvacl->expires = 0;
4791+ }
4792+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
4793+ gr_remove_uid(gr_usermode->segv_uid);
4794+ }
4795+ } else {
4796+ security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
4797+ error = -EPERM;
4798+ }
4799+ break;
4800+ case SPROLE:
4801+ if (unlikely(!(gr_status & GR_READY))) {
4802+ security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
4803+ error = -EAGAIN;
4804+ break;
4805+ }
4806+
4807+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
4808+ && time_before_eq(current->role->expires, get_seconds())) {
4809+ current->role->expires = 0;
4810+ current->role->auth_attempts = 0;
4811+ }
4812+
4813+ if (time_after(current->role->expires, get_seconds())) {
4814+ error = -EBUSY;
4815+ goto out;
4816+ }
4817+
4818+ if (lookup_special_role_auth
4819+ (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
4820+ && ((!sprole_salt && !sprole_sum)
4821+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
4822+ assign_special_role(gr_usermode->sp_role);
4823+ security_alert_good(GR_SPROLES_ACL_MSG,
4824+ (current->parent) ? current->
4825+ parent->role->rolename : "",
4826+ acl_sp_role_value, DEFAULTSECARGS);
4827+ } else {
4828+ security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
4829+ DEFAULTSECARGS);
4830+ error = -EPERM;
4831+ current->role->auth_attempts++;
4832+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
4833+ current->role->expires =
4834+ get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
4835+ security_alert(GR_MAXROLEPW_ACL_MSG,
4836+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
4837+ gr_usermode->sp_role, DEFAULTSECARGS);
4838+ }
4839+
4840+ goto out;
4841+ }
4842+ break;
4843+ case UNSPROLE:
4844+ if (unlikely(!(gr_status & GR_READY))) {
4845+ security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
4846+ error = -EAGAIN;
4847+ break;
4848+ }
4849+
4850+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
4851+ && time_before_eq(current->role->expires, get_seconds())) {
4852+ current->role->expires = 0;
4853+ current->role->auth_attempts = 0;
4854+ }
4855+
4856+ if (time_after(current->role->expires, get_seconds())) {
4857+ error = -EBUSY;
4858+ goto out;
4859+ }
4860+
4861+ if ((current->role->roletype & GR_ROLE_SPECIAL) &&
4862+ lookup_special_role_auth
4863+ (current->role->rolename, &sprole_salt, &sprole_sum)
4864+ && ((!sprole_salt && !sprole_sum)
4865+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
4866+ security_alert_good(GR_UNSPROLES_ACL_MSG,
4867+ (current->parent) ? current->
4868+ parent->role->rolename : "",
4869+ (current->parent) ? current->
4870+ parent->acl_role_id : 0, DEFAULTSECARGS);
4871+ gr_set_acls(1);
4872+ if (current->parent)
4873+ current->parent->acl_sp_role = 0;
4874+ } else {
4875+ security_alert(GR_UNSPROLEF_ACL_MSG, current->role->rolename,
4876+ DEFAULTSECARGS);
4877+ error = -EPERM;
4878+ current->role->auth_attempts++;
4879+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
4880+ current->role->expires =
4881+ get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
4882+ security_alert(GR_MAXROLEPW_ACL_MSG,
4883+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
4884+ current->role->rolename, DEFAULTSECARGS);
4885+ }
4886+
4887+ goto out;
4888+ }
4889+ break;
4890+ default:
4891+ security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
4892+ DEFAULTSECARGS);
4893+ error = -EINVAL;
4894+ break;
4895+ }
4896+
4897+ if (error != -EPERM)
4898+ goto out;
4899+
4900+ gr_auth_attempts++;
4901+
4902+ if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
4903+ security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
4904+ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
4905+ }
4906+
4907+ out:
4908+ up(&gr_dev_sem);
4909+ return error;
4910+}
4911+
4912+int
4913+gr_set_acls(const int type)
4914+{
4915+ struct acl_object_label *obj;
4916+ struct task_struct *task, *task2;
4917+ struct file *filp;
4918+ unsigned short i;
4919+
4920+ read_lock(&tasklist_lock);
4921+ for_each_process(task2) {
4922+ task = task2;
4923+ do {
4924+ /* check to see if we're called from the exit handler,
4925+ if so, only replace ACLs that have inherited the admin
4926+ ACL */
4927+
4928+ if (type && (task->role != current->role ||
4929+ task->acl_role_id != current->acl_role_id))
4930+ continue;
4931+
4932+ task->acl_role_id = 0;
4933+
4934+ if ((filp = task->exec_file)) {
4935+ do_set_role_label(task, task->uid, task->gid);
4936+
4937+ task->acl =
4938+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
4939+ task->role);
4940+ if (task->acl) {
4941+ struct acl_subject_label *curr;
4942+ curr = task->acl;
4943+
4944+ task->is_writable = 0;
4945+ /* ignore additional mmap checks for processes that are writable
4946+ by the default ACL */
4947+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
4948+ if (unlikely(obj->mode & GR_WRITE))
4949+ task->is_writable = 1;
4950+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
4951+ if (unlikely(obj->mode & GR_WRITE))
4952+ task->is_writable = 1;
4953+
4954+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
4955+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
4956+#endif
4957+ if (!(curr->mode & GR_LEARN))
4958+ for (i = 0; i < RLIM_NLIMITS; i++) {
4959+ if (!(curr->resmask & (1 << i)))
4960+ continue;
4961+
4962+ task->rlim[i].rlim_cur =
4963+ curr->res[i].rlim_cur;
4964+ task->rlim[i].rlim_max =
4965+ curr->res[i].rlim_max;
4966+ }
4967+ } else {
4968+ read_unlock(&tasklist_lock);
4969+ security_alert_good(GR_DEFACL_MSG, task->comm,
4970+ task->pid);
4971+ return 1;
4972+ }
4973+ } else {
4974+ // it's a kernel process
4975+ task->role = kernel_role;
4976+ task->acl = kernel_role->root_label;
4977+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
4978+ task->acl->mode &= ~GR_FIND;
4979+#endif
4980+ }
4981+ } while ((task = next_thread(task)) != task2);
4982+ }
4983+ read_unlock(&tasklist_lock);
4984+ return 0;
4985+}
4986+
4987+EXPORT_SYMBOL(gr_learn_resource);
4988+
4989+void
4990+gr_learn_resource(const struct task_struct *task,
4991+ const int res, const unsigned long wanted, const int gt)
4992+{
4993+ struct acl_subject_label *acl;
4994+
4995+ if (unlikely((gr_status & GR_READY) &&
4996+ task->acl && (task->acl->mode & GR_LEARN)))
4997+ goto skip_reslog;
4998+
4999+#ifdef CONFIG_GRKERNSEC_RESLOG
5000+ gr_log_resource(task, res, wanted, gt);
5001+#endif
5002+ skip_reslog:
5003+
5004+ if (unlikely(!(gr_status & GR_READY) || !wanted))
5005+ return;
5006+
5007+ acl = task->acl;
5008+
5009+ if (likely(!acl || !(acl->mode & GR_LEARN) ||
5010+ !(acl->resmask & (1 << (unsigned short) res))))
5011+ return;
5012+
5013+ if (wanted >= acl->res[res].rlim_cur) {
5014+ unsigned long res_add;
5015+
5016+ res_add = wanted;
5017+ switch (res) {
5018+ case RLIMIT_CPU:
5019+ res_add += GR_RLIM_CPU_BUMP;
5020+ break;
5021+ case RLIMIT_FSIZE:
5022+ res_add += GR_RLIM_FSIZE_BUMP;
5023+ break;
5024+ case RLIMIT_DATA:
5025+ res_add += GR_RLIM_DATA_BUMP;
5026+ break;
5027+ case RLIMIT_STACK:
5028+ res_add += GR_RLIM_STACK_BUMP;
5029+ break;
5030+ case RLIMIT_CORE:
5031+ res_add += GR_RLIM_CORE_BUMP;
5032+ break;
5033+ case RLIMIT_RSS:
5034+ res_add += GR_RLIM_RSS_BUMP;
5035+ break;
5036+ case RLIMIT_NPROC:
5037+ res_add += GR_RLIM_NPROC_BUMP;
5038+ break;
5039+ case RLIMIT_NOFILE:
5040+ res_add += GR_RLIM_NOFILE_BUMP;
5041+ break;
5042+ case RLIMIT_MEMLOCK:
5043+ res_add += GR_RLIM_MEMLOCK_BUMP;
5044+ break;
5045+ case RLIMIT_AS:
5046+ res_add += GR_RLIM_AS_BUMP;
5047+ break;
5048+ case RLIMIT_LOCKS:
5049+ res_add += GR_RLIM_LOCKS_BUMP;
5050+ break;
5051+ }
5052+
5053+ acl->res[res].rlim_cur = res_add;
5054+
5055+ if (wanted > acl->res[res].rlim_max)
5056+ acl->res[res].rlim_max = res_add;
5057+
5058+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
5059+ current->role->roletype, acl->filename,
5060+ acl->res[res].rlim_cur, acl->res[res].rlim_max,
5061+ "", (unsigned long) res);
5062+ }
5063+
5064+ return;
5065+}
5066+
1db5cd70
PS
5067+#ifdef CONFIG_SYSCTL
5068+extern struct proc_dir_entry *proc_sys_root;
5069+
5070+
5071+/* the following function is called under the BKL */
5072+
5073+__u32
5074+gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
5075+ const void *newval)
5076+{
5077+ struct proc_dir_entry *tmp;
5078+ struct nameidata nd;
5079+ const char *proc_sys = "/proc/sys";
5080+ char *path;
5081+ struct acl_object_label *obj;
5082+ unsigned short len = 0, pos = 0, depth = 0, i;
5083+ __u32 err = 0;
5084+ __u32 mode = 0;
5085+
5086+ if (unlikely(!(gr_status & GR_READY)))
5087+ return 1;
5088+
5089+ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
5090+
5091+ if (oldval)
5092+ mode |= GR_READ;
5093+ if (newval)
5094+ mode |= GR_WRITE;
5095+
5096+ /* convert the requested sysctl entry into a pathname */
5097+
5098+ for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
5099+ len += strlen(tmp->name);
5100+ len++;
5101+ depth++;
5102+ }
5103+
5104+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
5105+ return 0; /* deny */
5106+
5107+ memset(path, 0, PAGE_SIZE);
5108+
5109+ memcpy(path, proc_sys, strlen(proc_sys));
5110+
5111+ pos += strlen(proc_sys);
5112+
5113+ for (; depth > 0; depth--) {
5114+ path[pos] = '/';
5115+ pos++;
5116+ for (i = 1, tmp = table->de; tmp != proc_sys_root;
5117+ tmp = tmp->parent) {
5118+ if (depth == i) {
5119+ memcpy(path + pos, tmp->name,
5120+ strlen(tmp->name));
5121+ pos += strlen(tmp->name);
5122+ }
5123+ i++;
5124+ }
5125+ }
5126+
5127+ err = path_lookup(path, LOOKUP_FOLLOW, &nd);
5128+
5129+ if (err)
5130+ goto out;
5131+
5132+ obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
5133+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
5134+
5135+ if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
5136+ __u32 new_mode = mode;
5137+
5138+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
5139+
5140+ err = new_mode;
5141+ gr_log_learn(current->role, current->uid, current->gid,
5142+ current, path, new_mode);
5143+ } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
5144+ security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
5145+ (mode & GR_READ) ? " reading" : "",
5146+ (mode & GR_WRITE) ? " writing" : "",
5147+ DEFAULTSECARGS);
5148+ err = 0;
5149+ } else if ((err & mode) != mode) {
5150+ err = 0;
5151+ } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
5152+ security_audit(GR_SYSCTL_ACL_MSG, "successful",
5153+ path, (mode & GR_READ) ? " reading" : "",
5154+ (mode & GR_WRITE) ? " writing" : "",
5155+ DEFAULTSECARGS);
5156+ }
5157+
5158+ path_release(&nd);
5159+
5160+ out:
5161+ return err;
5162+}
5163+#endif
5164+
5165+int
5166+gr_handle_proc_ptrace(struct task_struct *task)
5167+{
5168+ struct file *filp;
5169+ struct task_struct *tmp = task;
5170+ struct task_struct *curtemp = current;
5171+ __u32 retmode;
5172+
5173+ if (unlikely(!(gr_status & GR_READY)))
5174+ return 0;
5175+
5176+ filp = task->exec_file;
5177+
5178+ read_lock(&tasklist_lock);
5179+ while (tmp->pid > 0) {
5180+ if (tmp == curtemp)
5181+ break;
5182+ tmp = tmp->parent;
5183+ }
5184+ read_unlock(&tasklist_lock);
5185+
5186+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))
5187+ return 1;
5188+
5189+ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
5190+
5191+ if (retmode & GR_NOPTRACE)
5192+ return 1;
5193+
5194+ if (!(current->acl->mode & GR_OVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
5195+ && (current->acl != task->acl || (current->acl != current->role->root_label
5196+ && current->pid != task->pid)))
5197+ return 1;
5198+
5199+ return 0;
5200+}
5201+
5202+int
5203+gr_handle_ptrace(struct task_struct *task, const long request)
5204+{
5205+ struct file *filp;
5206+ struct task_struct *tmp = task;
5207+ struct task_struct *curtemp = current;
5208+ __u32 retmode;
5209+
5210+ if (unlikely(!(gr_status & GR_READY)))
5211+ return 0;
5212+
5213+ filp = task->exec_file;
5214+
5215+ if (task->acl->mode & GR_NOPTRACE) {
5216+ security_alert(GR_PTRACE_ACL_MSG, filp ?
5217+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt)
5218+ : "(none)", task->comm, task->pid,
5219+ DEFAULTSECARGS);
5220+ return 1;
5221+ }
5222+
5223+ read_lock(&tasklist_lock);
5224+ while (tmp->pid > 0) {
5225+ if (tmp == curtemp)
5226+ break;
5227+ tmp = tmp->parent;
5228+ }
5229+ read_unlock(&tasklist_lock);
5230+
5231+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
5232+ security_alert(GR_PTRACE_ACL_MSG, filp ?
5233+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt)
5234+ : "(none)", task->comm, task->pid,
5235+ DEFAULTSECARGS);
5236+ return 1;
5237+ }
5238+
5239+ if (unlikely(!filp))
5240+ return 0;
5241+
5242+ retmode = gr_search_file(filp->f_dentry, GR_PTRACERD | GR_NOPTRACE, filp->f_vfsmnt);
5243+
5244+ if (retmode & GR_NOPTRACE) {
5245+ security_alert(GR_PTRACE_ACL_MSG, gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
5246+ task->comm, task->pid, DEFAULTSECARGS);
5247+ return 1;
5248+ }
5249+
5250+ if (retmode & GR_PTRACERD) {
5251+ switch (request) {
5252+ case PTRACE_POKETEXT:
5253+ case PTRACE_POKEDATA:
5254+ case PTRACE_POKEUSR:
5255+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
5256+ case PTRACE_SETREGS:
5257+ case PTRACE_SETFPREGS:
5258+#endif
5259+#ifdef CONFIG_X86
5260+ case PTRACE_SETFPXREGS:
5261+#endif
5262+#ifdef CONFIG_ALTIVEC
5263+ case PTRACE_SETVRREGS:
5264+#endif
5265+ return 1;
5266+ default:
5267+ return 0;
5268+ }
5269+ } else if (!(current->acl->mode & GR_OVERRIDE) &&
5270+ !(current->role->roletype & GR_ROLE_GOD)
5271+ && (current->acl != task->acl
5272+ || (current->acl != current->role->root_label
5273+ && current->pid != task->pid))) {
5274+ security_alert(GR_PTRACE_ACL_MSG,
5275+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
5276+ task->comm, task->pid, DEFAULTSECARGS);
5277+ return 1;
5278+ }
5279+
5280+ return 0;
5281+}
5282+
5283+int
5284+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
5285+{
5286+ __u32 retmode;
5287+ struct acl_subject_label *subj;
5288+
5289+ if (unlikely(!(gr_status & GR_READY)))
5290+ return 0;
5291+
5292+ if (unlikely
5293+ ((current->ptrace & PT_PTRACED)
5294+ && !(current->acl->mode & GR_OVERRIDE)))
5295+ retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
5296+ else
5297+ return 0;
5298+
5299+ subj = chk_subj_label(dentry, mnt, current->role);
5300+
5301+ if (!(retmode & GR_PTRACERD) &&
5302+ !(current->role->roletype & GR_ROLE_GOD) &&
5303+ (current->acl != subj)) {
5304+ security_alert(GR_PTRACE_EXEC_ACL_MSG,
5305+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
5306+ return 1;
5307+ }
5308+
5309+ return 0;
5310+}
5311+
5312+int
5313+gr_handle_mmap(const struct file *filp, const unsigned long prot)
5314+{
5315+ struct acl_object_label *obj, *obj2;
5316+
5317+ if (unlikely(!(gr_status & GR_READY) ||
5318+ (current->acl->mode & GR_OVERRIDE) || !filp ||
5319+ !(prot & PROT_EXEC)))
5320+ return 0;
5321+
5322+ if (unlikely(current->is_writable))
5323+ return 0;
5324+
5325+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
5326+ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
5327+ current->role->root_label);
5328+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
5329+ security_alert(GR_WRITLIB_ACL_MSG,
5330+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
5331+ DEFAULTSECARGS);
5332+ return 1;
5333+ }
5334+
5335+ return 0;
5336+}
5337+
5338+int
5339+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
5340+{
5341+ __u32 mode;
5342+
5343+ if (unlikely(!file || !(prot & PROT_EXEC)))
5344+ return 1;
5345+
5346+ mode =
5347+ gr_search_file(file->f_dentry,
5348+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
5349+ file->f_vfsmnt);
5350+
5351+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
5352+ security_alert(GR_MMAP_ACL_MSG, "denied",
5353+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
5354+ DEFAULTSECARGS);
5355+ return 0;
5356+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
5357+ return 0;
5358+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
5359+ security_audit(GR_MMAP_ACL_MSG, "successful",
5360+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
5361+ DEFAULTSECARGS);
5362+ return 1;
5363+ }
5364+
5365+ return 1;
5366+}
5367+
5368+int
5369+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
5370+{
5371+ __u32 mode;
5372+
5373+ if (unlikely(!file || !(prot & PROT_EXEC)))
5374+ return 1;
5375+
5376+ mode =
5377+ gr_search_file(file->f_dentry,
5378+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
5379+ file->f_vfsmnt);
5380+
5381+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
5382+ security_alert(GR_MPROTECT_ACL_MSG, "denied",
5383+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
5384+ DEFAULTSECARGS);
5385+ return 0;
5386+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
5387+ return 0;
5388+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
5389+ security_audit(GR_MPROTECT_ACL_MSG, "successful",
5390+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
5391+ DEFAULTSECARGS);
5392+ return 1;
5393+ }
5394+
5395+ return 1;
5396+}
5397+
5398+void
5399+gr_acl_handle_psacct(struct task_struct *task, const long code)
5400+{
5401+ u64 runtime64;
5402+ unsigned long runtime;
5403+ unsigned long cputime;
5404+ unsigned int wday, cday;
5405+ __u8 whr, chr;
5406+ __u8 wmin, cmin;
5407+ __u8 wsec, csec;
5408+ char cur_tty[64] = { 0 };
5409+ char parent_tty[64] = { 0 };
5410+
5411+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
5412+ !(task->acl->mode & GR_PROCACCT)))
5413+ return;
5414+
5415+ runtime64 = get_jiffies_64() - task->start_time;
5416+ do_div(runtime64, HZ);
5417+ runtime = (unsigned long)runtime64;
5418+ wday = runtime / (3600 * 24);
5419+ runtime -= wday * (3600 * 24);
5420+ whr = runtime / 3600;
5421+ runtime -= whr * 3600;
5422+ wmin = runtime / 60;
5423+ runtime -= wmin * 60;
5424+ wsec = runtime;
5425+
5426+ cputime = (task->utime + task->stime) / HZ;
5427+ cday = cputime / (3600 * 24);
5428+ cputime -= cday * (3600 * 24);
5429+ chr = cputime / 3600;
5430+ cputime -= chr * 3600;
5431+ cmin = cputime / 60;
5432+ cputime -= cmin * 60;
5433+ csec = cputime;
5434+
5435+ security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
b9213dc3 5436+ task->pid, NIPQUAD(task->curr_ip), tty_name(task->signal->tty,
1db5cd70
PS
5437+ cur_tty),
5438+ task->uid, task->euid, task->gid, task->egid, wday, whr,
5439+ wmin, wsec, cday, chr, cmin, csec,
5440+ (task->flags & PF_SIGNALED) ? "killed by signal" : "exited",
5441+ code, gr_parent_task_fullpath(task),
5442+ task->parent->comm, task->parent->pid,
5443+ NIPQUAD(task->parent->curr_ip),
b9213dc3 5444+ tty_name(task->parent->signal->tty, parent_tty),
1db5cd70
PS
5445+ task->parent->uid, task->parent->euid, task->parent->gid,
5446+ task->parent->egid);
5447+
5448+ return;
5449+}
5450+
5451+EXPORT_SYMBOL(gr_set_kernel_label);
5452+
5453+void gr_set_kernel_label(struct task_struct *task)
5454+{
5455+ if (gr_status & GR_READY) {
5456+ task->role = kernel_role;
5457+ task->acl = kernel_role->root_label;
5458+ }
5459+ return;
5460+}
5461diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_cap.c linux-2.6.7-rc1/grsecurity/gracl_cap.c
5462--- linux-2.6.7-rc1.orig/grsecurity/gracl_cap.c 1970-01-01 01:00:00.000000000 +0100
5463+++ linux-2.6.7-rc1/grsecurity/gracl_cap.c 2004-05-25 14:33:58.909404736 +0200
5464@@ -0,0 +1,115 @@
5465+/* capability handling routines, (c) Brad Spengler 2002,2003 */
5466+
5467+#include <linux/kernel.h>
5468+#include <linux/module.h>
5469+#include <linux/sched.h>
5470+#include <linux/capability.h>
5471+#include <linux/gracl.h>
5472+#include <linux/grsecurity.h>
5473+#include <linux/grinternal.h>
5474+
5475+static const char *captab_log[29] = {
5476+ "CAP_CHOWN",
5477+ "CAP_DAC_OVERRIDE",
5478+ "CAP_DAC_READ_SEARCH",
5479+ "CAP_FOWNER",
5480+ "CAP_FSETID",
5481+ "CAP_KILL",
5482+ "CAP_SETGID",
5483+ "CAP_SETUID",
5484+ "CAP_SETPCAP",
5485+ "CAP_LINUX_IMMUTABLE",
5486+ "CAP_NET_BIND_SERVICE",
5487+ "CAP_NET_BROADCAST",
5488+ "CAP_NET_ADMIN",
5489+ "CAP_NET_RAW",
5490+ "CAP_IPC_LOCK",
5491+ "CAP_IPC_OWNER",
5492+ "CAP_SYS_MODULE",
5493+ "CAP_SYS_RAWIO",
5494+ "CAP_SYS_CHROOT",
5495+ "CAP_SYS_PTRACE",
5496+ "CAP_SYS_PACCT",
5497+ "CAP_SYS_ADMIN",
5498+ "CAP_SYS_BOOT",
5499+ "CAP_SYS_NICE",
5500+ "CAP_SYS_RESOURCE",
5501+ "CAP_SYS_TIME",
5502+ "CAP_SYS_TTY_CONFIG",
5503+ "CAP_MKNOD",
5504+ "CAP_LEASE"
5505+};
5506+
5507+EXPORT_SYMBOL(gr_task_is_capable);
5508+
5509+int
5510+gr_task_is_capable(struct task_struct *task, const int cap)
5511+{
5512+ struct acl_subject_label *curracl;
5513+ __u32 cap_drop = 0, cap_mask = 0;
5514+
5515+ if (!gr_acl_is_enabled())
5516+ return 1;
5517+
5518+ curracl = task->acl;
5519+
5520+ cap_drop = curracl->cap_lower;
5521+ cap_mask = curracl->cap_mask;
5522+
5523+ while ((curracl = curracl->parent_subject)) {
5524+ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
5525+ cap_mask |= curracl->cap_mask;
5526+ }
5527+
5528+ if (!cap_raised(cap_drop, cap))
5529+ return 1;
5530+
5531+ curracl = task->acl;
5532+
5533+ if ((curracl->mode & GR_LEARN)
5534+ && cap_raised(task->cap_effective, cap)) {
5535+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
5536+ task->role->roletype, task->uid,
5537+ task->gid, task->exec_file ?
5538+ gr_to_filename(task->exec_file->f_dentry,
5539+ task->exec_file->f_vfsmnt) : curracl->filename,
5540+ curracl->filename, 0UL,
5541+ 0UL, "", (unsigned long) cap, NIPQUAD(task->curr_ip));
5542+ return 1;
5543+ }
5544+
5545+ if ((cap >= 0) && (cap < 29) && cap_raised(task->cap_effective, cap))
5546+ security_alert(GR_CAP_ACL_MSG, captab_log[cap],
5547+ gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid,
5548+ task->gid, task->egid, gr_parent_task_fullpath(task),
5549+ task->parent->comm, task->parent->pid, task->parent->uid,
5550+ task->parent->euid, task->parent->gid, task->parent->egid);
5551+
5552+ return 0;
5553+}
5554+
5555+int
5556+gr_is_capable_nolog(const int cap)
5557+{
5558+ struct acl_subject_label *curracl;
5559+ __u32 cap_drop = 0, cap_mask = 0;
5560+
5561+ if (!gr_acl_is_enabled())
5562+ return 1;
5563+
5564+ curracl = current->acl;
5565+
5566+ cap_drop = curracl->cap_lower;
5567+ cap_mask = curracl->cap_mask;
5568+
5569+ while ((curracl = curracl->parent_subject)) {
5570+ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
5571+ cap_mask |= curracl->cap_mask;
5572+ }
5573+
5574+ if (!cap_raised(cap_drop, cap))
5575+ return 1;
5576+
5577+ return 0;
5578+}
5579+
5580diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_fs.c linux-2.6.7-rc1/grsecurity/gracl_fs.c
5581--- linux-2.6.7-rc1.orig/grsecurity/gracl_fs.c 1970-01-01 01:00:00.000000000 +0100
5582+++ linux-2.6.7-rc1/grsecurity/gracl_fs.c 2004-05-25 14:33:58.913404128 +0200
5583@@ -0,0 +1,460 @@
5584+#include <linux/kernel.h>
5585+#include <linux/sched.h>
5586+#include <linux/types.h>
5587+#include <linux/fs.h>
5588+#include <linux/file.h>
5589+#include <linux/grsecurity.h>
5590+#include <linux/grinternal.h>
5591+#include <linux/gracl.h>
5592+
5593+__u32
5594+gr_acl_handle_hidden_file(const struct dentry * dentry,
5595+ const struct vfsmount * mnt)
5596+{
5597+ __u32 mode;
5598+
5599+ if (unlikely(!dentry->d_inode))
5600+ return GR_FIND;
5601+
5602+ mode =
5603+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
5604+
5605+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
5606+ security_audit(GR_HIDDEN_ACL_MSG, "successful",
5607+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
5608+ return mode;
5609+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
5610+ security_alert(GR_HIDDEN_ACL_MSG, "denied",
5611+ gr_to_filename(dentry, mnt),
5612+ DEFAULTSECARGS);
5613+ return 0;
5614+ } else if (unlikely(!(mode & GR_FIND)))
5615+ return 0;
5616+
5617+ return GR_FIND;
5618+}
5619+
5620+__u32
5621+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
5622+ const int fmode)
5623+{
5624+ __u32 reqmode = GR_FIND;
5625+ __u32 mode;
5626+
5627+ if (unlikely(!dentry->d_inode))
5628+ return reqmode;
5629+
5630+ if (unlikely(fmode & O_APPEND))
5631+ reqmode |= GR_APPEND;
5632+ else if (unlikely(fmode & FMODE_WRITE))
5633+ reqmode |= GR_WRITE;
5634+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
5635+ reqmode |= GR_READ;
5636+
5637+ mode =
5638+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
5639+ mnt);
5640+
5641+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
5642+ security_audit(GR_OPEN_ACL_MSG, "successful",
5643+ gr_to_filename(dentry, mnt),
5644+ reqmode & GR_READ ? " reading" : "",
5645+ reqmode & GR_WRITE ? " writing" :
5646+ reqmode & GR_APPEND ? " appending" : "",
5647+ DEFAULTSECARGS);
5648+ return reqmode;
5649+ } else
5650+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
5651+ {
5652+ security_alert(GR_OPEN_ACL_MSG, "denied",
5653+ gr_to_filename(dentry, mnt),
5654+ reqmode & GR_READ ? " reading" : "",
5655+ reqmode & GR_WRITE ? " writing" : reqmode &
5656+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
5657+ return 0;
5658+ } else if (unlikely((mode & reqmode) != reqmode))
5659+ return 0;
5660+
5661+ return reqmode;
5662+}
5663+
5664+__u32
5665+gr_acl_handle_creat(const struct dentry * dentry,
5666+ const struct dentry * p_dentry,
5667+ const struct vfsmount * p_mnt, const int fmode,
5668+ const int imode)
5669+{
5670+ __u32 reqmode = GR_WRITE | GR_CREATE;
5671+ __u32 mode;
5672+
5673+ if (unlikely(fmode & O_APPEND))
5674+ reqmode |= GR_APPEND;
5675+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
5676+ reqmode |= GR_READ;
5677+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
5678+ reqmode |= GR_SETID;
5679+
5680+ mode =
5681+ gr_check_create(dentry, p_dentry, p_mnt,
5682+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
5683+
5684+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
5685+ security_audit(GR_CREATE_ACL_MSG, "successful",
5686+ gr_to_filename(dentry, p_mnt),
5687+ reqmode & GR_READ ? " reading" : "",
5688+ reqmode & GR_WRITE ? " writing" :
5689+ reqmode & GR_APPEND ? " appending" : "",
5690+ DEFAULTSECARGS);
5691+ return reqmode;
5692+ } else
5693+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
5694+ {
5695+ security_alert(GR_CREATE_ACL_MSG, "denied",
5696+ gr_to_filename(dentry, p_mnt),
5697+ reqmode & GR_READ ? " reading" : "",
5698+ reqmode & GR_WRITE ? " writing" : reqmode &
5699+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
5700+ return 0;
5701+ } else if (unlikely((mode & reqmode) != reqmode))
5702+ return 0;
5703+
5704+ return reqmode;
5705+}
5706+
5707+__u32
5708+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
5709+ const int fmode)
5710+{
5711+ __u32 mode, reqmode = GR_FIND;
5712+
5713+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
5714+ reqmode |= GR_EXEC;
5715+ if (fmode & S_IWOTH)
5716+ reqmode |= GR_WRITE;
5717+ if (fmode & S_IROTH)
5718+ reqmode |= GR_READ;
5719+
5720+ mode =
5721+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
5722+ mnt);
5723+
5724+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
5725+ security_audit(GR_ACCESS_ACL_MSG, "successful",
5726+ gr_to_filename(dentry, mnt),
5727+ reqmode & GR_READ ? " reading" : "",
5728+ reqmode & GR_WRITE ? " writing" : "",
5729+ reqmode & GR_EXEC ? " executing" : "",
5730+ DEFAULTSECARGS);
5731+ return reqmode;
5732+ } else
5733+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
5734+ {
5735+ security_alert(GR_ACCESS_ACL_MSG, "denied",
5736+ gr_to_filename(dentry, mnt),
5737+ reqmode & GR_READ ? " reading" : "",
5738+ reqmode & GR_WRITE ? " writing" : "",
5739+ reqmode & GR_EXEC ? " executing" : "",
5740+ DEFAULTSECARGS);
5741+ return 0;
5742+ } else if (unlikely((mode & reqmode) != reqmode))
5743+ return 0;
5744+
5745+ return reqmode;
5746+}
5747+
5748+#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
5749+{ \
5750+ __u32 mode; \
5751+ \
5752+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
5753+ \
5754+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
5755+ security_audit(fmt, "successful", \
5756+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
5757+ return mode; \
5758+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
5759+ security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
5760+ DEFAULTSECARGS); \
5761+ return 0; \
5762+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
5763+ return 0; \
5764+ \
5765+ return (reqmode); \
5766+}
5767+
5768+__u32
5769+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
5770+{
5771+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
5772+}
5773+
5774+__u32
5775+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
5776+{
5777+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
5778+}
5779+
5780+__u32
5781+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
5782+{
5783+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
5784+}
5785+
5786+__u32
5787+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
5788+{
5789+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
5790+}
5791+
5792+__u32
5793+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
5794+ mode_t mode)
5795+{
5796+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
5797+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
5798+ GR_FCHMOD_ACL_MSG);
5799+ } else {
5800+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
5801+ }
5802+}
5803+
5804+__u32
5805+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
5806+ mode_t mode)
5807+{
5808+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
5809+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
5810+ GR_CHMOD_ACL_MSG);
5811+ } else {
5812+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
5813+ }
5814+}
5815+
5816+__u32
5817+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
5818+{
5819+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
5820+}
5821+
5822+__u32
5823+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
5824+{
5825+ generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
5826+}
5827+
5828+__u32
5829+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
5830+{
5831+ generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
5832+ GR_UNIXCONNECT_ACL_MSG);
5833+}
5834+
5835+__u32
5836+gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
5837+ const ino_t ino)
5838+{
5839+ if (likely((unsigned long)(dentry->d_inode))) {
5840+ struct dentry d = *dentry;
5841+ struct inode inode = *(dentry->d_inode);
5842+
5843+ inode.i_ino = ino;
5844+ d.d_inode = &inode;
5845+
5846+ if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
5847+ return 0;
5848+ }
5849+
5850+ return 1;
5851+}
5852+
5853+__u32
5854+gr_acl_handle_link(const struct dentry * new_dentry,
5855+ const struct dentry * parent_dentry,
5856+ const struct vfsmount * parent_mnt,
5857+ const struct dentry * old_dentry,
5858+ const struct vfsmount * old_mnt, const char *to)
5859+{
5860+ __u32 needmode = GR_WRITE | GR_CREATE;
5861+ __u32 mode;
5862+
5863+ mode =
5864+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
5865+ old_mnt);
5866+
5867+ if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
5868+ security_audit(GR_LINK_ACL_MSG, "successful",
5869+ gr_to_filename(old_dentry, old_mnt), to,
5870+ DEFAULTSECARGS);
5871+ return mode;
5872+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
5873+ security_alert(GR_LINK_ACL_MSG, "denied",
5874+ gr_to_filename(old_dentry, old_mnt), to,
5875+ DEFAULTSECARGS);
5876+ return 0;
5877+ } else if (unlikely((mode & needmode) != needmode))
5878+ return 0;
5879+
5880+ return (GR_WRITE | GR_CREATE);
5881+}
5882+
5883+__u32
5884+gr_acl_handle_symlink(const struct dentry * new_dentry,
5885+ const struct dentry * parent_dentry,
5886+ const struct vfsmount * parent_mnt, const char *from)
5887+{
5888+ __u32 needmode = GR_WRITE | GR_CREATE;
5889+ __u32 mode;
5890+
5891+ mode =
5892+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
5893+ GR_CREATE | GR_AUDIT_CREATE |
5894+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
5895+
5896+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
5897+ security_audit(GR_SYMLINK_ACL_MSG, "successful",
5898+ from, gr_to_filename(new_dentry, parent_mnt),
5899+ DEFAULTSECARGS);
5900+ return mode;
5901+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
5902+ security_alert(GR_SYMLINK_ACL_MSG, "denied",
5903+ from, gr_to_filename(new_dentry, parent_mnt),
5904+ DEFAULTSECARGS);
5905+ return 0;
5906+ } else if (unlikely((mode & needmode) != needmode))
5907+ return 0;
5908+
5909+ return (GR_WRITE | GR_CREATE);
5910+}
5911+
5912+#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
5913+{ \
5914+ __u32 mode; \
5915+ \
5916+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
5917+ \
5918+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
5919+ security_audit(fmt, "successful", \
5920+ gr_to_filename(new_dentry, parent_mnt), \
5921+ DEFAULTSECARGS); \
5922+ return mode; \
5923+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
5924+ security_alert(fmt, "denied", \
5925+ gr_to_filename(new_dentry, parent_mnt), \
5926+ DEFAULTSECARGS); \
5927+ return 0; \
5928+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
5929+ return 0; \
5930+ \
5931+ return (reqmode); \
5932+}
5933+
5934+__u32
5935+gr_acl_handle_mknod(const struct dentry * new_dentry,
5936+ const struct dentry * parent_dentry,
5937+ const struct vfsmount * parent_mnt,
5938+ const int mode)
5939+{
5940+ __u32 reqmode = GR_WRITE | GR_CREATE;
5941+ if (unlikely(mode & (S_ISUID | S_ISGID)))
5942+ reqmode |= GR_SETID;
5943+
5944+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
5945+ reqmode, GR_MKNOD_ACL_MSG);
5946+}
5947+
5948+__u32
5949+gr_acl_handle_mkdir(const struct dentry *new_dentry,
5950+ const struct dentry *parent_dentry,
5951+ const struct vfsmount *parent_mnt)
5952+{
5953+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
5954+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
5955+}
5956+
5957+#define RENAME_CHECK_SUCCESS(old, new) \
5958+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
5959+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
5960+
5961+int
5962+gr_acl_handle_rename(struct dentry *new_dentry,
5963+ struct dentry *parent_dentry,
5964+ const struct vfsmount *parent_mnt,
5965+ struct dentry *old_dentry,
5966+ struct inode *old_parent_inode,
5967+ struct vfsmount *old_mnt, const char *newname)
5968+{
5969+ __u32 comp1, comp2;
5970+ int error = 0;
5971+
5972+ if (unlikely(!gr_acl_is_enabled()))
5973+ return 0;
5974+
5975+ if (!new_dentry->d_inode) {
5976+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
5977+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
5978+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
5979+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
5980+ GR_DELETE | GR_AUDIT_DELETE |
5981+ GR_AUDIT_READ | GR_AUDIT_WRITE |
5982+ GR_SUPPRESS, old_mnt);
5983+ } else {
5984+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
5985+ GR_CREATE | GR_DELETE |
5986+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
5987+ GR_AUDIT_READ | GR_AUDIT_WRITE |
5988+ GR_SUPPRESS, parent_mnt);
5989+ comp2 =
5990+ gr_search_file(old_dentry,
5991+ GR_READ | GR_WRITE | GR_AUDIT_READ |
5992+ GR_DELETE | GR_AUDIT_DELETE |
5993+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
5994+ }
5995+
5996+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
5997+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
5998+ security_audit(GR_RENAME_ACL_MSG, "successful",
5999+ gr_to_filename(old_dentry, old_mnt),
6000+ newname, DEFAULTSECARGS);
6001+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
6002+ && !(comp2 & GR_SUPPRESS)) {
6003+ security_alert(GR_RENAME_ACL_MSG, "denied",
6004+ gr_to_filename(old_dentry, old_mnt), newname,
6005+ DEFAULTSECARGS);
6006+ error = -EACCES;
6007+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
6008+ error = -EACCES;
6009+
6010+ return error;
6011+}
6012+
6013+void
6014+gr_acl_handle_exit(void)
6015+{
6016+ u16 id;
6017+ char *rolename;
6018+
6019+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
6020+ id = current->acl_role_id;
6021+ rolename = current->role->rolename;
6022+ gr_set_acls(1);
6023+ security_alert_good(GR_SPROLEL_ACL_MSG,
6024+ rolename, id, DEFAULTSECARGS);
6025+ }
6026+
6027+ if (current->exec_file) {
6028+ fput(current->exec_file);
6029+ current->exec_file = NULL;
6030+ }
6031+}
6032+
6033+int
6034+gr_acl_handle_procpidmem(const struct task_struct *task)
6035+{
6036+ if (unlikely(!gr_acl_is_enabled()))
6037+ return 0;
6038+
6039+ if (task->acl->mode & GR_PROTPROCFD)
6040+ return -EACCES;
6041+
6042+ return 0;
6043+}
6044diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_ip.c linux-2.6.7-rc1/grsecurity/gracl_ip.c
6045--- linux-2.6.7-rc1.orig/grsecurity/gracl_ip.c 1970-01-01 01:00:00.000000000 +0100
6046+++ linux-2.6.7-rc1/grsecurity/gracl_ip.c 2004-05-25 14:33:58.916403672 +0200
6047@@ -0,0 +1,236 @@
6048+/*
6049+ * grsecurity/gracl_ip.c
6050+ * Copyright Brad Spengler 2002, 2003
6051+ *
6052+ */
6053+
6054+#include <linux/kernel.h>
6055+#include <asm/uaccess.h>
6056+#include <asm/errno.h>
6057+#include <net/sock.h>
6058+#include <linux/file.h>
6059+#include <linux/fs.h>
6060+#include <linux/net.h>
6061+#include <linux/in.h>
6062+#include <linux/skbuff.h>
6063+#include <linux/ip.h>
6064+#include <linux/udp.h>
6065+#include <linux/smp_lock.h>
6066+#include <linux/types.h>
6067+#include <linux/sched.h>
6068+#include <linux/gracl.h>
6069+#include <linux/grsecurity.h>
6070+#include <linux/grinternal.h>
6071+
6072+#define GR_BIND 0x01
6073+#define GR_CONNECT 0x02
6074+
6075+static const char * gr_protocols[256] = {
6076+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
6077+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
6078+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
6079+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
6080+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
6081+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
6082+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
6083+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
6084+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
6085+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
6086+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
6087+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
6088+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
6089+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
6090+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
6091+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
6092+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
6093+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
6094+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
6095+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
6096+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
6097+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
6098+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
6099+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
6100+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
6101+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
6102+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
6103+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
6104+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
6105+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
6106+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
6107+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
6108+ };
6109+
6110+static const char * gr_socktypes[11] = {
6111+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
6112+ "unknown:7", "unknown:8", "unknown:9", "packet"
6113+ };
6114+
6115+__inline__ const char *
6116+gr_proto_to_name(unsigned char proto)
6117+{
6118+ return gr_protocols[proto];
6119+}
6120+
6121+__inline__ const char *
6122+gr_socktype_to_name(unsigned char type)
6123+{
6124+ return gr_socktypes[type];
6125+}
6126+
6127+int
6128+gr_search_socket(const int domain, const int type, const int protocol)
6129+{
6130+ struct acl_subject_label *curr;
6131+
6132+ if (unlikely(!gr_acl_is_enabled()))
6133+ goto exit;
6134+
6135+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
6136+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
6137+ goto exit; // let the kernel handle it
6138+
6139+ curr = current->acl;
6140+
6141+ if (!curr->ips)
6142+ goto exit;
6143+
6144+ if ((curr->ip_type & (1 << type)) &&
6145+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
6146+ goto exit;
6147+
6148+ if (curr->mode & GR_LEARN) {
6149+ /* we don't place acls on raw sockets , and sometimes
6150+ dgram/ip sockets are opened for ioctl and not
6151+ bind/connect, so we'll fake a bind learn log */
6152+ if (type == SOCK_RAW || type == SOCK_PACKET) {
6153+ __u32 fakeip = 0;
6154+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
6155+ current->role->roletype, current->uid,
6156+ current->gid, current->exec_file ?
6157+ gr_to_filename(current->exec_file->f_dentry,
6158+ current->exec_file->f_vfsmnt) :
6159+ curr->filename, curr->filename,
6160+ NIPQUAD(fakeip), 0, type,
6161+ protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
6162+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
6163+ __u32 fakeip = 0;
6164+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
6165+ current->role->roletype, current->uid,
6166+ current->gid, current->exec_file ?
6167+ gr_to_filename(current->exec_file->f_dentry,
6168+ current->exec_file->f_vfsmnt) :
6169+ curr->filename, curr->filename,
6170+ NIPQUAD(fakeip), 0, type,
6171+ protocol, GR_BIND, NIPQUAD(current->curr_ip));
6172+ }
6173+ /* we'll log when they use connect or bind */
6174+ goto exit;
6175+ }
6176+
6177+ security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
6178+ gr_proto_to_name(protocol), DEFAULTSECARGS);
6179+
6180+ return 0;
6181+ exit:
6182+ return 1;
6183+}
6184+
6185+static __inline__ int
6186+gr_search_connectbind(const int mode, const struct sock *sk,
6187+ const struct sockaddr_in *addr, const int type)
6188+{
6189+ struct acl_subject_label *curr;
6190+ struct acl_ip_label *ip;
6191+ unsigned long i;
6192+ __u32 ip_addr = 0;
6193+ __u16 ip_port = 0;
6194+
6195+ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
6196+ return 1;
6197+
6198+ curr = current->acl;
6199+
6200+ if (!curr->ips)
6201+ return 1;
6202+
6203+ ip_addr = addr->sin_addr.s_addr;
6204+ ip_port = ntohs(addr->sin_port);
6205+
6206+ for (i = 0; i < curr->ip_num; i++) {
6207+ ip = *(curr->ips + i);
6208+ if ((ip->mode & mode) &&
6209+ (ip_port >= ip->low) &&
6210+ (ip_port <= ip->high) &&
6211+ ((ntohl(ip_addr) & ip->netmask) ==
6212+ (ntohl(ip->addr) & ip->netmask))
6213+ && (ip->
6214+ proto[sk->sk_protocol / 32] & (1 << (sk->sk_protocol % 32)))
6215+ && (ip->type & (1 << type)))
6216+ return 1;
6217+ }
6218+
6219+ if (curr->mode & GR_LEARN) {
6220+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
6221+ current->role->roletype, current->uid,
6222+ current->gid, current->exec_file ?
6223+ gr_to_filename(current->exec_file->f_dentry,
6224+ current->exec_file->f_vfsmnt) :
6225+ curr->filename, curr->filename,
6226+ NIPQUAD(ip_addr), ip_port, type,
6227+ sk->sk_protocol, mode, NIPQUAD(current->curr_ip));
6228+ return 1;
6229+ }
6230+
6231+ if (mode == GR_BIND)
6232+ security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
6233+ gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
6234+ DEFAULTSECARGS);
6235+ else if (mode == GR_CONNECT)
6236+ security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
6237+ gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
6238+ DEFAULTSECARGS);
6239+
6240+ return 0;
6241+}
6242+
6243+int
6244+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
6245+{
6246+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
6247+}
6248+
6249+int
6250+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
6251+{
6252+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
6253+}
6254+
6255+int
6256+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
6257+{
6258+ if (addr)
6259+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
6260+ else {
6261+ struct sockaddr_in sin;
6262+ const struct inet_opt *inet = inet_sk(sk);
6263+
6264+ sin.sin_addr.s_addr = inet->daddr;
6265+ sin.sin_port = inet->dport;
6266+
6267+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
6268+ }
6269+}
6270+
6271+int
6272+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
6273+{
6274+ struct sockaddr_in sin;
6275+
6276+ if (unlikely(skb->len < sizeof (struct udphdr)))
6277+ return 1; // skip this packet
6278+
6279+ sin.sin_addr.s_addr = skb->nh.iph->saddr;
6280+ sin.sin_port = skb->h.uh->source;
6281+
6282+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
6283+}
6284diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_learn.c linux-2.6.7-rc1/grsecurity/gracl_learn.c
6285--- linux-2.6.7-rc1.orig/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100
6286+++ linux-2.6.7-rc1/grsecurity/gracl_learn.c 2004-05-25 14:33:58.919403216 +0200
6287@@ -0,0 +1,204 @@
6288+#include <linux/kernel.h>
6289+#include <linux/mm.h>
6290+#include <linux/sched.h>
6291+#include <linux/poll.h>
6292+#include <linux/smp_lock.h>
6293+#include <linux/string.h>
6294+#include <linux/file.h>
6295+#include <linux/types.h>
6296+#include <linux/vmalloc.h>
6297+#include <linux/grinternal.h>
6298+
6299+extern ssize_t write_grsec_handler(struct file * file, const char * buf,
6300+ size_t count, loff_t *ppos);
6301+extern int gr_acl_is_enabled(void);
6302+
6303+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
6304+static int gr_learn_attached;
6305+
6306+/* use a 512k buffer */
6307+#define LEARN_BUFFER_SIZE (512 * 1024)
6308+
6309+static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
6310+static DECLARE_MUTEX(gr_learn_user_sem);
6311+
6312+/* we need to maintain two buffers, so that the kernel context of grlearn
6313+ uses a semaphore around the userspace copying, and the other kernel contexts
6314+ use a spinlock when copying into the buffer, since they cannot sleep
6315+*/
6316+static char *learn_buffer;
6317+static char *learn_buffer_user;
6318+static int learn_buffer_len;
6319+static int learn_buffer_user_len;
6320+
6321+static ssize_t
6322+read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
6323+{
6324+ DECLARE_WAITQUEUE(wait, current);
6325+ ssize_t retval = 0;
6326+
6327+ add_wait_queue(&learn_wait, &wait);
6328+ set_current_state(TASK_INTERRUPTIBLE);
6329+ do {
6330+ down(&gr_learn_user_sem);
6331+ spin_lock(&gr_learn_lock);
6332+ if (learn_buffer_len)
6333+ break;
6334+ spin_unlock(&gr_learn_lock);
6335+ up(&gr_learn_user_sem);
6336+ if (file->f_flags & O_NONBLOCK) {
6337+ retval = -EAGAIN;
6338+ goto out;
6339+ }
6340+ if (signal_pending(current)) {
6341+ retval = -ERESTARTSYS;
6342+ goto out;
6343+ }
6344+
6345+ schedule();
6346+ } while (1);
6347+
6348+ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
6349+ learn_buffer_user_len = learn_buffer_len;
6350+ retval = learn_buffer_len;
6351+ learn_buffer_len = 0;
6352+
6353+ spin_unlock(&gr_learn_lock);
6354+
6355+ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
6356+ retval = -EFAULT;
6357+
6358+ up(&gr_learn_user_sem);
6359+out:
6360+ set_current_state(TASK_RUNNING);
6361+ remove_wait_queue(&learn_wait, &wait);
6362+ return retval;
6363+}
6364+
6365+static unsigned int
6366+poll_learn(struct file * file, poll_table * wait)
6367+{
6368+ poll_wait(file, &learn_wait, wait);
6369+
6370+ if (learn_buffer_len)
6371+ return (POLLIN | POLLRDNORM);
6372+
6373+ return 0;
6374+}
6375+
6376+void
6377+gr_clear_learn_entries(void)
6378+{
6379+ char *tmp;
6380+
6381+ down(&gr_learn_user_sem);
6382+ if (learn_buffer != NULL) {
6383+ spin_lock(&gr_learn_lock);
6384+ tmp = learn_buffer;
6385+ learn_buffer = NULL;
6386+ spin_unlock(&gr_learn_lock);
6387+ vfree(learn_buffer);
6388+ }
6389+ if (learn_buffer_user != NULL) {
6390+ vfree(learn_buffer_user);
6391+ learn_buffer_user = NULL;
6392+ }
6393+ learn_buffer_len = 0;
6394+ up(&gr_learn_user_sem);
6395+
6396+ return;
6397+}
6398+
6399+void
6400+gr_add_learn_entry(const char *fmt, ...)
6401+{
6402+ va_list args;
6403+ unsigned int len;
6404+
6405+ if (!gr_learn_attached)
6406+ return;
6407+
6408+ spin_lock(&gr_learn_lock);
6409+
6410+ /* leave a gap at the end so we know when it's "full" but don't have to
6411+ compute the exact length of the string we're trying to append
6412+ */
6413+ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
6414+ spin_unlock(&gr_learn_lock);
6415+ wake_up_interruptible(&learn_wait);
6416+ return;
6417+ }
6418+ if (learn_buffer == NULL) {
6419+ spin_unlock(&gr_learn_lock);
6420+ return;
6421+ }
6422+
6423+ va_start(args, fmt);
6424+ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
6425+ va_end(args);
6426+
6427+ learn_buffer_len += len + 1;
6428+
6429+ spin_unlock(&gr_learn_lock);
6430+ wake_up_interruptible(&learn_wait);
6431+
6432+ return;
6433+}
6434+
6435+static int
6436+open_learn(struct inode *inode, struct file *file)
6437+{
6438+ if (file->f_mode & FMODE_READ && gr_learn_attached)
6439+ return -EBUSY;
6440+ if (file->f_mode & FMODE_READ) {
6441+ down(&gr_learn_user_sem);
6442+ if (learn_buffer == NULL)
6443+ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
6444+ if (learn_buffer_user == NULL)
6445+ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
6446+ if (learn_buffer == NULL)
6447+ return -ENOMEM;
6448+ if (learn_buffer_user == NULL)
6449+ return -ENOMEM;
6450+ learn_buffer_len = 0;
6451+ learn_buffer_user_len = 0;
6452+ gr_learn_attached = 1;
6453+ up(&gr_learn_user_sem);
6454+ }
6455+ return 0;
6456+}
6457+
6458+static int
6459+close_learn(struct inode *inode, struct file *file)
6460+{
6461+ char *tmp;
6462+
6463+ if (file->f_mode & FMODE_READ) {
6464+ down(&gr_learn_user_sem);
6465+ if (learn_buffer != NULL) {
6466+ spin_lock(&gr_learn_lock);
6467+ tmp = learn_buffer;
6468+ learn_buffer = NULL;
6469+ spin_unlock(&gr_learn_lock);
6470+ vfree(tmp);
6471+ }
6472+ if (learn_buffer_user != NULL) {
6473+ vfree(learn_buffer_user);
6474+ learn_buffer_user = NULL;
6475+ }
6476+ learn_buffer_len = 0;
6477+ learn_buffer_user_len = 0;
6478+ gr_learn_attached = 0;
6479+ up(&gr_learn_user_sem);
6480+ }
6481+
6482+ return 0;
6483+}
6484+
6485+struct file_operations grsec_fops = {
6486+ read: read_learn,
6487+ write: write_grsec_handler,
6488+ open: open_learn,
6489+ release: close_learn,
6490+ poll: poll_learn,
6491+};
6492diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_res.c linux-2.6.7-rc1/grsecurity/gracl_res.c
6493--- linux-2.6.7-rc1.orig/grsecurity/gracl_res.c 1970-01-01 01:00:00.000000000 +0100
6494+++ linux-2.6.7-rc1/grsecurity/gracl_res.c 2004-05-25 14:33:58.920403064 +0200
6495@@ -0,0 +1,50 @@
6496+/* resource handling routines (c) Brad Spengler 2002, 2003 */
6497+
6498+#include <linux/kernel.h>
6499+#include <linux/sched.h>
6500+#include <linux/gracl.h>
6501+#include <linux/grinternal.h>
6502+
6503+static const char *restab_log[11] = {
6504+ "RLIMIT_CPU",
6505+ "RLIMIT_FSIZE",
6506+ "RLIMIT_DATA",
6507+ "RLIMIT_STACK",
6508+ "RLIMIT_CORE",
6509+ "RLIMIT_RSS",
6510+ "RLIMIT_NPROC",
6511+ "RLIMIT_NOFILE",
6512+ "RLIMIT_MEMLOCK",
6513+ "RLIMIT_AS",
6514+ "RLIMIT_LOCKS"
6515+};
6516+
6517+__inline__ void
6518+gr_log_resource(const struct task_struct *task,
6519+ const int res, const unsigned long wanted, const int gt)
6520+{
6521+ if (unlikely(res == RLIMIT_NPROC &&
6522+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
6523+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
6524+ return;
6525+
6526+ preempt_disable();
6527+
6528+ if (unlikely(((gt && wanted > task->rlim[res].rlim_cur) ||
6529+ (!gt && wanted >= task->rlim[res].rlim_cur)) &&
6530+ task->rlim[res].rlim_cur != RLIM_INFINITY))
6531+ security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
6532+ task->rlim[res].rlim_cur,
6533+ gr_task_fullpath(task), task->comm,
6534+ task->pid, task->uid, task->euid,
6535+ task->gid, task->egid,
6536+ gr_parent_task_fullpath(task),
6537+ task->parent->comm,
6538+ task->parent->pid, task->parent->uid,
6539+ task->parent->euid, task->parent->gid,
6540+ task->parent->egid);
6541+
6542+ preempt_enable_no_resched();
6543+
6544+ return;
6545+}
6546diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_segv.c linux-2.6.7-rc1/grsecurity/gracl_segv.c
6547--- linux-2.6.7-rc1.orig/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100
6548+++ linux-2.6.7-rc1/grsecurity/gracl_segv.c 2004-05-25 14:33:58.922402760 +0200
6549@@ -0,0 +1,330 @@
6550+/*
6551+ * grsecurity/gracl_segv.c
6552+ * Copyright Brad Spengler 2002, 2003
6553+ *
6554+ */
6555+
6556+#include <linux/kernel.h>
6557+#include <linux/mm.h>
6558+#include <asm/uaccess.h>
6559+#include <asm/errno.h>
6560+#include <asm/mman.h>
6561+#include <net/sock.h>
6562+#include <linux/file.h>
6563+#include <linux/fs.h>
6564+#include <linux/net.h>
6565+#include <linux/in.h>
6566+#include <linux/smp_lock.h>
6567+#include <linux/slab.h>
6568+#include <linux/types.h>
6569+#include <linux/sched.h>
6570+#include <linux/timer.h>
6571+#include <linux/gracl.h>
6572+#include <linux/grsecurity.h>
6573+#include <linux/grinternal.h>
6574+
6575+static struct crash_uid *uid_set;
6576+static unsigned short uid_used;
6577+static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
6578+extern rwlock_t gr_inode_lock;
6579+extern struct acl_subject_label *
6580+ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
6581+ struct acl_role_label *role);
6582+extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
6583+
6584+int
6585+gr_init_uidset(void)
6586+{
6587+ uid_set =
6588+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
6589+ uid_used = 0;
6590+
6591+ return uid_set ? 1 : 0;
6592+}
6593+
6594+void
6595+gr_free_uidset(void)
6596+{
6597+ if (uid_set)
6598+ kfree(uid_set);
6599+
6600+ return;
6601+}
6602+
6603+int
6604+gr_find_uid(const uid_t uid)
6605+{
6606+ struct crash_uid *tmp = uid_set;
6607+ uid_t buid;
6608+ int low = 0, high = uid_used - 1, mid;
6609+
6610+ while (high >= low) {
6611+ mid = (low + high) >> 1;
6612+ buid = tmp[mid].uid;
6613+ if (buid == uid)
6614+ return mid;
6615+ if (buid > uid)
6616+ high = mid - 1;
6617+ if (buid < uid)
6618+ low = mid + 1;
6619+ }
6620+
6621+ return -1;
6622+}
6623+
6624+static __inline__ void
6625+gr_insertsort(void)
6626+{
6627+ unsigned short i, j;
6628+ struct crash_uid index;
6629+
6630+ for (i = 1; i < uid_used; i++) {
6631+ index = uid_set[i];
6632+ j = i;
6633+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
6634+ uid_set[j] = uid_set[j - 1];
6635+ j--;
6636+ }
6637+ uid_set[j] = index;
6638+ }
6639+
6640+ return;
6641+}
6642+
6643+static __inline__ void
6644+gr_insert_uid(const uid_t uid, const unsigned long expires)
6645+{
6646+ int loc;
6647+
6648+ if (uid_used == GR_UIDTABLE_MAX)
6649+ return;
6650+
6651+ loc = gr_find_uid(uid);
6652+
6653+ if (loc >= 0) {
6654+ uid_set[loc].expires = expires;
6655+ return;
6656+ }
6657+
6658+ uid_set[uid_used].uid = uid;
6659+ uid_set[uid_used].expires = expires;
6660+ uid_used++;
6661+
6662+ gr_insertsort();
6663+
6664+ return;
6665+}
6666+
6667+void
6668+gr_remove_uid(const unsigned short loc)
6669+{
6670+ unsigned short i;
6671+
6672+ for (i = loc + 1; i < uid_used; i++)
6673+ uid_set[i - i] = uid_set[i];
6674+
6675+ uid_used--;
6676+
6677+ return;
6678+}
6679+
6680+int
6681+gr_check_crash_uid(const uid_t uid)
6682+{
6683+ int loc;
6684+
6685+ if (unlikely(!gr_acl_is_enabled()))
6686+ return 0;
6687+
6688+ read_lock(&gr_uid_lock);
6689+ loc = gr_find_uid(uid);
6690+ read_unlock(&gr_uid_lock);
6691+
6692+ if (loc < 0)
6693+ return 0;
6694+
6695+ write_lock(&gr_uid_lock);
6696+ if (time_before_eq(uid_set[loc].expires, get_seconds()))
6697+ gr_remove_uid(loc);
6698+ else {
6699+ write_unlock(&gr_uid_lock);
6700+ return 1;
6701+ }
6702+
6703+ write_unlock(&gr_uid_lock);
6704+ return 0;
6705+}
6706+
6707+static __inline__ int
6708+proc_is_setxid(const struct task_struct *task)
6709+{
6710+ if (task->uid != task->euid || task->uid != task->suid ||
6711+ task->uid != task->fsuid)
6712+ return 1;
6713+ if (task->gid != task->egid || task->gid != task->sgid ||
6714+ task->gid != task->fsgid)
6715+ return 1;
6716+
6717+ return 0;
6718+}
6719+static __inline__ int
6720+gr_fake_force_sig(int sig, struct task_struct *t)
6721+{
6722+ unsigned long int flags;
6723+ int ret;
6724+
6725+ spin_lock_irqsave(&t->sighand->siglock, flags);
6726+ if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
6727+ t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
6728+ sigdelset(&t->blocked, sig);
6729+ recalc_sigpending_tsk(t);
6730+ }
6731+ ret = specific_send_sig_info(sig, (void*)1L, t);
6732+ spin_unlock_irqrestore(&t->sighand->siglock, flags);
6733+
6734+ return ret;
6735+}
6736+
6737+void
6738+gr_handle_crash(struct task_struct *task, const int sig)
6739+{
6740+ struct acl_subject_label *curr;
6741+ struct acl_subject_label *curr2;
6742+ struct task_struct *tsk, *tsk2;
6743+
6744+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
6745+ return;
6746+
6747+ if (unlikely(!gr_acl_is_enabled()))
6748+ return;
6749+
6750+ curr = task->acl;
6751+
6752+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
6753+ return;
6754+
6755+ if (time_before_eq(curr->expires, get_seconds())) {
6756+ curr->expires = 0;
6757+ curr->crashes = 0;
6758+ }
6759+
6760+ curr->crashes++;
6761+
6762+ if (!curr->expires)
6763+ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
6764+
6765+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
6766+ time_after(curr->expires, get_seconds())) {
6767+ if (task->uid && proc_is_setxid(task)) {
6768+ security_alert(GR_SEGVSTART_ACL_MSG,
6769+ gr_task_fullpath(task), task->comm,
6770+ task->pid, task->uid, task->euid,
6771+ task->gid, task->egid,
6772+ gr_parent_task_fullpath(task),
6773+ task->parent->comm, task->parent->pid,
6774+ task->parent->uid, task->parent->euid,
6775+ task->parent->gid, task->parent->egid,
6776+ task->uid,
6777+ curr->res[GR_CRASH_RES].rlim_max);
6778+ write_lock(&gr_uid_lock);
6779+ gr_insert_uid(task->uid, curr->expires);
6780+ write_unlock(&gr_uid_lock);
6781+ curr->expires = 0;
6782+ curr->crashes = 0;
6783+ read_lock(&tasklist_lock);
6784+ for_each_process(tsk) {
6785+ tsk2 = tsk;
6786+ do {
6787+ if (tsk2 != task && tsk2->uid == task->uid)
6788+ gr_fake_force_sig(SIGKILL, tsk2);
6789+ } while ((tsk2 = next_thread(tsk2)) != tsk);
6790+ }
6791+ read_unlock(&tasklist_lock);
6792+ } else {
6793+ security_alert(GR_SEGVNOSUID_ACL_MSG,
6794+ gr_task_fullpath(task), task->comm,
6795+ task->pid, task->uid, task->euid,
6796+ task->gid, task->egid,
6797+ gr_parent_task_fullpath(task),
6798+ task->parent->comm, task->parent->pid,
6799+ task->parent->uid, task->parent->euid,
6800+ task->parent->gid, task->parent->egid,
6801+ curr->res[GR_CRASH_RES].rlim_max);
6802+ read_lock(&tasklist_lock);
6803+ for_each_process(tsk) {
6804+ tsk2 = tsk;
6805+ do {
6806+ if (likely(tsk2 != task)) {
6807+ curr2 = tsk2->acl;
6808+
6809+ if (curr2->device == curr->device &&
6810+ curr2->inode == curr->inode)
6811+ gr_fake_force_sig(SIGKILL, tsk2);
6812+ }
6813+ } while ((tsk2 = next_thread(tsk2)) != tsk);
6814+ }
6815+ read_unlock(&tasklist_lock);
6816+ }
6817+ }
6818+
6819+ return;
6820+}
6821+
6822+int
6823+gr_check_crash_exec(const struct file *filp)
6824+{
6825+ struct acl_subject_label *curr;
6826+
6827+ if (unlikely(!gr_acl_is_enabled()))
6828+ return 0;
6829+
6830+ read_lock(&gr_inode_lock);
6831+ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
6832+ filp->f_dentry->d_inode->i_sb->s_dev,
6833+ current->role);
6834+ read_unlock(&gr_inode_lock);
6835+
6836+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
6837+ (!curr->crashes && !curr->expires))
6838+ return 0;
6839+
6840+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
6841+ time_after(curr->expires, get_seconds()))
6842+ return 1;
6843+ else if (time_before_eq(curr->expires, get_seconds())) {
6844+ curr->crashes = 0;
6845+ curr->expires = 0;
6846+ }
6847+
6848+ return 0;
6849+}
6850+
6851+void
6852+gr_handle_alertkill(void)
6853+{
6854+ struct acl_subject_label *curracl;
6855+ __u32 curr_ip;
6856+ struct task_struct *task, *task2;
6857+
6858+ if (unlikely(!gr_acl_is_enabled()))
6859+ return;
6860+
6861+ curracl = current->acl;
6862+ curr_ip = current->curr_ip;
6863+
6864+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
6865+ (curr_ip != 0xffffffff)) {
6866+ read_lock(&tasklist_lock);
6867+ for_each_process(task) {
6868+ task2 = task;
6869+ do {
6870+ if (task2->curr_ip == curr_ip)
6871+ gr_fake_force_sig(SIGKILL, task2);
6872+ } while ((task2 = next_thread(task2)) != task);
6873+ }
6874+ read_unlock(&tasklist_lock);
6875+ } else if (curracl->mode & GR_KILLPROC)
6876+ gr_fake_force_sig(SIGKILL, current);
6877+
6878+ return;
6879+}
6880diff -uNr linux-2.6.7-rc1.orig/grsecurity/gracl_shm.c linux-2.6.7-rc1/grsecurity/gracl_shm.c
6881--- linux-2.6.7-rc1.orig/grsecurity/gracl_shm.c 1970-01-01 01:00:00.000000000 +0100
6882+++ linux-2.6.7-rc1/grsecurity/gracl_shm.c 2004-05-25 14:33:58.924402456 +0200
6883@@ -0,0 +1,36 @@
6884+/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
6885+
6886+#include <linux/kernel.h>
6887+#include <linux/mm.h>
6888+#include <linux/sched.h>
6889+#include <linux/file.h>
6890+#include <linux/ipc.h>
6891+#include <linux/gracl.h>
6892+#include <linux/grsecurity.h>
6893+#include <linux/grinternal.h>
6894+
6895+int
6896+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
6897+ const time_t shm_createtime, const uid_t cuid, const int shmid)
6898+{
6899+ struct task_struct *task;
6900+
6901+ if (!gr_acl_is_enabled())
6902+ return 1;
6903+
6904+ task = find_task_by_pid(shm_cprid);
6905+
6906+ if (unlikely(!task))
6907+ task = find_task_by_pid(shm_lapid);
6908+
6909+ if (unlikely(task && ((task->start_time < shm_createtime) ||
6910+ (task->pid == shm_lapid)) &&
6911+ (task->acl->mode & GR_PROTSHM) &&
6912+ (task->acl != current->acl))) {
6913+ security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
6914+ DEFAULTSECARGS);
6915+ return 0;
6916+ }
6917+
6918+ return 1;
6919+}
6920diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_chdir.c linux-2.6.7-rc1/grsecurity/grsec_chdir.c
6921--- linux-2.6.7-rc1.orig/grsecurity/grsec_chdir.c 1970-01-01 01:00:00.000000000 +0100
6922+++ linux-2.6.7-rc1/grsecurity/grsec_chdir.c 2004-05-25 14:33:58.925402304 +0200
6923@@ -0,0 +1,20 @@
6924+#include <linux/kernel.h>
6925+#include <linux/sched.h>
6926+#include <linux/fs.h>
6927+#include <linux/file.h>
6928+#include <linux/grsecurity.h>
6929+#include <linux/grinternal.h>
6930+
6931+void
6932+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
6933+{
6934+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
6935+ if ((grsec_enable_chdir && grsec_enable_group &&
6936+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
6937+ !grsec_enable_group)) {
6938+ security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
6939+ DEFAULTSECARGS);
6940+ }
6941+#endif
6942+ return;
6943+}
6944diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_chroot.c linux-2.6.7-rc1/grsecurity/grsec_chroot.c
6945--- linux-2.6.7-rc1.orig/grsecurity/grsec_chroot.c 1970-01-01 01:00:00.000000000 +0100
6946+++ linux-2.6.7-rc1/grsecurity/grsec_chroot.c 2004-05-25 14:33:58.928401848 +0200
6947@@ -0,0 +1,348 @@
6948+#include <linux/kernel.h>
6949+#include <linux/module.h>
6950+#include <linux/sched.h>
6951+#include <linux/file.h>
6952+#include <linux/fs.h>
6953+#include <linux/mount.h>
6954+#include <linux/types.h>
6955+#include <linux/grinternal.h>
6956+
6957+int
6958+gr_handle_chroot_unix(const pid_t pid)
6959+{
6960+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
6961+ struct pid *spid = NULL;
6962+
6963+ if (unlikely(!grsec_enable_chroot_unix))
6964+ return 1;
6965+
6966+ if (likely(!proc_is_chrooted(current)))
6967+ return 1;
6968+
6969+ read_lock(&tasklist_lock);
6970+
6971+ spid = find_pid(PIDTYPE_PID, pid);
6972+ if (spid) {
6973+ struct task_struct *p;
6974+ p = pid_task(spid->task_list.next, PIDTYPE_PID);
6975+ if (unlikely(!have_same_root(current, p))) {
6976+ read_unlock(&tasklist_lock);
6977+ security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
6978+ return 0;
6979+ }
6980+ }
6981+ read_unlock(&tasklist_lock);
6982+#endif
6983+ return 1;
6984+}
6985+
6986+int
6987+gr_handle_chroot_nice(void)
6988+{
6989+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
6990+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
6991+ security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
6992+ return -EPERM;
6993+ }
6994+#endif
6995+ return 0;
6996+}
6997+
6998+int
6999+gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
7000+{
7001+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
7002+ if (grsec_enable_chroot_nice && (!have_same_root(p, current)
7003+ || (have_same_root(p, current)
7004+ && (niceval < task_nice(p))
7005+ && proc_is_chrooted(current)))) {
7006+ security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
7007+ DEFAULTSECARGS);
7008+ return -ESRCH;
7009+ }
7010+#endif
7011+ return 0;
7012+}
7013+
7014+int
7015+gr_handle_chroot_capset(const struct task_struct *target)
7016+{
7017+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7018+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
7019+ !have_same_root(current, target)) {
7020+ security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
7021+ DEFAULTSECARGS);
7022+ return 1;
7023+ }
7024+#endif
7025+ return 0;
7026+}
7027+
7028+int
7029+gr_handle_chroot_rawio(const struct inode *inode)
7030+{
7031+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7032+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
7033+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
7034+ return 1;
7035+#endif
7036+ return 0;
7037+}
7038+
7039+int
7040+gr_pid_is_chrooted(const struct task_struct *p)
7041+{
7042+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
7043+ if (!grsec_enable_chroot_findtask || (current->pid <= 1))
7044+ return 0;
7045+
7046+ if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
7047+ child_reaper && child_reaper->fs && child_reaper->fs->root &&
7048+ child_reaper->fs->root->d_inode && current && current->fs &&
7049+ current->fs->root && current->fs->root->d_inode) {
7050+ if (proc_is_chrooted(current) && !have_same_root(current, p))
7051+ return 1;
7052+ }
7053+#endif
7054+ return 0;
7055+}
7056+
7057+EXPORT_SYMBOL(gr_pid_is_chrooted);
7058+
7059+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
7060+int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
7061+{
7062+ struct dentry *dentry = (struct dentry *)u_dentry;
7063+ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
7064+ struct dentry *realroot;
7065+ struct vfsmount *realrootmnt;
7066+ struct dentry *currentroot;
7067+ struct vfsmount *currentmnt;
7068+
7069+ read_lock(&child_reaper->fs->lock);
7070+ realrootmnt = mntget(child_reaper->fs->rootmnt);
7071+ realroot = dget(child_reaper->fs->root);
7072+ read_unlock(&child_reaper->fs->lock);
7073+
7074+ read_lock(&current->fs->lock);
7075+ currentmnt = mntget(current->fs->rootmnt);
7076+ currentroot = dget(current->fs->root);
7077+ read_unlock(&current->fs->lock);
7078+
7079+ spin_lock(&dcache_lock);
7080+ for (;;) {
7081+ if (unlikely((dentry == realroot && mnt == realrootmnt)
7082+ || (dentry == currentroot && mnt == currentmnt)))
7083+ break;
7084+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
7085+ if (mnt->mnt_parent == mnt)
7086+ break;
7087+ dentry = mnt->mnt_mountpoint;
7088+ mnt = mnt->mnt_parent;
7089+ continue;
7090+ }
7091+ dentry = dentry->d_parent;
7092+ }
7093+ spin_unlock(&dcache_lock);
7094+
7095+ dput(currentroot);
7096+ mntput(currentmnt);
7097+
7098+ if (dentry == realroot && mnt == realrootmnt) {
7099+ /* access is outside of chroot */
7100+ dput(realroot);
7101+ mntput(realrootmnt);
7102+ return 0;
7103+ }
7104+
7105+ dput(realroot);
7106+ mntput(realrootmnt);
7107+ return 1;
7108+}
7109+#endif
7110+
7111+int
7112+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
7113+{
7114+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
7115+ if (!grsec_enable_chroot_fchdir)
7116+ return 1;
7117+
7118+ if (!proc_is_chrooted(current))
7119+ return 1;
7120+ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
7121+ security_alert(GR_CHROOT_FCHDIR_MSG,
7122+ gr_to_filename(u_dentry, u_mnt),
7123+ DEFAULTSECARGS);
7124+ return 0;
7125+ }
7126+#endif
7127+ return 1;
7128+}
7129+
7130+int
7131+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
7132+ const time_t shm_createtime)
7133+{
7134+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
7135+ struct pid *pid = NULL;
7136+ u64 starttime64;
7137+ time_t starttime;
7138+
7139+ if (unlikely(!grsec_enable_chroot_shmat))
7140+ return 1;
7141+
7142+ if (likely(!proc_is_chrooted(current)))
7143+ return 1;
7144+
7145+ read_lock(&tasklist_lock);
7146+
7147+ pid = find_pid(PIDTYPE_PID, shm_cprid);
7148+ if (pid) {
7149+ struct task_struct *p;
7150+ p = pid_task(pid->task_list.next, PIDTYPE_PID);
7151+ starttime64 = p->start_time;
7152+ do_div(starttime64, HZ);
7153+ starttime = (time_t) starttime64;
7154+ if (unlikely(!have_same_root(current, p) &&
7155+ time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
7156+ read_unlock(&tasklist_lock);
7157+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
7158+ return 0;
7159+ }
7160+ } else {
7161+ pid = find_pid(PIDTYPE_PID, shm_lapid);
7162+ if (pid) {
7163+ struct task_struct *p;
7164+ p = pid_task(pid->task_list.next, PIDTYPE_PID);
7165+ if (unlikely(!have_same_root(current, p))) {
7166+ read_unlock(&tasklist_lock);
7167+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
7168+ return 0;
7169+ }
7170+ }
7171+ }
7172+
7173+ read_unlock(&tasklist_lock);
7174+#endif
7175+ return 1;
7176+}
7177+
7178+void
7179+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
7180+{
7181+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
7182+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
7183+ security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
7184+ DEFAULTSECARGS);
7185+#endif
7186+ return;
7187+}
7188+
7189+int
7190+gr_handle_chroot_mknod(const struct dentry *dentry,
7191+ const struct vfsmount *mnt, const int mode)
7192+{
7193+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
7194+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
7195+ proc_is_chrooted(current)) {
7196+ security_alert(GR_MKNOD_CHROOT_MSG,
7197+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
7198+ return -EPERM;
7199+ }
7200+#endif
7201+ return 0;
7202+}
7203+
7204+int
7205+gr_handle_chroot_mount(const struct dentry *dentry,
7206+ const struct vfsmount *mnt, const char *dev_name)
7207+{
7208+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
7209+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
7210+ security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
7211+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
7212+ return -EPERM;
7213+ }
7214+#endif
7215+ return 0;
7216+}
7217+
7218+int
7219+gr_handle_chroot_pivot(void)
7220+{
7221+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
7222+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
7223+ security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
7224+ return -EPERM;
7225+ }
7226+#endif
7227+ return 0;
7228+}
7229+
7230+int
7231+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
7232+{
7233+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
7234+ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
7235+ !gr_is_outside_chroot(dentry, mnt)) {
7236+ security_alert(GR_CHROOT_CHROOT_MSG,
7237+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
7238+ return -EPERM;
7239+ }
7240+#endif
7241+ return 0;
7242+}
7243+
7244+void
7245+gr_handle_chroot_caps(struct task_struct *task)
7246+{
7247+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7248+ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
7249+ task->cap_permitted =
7250+ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
7251+ task->cap_inheritable =
7252+ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
7253+ task->cap_effective =
7254+ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
7255+ }
7256+#endif
7257+ return;
7258+}
7259+
7260+int
7261+gr_handle_chroot_sysctl(const int op)
7262+{
7263+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
7264+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
7265+ && (op & 002))
7266+ return -EACCES;
7267+#endif
7268+ return 0;
7269+}
7270+
7271+void
7272+gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
7273+{
7274+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
7275+ if (grsec_enable_chroot_chdir)
7276+ set_fs_pwd(current->fs, mnt, dentry);
7277+#endif
7278+ return;
7279+}
7280+
7281+int
7282+gr_handle_chroot_chmod(const struct dentry *dentry,
7283+ const struct vfsmount *mnt, const int mode)
7284+{
7285+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
7286+ if (grsec_enable_chroot_chmod &&
7287+ ((mode & S_ISUID) || (mode & S_ISGID)) &&
7288+ proc_is_chrooted(current)) {
7289+ security_alert(GR_CHMOD_CHROOT_MSG,
7290+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
7291+ return -EPERM;
7292+ }
7293+#endif
7294+ return 0;
7295+}
7296diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_disabled.c linux-2.6.7-rc1/grsecurity/grsec_disabled.c
7297--- linux-2.6.7-rc1.orig/grsecurity/grsec_disabled.c 1970-01-01 01:00:00.000000000 +0100
7298+++ linux-2.6.7-rc1/grsecurity/grsec_disabled.c 2004-05-25 14:33:58.931401392 +0200
6a84f544 7299@@ -0,0 +1,392 @@
1db5cd70
PS
7300+/*
7301+ * when grsecurity is disabled, compile all external functions into nothing
7302+ */
7303+
7304+#include <linux/kernel.h>
7305+#include <linux/module.h>
7306+#include <linux/config.h>
7307+#include <linux/sched.h>
7308+#include <linux/file.h>
7309+#include <linux/fs.h>
7310+#include <linux/kdev_t.h>
7311+#include <linux/net.h>
7312+#include <linux/in.h>
7313+#include <linux/ip.h>
7314+#include <linux/skbuff.h>
7315+#include <linux/sysctl.h>
7316+
1db5cd70
PS
7317+#ifdef CONFIG_SYSCTL
7318+__inline__ __u32
7319+gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
7320+{
7321+ return mode;
7322+}
7323+#endif
7324+
7325+__inline__ int
7326+gr_acl_is_enabled(void)
7327+{
7328+ return 0;
7329+}
7330+
7331+__inline__ int
7332+gr_handle_rawio(const struct inode *inode)
7333+{
7334+ return 0;
7335+}
7336+
7337+__inline__ void
7338+gr_acl_handle_psacct(struct task_struct *task, const long code)
7339+{
7340+ return;
7341+}
7342+
7343+__inline__ int
7344+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
7345+{
7346+ return 0;
7347+}
7348+
7349+__inline__ int
7350+gr_handle_mmap(const struct file *filp, const unsigned long prot)
7351+{
7352+ return 0;
7353+}
7354+
7355+__inline__ int
7356+gr_handle_ptrace(struct task_struct *task, const long request)
7357+{
7358+ return 0;
7359+}
7360+
7361+__inline__ int
7362+gr_handle_proc_ptrace(struct task_struct *task)
7363+{
7364+ return 0;
7365+}
7366+
7367+__inline__ void
7368+gr_learn_resource(const struct task_struct *task,
7369+ const int res, const unsigned long wanted, const int gt)
7370+{
7371+ return;
7372+}
7373+
7374+__inline__ int
7375+gr_set_acls(const int type)
7376+{
7377+ return 0;
7378+}
7379+
7380+__inline__ int
7381+gr_check_hidden_task(const struct task_struct *tsk)
7382+{
7383+ return 0;
7384+}
7385+
7386+__inline__ int
7387+gr_check_protected_task(const struct task_struct *task)
7388+{
7389+ return 0;
7390+}
7391+
7392+__inline__ void
7393+gr_copy_label(struct task_struct *tsk)
7394+{
7395+ return;
7396+}
7397+
7398+__inline__ void
1db5cd70
PS
7399+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
7400+{
7401+ return;
7402+}
7403+
7404+__inline__ void
7405+gr_handle_delete(const ino_t ino, const dev_t dev)
7406+{
7407+ return;
7408+}
7409+
7410+__inline__ void
7411+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
7412+{
7413+ return;
7414+}
7415+
7416+__inline__ void
7417+gr_handle_crash(struct task_struct *task, const int sig)
7418+{
7419+ return;
7420+}
7421+
7422+__inline__ int
7423+gr_check_crash_exec(const struct file *filp)
7424+{
7425+ return 0;
7426+}
7427+
7428+__inline__ int
7429+gr_check_crash_uid(const uid_t uid)
7430+{
7431+ return 0;
7432+}
7433+
7434+__inline__ void
7435+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
7436+ struct dentry *old_dentry,
7437+ struct dentry *new_dentry,
7438+ struct vfsmount *mnt, const __u8 replace)
7439+{
7440+ return;
7441+}
7442+
7443+__inline__ int
7444+gr_search_socket(const int family, const int type, const int protocol)
7445+{
7446+ return 1;
7447+}
7448+
7449+__inline__ int
7450+gr_search_connectbind(const int mode, const struct socket *sock,
7451+ const struct sockaddr_in *addr)
7452+{
7453+ return 1;
7454+}
7455+
7456+__inline__ int
7457+gr_task_is_capable(struct task_struct *task, const int cap)
7458+{
7459+ return 1;
7460+}
7461+
7462+__inline__ int
7463+gr_is_capable_nolog(const int cap)
7464+{
7465+ return 1;
7466+}
7467+
7468+__inline__ void
7469+gr_handle_alertkill(void)
7470+{
7471+ return;
7472+}
7473+
7474+__inline__ __u32
7475+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
7476+{
7477+ return 1;
7478+}
7479+
7480+__inline__ __u32
7481+gr_acl_handle_hidden_file(const struct dentry * dentry,
7482+ const struct vfsmount * mnt)
7483+{
7484+ return 1;
7485+}
7486+
7487+__inline__ __u32
7488+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
7489+ const int fmode)
7490+{
7491+ return 1;
7492+}
7493+
7494+__inline__ __u32
7495+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
7496+{
7497+ return 1;
7498+}
7499+
7500+__inline__ __u32
7501+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
7502+{
7503+ return 1;
7504+}
7505+
7506+__inline__ int
7507+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
7508+ unsigned int *vm_flags)
7509+{
7510+ return 1;
7511+}
7512+
7513+__inline__ __u32
7514+gr_acl_handle_truncate(const struct dentry * dentry,
7515+ const struct vfsmount * mnt)
7516+{
7517+ return 1;
7518+}
7519+
7520+__inline__ __u32
7521+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
7522+{
7523+ return 1;
7524+}
7525+
7526+__inline__ __u32
7527+gr_acl_handle_access(const struct dentry * dentry,
7528+ const struct vfsmount * mnt, const int fmode)
7529+{
7530+ return 1;
7531+}
7532+
7533+__inline__ __u32
7534+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
7535+ mode_t mode)
7536+{
7537+ return 1;
7538+}
7539+
7540+__inline__ __u32
7541+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
7542+ mode_t mode)
7543+{
7544+ return 1;
7545+}
7546+
7547+__inline__ __u32
7548+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
7549+{
7550+ return 1;
7551+}
7552+
7553+__inline__ void
7554+grsecurity_init(void)
7555+{
7556+ return;
7557+}
7558+
7559+__inline__ __u32
7560+gr_acl_handle_mknod(const struct dentry * new_dentry,
7561+ const struct dentry * parent_dentry,
7562+ const struct vfsmount * parent_mnt,
7563+ const int mode)
7564+{
7565+ return 1;
7566+}
7567+
7568+__inline__ __u32
7569+gr_acl_handle_mkdir(const struct dentry * new_dentry,
7570+ const struct dentry * parent_dentry,
7571+ const struct vfsmount * parent_mnt)
7572+{
7573+ return 1;
7574+}
7575+
7576+__inline__ __u32
7577+gr_acl_handle_symlink(const struct dentry * new_dentry,
7578+ const struct dentry * parent_dentry,
7579+ const struct vfsmount * parent_mnt, const char *from)
7580+{
7581+ return 1;
7582+}
7583+
7584+__inline__ __u32
7585+gr_acl_handle_link(const struct dentry * new_dentry,
7586+ const struct dentry * parent_dentry,
7587+ const struct vfsmount * parent_mnt,
7588+ const struct dentry * old_dentry,
7589+ const struct vfsmount * old_mnt, const char *to)
7590+{
7591+ return 1;
7592+}
7593+
7594+__inline__ int
7595+gr_acl_handle_rename(const struct dentry *new_dentry,
7596+ const struct dentry *parent_dentry,
7597+ const struct vfsmount *parent_mnt,
7598+ const struct dentry *old_dentry,
7599+ const struct inode *old_parent_inode,
7600+ const struct vfsmount *old_mnt, const char *newname)
7601+{
7602+ return 0;
7603+}
7604+
7605+__inline__ __u32
7606+gr_acl_handle_filldir(const struct dentry * dentry,
7607+ const struct vfsmount * mnt, const ino_t ino)
7608+{
7609+ return 1;
7610+}
7611+
7612+__inline__ int
7613+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
7614+ const time_t shm_createtime, const uid_t cuid, const int shmid)
7615+{
7616+ return 1;
7617+}
7618+
7619+__inline__ int
7620+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
7621+{
7622+ return 1;
7623+}
7624+
7625+__inline__ int
7626+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
7627+{
7628+ return 1;
7629+}
7630+
7631+__inline__ __u32
7632+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
7633+{
7634+ return 1;
7635+}
7636+
7637+__inline__ __u32
7638+gr_acl_handle_creat(const struct dentry * dentry,
7639+ const struct dentry * p_dentry,
7640+ const struct vfsmount * p_mnt, const int fmode,
7641+ const int imode)
7642+{
7643+ return 1;
7644+}
7645+
7646+__inline__ void
7647+gr_acl_handle_exit(void)
7648+{
7649+ return;
7650+}
7651+
7652+__inline__ int
7653+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
7654+{
7655+ return 1;
7656+}
7657+
7658+__inline__ void
7659+gr_set_role_label(const uid_t uid, const gid_t gid)
7660+{
7661+ return;
7662+}
7663+
7664+__inline__ int
7665+gr_acl_handle_procpidmem(const struct task_struct *task)
7666+{
7667+ return 0;
7668+}
7669+
7670+__inline__ int
7671+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
7672+{
7673+ return 1;
7674+}
7675+
7676+__inline__ int
7677+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
7678+{
7679+ return 1;
7680+}
7681+
7682+__inline__ void
7683+gr_set_kernel_label(struct task_struct *task)
7684+{
7685+ return;
7686+}
7687+
7688+EXPORT_SYMBOL(gr_task_is_capable);
7689+EXPORT_SYMBOL(gr_learn_resource);
7690+EXPORT_SYMBOL(gr_set_kernel_label);
7691+
7692diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_exec.c linux-2.6.7-rc1/grsecurity/grsec_exec.c
7693--- linux-2.6.7-rc1.orig/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100
7694+++ linux-2.6.7-rc1/grsecurity/grsec_exec.c 2004-05-25 14:33:58.932401240 +0200
7695@@ -0,0 +1,71 @@
7696+#include <linux/kernel.h>
7697+#include <linux/sched.h>
7698+#include <linux/file.h>
7699+#include <linux/binfmts.h>
7700+#include <linux/fs.h>
7701+#include <linux/types.h>
7702+#include <linux/grdefs.h>
7703+#include <linux/grinternal.h>
7704+#include <linux/capability.h>
7705+
7706+#include <asm/uaccess.h>
7707+
7708+int
7709+gr_handle_nproc(void)
7710+{
7711+#ifdef CONFIG_GRKERNSEC_EXECVE
7712+ if (grsec_enable_execve && current->user &&
7713+ (atomic_read(&current->user->processes) >
7714+ current->rlim[RLIMIT_NPROC].rlim_cur) &&
7715+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
7716+ security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
7717+ return -EAGAIN;
7718+ }
7719+#endif
7720+ return 0;
7721+}
7722+
7723+void
7724+gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
7725+{
7726+#ifdef CONFIG_GRKERNSEC_EXECLOG
7727+ char grarg[64] = { 0 };
7728+ __u8 execlen = 0;
7729+ unsigned int i;
7730+
7731+ if (!((grsec_enable_execlog && grsec_enable_group &&
7732+ in_group_p(grsec_audit_gid))
7733+ || (grsec_enable_execlog && !grsec_enable_group)))
7734+ return;
7735+
7736+ if (unlikely(!argv))
7737+ goto log;
7738+
7739+ for (i = 0; i < bprm->argc && execlen < 62; i++) {
7740+ char *p;
7741+ __u8 len;
7742+
7743+ if (get_user(p, argv + i))
7744+ goto log;
7745+ if (!p)
7746+ goto log;
7747+ len = strnlen_user(p, 62 - execlen);
7748+ if (len > 62 - execlen)
7749+ len = 62 - execlen;
7750+ else if (len > 0)
7751+ len--;
7752+ if (copy_from_user(grarg + execlen, p, len))
7753+ goto log;
7754+ execlen += len;
7755+ *(grarg + execlen) = ' ';
7756+ *(grarg + execlen + 1) = '\0';
7757+ execlen++;
7758+ }
7759+
7760+ log:
7761+ security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
7762+ bprm->file->f_vfsmnt),
7763+ grarg, DEFAULTSECARGS);
7764+#endif
7765+ return;
7766+}
7767diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_fifo.c linux-2.6.7-rc1/grsecurity/grsec_fifo.c
7768--- linux-2.6.7-rc1.orig/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100
7769+++ linux-2.6.7-rc1/grsecurity/grsec_fifo.c 2004-05-25 14:33:58.934400936 +0200
7770@@ -0,0 +1,24 @@
7771+#include <linux/kernel.h>
7772+#include <linux/sched.h>
7773+#include <linux/fs.h>
7774+#include <linux/file.h>
7775+#include <linux/grinternal.h>
7776+
7777+int
7778+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
7779+ const struct dentry *dir, const int flag, const int acc_mode)
7780+{
7781+#ifdef CONFIG_GRKERNSEC_FIFO
7782+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
7783+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
7784+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
7785+ (current->fsuid != dentry->d_inode->i_uid)) {
7786+ if (!vfs_permission(dentry->d_inode, acc_mode))
7787+ security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
7788+ dentry->d_inode->i_uid,
7789+ dentry->d_inode->i_gid, DEFAULTSECARGS);
7790+ return -EACCES;
7791+ }
7792+#endif
7793+ return 0;
7794+}
7795diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_fork.c linux-2.6.7-rc1/grsecurity/grsec_fork.c
7796--- linux-2.6.7-rc1.orig/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100
7797+++ linux-2.6.7-rc1/grsecurity/grsec_fork.c 2004-05-25 14:33:58.935400784 +0200
7798@@ -0,0 +1,14 @@
7799+#include <linux/kernel.h>
7800+#include <linux/sched.h>
7801+#include <linux/grsecurity.h>
7802+#include <linux/grinternal.h>
7803+
7804+void
7805+gr_log_forkfail(const int retval)
7806+{
7807+#ifdef CONFIG_GRKERNSEC_FORKFAIL
7808+ if (grsec_enable_forkfail)
7809+ security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
7810+#endif
7811+ return;
7812+}
7813diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_init.c linux-2.6.7-rc1/grsecurity/grsec_init.c
7814--- linux-2.6.7-rc1.orig/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100
7815+++ linux-2.6.7-rc1/grsecurity/grsec_init.c 2004-05-25 14:33:58.938400328 +0200
806c2378 7816@@ -0,0 +1,223 @@
1db5cd70
PS
7817+#include <linux/kernel.h>
7818+#include <linux/sched.h>
7819+#include <linux/mm.h>
7820+#include <linux/smp_lock.h>
7821+#include <linux/gracl.h>
7822+#include <linux/slab.h>
7823+#include <linux/vmalloc.h>
7824+#include <linux/percpu.h>
7825+
7826+int grsec_enable_link;
7827+int grsec_enable_dmesg;
7828+int grsec_enable_fifo;
7829+int grsec_enable_execve;
7830+int grsec_enable_execlog;
7831+int grsec_enable_signal;
7832+int grsec_enable_forkfail;
7833+int grsec_enable_time;
1db5cd70
PS
7834+int grsec_enable_group;
7835+int grsec_audit_gid;
7836+int grsec_enable_chdir;
7837+int grsec_enable_audit_ipc;
7838+int grsec_enable_mount;
7839+int grsec_enable_chroot_findtask;
7840+int grsec_enable_chroot_mount;
7841+int grsec_enable_chroot_shmat;
7842+int grsec_enable_chroot_fchdir;
7843+int grsec_enable_chroot_double;
7844+int grsec_enable_chroot_pivot;
7845+int grsec_enable_chroot_chdir;
7846+int grsec_enable_chroot_chmod;
7847+int grsec_enable_chroot_mknod;
7848+int grsec_enable_chroot_nice;
7849+int grsec_enable_chroot_execlog;
7850+int grsec_enable_chroot_caps;
7851+int grsec_enable_chroot_sysctl;
7852+int grsec_enable_chroot_unix;
7853+int grsec_enable_tpe;
7854+int grsec_tpe_gid;
7855+int grsec_enable_tpe_all;
7856+int grsec_enable_randpid;
7857+int grsec_enable_randid;
7858+int grsec_enable_randisn;
7859+int grsec_enable_randsrc;
7860+int grsec_enable_randrpc;
7861+int grsec_enable_socket_all;
7862+int grsec_socket_all_gid;
7863+int grsec_enable_socket_client;
7864+int grsec_socket_client_gid;
7865+int grsec_enable_socket_server;
7866+int grsec_socket_server_gid;
7867+int grsec_lock;
7868+
7869+spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
7870+unsigned long grsec_alert_wtime = 0;
7871+unsigned long grsec_alert_fyet = 0;
7872+
7873+spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
7874+unsigned long grsec_alertgood_wtime = 0;
7875+unsigned long grsec_alertgood_fyet = 0;
7876+
7877+spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
7878+
7879+char *gr_shared_page[4];
7880+extern struct gr_arg *gr_usermode;
7881+extern unsigned char *gr_system_salt;
7882+extern unsigned char *gr_system_sum;
7883+extern struct task_struct **gr_conn_table;
7884+extern const unsigned int gr_conn_table_size;
7885+
7886+void
7887+grsecurity_init(void)
7888+{
7889+ int j;
7890+ /* create the per-cpu shared pages */
7891+
7892+ preempt_disable();
7893+ for (j = 0; j < 4; j++) {
7894+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(char *));
7895+ if (gr_shared_page[j] == NULL) {
7896+ panic("Unable to allocate grsecurity shared page");
7897+ return;
7898+ }
7899+ }
7900+ preempt_enable();
7901+
7902+ /* create hash tables for ip tagging */
7903+
7904+ gr_conn_table = (struct task_struct **) vmalloc(gr_conn_table_size * sizeof(struct task_struct *));
7905+ if (gr_conn_table == NULL) {
7906+ panic("Unable to allocate grsecurity IP tagging table");
7907+ return;
7908+ }
7909+ memset(gr_conn_table, 0, gr_conn_table_size * sizeof(struct task_struct *));
7910+
7911+ /* allocate memory for authentication structure */
7912+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
7913+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
7914+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
7915+
7916+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
7917+ panic("Unable to allocate grsecurity authentication structure");
7918+ return;
7919+ }
7920+
7921+#ifndef CONFIG_GRKERNSEC_SYSCTL
7922+ grsec_lock = 1;
1db5cd70
PS
7923+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
7924+ grsec_enable_group = 1;
7925+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
7926+#endif
7927+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
7928+ grsec_enable_chdir = 1;
7929+#endif
7930+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
7931+ grsec_enable_audit_ipc = 1;
7932+#endif
7933+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
7934+ grsec_enable_mount = 1;
7935+#endif
7936+#ifdef CONFIG_GRKERNSEC_LINK
7937+ grsec_enable_link = 1;
7938+#endif
7939+#ifdef CONFIG_GRKERNSEC_DMESG
7940+ grsec_enable_dmesg = 1;
7941+#endif
7942+#ifdef CONFIG_GRKERNSEC_FIFO
7943+ grsec_enable_fifo = 1;
7944+#endif
7945+#ifdef CONFIG_GRKERNSEC_EXECVE
7946+ grsec_enable_execve = 1;
7947+#endif
7948+#ifdef CONFIG_GRKERNSEC_EXECLOG
7949+ grsec_enable_execlog = 1;
7950+#endif
7951+#ifdef CONFIG_GRKERNSEC_SIGNAL
7952+ grsec_enable_signal = 1;
7953+#endif
7954+#ifdef CONFIG_GRKERNSEC_FORKFAIL
7955+ grsec_enable_forkfail = 1;
7956+#endif
7957+#ifdef CONFIG_GRKERNSEC_TIME
7958+ grsec_enable_time = 1;
7959+#endif
7960+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
7961+ grsec_enable_chroot_findtask = 1;
7962+#endif
7963+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
7964+ grsec_enable_chroot_unix = 1;
7965+#endif
7966+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
7967+ grsec_enable_chroot_mount = 1;
7968+#endif
7969+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
7970+ grsec_enable_chroot_fchdir = 1;
7971+#endif
7972+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
7973+ grsec_enable_chroot_shmat = 1;
7974+#endif
7975+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
7976+ grsec_enable_chroot_double = 1;
7977+#endif
7978+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
7979+ grsec_enable_chroot_pivot = 1;
7980+#endif
7981+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
7982+ grsec_enable_chroot_chdir = 1;
7983+#endif
7984+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
7985+ grsec_enable_chroot_chmod = 1;
7986+#endif
7987+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
7988+ grsec_enable_chroot_mknod = 1;
7989+#endif
7990+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
7991+ grsec_enable_chroot_nice = 1;
7992+#endif
7993+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
7994+ grsec_enable_chroot_execlog = 1;
7995+#endif
7996+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7997+ grsec_enable_chroot_caps = 1;
7998+#endif
7999+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
8000+ grsec_enable_chroot_sysctl = 1;
8001+#endif
8002+#ifdef CONFIG_GRKERNSEC_TPE
8003+ grsec_enable_tpe = 1;
8004+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
8005+#ifdef CONFIG_GRKERNSEC_TPE_ALL
8006+ grsec_enable_tpe_all = 1;
8007+#endif
8008+#endif
8009+#ifdef CONFIG_GRKERNSEC_RANDPID
8010+ grsec_enable_randpid = 1;
8011+#endif
8012+#ifdef CONFIG_GRKERNSEC_RANDID
8013+ grsec_enable_randid = 1;
8014+#endif
8015+#ifdef CONFIG_GRKERNSEC_RANDISN
8016+ grsec_enable_randisn = 1;
8017+#endif
8018+#ifdef CONFIG_GRKERNSEC_RANDSRC
8019+ grsec_enable_randsrc = 1;
8020+#endif
8021+#ifdef CONFIG_GRKERNSEC_RANDRPC
8022+ grsec_enable_randrpc = 1;
8023+#endif
8024+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
8025+ grsec_enable_socket_all = 1;
8026+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
8027+#endif
8028+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
8029+ grsec_enable_socket_client = 1;
8030+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
8031+#endif
8032+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
8033+ grsec_enable_socket_server = 1;
8034+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
8035+#endif
8036+#endif
8037+
8038+ return;
8039+}
8040diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_ipc.c linux-2.6.7-rc1/grsecurity/grsec_ipc.c
8041--- linux-2.6.7-rc1.orig/grsecurity/grsec_ipc.c 1970-01-01 01:00:00.000000000 +0100
8042+++ linux-2.6.7-rc1/grsecurity/grsec_ipc.c 2004-05-25 14:33:58.939400176 +0200
8043@@ -0,0 +1,81 @@
8044+#include <linux/kernel.h>
8045+#include <linux/sched.h>
8046+#include <linux/types.h>
8047+#include <linux/ipc.h>
8048+#include <linux/grsecurity.h>
8049+#include <linux/grinternal.h>
8050+
8051+void
8052+gr_log_msgget(const int ret, const int msgflg)
8053+{
8054+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8055+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8056+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
8057+ !grsec_enable_group)) && (ret >= 0)
8058+ && (msgflg & IPC_CREAT))
8059+ security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
8060+#endif
8061+ return;
8062+}
8063+
8064+void
8065+gr_log_msgrm(const uid_t uid, const uid_t cuid)
8066+{
8067+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8068+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8069+ grsec_enable_audit_ipc) ||
8070+ (grsec_enable_audit_ipc && !grsec_enable_group))
8071+ security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
8072+#endif
8073+ return;
8074+}
8075+
8076+void
8077+gr_log_semget(const int err, const int semflg)
8078+{
8079+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8080+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8081+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
8082+ !grsec_enable_group)) && (err >= 0)
8083+ && (semflg & IPC_CREAT))
8084+ security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
8085+#endif
8086+ return;
8087+}
8088+
8089+void
8090+gr_log_semrm(const uid_t uid, const uid_t cuid)
8091+{
8092+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8093+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8094+ grsec_enable_audit_ipc) ||
8095+ (grsec_enable_audit_ipc && !grsec_enable_group))
8096+ security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
8097+#endif
8098+ return;
8099+}
8100+
8101+void
8102+gr_log_shmget(const int err, const int shmflg, const size_t size)
8103+{
8104+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8105+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8106+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
8107+ !grsec_enable_group)) && (err >= 0)
8108+ && (shmflg & IPC_CREAT))
8109+ security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
8110+#endif
8111+ return;
8112+}
8113+
8114+void
8115+gr_log_shmrm(const uid_t uid, const uid_t cuid)
8116+{
8117+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8118+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8119+ grsec_enable_audit_ipc) ||
8120+ (grsec_enable_audit_ipc && !grsec_enable_group))
8121+ security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
8122+#endif
8123+ return;
8124+}
8125diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_link.c linux-2.6.7-rc1/grsecurity/grsec_link.c
8126--- linux-2.6.7-rc1.orig/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100
8127+++ linux-2.6.7-rc1/grsecurity/grsec_link.c 2004-05-25 14:33:58.941399872 +0200
8128@@ -0,0 +1,41 @@
8129+#include <linux/kernel.h>
8130+#include <linux/sched.h>
8131+#include <linux/fs.h>
8132+#include <linux/file.h>
8133+#include <linux/grinternal.h>
8134+
8135+int
8136+gr_handle_follow_link(const struct inode *parent,
8137+ const struct inode *inode,
8138+ const struct dentry *dentry, const struct vfsmount *mnt)
8139+{
8140+#ifdef CONFIG_GRKERNSEC_LINK
8141+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
8142+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
8143+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
8144+ security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
8145+ inode->i_uid, inode->i_gid, DEFAULTSECARGS);
8146+ return -EACCES;
8147+ }
8148+#endif
8149+ return 0;
8150+}
8151+
8152+int
8153+gr_handle_hardlink(const struct dentry *dentry,
8154+ const struct vfsmount *mnt,
8155+ struct inode *inode, const int mode, const char *to)
8156+{
8157+#ifdef CONFIG_GRKERNSEC_LINK
8158+ if (grsec_enable_link && current->fsuid != inode->i_uid &&
8159+ (!S_ISREG(mode) || (mode & S_ISUID) ||
8160+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
8161+ (vfs_permission(inode, MAY_READ | MAY_WRITE))) &&
8162+ !capable(CAP_FOWNER) && current->uid) {
8163+ security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
8164+ inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
8165+ return -EPERM;
8166+ }
8167+#endif
8168+ return 0;
8169+}
8170diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_mem.c linux-2.6.7-rc1/grsecurity/grsec_mem.c
8171--- linux-2.6.7-rc1.orig/grsecurity/grsec_mem.c 1970-01-01 01:00:00.000000000 +0100
8172+++ linux-2.6.7-rc1/grsecurity/grsec_mem.c 2004-05-25 14:33:58.943399568 +0200
8173@@ -0,0 +1,54 @@
8174+#include <linux/kernel.h>
8175+#include <linux/sched.h>
8176+#include <linux/mm.h>
8177+#include <linux/mman.h>
8178+#include <linux/grinternal.h>
8179+
8180+void
8181+gr_handle_ioperm(void)
8182+{
8183+ security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
8184+ return;
8185+}
8186+
8187+void
8188+gr_handle_iopl(void)
8189+{
8190+ security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
8191+ return;
8192+}
8193+
8194+void
8195+gr_handle_mem_write(void)
8196+{
8197+ security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
8198+ return;
8199+}
8200+
8201+void
8202+gr_handle_kmem_write(void)
8203+{
8204+ security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
8205+ return;
8206+}
8207+
8208+void
8209+gr_handle_open_port(void)
8210+{
8211+ security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
8212+ return;
8213+}
8214+
8215+int
8216+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
8217+{
8218+ if (offset < __pa(high_memory) && (vma->vm_flags & VM_WRITE) &&
8219+ !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
8220+ !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
8221+ security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
8222+ return -EPERM;
8223+ } else if (offset < __pa(high_memory))
8224+ vma->vm_flags &= ~VM_MAYWRITE;
8225+
8226+ return 0;
8227+}
8228diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_mount.c linux-2.6.7-rc1/grsecurity/grsec_mount.c
8229--- linux-2.6.7-rc1.orig/grsecurity/grsec_mount.c 1970-01-01 01:00:00.000000000 +0100
8230+++ linux-2.6.7-rc1/grsecurity/grsec_mount.c 2004-05-25 14:33:58.944399416 +0200
8231@@ -0,0 +1,34 @@
8232+#include <linux/kernel.h>
8233+#include <linux/sched.h>
8234+#include <linux/grsecurity.h>
8235+#include <linux/grinternal.h>
8236+
8237+void
8238+gr_log_remount(const char *devname, const int retval)
8239+{
8240+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
8241+ if (grsec_enable_mount && (retval >= 0))
8242+ security_audit(GR_REMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
8243+#endif
8244+ return;
8245+}
8246+
8247+void
8248+gr_log_unmount(const char *devname, const int retval)
8249+{
8250+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
8251+ if (grsec_enable_mount && (retval >= 0))
8252+ security_audit(GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
8253+#endif
8254+ return;
8255+}
8256+
8257+void
8258+gr_log_mount(const char *from, const char *to, const int retval)
8259+{
8260+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
8261+ if (grsec_enable_mount && (retval >= 0))
8262+ security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
8263+#endif
8264+ return;
8265+}
8266diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_rand.c linux-2.6.7-rc1/grsecurity/grsec_rand.c
8267--- linux-2.6.7-rc1.orig/grsecurity/grsec_rand.c 1970-01-01 01:00:00.000000000 +0100
8268+++ linux-2.6.7-rc1/grsecurity/grsec_rand.c 2004-05-25 14:33:58.946399112 +0200
8269@@ -0,0 +1,22 @@
8270+#include <linux/kernel.h>
8271+#include <linux/sched.h>
8272+#include <linux/smp_lock.h>
8273+#include <linux/grsecurity.h>
8274+#include <linux/grinternal.h>
8275+
8276+extern int pid_max;
8277+
8278+int
8279+gr_random_pid(void)
8280+{
8281+#ifdef CONFIG_GRKERNSEC_RANDPID
8282+ int pid;
8283+
8284+ if (grsec_enable_randpid && current->fs->root) {
8285+
8286+ pid = 1 + (get_random_long() % pid_max);
8287+ return pid;
8288+ }
8289+#endif
8290+ return 0;
8291+}
8292diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_sig.c linux-2.6.7-rc1/grsecurity/grsec_sig.c
8293--- linux-2.6.7-rc1.orig/grsecurity/grsec_sig.c 1970-01-01 01:00:00.000000000 +0100
8294+++ linux-2.6.7-rc1/grsecurity/grsec_sig.c 2004-05-25 14:33:58.951398352 +0200
8295@@ -0,0 +1,48 @@
8296+#include <linux/kernel.h>
8297+#include <linux/sched.h>
8298+#include <linux/grsecurity.h>
8299+#include <linux/grinternal.h>
8300+
8301+void
8302+gr_log_signal(const int sig, const struct task_struct *t)
8303+{
8304+#ifdef CONFIG_GRKERNSEC_SIGNAL
8305+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
8306+ (sig == SIGABRT) || (sig == SIGBUS))) {
8307+ if (t->pid == current->pid) {
8308+ security_alert_good(GR_UNISIGLOG_MSG, sig,
8309+ DEFAULTSECARGS);
8310+ } else {
8311+ security_alert_good(GR_DUALSIGLOG_MSG, sig,
8312+ gr_task_fullpath0(t), t->comm,
8313+ t->pid, t->uid, t->euid, t->gid,
8314+ t->egid, gr_parent_task_fullpath0(t),
8315+ t->parent->comm,
8316+ t->parent->pid, t->parent->uid,
8317+ t->parent->euid, t->parent->gid,
8318+ t->parent->egid, DEFAULTSECARGS);
8319+ }
8320+ }
8321+#endif
8322+ return;
8323+}
8324+
8325+int
8326+gr_handle_signal(const struct task_struct *p, const int sig)
8327+{
8328+#ifdef CONFIG_GRKERNSEC
8329+ if (current->pid > 1 && gr_check_protected_task(p)) {
8330+ security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p),
8331+ p->comm, p->pid, p->uid,
8332+ p->euid, p->gid, p->egid,
8333+ gr_parent_task_fullpath0(p), p->parent->comm,
8334+ p->parent->pid, p->parent->uid,
8335+ p->parent->euid, p->parent->gid,
8336+ p->parent->egid, DEFAULTSECARGS);
8337+ return -EPERM;
8338+ } else if (gr_pid_is_chrooted(p)) {
8339+ return -EPERM;
8340+ }
8341+#endif
8342+ return 0;
8343+}
8344diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_sock.c linux-2.6.7-rc1/grsecurity/grsec_sock.c
8345--- linux-2.6.7-rc1.orig/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100
8346+++ linux-2.6.7-rc1/grsecurity/grsec_sock.c 2004-05-25 14:33:58.953398048 +0200
8347@@ -0,0 +1,256 @@
8348+#include <linux/kernel.h>
8349+#include <linux/module.h>
8350+#include <linux/sched.h>
8351+#include <linux/file.h>
8352+#include <linux/net.h>
8353+#include <linux/in.h>
8354+#include <linux/ip.h>
8355+#include <net/sock.h>
8356+#include <linux/grsecurity.h>
8357+#include <linux/grinternal.h>
8358+#include <linux/gracl.h>
8359+
8360+#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
8361+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
8362+EXPORT_SYMBOL(udp_v4_lookup);
8363+#endif
8364+#if defined(CONFIG_GRKERNSEC_RANDID)
8365+EXPORT_SYMBOL(ip_randomid);
8366+#endif
8367+#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
8368+EXPORT_SYMBOL(get_random_long);
8369+#endif
8370+#ifdef CONFIG_GRKERNSEC_RANDISN
8371+EXPORT_SYMBOL(ip_randomisn);
8372+EXPORT_SYMBOL(grsec_enable_randisn);
8373+#endif
8374+#ifdef CONFIG_GRKERNSEC_RANDID
8375+EXPORT_SYMBOL(grsec_enable_randid);
8376+#endif
8377+#ifdef CONFIG_GRKERNSEC_RANDSRC
8378+EXPORT_SYMBOL(grsec_enable_randsrc);
8379+#endif
8380+#ifdef CONFIG_GRKERNSEC_RANDRPC
8381+EXPORT_SYMBOL(grsec_enable_randrpc);
8382+#endif
8383+
8384+EXPORT_SYMBOL(gr_cap_rtnetlink);
8385+
8386+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
8387+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
8388+
8389+EXPORT_SYMBOL(gr_search_udp_recvmsg);
8390+EXPORT_SYMBOL(gr_search_udp_sendmsg);
8391+
8392+#ifdef CONFIG_UNIX_MODULE
8393+EXPORT_SYMBOL(gr_acl_handle_unix);
8394+EXPORT_SYMBOL(gr_acl_handle_mknod);
8395+EXPORT_SYMBOL(gr_handle_chroot_unix);
8396+EXPORT_SYMBOL(gr_handle_create);
8397+#endif
8398+
8399+#ifdef CONFIG_GRKERNSEC
8400+struct task_struct **gr_conn_table;
8401+const unsigned int gr_conn_table_size = 65521;
8402+struct task_struct *deleted_conn = (struct task_struct *)~0;
8403+spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
8404+
8405+extern __inline__ const char * gr_socktype_to_name(unsigned char type);
8406+extern __inline__ const char * gr_proto_to_name(unsigned char proto);
8407+
8408+static __inline__ int
8409+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
8410+{
8411+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
8412+}
8413+
8414+static __inline__ int
8415+conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr,
8416+ __u16 sport, __u16 dport)
8417+{
8418+ if (unlikely(task != deleted_conn && task->gr_saddr == saddr &&
8419+ task->gr_daddr == daddr && task->gr_sport == sport &&
8420+ task->gr_dport == dport))
8421+ return 1;
8422+ else
8423+ return 0;
8424+}
8425+
8426+void gr_add_to_task_ip_table(struct task_struct *task)
8427+{
8428+ unsigned int index;
8429+
8430+ if (unlikely(gr_conn_table == NULL))
8431+ return;
8432+
8433+ if (!thread_group_leader(task))
8434+ task = task->group_leader;
8435+
8436+ index = conn_hash(task->gr_saddr, task->gr_daddr,
8437+ task->gr_sport, task->gr_dport,
8438+ gr_conn_table_size);
8439+
8440+ spin_lock(&gr_conn_table_lock);
8441+
8442+ while (gr_conn_table[index] && gr_conn_table[index] != deleted_conn) {
8443+ index = (index + 1) % gr_conn_table_size;
8444+ }
8445+
8446+ gr_conn_table[index] = task;
8447+
8448+ spin_unlock(&gr_conn_table_lock);
8449+
8450+ return;
8451+}
8452+
8453+void gr_del_task_from_ip_table_nolock(struct task_struct *task)
8454+{
8455+ unsigned int index;
8456+
8457+ if (unlikely(gr_conn_table == NULL))
8458+ return;
8459+
8460+ if (!thread_group_leader(task))
8461+ task = task->group_leader;
8462+
8463+ index = conn_hash(task->gr_saddr, task->gr_daddr,
8464+ task->gr_sport, task->gr_dport,
8465+ gr_conn_table_size);
8466+
8467+ while (gr_conn_table[index] && !conn_match(gr_conn_table[index],
8468+ task->gr_saddr, task->gr_daddr, task->gr_sport,
8469+ task->gr_dport)) {
8470+ index = (index + 1) % gr_conn_table_size;
8471+ }
8472+
8473+ if (gr_conn_table[index]) {
8474+ if (gr_conn_table[(index + 1) % gr_conn_table_size])
8475+ gr_conn_table[index] = deleted_conn;
8476+ else
8477+ gr_conn_table[index] = NULL;
8478+ }
8479+
8480+ return;
8481+}
8482+
8483+struct task_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
8484+ __u16 sport, __u16 dport)
8485+{
8486+ unsigned int index;
8487+
8488+ if (unlikely(gr_conn_table == NULL))
8489+ return NULL;
8490+
8491+ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
8492+
8493+ while (gr_conn_table[index] && !conn_match(gr_conn_table[index],
8494+ saddr, daddr, sport, dport)) {
8495+ index = (index + 1) % gr_conn_table_size;
8496+ }
8497+
8498+ return gr_conn_table[index];
8499+}
8500+
8501+#endif
8502+
8503+void gr_del_task_from_ip_table(struct task_struct *task)
8504+{
8505+#ifdef CONFIG_GRKERNSEC
8506+ spin_lock(&gr_conn_table_lock);
8507+ if (!thread_group_leader(task))
8508+ gr_del_task_from_ip_table_nolock(task->group_leader);
8509+ else
8510+ gr_del_task_from_ip_table_nolock(task);
8511+ spin_unlock(&gr_conn_table_lock);
8512+#endif
8513+ return;
8514+}
8515+
8516+void
8517+gr_attach_curr_ip(const struct sock *sk)
8518+{
8519+#ifdef CONFIG_GRKERNSEC
8520+ struct task_struct *p;
8521+ struct task_struct *set;
8522+ const struct inet_opt *inet = inet_sk(sk);
8523+
8524+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
8525+ return;
8526+
8527+ set = current;
8528+ if (!thread_group_leader(set))
8529+ set = set->group_leader;
8530+
8531+ spin_lock(&gr_conn_table_lock);
8532+ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
8533+ inet->dport, inet->sport);
8534+ if (unlikely(p != NULL)) {
8535+ set->curr_ip = p->curr_ip;
8536+ set->used_accept = 1;
8537+ gr_del_task_from_ip_table_nolock(p);
8538+ spin_unlock(&gr_conn_table_lock);
8539+ return;
8540+ }
8541+ spin_unlock(&gr_conn_table_lock);
8542+
8543+ set->curr_ip = inet->daddr;
8544+ set->used_accept = 1;
8545+#endif
8546+ return;
8547+}
8548+
8549+int
8550+gr_handle_sock_all(const int family, const int type, const int protocol)
8551+{
8552+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
8553+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
8554+ (family != AF_UNIX) && (family != AF_LOCAL)) {
8555+ security_alert(GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol),
8556+ DEFAULTSECARGS);
8557+ return -EACCES;
8558+ }
8559+#endif
8560+ return 0;
8561+}
8562+
8563+int
8564+gr_handle_sock_server(const struct sockaddr *sck)
8565+{
8566+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
8567+ if (grsec_enable_socket_server &&
8568+ in_group_p(grsec_socket_server_gid) &&
8569+ sck && (sck->sa_family != AF_UNIX) &&
8570+ (sck->sa_family != AF_LOCAL)) {
8571+ security_alert(GR_BIND_MSG, DEFAULTSECARGS);
8572+ return -EACCES;
8573+ }
8574+#endif
8575+ return 0;
8576+}
8577+
8578+int
8579+gr_handle_sock_client(const struct sockaddr *sck)
8580+{
8581+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
8582+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
8583+ sck && (sck->sa_family != AF_UNIX) &&
8584+ (sck->sa_family != AF_LOCAL)) {
8585+ security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
8586+ return -EACCES;
8587+ }
8588+#endif
8589+ return 0;
8590+}
8591+
8592+__u32
8593+gr_cap_rtnetlink(void)
8594+{
8595+#ifdef CONFIG_GRKERNSEC
8596+ if (!gr_acl_is_enabled())
8597+ return current->cap_effective;
8598+ else
8599+ return (current->cap_effective & ~(current->acl->cap_lower));
8600+#else
8601+ return current->cap_effective;
8602+#endif
8603+}
8604diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_sysctl.c linux-2.6.7-rc1/grsecurity/grsec_sysctl.c
8605--- linux-2.6.7-rc1.orig/grsecurity/grsec_sysctl.c 1970-01-01 01:00:00.000000000 +0100
8606+++ linux-2.6.7-rc1/grsecurity/grsec_sysctl.c 2004-05-25 14:33:58.956397592 +0200
806c2378 8607@@ -0,0 +1,443 @@
1db5cd70
PS
8608+#include <linux/kernel.h>
8609+#include <linux/sched.h>
8610+#include <linux/sysctl.h>
8611+#include <linux/grsecurity.h>
8612+#include <linux/grinternal.h>
8613+
8614+int
8615+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
8616+{
8617+#ifdef CONFIG_GRKERNSEC_SYSCTL
8618+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
8619+ security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
8620+ return -EACCES;
8621+ }
8622+#endif
8623+ return 0;
8624+}
8625+
8626+#ifdef CONFIG_GRKERNSEC_SYSCTL
8627+enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
8628+GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
8629+GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
8630+GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
8631+GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
8632+GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
8633+GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
8634+GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
8635+GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
806c2378 8636+GS_FINDTASK, GS_LOCK};
1db5cd70
PS
8637+
8638+
8639+ctl_table grsecurity_table[] = {
8640+#ifdef CONFIG_GRKERNSEC_LINK
8641+ {
8642+ .ctl_name = GS_LINK,
8643+ .procname = "linking_restrictions",
8644+ .data = &grsec_enable_link,
8645+ .maxlen = sizeof(int),
8646+ .mode = 0600,
8647+ .proc_handler = &proc_dointvec,
8648+ },
8649+#endif
8650+#ifdef CONFIG_GRKERNSEC_FIFO
8651+ {
8652+ .ctl_name = GS_FIFO,
8653+ .procname = "fifo_restrictions",
8654+ .data = &grsec_enable_fifo,
8655+ .maxlen = sizeof(int),
8656+ .mode = 0600,
8657+ .proc_handler = &proc_dointvec,
8658+ },
8659+#endif
8660+#ifdef CONFIG_GRKERNSEC_EXECVE
8661+ {
8662+ .ctl_name = GS_EXECVE,
8663+ .procname = "execve_limiting",
8664+ .data = &grsec_enable_execve,
8665+ .maxlen = sizeof(int),
8666+ .mode = 0600,
8667+ .proc_handler = &proc_dointvec,
8668+ },
8669+#endif
8670+#ifdef CONFIG_GRKERNSEC_EXECLOG
8671+ {
8672+ .ctl_name = GS_EXECLOG,
8673+ .procname = "exec_logging",
8674+ .data = &grsec_enable_execlog,
8675+ .maxlen = sizeof(int),
8676+ .mode = 0600,
8677+ .proc_handler = &proc_dointvec,
8678+ },
8679+#endif
8680+#ifdef CONFIG_GRKERNSEC_SIGNAL
8681+ {
8682+ .ctl_name = GS_SIGNAL,
8683+ .procname = "signal_logging",
8684+ .data = &grsec_enable_signal,
8685+ .maxlen = sizeof(int),
8686+ .mode = 0600,
8687+ .proc_handler = &proc_dointvec,
8688+ },
8689+#endif
8690+#ifdef CONFIG_GRKERNSEC_FORKFAIL
8691+ {
8692+ .ctl_name = GS_FORKFAIL,
8693+ .procname = "forkfail_logging",
8694+ .data = &grsec_enable_forkfail,
8695+ .maxlen = sizeof(int),
8696+ .mode = 0600,
8697+ .proc_handler = &proc_dointvec,
8698+ },
8699+#endif
8700+#ifdef CONFIG_GRKERNSEC_TIME
8701+ {
8702+ .ctl_name = GS_TIME,
8703+ .procname = "timechange_logging",
8704+ .data = &grsec_enable_time,
8705+ .maxlen = sizeof(int),
8706+ .mode = 0600,
8707+ .proc_handler = &proc_dointvec,
8708+ },
8709+#endif
8710+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
8711+ {
8712+ .ctl_name = GS_CHROOT_SHMAT,
8713+ .procname = "chroot_deny_shmat",
8714+ .data = &grsec_enable_chroot_shmat,
8715+ .maxlen = sizeof(int),
8716+ .mode = 0600,
8717+ .proc_handler = &proc_dointvec,
8718+ },
8719+#endif
8720+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
8721+ {
8722+ .ctl_name = GS_CHROOT_UNIX,
8723+ .procname = "chroot_deny_unix",
8724+ .data = &grsec_enable_chroot_unix,
8725+ .maxlen = sizeof(int),
8726+ .mode = 0600,
8727+ .proc_handler = &proc_dointvec,
8728+ },
8729+#endif
8730+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
8731+ {
8732+ .ctl_name = GS_CHROOT_MNT,
8733+ .procname = "chroot_deny_mount",
8734+ .data = &grsec_enable_chroot_mount,
8735+ .maxlen = sizeof(int),
8736+ .mode = 0600,
8737+ .proc_handler = &proc_dointvec,
8738+ },
8739+#endif
8740+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
8741+ {
8742+ .ctl_name = GS_CHROOT_FCHDIR,
8743+ .procname = "chroot_deny_fchdir",
8744+ .data = &grsec_enable_chroot_fchdir,
8745+ .maxlen = sizeof(int),
8746+ .mode = 0600,
8747+ .proc_handler = &proc_dointvec,
8748+ },
8749+#endif
8750+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
8751+ {
8752+ .ctl_name = GS_CHROOT_DBL,
8753+ .procname = "chroot_deny_chroot",
8754+ .data = &grsec_enable_chroot_double,
8755+ .maxlen = sizeof(int),
8756+ .mode = 0600,
8757+ .proc_handler = &proc_dointvec,
8758+ },
8759+#endif
8760+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
8761+ {
8762+ .ctl_name = GS_CHROOT_PVT,
8763+ .procname = "chroot_deny_pivot",
8764+ .data = &grsec_enable_chroot_pivot,
8765+ .maxlen = sizeof(int),
8766+ .mode = 0600,
8767+ .proc_handler = &proc_dointvec,
8768+ },
8769+#endif
8770+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
8771+ {
8772+ .ctl_name = GS_CHROOT_CD,
8773+ .procname = "chroot_enforce_chdir",
8774+ .data = &grsec_enable_chroot_chdir,
8775+ .maxlen = sizeof(int),
8776+ .mode = 0600,
8777+ .proc_handler = &proc_dointvec,
8778+ },
8779+#endif
8780+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
8781+ {
8782+ .ctl_name = GS_CHROOT_CM,
8783+ .procname = "chroot_deny_chmod",
8784+ .data = &grsec_enable_chroot_chmod,
8785+ .maxlen = sizeof(int),
8786+ .mode = 0600,
8787+ .proc_handler = &proc_dointvec,
8788+ },
8789+#endif
8790+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
8791+ {
8792+ .ctl_name = GS_CHROOT_MK,
8793+ .procname = "chroot_deny_mknod",
8794+ .data = &grsec_enable_chroot_mknod,
8795+ .maxlen = sizeof(int),
8796+ .mode = 0600,
8797+ .proc_handler = &proc_dointvec,
8798+ },
8799+#endif
8800+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
8801+ {
8802+ .ctl_name = GS_CHROOT_NI,
8803+ .procname = "chroot_restrict_nice",
8804+ .data = &grsec_enable_chroot_nice,
8805+ .maxlen = sizeof(int),
8806+ .mode = 0600,
8807+ .proc_handler = &proc_dointvec,
8808+ },
8809+#endif
8810+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
8811+ {
8812+ .ctl_name = GS_CHROOT_EXECLOG,
8813+ .procname = "chroot_execlog",
8814+ .data = &grsec_enable_chroot_execlog,
8815+ .maxlen = sizeof(int),
8816+ .mode = 0600,
8817+ .proc_handler = &proc_dointvec,
8818+ },
8819+#endif
8820+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
8821+ {
8822+ .ctl_name = GS_CHROOT_CAPS,
8823+ .procname = "chroot_caps",
8824+ .data = &grsec_enable_chroot_caps,
8825+ .maxlen = sizeof(int),
8826+ .mode = 0600,
8827+ .proc_handler = &proc_dointvec,
8828+ },
8829+#endif
8830+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
8831+ {
8832+ .ctl_name = GS_CHROOT_SYSCTL,
8833+ .procname = "chroot_deny_sysctl",
8834+ .data = &grsec_enable_chroot_sysctl,
8835+ .maxlen = sizeof(int),
8836+ .mode = 0600,
8837+ .proc_handler = &proc_dointvec,
8838+ },
8839+#endif
8840+#ifdef CONFIG_GRKERNSEC_TPE
8841+ {
8842+ .ctl_name = GS_TPE,
8843+ .procname = "tpe",
8844+ .data = &grsec_enable_tpe,
8845+ .maxlen = sizeof(int),
8846+ .mode = 0600,
8847+ .proc_handler = &proc_dointvec,
8848+ },
8849+ {
8850+ .ctl_name = GS_TPE_GID,
8851+ .procname = "tpe_gid",
8852+ .data = &grsec_tpe_gid,
8853+ .maxlen = sizeof(int),
8854+ .mode = 0600,
8855+ .proc_handler = &proc_dointvec,
8856+ },
8857+#endif
8858+#ifdef CONFIG_GRKERNSEC_TPE_ALL
8859+ {
8860+ .ctl_name = GS_TPE_ALL,
8861+ .procname = "tpe_restrict_all",
8862+ .data = &grsec_enable_tpe_all,
8863+ .maxlen = sizeof(int),
8864+ .mode = 0600,
8865+ .proc_handler = &proc_dointvec,
8866+ },
8867+#endif
8868+#ifdef CONFIG_GRKERNSEC_RANDPID
8869+ {
8870+ .ctl_name = GS_RANDPID,
8871+ .procname = "rand_pids",
8872+ .data = &grsec_enable_randpid,
8873+ .maxlen = sizeof(int),
8874+ .mode = 0600,
8875+ .proc_handler = &proc_dointvec,
8876+ },
8877+#endif
8878+#ifdef CONFIG_GRKERNSEC_RANDID
8879+ {
8880+ .ctl_name = GS_RANDID,
8881+ .procname = "rand_ip_ids",
8882+ .data = &grsec_enable_randid,
8883+ .maxlen = sizeof(int),
8884+ .mode = 0600,
8885+ .proc_handler = &proc_dointvec,
8886+ },
8887+#endif
8888+#ifdef CONFIG_GRKERNSEC_RANDSRC
8889+ {
8890+ .ctl_name = GS_RANDSRC,
8891+ .procname = "rand_tcp_src_ports",
8892+ .data = &grsec_enable_randsrc,
8893+ .maxlen = sizeof(int),
8894+ .mode = 0600,
8895+ .proc_handler = &proc_dointvec,
8896+ },
8897+#endif
8898+#ifdef CONFIG_GRKERNSEC_RANDISN
8899+ {
8900+ .ctl_name = GS_RANDISN,
8901+ .procname = "rand_isns",
8902+ .data = &grsec_enable_randisn,
8903+ .maxlen = sizeof(int),
8904+ .mode = 0600,
8905+ .proc_handler = &proc_dointvec,
8906+ },
8907+#endif
8908+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
8909+ {
8910+ .ctl_name = GS_SOCKET_ALL,
8911+ .procname = "socket_all",
8912+ .data = &grsec_enable_socket_all,
8913+ .maxlen = sizeof(int),
8914+ .mode = 0600,
8915+ .proc_handler = &proc_dointvec,
8916+ },
8917+ {
8918+ .ctl_name = GS_SOCKET_ALL_GID,
8919+ .procname = "socket_all_gid",
8920+ .data = &grsec_socket_all_gid,
8921+ .maxlen = sizeof(int),
8922+ .mode = 0600,
8923+ .proc_handler = &proc_dointvec,
8924+ },
8925+#endif
8926+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
8927+ {
8928+ .ctl_name = GS_SOCKET_CLIENT,
8929+ .procname = "socket_client",
8930+ .data = &grsec_enable_socket_client,
8931+ .maxlen = sizeof(int),
8932+ .mode = 0600,
8933+ .proc_handler = &proc_dointvec,
8934+ },
8935+ {
8936+ .ctl_name = GS_SOCKET_CLIENT_GID,
8937+ .procname = "socket_client_gid",
8938+ .data = &grsec_socket_client_gid,
8939+ .maxlen = sizeof(int),
8940+ .mode = 0600,
8941+ .proc_handler = &proc_dointvec,
8942+ },
8943+#endif
8944+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
8945+ {
8946+ .ctl_name = GS_SOCKET_SERVER,
8947+ .procname = "socket_server",
8948+ .data = &grsec_enable_socket_server,
8949+ .maxlen = sizeof(int),
8950+ .mode = 0600,
8951+ .proc_handler = &proc_dointvec,
8952+ },
8953+ {
8954+ .ctl_name = GS_SOCKET_SERVER_GID,
8955+ .procname = "socket_server_gid",
8956+ .data = &grsec_socket_server_gid,
8957+ .maxlen = sizeof(int),
8958+ .mode = 0600,
8959+ .proc_handler = &proc_dointvec,
8960+ },
8961+#endif
8962+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
8963+ {
8964+ .ctl_name = GS_GROUP,
8965+ .procname = "audit_group",
8966+ .data = &grsec_enable_group,
8967+ .maxlen = sizeof(int),
8968+ .mode = 0600,
8969+ .proc_handler = &proc_dointvec,
8970+ },
8971+ {
8972+ .ctl_name = GS_GID,
8973+ .procname = "audit_gid",
8974+ .data = &grsec_audit_gid,
8975+ .maxlen = sizeof(int),
8976+ .mode = 0600,
8977+ .proc_handler = &proc_dointvec,
8978+ },
8979+#endif
8980+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
8981+ {
8982+ .ctl_name = GS_ACHDIR,
8983+ .procname = "audit_chdir",
8984+ .data = &grsec_enable_chdir,
8985+ .maxlen = sizeof(int),
8986+ .mode = 0600,
8987+ .proc_handler = &proc_dointvec,
8988+ },
8989+#endif
8990+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
8991+ {
8992+ .ctl_name = GS_AMOUNT,
8993+ .procname = "audit_mount",
8994+ .data = &grsec_enable_mount,
8995+ .maxlen = sizeof(int),
8996+ .mode = 0600,
8997+ .proc_handler = &proc_dointvec,
8998+ },
8999+#endif
9000+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
9001+ {
9002+ .ctl_name = GS_AIPC,
9003+ .procname = "audit_ipc",
9004+ .data = &grsec_enable_audit_ipc,
9005+ .maxlen = sizeof(int),
9006+ .mode = 0600,
9007+ .proc_handler = &proc_dointvec,
9008+ },
9009+#endif
1db5cd70
PS
9010+#ifdef CONFIG_GRKERNSEC_DMESG
9011+ {
9012+ .ctl_name = GS_DMSG,
9013+ .procname = "dmesg",
9014+ .data = &grsec_enable_dmesg,
9015+ .maxlen = sizeof(int),
9016+ .mode = 0600,
9017+ .proc_handler = &proc_dointvec,
9018+ },
9019+#endif
9020+#ifdef CONFIG_GRKERNSEC_RANDRPC
9021+ {
9022+ .ctl_name = GS_RANDRPC,
9023+ .procname = "rand_rpc",
9024+ .data = &grsec_enable_randrpc,
9025+ .maxlen = sizeof(int),
9026+ .mode = 0600,
9027+ .proc_handler = &proc_dointvec,
9028+ },
9029+#endif
9030+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
9031+ {
9032+ .ctl_name = GS_FINDTASK,
9033+ .procname = "chroot_findtask",
9034+ .data = &grsec_enable_chroot_findtask,
9035+ .maxlen = sizeof(int),
9036+ .mode = 0600,
9037+ .proc_handler = &proc_dointvec,
9038+ },
9039+#endif
9040+ {
9041+ .ctl_name = GS_LOCK,
9042+ .procname = "grsec_lock",
9043+ .data = &grsec_lock,
9044+ .maxlen = sizeof(int),
9045+ .mode = 0600,
9046+ .proc_handler = &proc_dointvec,
9047+ },
9048+ { .ctl_name = 0 }
9049+};
9050+#endif
1db5cd70
PS
9051diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_time.c linux-2.6.7-rc1/grsecurity/grsec_time.c
9052--- linux-2.6.7-rc1.orig/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100
9053+++ linux-2.6.7-rc1/grsecurity/grsec_time.c 2004-05-25 14:33:58.958397288 +0200
9054@@ -0,0 +1,13 @@
9055+#include <linux/kernel.h>
9056+#include <linux/sched.h>
9057+#include <linux/grinternal.h>
9058+
9059+void
9060+gr_log_timechange(void)
9061+{
9062+#ifdef CONFIG_GRKERNSEC_TIME
9063+ if (grsec_enable_time)
9064+ security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
9065+#endif
9066+ return;
9067+}
9068diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsec_tpe.c linux-2.6.7-rc1/grsecurity/grsec_tpe.c
9069--- linux-2.6.7-rc1.orig/grsecurity/grsec_tpe.c 1970-01-01 01:00:00.000000000 +0100
9070+++ linux-2.6.7-rc1/grsecurity/grsec_tpe.c 2004-05-25 14:33:58.960396984 +0200
9071@@ -0,0 +1,35 @@
9072+#include <linux/kernel.h>
9073+#include <linux/sched.h>
9074+#include <linux/file.h>
9075+#include <linux/fs.h>
9076+#include <linux/grinternal.h>
9077+
9078+extern int gr_acl_tpe_check(void);
9079+
9080+int
9081+gr_tpe_allow(const struct file *file)
9082+{
9083+#ifdef CONFIG_GRKERNSEC
9084+ struct inode *inode = file->f_dentry->d_parent->d_inode;
9085+
9086+ if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
9087+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
9088+ (inode->i_mode & S_IWOTH))))) {
9089+ security_alert(GR_EXEC_TPE_MSG,
9090+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
9091+ DEFAULTSECARGS);
9092+ return 0;
9093+ }
9094+#ifdef CONFIG_GRKERNSEC_TPE_ALL
9095+ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
9096+ ((inode->i_uid && (inode->i_uid != current->uid)) ||
9097+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
9098+ security_alert(GR_EXEC_TPE_MSG,
9099+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
9100+ DEFAULTSECARGS);
9101+ return 0;
9102+ }
9103+#endif
9104+#endif
9105+ return 1;
9106+}
9107diff -uNr linux-2.6.7-rc1.orig/grsecurity/grsum.c linux-2.6.7-rc1/grsecurity/grsum.c
9108--- linux-2.6.7-rc1.orig/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100
9109+++ linux-2.6.7-rc1/grsecurity/grsum.c 2004-05-25 14:33:58.961396832 +0200
9110@@ -0,0 +1,59 @@
9111+#include <linux/kernel.h>
9112+#include <linux/sched.h>
9113+#include <linux/mm.h>
9114+#include <asm/scatterlist.h>
9115+#include <linux/crypto.h>
9116+#include <linux/gracl.h>
9117+
9118+
9119+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
9120+#error "crypto and sha256 must be built into the kernel"
9121+#endif
9122+
9123+int
9124+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
9125+{
9126+ char *p;
9127+ struct crypto_tfm *tfm;
9128+ unsigned char temp_sum[GR_SHA_LEN];
9129+ struct scatterlist sg[2];
9130+ volatile int retval = 0;
9131+ volatile int dummy = 0;
9132+ unsigned int i;
9133+
9134+ tfm = crypto_alloc_tfm("sha256", 0);
9135+ if (tfm == NULL) {
9136+ /* should never happen, since sha256 should be built in */
9137+ return 1;
9138+ }
9139+
9140+ crypto_digest_init(tfm);
9141+
9142+ p = salt;
9143+ sg[0].page = virt_to_page(p);
9144+ sg[0].offset = ((long) p & ~PAGE_MASK);
9145+ sg[0].length = GR_SALT_LEN;
9146+
9147+ crypto_digest_update(tfm, sg, 1);
9148+
9149+ p = entry->pw;
9150+ sg[0].page = virt_to_page(p);
9151+ sg[0].offset = ((long) p & ~PAGE_MASK);
9152+ sg[0].length = strlen(entry->pw);
9153+
9154+ crypto_digest_update(tfm, sg, 1);
9155+
9156+ crypto_digest_final(tfm, temp_sum);
9157+
9158+ memset(entry->pw, 0, GR_PW_LEN);
9159+
9160+ for (i = 0; i < GR_SHA_LEN; i++)
9161+ if (sum[i] != temp_sum[i])
9162+ retval = 1;
9163+ else
9164+ dummy = 1; // waste a cycle
9165+
9166+ crypto_free_tfm(tfm);
9167+
9168+ return retval;
9169+}
9170diff -uNr linux-2.6.7-rc1.orig/grsecurity/Kconfig linux-2.6.7-rc1/grsecurity/Kconfig
9171--- linux-2.6.7-rc1.orig/grsecurity/Kconfig 1970-01-01 01:00:00.000000000 +0100
9172+++ linux-2.6.7-rc1/grsecurity/Kconfig 2004-05-25 14:33:58.846414312 +0200
3aa50353 9173@@ -0,0 +1,819 @@
1db5cd70
PS
9174+#
9175+# grecurity configuration
9176+#
9177+
9178+menu "Grsecurity"
9179+
9180+config GRKERNSEC
9181+ bool "Grsecurity"
9182+ select CRYPTO
9183+ select CRYPTO_SHA256
9184+ help
9185+ If you say Y here, you will be able to configure many features
9186+ that will enhance the security of your system. It is highly
9187+ recommended that you say Y here and read through the help
9188+ for each option so that you fully understand the features and
9189+ can evaluate their usefulness for your machine.
9190+
9191+choice
9192+ prompt "Security Level"
9193+ depends GRKERNSEC
9194+ default GRKERNSEC_CUSTOM
9195+
9196+config GRKERNSEC_LOW
9197+ bool "Low"
9198+ select GRKERNSEC_LINK
9199+ select GRKERNSEC_FIFO
9200+ select GRKERNSEC_RANDPID
9201+ select GRKERNSEC_EXECVE
9202+ select GRKERNSEC_RANDNET
9203+ select GRKERNSEC_RANDISN
9204+ select GRKERNSEC_DMESG
9205+ select GRKERNSEC_RANDID
9206+ select GRKERNSEC_CHROOT_CHDIR
9207+ help
9208+ If you choose this option, several of the grsecurity options will
9209+ be enabled that will give you greater protection against a number
9210+ of attacks, while assuring that none of your software will have any
9211+ conflicts with the additional security measures. If you run a lot
9212+ of unusual software, or you are having problems with the higher
9213+ security levels, you should say Y here. With this option, the
9214+ following features are enabled:
9215+
9216+ - Linking Restrictions
9217+ - FIFO Restrictions
9218+ - Randomized PIDs
9219+ - Enforcing RLIMIT_NPROC on execve
9220+ - Restricted dmesg
9221+ - Randomized IP IDs
9222+ - Enforced chdir("/") on chroot
9223+
9224+config GRKERNSEC_MEDIUM
9225+ bool "Medium"
1db5cd70
PS
9226+ select GRKERNSEC_PROC_MEMMAP
9227+ select GRKERNSEC_CHROOT_SYSCTL
9228+ select GRKERNSEC_LINK
9229+ select GRKERNSEC_FIFO
9230+ select GRKERNSEC_RANDPID
9231+ select GRKERNSEC_EXECVE
9232+ select GRKERNSEC_DMESG
9233+ select GRKERNSEC_RANDID
9234+ select GRKERNSEC_RANDNET
9235+ select GRKERNSEC_RANDISN
9236+ select GRKERNSEC_RANDSRC
9237+ select GRKERNSEC_RANDRPC
9238+ select GRKERNSEC_FORKFAIL
9239+ select GRKERNSEC_TIME
9240+ select GRKERNSEC_SIGNAL
9241+ select GRKERNSEC_CHROOT
9242+ select GRKERNSEC_CHROOT_UNIX
9243+ select GRKERNSEC_CHROOT_MOUNT
9244+ select GRKERNSEC_CHROOT_PIVOT
9245+ select GRKERNSEC_CHROOT_DOUBLE
9246+ select GRKERNSEC_CHROOT_CHDIR
9247+ select GRKERNSEC_CHROOT_MKNOD
9248+ select GRKERNSEC_PROC
9249+ select GRKERNSEC_PROC_USERGROUP
1db5cd70
PS
9250+
9251+ help
9252+ If you say Y here, several features in addition to those included
9253+ in the low additional security level will be enabled. These
9254+ features provide even more security to your system, though in rare
9255+ cases they may be incompatible with very old or poorly written
9256+ software. If you enable this option, make sure that your auth
9257+ service (identd) is running as gid 1001. With this option,
9258+ the following features (in addition to those provided in the
9259+ low additional security level) will be enabled:
9260+
9261+ - Randomized TCP Source Ports
9262+ - Failed Fork Logging
9263+ - Time Change Logging
9264+ - Signal Logging
9265+ - Deny Mounts in chroot
9266+ - Deny Double chrooting
9267+ - Deny Sysctl Writes in chroot
9268+ - Deny Mknod in chroot
9269+ - Deny Access to Abstract AF_UNIX Sockets out of chroot
9270+ - Deny pivot_root in chroot
9271+ - Denied Writes of /dev/kmem, /dev/mem, and /dev/port
9272+ - /proc restrictions with special GID set to 10 (usually wheel)
1db5cd70
PS
9273+
9274+config GRKERNSEC_HIGH
9275+ bool "High"
9276+ select GRKERNSEC_LINK
9277+ select GRKERNSEC_FIFO
9278+ select GRKERNSEC_RANDPID
9279+ select GRKERNSEC_EXECVE
9280+ select GRKERNSEC_DMESG
9281+ select GRKERNSEC_RANDID
9282+ select GRKERNSEC_RANDSRC
9283+ select GRKERNSEC_RANDRPC
9284+ select GRKERNSEC_FORKFAIL
9285+ select GRKERNSEC_TIME
9286+ select GRKERNSEC_SIGNAL
9287+ select GRKERNSEC_CHROOT_SHMAT
9288+ select GRKERNSEC_CHROOT_UNIX
9289+ select GRKERNSEC_CHROOT_MOUNT
9290+ select GRKERNSEC_CHROOT_FCHDIR
9291+ select GRKERNSEC_CHROOT_PIVOT
9292+ select GRKERNSEC_CHROOT_DOUBLE
9293+ select GRKERNSEC_CHROOT_CHDIR
9294+ select GRKERNSEC_CHROOT_MKNOD
9295+ select GRKERNSEC_CHROOT_CAPS
9296+ select GRKERNSEC_CHROOT_SYSCTL
9297+ select GRKERNSEC_CHROOT_FINDTASK
9298+ select GRKERNSEC_PROC
9299+ select GRKERNSEC_PROC_MEMMAP
9300+ select GRKERNSEC_HIDESYM
9301+ select GRKERNSEC_PROC_USERGROUP
9302+ select GRKERNSEC_KMEM
9303+ select GRKERNSEC_RESLOG
9304+ select GRKERNSEC_RANDNET
9305+ select GRKERNSEC_RANDISN
9306+ select GRKERNSEC_PROC_ADD
9307+ select GRKERNSEC_CHROOT_CHMOD
9308+ select GRKERNSEC_CHROOT_NICE
9309+ select GRKERNSEC_AUDIT_MOUNT
1db5cd70
PS
9310+ help
9311+ If you say Y here, many of the features of grsecurity will be
9312+ enabled, which will protect you against many kinds of attacks
9313+ against your system. The heightened security comes at a cost
9314+ of an increased chance of incompatibilities with rare software
3aa50353
PS
9315+ on your machine. Also remember that since the /proc restrictions
9316+ are enabled, you must run your identd as gid 1001.
9317+ This security level enables the following features in addition
9318+ to those listed in the low and medium security levels:
1db5cd70
PS
9319+
9320+ - Additional /proc Restrictions
9321+ - Chmod Restrictions in chroot
9322+ - No Signals, Ptrace, or Viewing of Processes Outside of chroot
9323+ - Capability Restrictions in chroot
9324+ - Deny fchdir out of chroot
9325+ - Priority Restrictions in chroot
1db5cd70
PS
9326+ - Mprotect Restrictions
9327+ - Removal of Addresses from /proc/<pid>/[maps|stat]
1db5cd70
PS
9328+ - Mount/Unmount/Remount Logging
9329+ - Kernel Symbol Hiding
9330+
9331+config GRKERNSEC_CUSTOM
9332+ bool "Custom"
9333+ help
9334+ If you say Y here, you will be able to configure every grsecurity
9335+ option, which allows you to enable many more features that aren't
9336+ covered in the basic security levels. These additional features
9337+ include TPE, socket restrictions, and the sysctl system for
9338+ grsecurity. It is advised that you read through the help for
9339+ each option to determine its usefulness in your situation.
9340+
9341+endchoice
9342+
9343+menu "Address Space Protection"
9344+depends on GRKERNSEC
9345+
9346+config GRKERNSEC_KMEM
9347+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
9348+ help
9349+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
9350+ be written to via mmap or otherwise to modify the running kernel.
9351+ /dev/port will also not be allowed to be opened. If you have module
9352+ support disabled, enabling this will close up four ways that are
9353+ currently used to insert malicious code into the running kernel.
9354+ Even with all these features enabled, we still highly recommend that
9355+ you use the ACL system, as it is still possible for an attacker to
9356+ modify the running kernel through privileged I/O granted by ioperm/iopl.
9357+ If you are not using XFree86, you may be able to stop this additional
9358+ case by enabling the 'Disable privileged I/O' option. Though nothing
9359+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
9360+ but only to video memory, which is the only writing we allow in this
9361+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
9362+ not be allowed to mprotect it with PROT_WRITE later.
9363+ Enabling this feature could make certain apps like VMWare stop working,
9364+ as they need to write to other locations in /dev/mem.
9365+ It is highly recommended that you say Y here if you meet all the
9366+ conditions above.
9367+
9368+config GRKERNSEC_IO
9369+ bool "Disable privileged I/O"
9370+ depends on X86
9371+ select RTC
9372+ help
9373+ If you say Y here, all ioperm and iopl calls will return an error.
9374+ Ioperm and iopl can be used to modify the running kernel.
9375+ Unfortunately, some programs need this access to operate properly,
9376+ the most notable of which are XFree86 and hwclock. hwclock can be
9377+ remedied by having RTC support in the kernel, so CONFIG_RTC is
9378+ enabled if this option is enabled, to ensure that hwclock operates
9379+ correctly. XFree86 still will not operate correctly with this option
9380+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
9381+ and you still want to protect your kernel against modification,
9382+ use the ACL system.
9383+
9384+config GRKERNSEC_PROC_MEMMAP
9385+ bool "Remove addresses from /proc/<pid>/[maps|stat]"
9386+ help
3aa50353
PS
9387+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files
9388+ will give no information about the addresses of its mappings.
1db5cd70
PS
9389+
9390+config GRKERNSEC_HIDESYM
9391+ bool "Hide kernel symbols"
9392+ help
9393+ If you say Y here, getting information on loaded modules, and
9394+ displaying all kernel symbols through a syscall will be restricted
9395+ to users with CAP_SYS_MODULE. This option is only effective
9396+ provided the following conditions are met:
9397+ 1) The kernel using grsecurity is not precompiled by some distribution
9398+ 2) You are using the ACL system and hiding other files such as your
9399+ kernel image and System.map
9400+ 3) You have the additional /proc restrictions enabled, which removes
9401+ /proc/kcore
9402+ If the above conditions are met, this option will aid to provide a
9403+ useful protection against local and remote kernel exploitation of
9404+ overflows and arbitrary read/write vulnerabilities.
9405+
9406+endmenu
9407+menu "Role Based Access Control Options"
9408+depends on GRKERNSEC
9409+
9410+config GRKERNSEC_ACL_HIDEKERN
9411+ bool "Hide kernel processes"
9412+ help
9413+ If you say Y here, when the RBAC system is enabled via gradm -E,
9414+ an additional ACL will be passed to the kernel that hides all kernel
9415+ processes. These processes will only be viewable by the authenticated
9416+ admin, or processes that have viewing access set.
9417+
9418+config GRKERNSEC_ACL_MAXTRIES
9419+ int "Maximum tries before password lockout"
9420+ default 3
9421+ help
9422+ This option enforces the maximum number of times a user can attempt
9423+ to authorize themselves with the grsecurity ACL system before being
9424+ denied the ability to attempt authorization again for a specified time.
9425+ The lower the number, the harder it will be to brute-force a password.
9426+
9427+config GRKERNSEC_ACL_TIMEOUT
9428+ int "Time to wait after max password tries, in seconds"
9429+ default 30
9430+ help
9431+ This option specifies the time the user must wait after attempting to
9432+ authorize to the ACL system with the maximum number of invalid
9433+ passwords. The higher the number, the harder it will be to brute-force
9434+ a password.
9435+
9436+endmenu
9437+menu "Filesystem Protections"
9438+depends on GRKERNSEC
9439+
9440+config GRKERNSEC_PROC
9441+ bool "Proc restrictions"
9442+ help
9443+ If you say Y here, the permissions of the /proc filesystem
9444+ will be altered to enhance system security and privacy. Depending
9445+ upon the options you choose, you can either restrict users to see
9446+ only the processes they themselves run, or choose a group that can
9447+ view all processes and files normally restricted to root if you choose
9448+ the "restrict to user only" option. NOTE: If you're running identd as
9449+ a non-root user, you will have to run it as the group you specify here.
9450+
9451+config GRKERNSEC_PROC_USER
9452+ bool "Restrict /proc to user only"
9453+ depends on GRKERNSEC_PROC
9454+ help
9455+ If you say Y here, non-root users will only be able to view their own
9456+ processes, and restricts them from viewing network-related information,
9457+ and viewing kernel symbol and module information.
9458+
9459+config GRKERNSEC_PROC_USERGROUP
9460+ bool "Allow special group"
9461+ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
9462+ help
9463+ If you say Y here, you will be able to select a group that will be
9464+ able to view all processes, network-related information, and
9465+ kernel and symbol information. This option is useful if you want
9466+ to run identd as a non-root user.
9467+
9468+config GRKERNSEC_PROC_GID
9469+ int "GID for special group"
9470+ depends on GRKERNSEC_PROC_USERGROUP
9471+ default 1001
9472+
9473+config GRKERNSEC_PROC_ADD
9474+ bool "Additional restrictions"
9475+ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
9476+ help
9477+ If you say Y here, additional restrictions will be placed on
9478+ /proc that keep normal users from viewing cpu and device information.
9479+
9480+config GRKERNSEC_LINK
9481+ bool "Linking restrictions"
9482+ help
9483+ If you say Y here, /tmp race exploits will be prevented, since users
9484+ will no longer be able to follow symlinks owned by other users in
9485+ world-writable +t directories (i.e. /tmp), unless the owner of the
9486+ symlink is the owner of the directory. users will also not be
9487+ able to hardlink to files they do not own. If the sysctl option is
9488+ enabled, a sysctl option with name "linking_restrictions" is created.
9489+
9490+config GRKERNSEC_FIFO
9491+ bool "FIFO restrictions"
9492+ help
9493+ If you say Y here, users will not be able to write to FIFOs they don't
9494+ own in world-writable +t directories (i.e. /tmp), unless the owner of
9495+ the FIFO is the same owner of the directory it's held in. If the sysctl
9496+ option is enabled, a sysctl option with name "fifo_restrictions" is
9497+ created.
9498+
9499+config GRKERNSEC_CHROOT
9500+ bool "Chroot jail restrictions"
9501+ help
9502+ If you say Y here, you will be able to choose several options that will
9503+ make breaking out of a chrooted jail much more difficult. If you
9504+ encounter no software incompatibilities with the following options, it
9505+ is recommended that you enable each one.
9506+
9507+config GRKERNSEC_CHROOT_MOUNT
9508+ bool "Deny mounts"
9509+ depends on GRKERNSEC_CHROOT
9510+ help
9511+ If you say Y here, processes inside a chroot will not be able to
9512+ mount or remount filesystems. If the sysctl option is enabled, a
9513+ sysctl option with name "chroot_deny_mount" is created.
9514+
9515+config GRKERNSEC_CHROOT_DOUBLE
9516+ bool "Deny double-chroots"
9517+ depends on GRKERNSEC_CHROOT
9518+ help
9519+ If you say Y here, processes inside a chroot will not be able to chroot
9520+ again outside the chroot. This is a widely used method of breaking
9521+ out of a chroot jail and should not be allowed. If the sysctl
9522+ option is enabled, a sysctl option with name
9523+ "chroot_deny_chroot" is created.
9524+
9525+config GRKERNSEC_CHROOT_PIVOT
9526+ bool "Deny pivot_root in chroot"
9527+ depends on GRKERNSEC_CHROOT
9528+ help
9529+ If you say Y here, processes inside a chroot will not be able to use
9530+ a function called pivot_root() that was introduced in Linux 2.3.41. It
9531+ works similar to chroot in that it changes the root filesystem. This
9532+ function could be misused in a chrooted process to attempt to break out
9533+ of the chroot, and therefore should not be allowed. If the sysctl
9534+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
9535+ created.
9536+
9537+config GRKERNSEC_CHROOT_CHDIR
9538+ bool "Enforce chdir(\"/\") on all chroots"
9539+ depends on GRKERNSEC_CHROOT
9540+ help
9541+ If you say Y here, the current working directory of all newly-chrooted
9542+ applications will be set to the the root directory of the chroot.
9543+ The man page on chroot(2) states:
9544+ Note that this call does not change the current working
9545+ directory, so that `.' can be outside the tree rooted at
9546+ `/'. In particular, the super-user can escape from a
9547+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
9548+
9549+ It is recommended that you say Y here, since it's not known to break
9550+ any software. If the sysctl option is enabled, a sysctl option with
9551+ name "chroot_enforce_chdir" is created.
9552+
9553+config GRKERNSEC_CHROOT_CHMOD
9554+ bool "Deny (f)chmod +s"
9555+ depends on GRKERNSEC_CHROOT
9556+ help
9557+ If you say Y here, processes inside a chroot will not be able to chmod
9558+ or fchmod files to make them have suid or sgid bits. This protects
9559+ against another published method of breaking a chroot. If the sysctl
9560+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
9561+ created.
9562+
9563+config GRKERNSEC_CHROOT_FCHDIR
9564+ bool "Deny fchdir out of chroot"
9565+ depends on GRKERNSEC_CHROOT
9566+ help
9567+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
9568+ to a file descriptor of the chrooting process that points to a directory
9569+ outside the filesystem will be stopped. If the sysctl option
9570+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
9571+
9572+config GRKERNSEC_CHROOT_MKNOD
9573+ bool "Deny mknod"
9574+ depends on GRKERNSEC_CHROOT
9575+ help
9576+ If you say Y here, processes inside a chroot will not be allowed to
9577+ mknod. The problem with using mknod inside a chroot is that it
9578+ would allow an attacker to create a device entry that is the same
9579+ as one on the physical root of your system, which could range from
9580+ anything from the console device to a device for your harddrive (which
9581+ they could then use to wipe the drive or steal data). It is recommended
9582+ that you say Y here, unless you run into software incompatibilities.
9583+ If the sysctl option is enabled, a sysctl option with name
9584+ "chroot_deny_mknod" is created.
9585+
9586+config GRKERNSEC_CHROOT_SHMAT
9587+ bool "Deny shmat() out of chroot"
9588+ depends on GRKERNSEC_CHROOT
9589+ help
9590+ If you say Y here, processes inside a chroot will not be able to attach
9591+ to shared memory segments that were created outside of the chroot jail.
9592+ It is recommended that you say Y here. If the sysctl option is enabled,
9593+ a sysctl option with name "chroot_deny_shmat" is created.
9594+
9595+config GRKERNSEC_CHROOT_UNIX
9596+ bool "Deny access to abstract AF_UNIX sockets out of chroot"
9597+ depends on GRKERNSEC_CHROOT
9598+ help
9599+ If you say Y here, processes inside a chroot will not be able to
9600+ connect to abstract (meaning not belonging to a filesystem) Unix
9601+ domain sockets that were bound outside of a chroot. It is recommended
9602+ that you say Y here. If the sysctl option is enabled, a sysctl option
9603+ with name "chroot_deny_unix" is created.
9604+
9605+config GRKERNSEC_CHROOT_FINDTASK
9606+ bool "Protect outside processes"
9607+ depends on GRKERNSEC_CHROOT
9608+ help
9609+ If you say Y here, processes inside a chroot will not be able to
9610+ kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
9611+ getsid, or view any process outside of the chroot. If the sysctl
9612+ option is enabled, a sysctl option with name "chroot_findtask" is
9613+ created.
9614+
9615+config GRKERNSEC_CHROOT_NICE
9616+ bool "Restrict priority changes"
9617+ depends on GRKERNSEC_CHROOT
9618+ help
9619+ If you say Y here, processes inside a chroot will not be able to raise
9620+ the priority of processes in the chroot, or alter the priority of
9621+ processes outside the chroot. This provides more security than simply
9622+ removing CAP_SYS_NICE from the process' capability set. If the
9623+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
9624+ is created.
9625+
9626+config GRKERNSEC_CHROOT_SYSCTL
9627+ bool "Deny sysctl writes"
9628+ depends on GRKERNSEC_CHROOT
9629+ help
9630+ If you say Y here, an attacker in a chroot will not be able to
9631+ write to sysctl entries, either by sysctl(2) or through a /proc
9632+ interface. It is strongly recommended that you say Y here. If the
9633+ sysctl option is enabled, a sysctl option with name
9634+ "chroot_deny_sysctl" is created.
9635+
9636+config GRKERNSEC_CHROOT_CAPS
9637+ bool "Capability restrictions"
9638+ depends on GRKERNSEC_CHROOT
9639+ help
9640+ If you say Y here, the capabilities on all root processes within a
9641+ chroot jail will be lowered to stop module insertion, raw i/o,
9642+ system and net admin tasks, rebooting the system, modifying immutable
9643+ files, modifying IPC owned by another, and changing the system time.
9644+ This is left an option because it can break some apps. Disable this
9645+ if your chrooted apps are having problems performing those kinds of
9646+ tasks. If the sysctl option is enabled, a sysctl option with
9647+ name "chroot_caps" is created.
9648+
9649+endmenu
9650+menu "Kernel Auditing"
9651+depends on GRKERNSEC
9652+
9653+config GRKERNSEC_AUDIT_GROUP
9654+ bool "Single group for auditing"
9655+ help
9656+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
9657+ will only operate on a group you specify. This option is recommended
9658+ if you only want to watch certain users instead of having a large
9659+ amount of logs from the entire system. If the sysctl option is enabled,
9660+ a sysctl option with name "audit_group" is created.
9661+
9662+config GRKERNSEC_AUDIT_GID
9663+ int "GID for auditing"
9664+ depends on GRKERNSEC_AUDIT_GROUP
9665+ default 1007
9666+
9667+config GRKERNSEC_EXECLOG
9668+ bool "Exec logging"
9669+ help
9670+ If you say Y here, all execve() calls will be logged (since the
9671+ other exec*() calls are frontends to execve(), all execution
9672+ will be logged). Useful for shell-servers that like to keep track
9673+ of their users. If the sysctl option is enabled, a sysctl option with
9674+ name "exec_logging" is created.
9675+ WARNING: This option when enabled will produce a LOT of logs, especially
9676+ on an active system.
9677+
9678+config GRKERNSEC_RESLOG
9679+ bool "Resource logging"
9680+ help
9681+ If you say Y here, all attempts to overstep resource limits will
9682+ be logged with the resource name, the requested size, and the current
9683+ limit. It is highly recommended that you say Y here.
9684+
9685+config GRKERNSEC_CHROOT_EXECLOG
9686+ bool "Log execs within chroot"
9687+ help
9688+ If you say Y here, all executions inside a chroot jail will be logged
9689+ to syslog. This can cause a large amount of logs if certain
9690+ applications (eg. djb's daemontools) are installed on the system, and
9691+ is therefore left as an option. If the sysctl option is enabled, a
9692+ sysctl option with name "chroot_execlog" is created.
9693+
9694+config GRKERNSEC_AUDIT_CHDIR
9695+ bool "Chdir logging"
9696+ help
9697+ If you say Y here, all chdir() calls will be logged. If the sysctl
9698+ option is enabled, a sysctl option with name "audit_chdir" is created.
9699+
9700+config GRKERNSEC_AUDIT_MOUNT
9701+ bool "(Un)Mount logging"
9702+ help
9703+ If you say Y here, all mounts and unmounts will be logged. If the
9704+ sysctl option is enabled, a sysctl option with name "audit_mount" is
9705+ created.
9706+
9707+config GRKERNSEC_AUDIT_IPC
9708+ bool "IPC logging"
9709+ help
9710+ If you say Y here, creation and removal of message queues, semaphores,
9711+ and shared memory will be logged. If the sysctl option is enabled, a
9712+ sysctl option with name "audit_ipc" is created.
9713+
9714+config GRKERNSEC_SIGNAL
9715+ bool "Signal logging"
9716+ help
9717+ If you say Y here, certain important signals will be logged, such as
9718+ SIGSEGV, which will as a result inform you of when a error in a program
9719+ occurred, which in some cases could mean a possible exploit attempt.
9720+ If the sysctl option is enabled, a sysctl option with name
9721+ "signal_logging" is created.
9722+
9723+config GRKERNSEC_FORKFAIL
9724+ bool "Fork failure logging"
9725+ help
9726+ If you say Y here, all failed fork() attempts will be logged.
9727+ This could suggest a fork bomb, or someone attempting to overstep
9728+ their process limit. If the sysctl option is enabled, a sysctl option
9729+ with name "forkfail_logging" is created.
9730+
9731+config GRKERNSEC_TIME
9732+ bool "Time change logging"
9733+ help
9734+ If you say Y here, any changes of the system clock will be logged.
9735+ If the sysctl option is enabled, a sysctl option with name
9736+ "timechange_logging" is created.
9737+
9738+config GRKERNSEC_PROC_IPADDR
9739+ bool "/proc/<pid>/ipaddr support"
9740+ help
9741+ If you say Y here, a new entry will be added to each /proc/<pid>
9742+ directory that contains the IP address of the person using the task.
9743+ The IP is carried across local TCP and AF_UNIX stream sockets.
9744+ This information can be useful for IDS/IPSes to perform remote response
9745+ to a local attack. The entry is readable by only the owner of the
9746+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
9747+ the RBAC system), and thus does not create privacy concerns.
9748+
1db5cd70
PS
9749+endmenu
9750+
9751+menu "Executable Protections"
9752+depends on GRKERNSEC
9753+
9754+config GRKERNSEC_EXECVE
9755+ bool "Enforce RLIMIT_NPROC on execs"
9756+ help
9757+ If you say Y here, users with a resource limit on processes will
9758+ have the value checked during execve() calls. The current system
9759+ only checks the system limit during fork() calls. If the sysctl option
9760+ is enabled, a sysctl option with name "execve_limiting" is created.
9761+
9762+config GRKERNSEC_DMESG
9763+ bool "Dmesg(8) restriction"
9764+ help
9765+ If you say Y here, non-root users will not be able to use dmesg(8)
9766+ to view up to the last 4kb of messages in the kernel's log buffer.
9767+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
9768+ created.
9769+
9770+config GRKERNSEC_RANDPID
9771+ bool "Randomized PIDs"
9772+ help
9773+ If you say Y here, all PIDs created on the system will be
9774+ pseudo-randomly generated. This is extremely effective along
9775+ with the /proc restrictions to disallow an attacker from guessing
9776+ pids of daemons, etc. PIDs are also used in some cases as part
9777+ of a naming system for temporary files, so this option would keep
9778+ those filenames from being predicted as well. We also use code
9779+ to make sure that PID numbers aren't reused too soon. If the sysctl
9780+ option is enabled, a sysctl option with name "rand_pids" is created.
9781+
9782+config GRKERNSEC_TPE
9783+ bool "Trusted Path Execution (TPE)"
9784+ help
9785+ If you say Y here, you will be able to choose a gid to add to the
9786+ supplementary groups of users you want to mark as "untrusted."
9787+ These users will not be able to execute any files that are not in
9788+ root-owned directories writable only by root. If the sysctl option
9789+ is enabled, a sysctl option with name "tpe" is created.
9790+
9791+config GRKERNSEC_TPE_ALL
9792+ bool "Partially restrict non-root users"
9793+ depends on GRKERNSEC_TPE
9794+ help
9795+ If you say Y here, All non-root users other than the ones in the
9796+ group specified in the main TPE option will only be allowed to
9797+ execute files in directories they own that are not group or
9798+ world-writable, or in directories owned by root and writable only by
9799+ root. If the sysctl option is enabled, a sysctl option with name
9800+ "tpe_restrict_all" is created.
9801+
9802+config GRKERNSEC_TPE_GID
9803+ int "GID for untrusted users"
9804+ depends on GRKERNSEC_TPE
9805+ default 1005
9806+ help
9807+ Here you can choose the GID to enable trusted path protection for.
9808+ Remember to add the users you want protection enabled for to the GID
9809+ specified here. If the sysctl option is enabled, whatever you choose
9810+ here won't matter. You'll have to specify the GID in your bootup
9811+ script by echoing the GID to the proper /proc entry. View the help
9812+ on the sysctl option for more information. If the sysctl option is
9813+ enabled, a sysctl option with name "tpe_gid" is created.
9814+
9815+endmenu
9816+menu "Network Protections"
9817+depends on GRKERNSEC
9818+
9819+config GRKERNSEC_RANDNET
9820+ bool "Larger entropy pools"
9821+ help
9822+ If you say Y here, the entropy pools used for many features of Linux
9823+ and grsecurity will be doubled in size. Since several grsecurity
9824+ features use additional randomness, it is recommended that you say Y
9825+ here. Saying Y here has a similar effect as modifying
9826+ /proc/sys/kernel/random/poolsize.
9827+
9828+config GRKERNSEC_RANDISN
9829+ bool "Truly random TCP ISN selection"
9830+ help
9831+ If you say Y here, Linux's default selection of TCP Initial Sequence
9832+ Numbers (ISNs) will be replaced with that of OpenBSD. Linux uses
9833+ an MD4 hash based on the connection plus a time value to create the
9834+ ISN, while OpenBSD's selection is random. If the sysctl option is
9835+ enabled, a sysctl option with name "rand_isns" is created.
9836+
9837+config GRKERNSEC_RANDID
9838+ bool "Randomized IP IDs"
9839+ help
9840+ If you say Y here, all the id field on all outgoing packets
9841+ will be randomized. This hinders os fingerprinters and
9842+ keeps your machine from being used as a bounce for an untraceable
9843+ portscan. Ids are used for fragmented packets, fragments belonging
9844+ to the same packet have the same id. By default linux only
9845+ increments the id value on each packet sent to an individual host.
9846+ We use a port of the OpenBSD random ip id code to achieve the
9847+ randomness, while keeping the possibility of id duplicates to
9848+ near none. If the sysctl option is enabled, a sysctl option with name
9849+ "rand_ip_ids" is created.
9850+
9851+config GRKERNSEC_RANDSRC
9852+ bool "Randomized TCP source ports"
9853+ default n if GRKERNSEC_LOW || GRKERNSEC_MID
9854+ default y if GRKERNSEC_HIGH
9855+ help
9856+ If you say Y here, situations where a source port is generated on the
9857+ fly for the TCP protocol (ie. with connect() ) will be altered so that
9858+ the source port is generated at random, instead of a simple incrementing
9859+ algorithm. If the sysctl option is enabled, a sysctl option with name
9860+ "rand_tcp_src_ports" is created.
9861+
9862+config GRKERNSEC_RANDRPC
9863+ bool "Randomized RPC XIDs"
9864+ help
9865+ If you say Y here, the method of determining XIDs for RPC requests will
9866+ be randomized, instead of using linux's default behavior of simply
9867+ incrementing the XID. If you want your RPC connections to be more
9868+ secure, say Y here. If the sysctl option is enabled, a sysctl option
9869+ with name "rand_rpc" is created.
9870+
9871+config GRKERNSEC_SOCKET
9872+ bool "Socket restrictions"
9873+ help
9874+ If you say Y here, you will be able to choose from several options.
9875+ If you assign a GID on your system and add it to the supplementary
9876+ groups of users you want to restrict socket access to, this patch
9877+ will perform up to three things, based on the option(s) you choose.
9878+
9879+config GRKERNSEC_SOCKET_ALL
9880+ bool "Deny any sockets to group"
9881+ depends on GRKERNSEC_SOCKET
9882+ help
9883+ If you say Y here, you will be able to choose a GID of whose users will
9884+ be unable to connect to other hosts from your machine or run server
9885+ applications from your machine. If the sysctl option is enabled, a
9886+ sysctl option with name "socket_all" is created.
9887+
9888+config GRKERNSEC_SOCKET_ALL_GID
9889+ int "GID to deny all sockets for"
9890+ depends on GRKERNSEC_SOCKET_ALL
9891+ default 1004
9892+ help
9893+ Here you can choose the GID to disable socket access for. Remember to
9894+ add the users you want socket access disabled for to the GID
9895+ specified here. If the sysctl option is enabled, whatever you choose
9896+ here won't matter. You'll have to specify the GID in your bootup
9897+ script by echoing the GID to the proper /proc entry. View the help
9898+ on the sysctl option for more information. If the sysctl option is
9899+ enabled, a sysctl option with name "socket_all_gid" is created.
9900+
9901+config GRKERNSEC_SOCKET_CLIENT
9902+ bool "Deny client sockets to group"
9903+ depends on GRKERNSEC_SOCKET
9904+ help
9905+ If you say Y here, you will be able to choose a GID of whose users will
9906+ be unable to connect to other hosts from your machine, but will be
9907+ able to run servers. If this option is enabled, all users in the group
9908+ you specify will have to use passive mode when initiating ftp transfers
9909+ from the shell on your machine. If the sysctl option is enabled, a
9910+ sysctl option with name "socket_client" is created.
9911+
9912+config GRKERNSEC_SOCKET_CLIENT_GID
9913+ int "GID to deny client sockets for"
9914+ depends on GRKERNSEC_SOCKET_CLIENT
9915+ default 1003
9916+ help
9917+ Here you can choose the GID to disable client socket access for.
9918+ Remember to add the users you want client socket access disabled for to
9919+ the GID specified here. If the sysctl option is enabled, whatever you
9920+ choose here won't matter. You'll have to specify the GID in your bootup
9921+ script by echoing the GID to the proper /proc entry. View the help
9922+ on the sysctl option for more information. If the sysctl option is
9923+ enabled, a sysctl option with name "socket_client_gid" is created.
9924+
9925+config GRKERNSEC_SOCKET_SERVER
9926+ bool "Deny server sockets to group"
9927+ depends on GRKERNSEC_SOCKET
9928+ help
9929+ If you say Y here, you will be able to choose a GID of whose users will
9930+ be unable to run server applications from your machine. If the sysctl
9931+ option is enabled, a sysctl option with name "socket_server" is created.
9932+
9933+config GRKERNSEC_SOCKET_SERVER_GID
9934+ int "GID to deny server sockets for"
9935+ depends on GRKERNSEC_SOCKET_SERVER
9936+ default 1002
9937+ help
9938+ Here you can choose the GID to disable server socket access for.
9939+ Remember to add the users you want server socket access disabled for to
9940+ the GID specified here. If the sysctl option is enabled, whatever you
9941+ choose here won't matter. You'll have to specify the GID in your bootup
9942+ script by echoing the GID to the proper /proc entry. View the help
9943+ on the sysctl option for more information. If the sysctl option is
9944+ enabled, a sysctl option with name "socket_server_gid" is created.
9945+
9946+endmenu
9947+menu "Sysctl support"
9948+depends on GRKERNSEC && SYSCTL
9949+
9950+config GRKERNSEC_SYSCTL
9951+ bool "Sysctl support"
9952+ help
9953+ If you say Y here, you will be able to change the options that
9954+ grsecurity runs with at bootup, without having to recompile your
9955+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
9956+ to enable (1) or disable (0) various features. All the sysctl entries
9957+ are mutable until the "grsec_lock" entry is set to a non-zero value.
9958+ All features are disabled by default. Please note that this option could
9959+ reduce the effectiveness of the added security of this patch if an ACL
9960+ system is not put in place. Your init scripts should be read-only, and
9961+ root should not have access to adding modules or performing raw i/o
9962+ operations. All options should be set at startup, and the grsec_lock
9963+ entry should be set to a non-zero value after all the options are set.
9964+ *THIS IS EXTREMELY IMPORTANT*
9965+
9966+endmenu
9967+menu "Logging Options"
9968+depends on GRKERNSEC
9969+
9970+config GRKERNSEC_FLOODTIME
9971+ int "Seconds in between log messages (minimum)"
9972+ default 10
9973+ help
9974+ This option allows you to enforce the number of seconds between
9975+ grsecurity log messages. The default should be suitable for most
9976+ people, however, if you choose to change it, choose a value small enough
9977+ to allow informative logs to be produced, but large enough to
9978+ prevent flooding.
9979+
9980+config GRKERNSEC_FLOODBURST
9981+ int "Number of messages in a burst (maximum)"
9982+ default 4
9983+ help
9984+ This option allows you to choose the maximum number of messages allowed
9985+ within the flood time interval you chose in a separate option. The
9986+ default should be suitable for most people, however if you find that
9987+ many of your logs are being interpreted as flooding, you may want to
9988+ raise this value.
9989+
9990+endmenu
9991+
9992+endmenu
9993diff -uNr linux-2.6.7-rc1.orig/grsecurity/Makefile linux-2.6.7-rc1/grsecurity/Makefile
9994--- linux-2.6.7-rc1.orig/grsecurity/Makefile 1970-01-01 01:00:00.000000000 +0100
9995+++ linux-2.6.7-rc1/grsecurity/Makefile 2004-05-25 14:33:58.847414160 +0200
9996@@ -0,0 +1,21 @@
9997+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
9998+# during 2001, 2002, and 2003 it has been completely redesigned by
9999+# Brad Spengler
10000+#
10001+# All code in this directory and various hooks inserted throughout the kernel
10002+# are copyright Brad Spengler, and released under the GPL, unless otherwise
10003+# noted (as in obsd_rand.c)
10004+
10005+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
10006+ grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
806c2378 10007+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o
1db5cd70
PS
10008+
10009+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
10010+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
10011+ gracl_learn.o
10012+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
10013+
10014+ifndef CONFIG_GRKERNSEC
10015+obj-y += grsec_disabled.o
10016+endif
10017+
10018diff -uNr linux-2.6.7-rc1.orig/grsecurity/obsd_rand.c linux-2.6.7-rc1/grsecurity/obsd_rand.c
10019--- linux-2.6.7-rc1.orig/grsecurity/obsd_rand.c 1970-01-01 01:00:00.000000000 +0100
10020+++ linux-2.6.7-rc1/grsecurity/obsd_rand.c 2004-05-25 14:33:58.964396376 +0200
10021@@ -0,0 +1,186 @@
10022+
10023+/*
10024+ * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
10025+ *
10026+ * Version 1.89, last modified 19-Sep-99
10027+ *
10028+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
10029+ * All rights reserved.
10030+ *
10031+ * Copyright 1998 Niels Provos <provos@citi.umich.edu>
10032+ * All rights reserved.
10033+ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
10034+ * such a mathematical system to generate more random (yet non-repeating)
10035+ * ids to solve the resolver/named problem. But Niels designed the
10036+ * actual system based on the constraints.
10037+ *
10038+ * Redistribution and use in source and binary forms, with or without
10039+ * modification, are permitted provided that the following conditions
10040+ * are met:
10041+ * 1. Redistributions of source code must retain the above copyright
10042+ * notice, this list of conditions and the following disclaimer,
10043+ * 2. Redistributions in binary form must reproduce the above copyright
10044+ * notice, this list of conditions and the following disclaimer in the
10045+ * documentation and/or other materials provided with the distribution.
10046+ *
10047+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
10048+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
10049+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
10050+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
10051+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10052+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10053+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
10054+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10055+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
10056+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10057+ */
10058+
10059+#include <linux/kernel.h>
10060+#include <linux/sched.h>
10061+#include <linux/time.h>
10062+#include <linux/timer.h>
10063+#include <linux/smp_lock.h>
10064+#include <linux/random.h>
10065+#include <linux/grsecurity.h>
10066+
10067+#define RU_OUT 180
10068+#define RU_MAX 30000
10069+#define RU_GEN 2
10070+#define RU_N 32749
10071+#define RU_AGEN 7
10072+#define RU_M 31104
10073+#define PFAC_N 3
10074+const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
10075+
10076+static __u16 ru_x;
10077+static __u16 ru_seed, ru_seed2;
10078+static __u16 ru_a, ru_b;
10079+static __u16 ru_g;
10080+static __u16 ru_counter = 0;
10081+static __u16 ru_msb = 0;
10082+static unsigned long ru_reseed = 0;
10083+static __u32 tmp;
10084+
10085+#define TCP_RNDISS_ROUNDS 15
10086+#define TCP_RNDISS_OUT 7200
10087+#define TCP_RNDISS_MAX 30000
10088+
10089+static __u8 tcp_rndiss_sbox[128];
10090+static __u16 tcp_rndiss_msb;
10091+static __u16 tcp_rndiss_cnt;
10092+static unsigned long tcp_rndiss_reseed;
10093+
10094+static __u16 pmod(__u16, __u16, __u16);
10095+static void ip_initid(void);
10096+__u16 ip_randomid(void);
10097+
10098+static __u16
10099+pmod(__u16 gen, __u16 exp, __u16 mod)
10100+{
10101+ __u16 s, t, u;
10102+
10103+ s = 1;
10104+ t = gen;
10105+ u = exp;
10106+
10107+ while (u) {
10108+ if (u & 1)
10109+ s = (s * t) % mod;
10110+ u >>= 1;
10111+ t = (t * t) % mod;
10112+ }
10113+ return (s);
10114+}
10115+
10116+static void
10117+ip_initid(void)
10118+{
10119+ __u16 j, i;
10120+ int noprime = 1;
10121+
10122+ ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
10123+
10124+ ru_seed = (tmp >> 16) & 0x7FFF;
10125+ ru_seed2 = get_random_long() & 0x7FFF;
10126+
10127+ ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
10128+ ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
10129+ while (ru_b % 3 == 0)
10130+ ru_b += 2;
10131+
10132+ j = (tmp = get_random_long()) % RU_N;
10133+ tmp = tmp >> 16;
10134+
10135+ while (noprime) {
10136+ for (i = 0; i < PFAC_N; i++)
10137+ if (j % pfacts[i] == 0)
10138+ break;
10139+
10140+ if (i >= PFAC_N)
10141+ noprime = 0;
10142+ else
10143+ j = (j + 1) % RU_N;
10144+ }
10145+
10146+ ru_g = pmod(RU_GEN, j, RU_N);
10147+ ru_counter = 0;
10148+
10149+ ru_reseed = xtime.tv_sec + RU_OUT;
10150+ ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
10151+}
10152+
10153+__u16
10154+ip_randomid(void)
10155+{
10156+ int i, n;
10157+
10158+ if (ru_counter >= RU_MAX || time_after(get_seconds(), ru_reseed))
10159+ ip_initid();
10160+
10161+ if (!tmp)
10162+ tmp = get_random_long();
10163+
10164+ n = tmp & 0x3;
10165+ tmp = tmp >> 2;
10166+ if (ru_counter + n >= RU_MAX)
10167+ ip_initid();
10168+ for (i = 0; i <= n; i++)
10169+ ru_x = (ru_a * ru_x + ru_b) % RU_M;
10170+ ru_counter += i;
10171+
10172+ return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
10173+}
10174+
10175+__u16
10176+tcp_rndiss_encrypt(__u16 val)
10177+{
10178+ __u16 sum = 0, i;
10179+
10180+ for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
10181+ sum += 0x79b9;
10182+ val ^= ((__u16) tcp_rndiss_sbox[(val ^ sum) & 0x7f]) << 7;
10183+ val = ((val & 0xff) << 7) | (val >> 8);
10184+ }
10185+
10186+ return val;
10187+}
10188+
10189+static void
10190+tcp_rndiss_init(void)
10191+{
10192+ get_random_bytes(tcp_rndiss_sbox, sizeof (tcp_rndiss_sbox));
10193+ tcp_rndiss_reseed = get_seconds() + TCP_RNDISS_OUT;
10194+ tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
10195+ tcp_rndiss_cnt = 0;
10196+}
10197+
10198+__u32
10199+ip_randomisn(void)
10200+{
10201+ if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
10202+ time_after(get_seconds(), tcp_rndiss_reseed))
10203+ tcp_rndiss_init();
10204+
10205+ return (((tcp_rndiss_encrypt(tcp_rndiss_cnt++) |
10206+ tcp_rndiss_msb) << 16) | (get_random_long() & 0x7fff));
10207+}
1db5cd70
PS
10208diff -uNr linux-2.6.7-rc1.orig/include/asm-i386/module.h linux-2.6.7-rc1/include/asm-i386/module.h
10209--- linux-2.6.7-rc1.orig/include/asm-i386/module.h 2004-05-23 07:53:35.000000000 +0200
10210+++ linux-2.6.7-rc1/include/asm-i386/module.h 2004-05-25 14:33:59.087377680 +0200
10211@@ -60,12 +60,18 @@
10212 #define MODULE_REGPARM ""
10213 #endif
10214
10215+#ifdef CONFIG_GRKERNSEC
10216+#define MODULE_GRSEC "GRSECURITY "
10217+#else
10218+#define MODULE_GRSEC ""
10219+#endif
10220+
10221 #ifdef CONFIG_4KSTACKS
10222 #define MODULE_STACKSIZE "4KSTACKS "
10223 #else
10224 #define MODULE_STACKSIZE ""
10225 #endif
10226
10227-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
10228+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
10229
10230 #endif /* _ASM_I386_MODULE_H */
1db5cd70
PS
10231diff -uNr linux-2.6.7-rc1.orig/include/linux/binfmts.h linux-2.6.7-rc1/include/linux/binfmts.h
10232--- linux-2.6.7-rc1.orig/include/linux/binfmts.h 2004-05-23 07:54:18.000000000 +0200
10233+++ linux-2.6.7-rc1/include/linux/binfmts.h 2004-05-25 14:33:59.302345000 +0200
10234@@ -36,6 +36,7 @@
10235 of the time same as filename, but could be
10236 different for binfmt_{misc,script} */
10237 unsigned long loader, exec;
10238+ int misc;
10239 };
10240
10241 /*
1db5cd70
PS
10242diff -uNr linux-2.6.7-rc1.orig/include/linux/fs.h linux-2.6.7-rc1/include/linux/fs.h
10243--- linux-2.6.7-rc1.orig/include/linux/fs.h 2004-05-23 07:53:47.000000000 +0200
10244+++ linux-2.6.7-rc1/include/linux/fs.h 2004-05-25 14:33:59.335339984 +0200
10245@@ -1192,7 +1192,7 @@
10246
10247 /* fs/open.c */
10248
10249-extern int do_truncate(struct dentry *, loff_t start);
10250+extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
10251 extern struct file *filp_open(const char *, int, int);
10252 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
10253 extern int filp_close(struct file *, fl_owner_t id);
10254diff -uNr linux-2.6.7-rc1.orig/include/linux/gracl.h linux-2.6.7-rc1/include/linux/gracl.h
10255--- linux-2.6.7-rc1.orig/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100
10256+++ linux-2.6.7-rc1/include/linux/gracl.h 2004-05-25 14:33:59.339339376 +0200
10257@@ -0,0 +1,246 @@
10258+#ifndef GR_ACL_H
10259+#define GR_ACL_H
10260+#endif
10261+#include <linux/grdefs.h>
10262+#include <linux/resource.h>
10263+#include <linux/dcache.h>
10264+#include <asm/resource.h>
10265+
10266+/* * * * * * * * * * * * * * * * * * * * *
10267+ * grsecurity ACL System
10268+ * Main header file
10269+ * Purpose: define most gracl data structures
10270+ * * * * * * * * * * * * * * * * * * * * */
10271+
10272+/* Major status information */
10273+
10274+#define GR_VERSION "grsecurity 2.0"
10275+
10276+enum {
10277+
10278+ SHUTDOWN = 0,
10279+ ENABLE = 1,
10280+ SPROLE = 2,
10281+ RELOAD = 3,
10282+ SEGVMOD = 4,
10283+ STATUS = 5,
10284+ UNSPROLE = 6
10285+};
10286+
10287+/* Password setup definitions
10288+ * kernel/grhash.c */
10289+enum {
10290+ GR_PW_LEN = 128,
10291+ GR_SALT_LEN = 16,
10292+ GR_SHA_LEN = 32,
10293+};
10294+
10295+enum {
10296+ GR_SPROLE_LEN = 64,
10297+};
10298+
10299+/* Begin Data Structures */
10300+
10301+struct sprole_pw {
10302+ unsigned char *rolename;
10303+ unsigned char salt[GR_SALT_LEN];
10304+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
10305+};
10306+
10307+struct name_entry {
10308+ ino_t inode;
10309+ dev_t device;
10310+ char *name;
10311+ __u16 len;
10312+};
10313+
10314+struct acl_role_db {
10315+ struct acl_role_label **r_hash;
10316+ __u32 r_size;
10317+};
10318+
10319+struct name_db {
10320+ struct name_entry **n_hash;
10321+ __u32 n_size;
10322+};
10323+
10324+struct crash_uid {
10325+ uid_t uid;
10326+ unsigned long expires;
10327+};
10328+
10329+struct gr_hash_struct {
10330+ void **table;
10331+ void **nametable;
10332+ void *first;
10333+ __u32 table_size;
10334+ __u32 used_size;
10335+ int type;
10336+};
10337+
10338+/* Userspace Grsecurity ACL data structures */
10339+struct acl_subject_label {
10340+ char *filename;
10341+ ino_t inode;
10342+ dev_t device;
10343+ __u32 mode;
10344+ __u32 cap_mask;
10345+ __u32 cap_lower;
10346+
10347+ struct rlimit res[RLIM_NLIMITS + 1];
10348+ __u16 resmask;
10349+
10350+ __u8 user_trans_type;
10351+ __u8 group_trans_type;
10352+ uid_t *user_transitions;
10353+ gid_t *group_transitions;
10354+ __u16 user_trans_num;
10355+ __u16 group_trans_num;
10356+
10357+ __u32 ip_proto[8];
10358+ __u32 ip_type;
10359+ struct acl_ip_label **ips;
10360+ __u32 ip_num;
10361+
10362+ __u32 crashes;
10363+ unsigned long expires;
10364+
10365+ struct acl_subject_label *parent_subject;
10366+ struct gr_hash_struct *hash;
10367+ struct acl_ip_label *ip_object;
10368+ struct acl_subject_label *prev;
10369+ struct acl_subject_label *next;
10370+
10371+ struct acl_object_label **obj_hash;
10372+ __u32 obj_hash_size;
10373+};
10374+
10375+struct role_allowed_ip {
10376+ __u32 addr;
10377+ __u32 netmask;
10378+
10379+ struct role_allowed_ip *prev;
10380+ struct role_allowed_ip *next;
10381+};
10382+
10383+struct role_transition {
10384+ char *rolename;
10385+
10386+ struct role_transition *prev;
10387+ struct role_transition *next;
10388+};
10389+
10390+struct acl_role_label {
10391+ char *rolename;
10392+ uid_t uidgid;
10393+ __u16 roletype;
10394+
10395+ __u16 auth_attempts;
10396+ unsigned long expires;
10397+
10398+ struct acl_subject_label *root_label;
10399+ struct gr_hash_struct *hash;
10400+
10401+ struct acl_role_label *prev;
10402+ struct acl_role_label *next;
10403+
10404+ struct role_transition *transitions;
10405+ struct role_allowed_ip *allowed_ips;
10406+ struct acl_subject_label **subj_hash;
10407+ __u32 subj_hash_size;
10408+};
10409+
10410+struct user_acl_role_db {
10411+ struct acl_role_label **r_table;
10412+ __u32 r_entries; /* number of entries in table */
10413+ __u32 s_entries; /* total number of subject acls */
10414+ __u32 i_entries; /* total number of ip acls */
10415+ __u32 o_entries; /* Total number of object acls */
10416+ __u32 g_entries; /* total number of globbed objects */
10417+ __u32 a_entries; /* total number of allowed ips */
10418+ __u32 t_entries; /* total number of transitions */
10419+};
10420+
10421+struct acl_object_label {
10422+ char *filename;
10423+ ino_t inode;
10424+ dev_t device;
10425+ __u32 mode;
10426+
10427+ struct acl_subject_label *nested;
10428+ struct acl_object_label *globbed;
10429+
10430+ /* next two structures not used */
10431+
10432+ struct acl_object_label *prev;
10433+ struct acl_object_label *next;
10434+};
10435+
10436+struct acl_ip_label {
10437+ __u32 addr;
10438+ __u32 netmask;
10439+ __u16 low, high;
10440+ __u8 mode;
10441+ __u32 type;
10442+ __u32 proto[8];
10443+
10444+ /* next two structures not used */
10445+
10446+ struct acl_ip_label *prev;
10447+ struct acl_ip_label *next;
10448+};
10449+
10450+struct gr_arg {
10451+ struct user_acl_role_db role_db;
10452+ unsigned char pw[GR_PW_LEN];
10453+ unsigned char salt[GR_SALT_LEN];
10454+ unsigned char sum[GR_SHA_LEN];
10455+ unsigned char sp_role[GR_SPROLE_LEN];
10456+ struct sprole_pw *sprole_pws;
10457+ dev_t segv_device;
10458+ ino_t segv_inode;
10459+ uid_t segv_uid;
10460+ __u16 num_sprole_pws;
10461+ __u16 mode;
10462+};
10463+
10464+struct subject_map {
10465+ struct acl_subject_label *user;
10466+ struct acl_subject_label *kernel;
10467+};
10468+
10469+struct acl_subj_map_db {
10470+ struct subject_map **s_hash;
10471+ __u32 s_size;
10472+};
10473+
10474+/* End Data Structures Section */
10475+
10476+/* Hash functions generated by empirical testing by Brad Spengler
10477+ Makes good use of the low bits of the inode. Generally 0-1 times
10478+ in loop for successful match. 0-3 for unsuccessful match.
10479+ Shift/add algorithm with modulus of table size and an XOR*/
10480+
10481+static __inline__ unsigned long
10482+rhash(const uid_t uid, const __u16 type, const unsigned long sz)
10483+{
10484+ return (((uid << type) + (uid ^ type)) % sz);
10485+}
10486+
10487+ static __inline__ unsigned long
10488+shash(const struct acl_subject_label *userp, const unsigned long sz)
10489+{
10490+ return ((const unsigned long)userp % sz);
10491+}
10492+
10493+static __inline__ unsigned long
10494+fhash(const ino_t ino, const dev_t dev, const unsigned long sz)
10495+{
10496+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
10497+}
10498+
10499+static __inline__ unsigned long
10500+nhash(const char *name, const __u16 len, const unsigned long sz)
10501+{
10502+ return full_name_hash(name, len) % sz;
10503+}
10504diff -uNr linux-2.6.7-rc1.orig/include/linux/gralloc.h linux-2.6.7-rc1/include/linux/gralloc.h
10505--- linux-2.6.7-rc1.orig/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100
10506+++ linux-2.6.7-rc1/include/linux/gralloc.h 2004-05-25 14:33:59.341339072 +0200
10507@@ -0,0 +1,8 @@
10508+#ifndef __GRALLOC_H
10509+#define __GRALLOC_H
10510+
10511+void acl_free_all(void);
10512+int acl_alloc_stack_init(unsigned long size);
10513+void *acl_alloc(unsigned long len);
10514+
10515+#endif
10516diff -uNr linux-2.6.7-rc1.orig/include/linux/grdefs.h linux-2.6.7-rc1/include/linux/grdefs.h
10517--- linux-2.6.7-rc1.orig/include/linux/grdefs.h 1970-01-01 01:00:00.000000000 +0100
10518+++ linux-2.6.7-rc1/include/linux/grdefs.h 2004-05-25 14:33:59.342338920 +0200
10519@@ -0,0 +1,116 @@
10520+#ifndef GRDEFS_H
10521+#define GRDEFS_H
10522+
10523+/* Begin grsecurity status declarations */
10524+
10525+enum {
10526+ GR_READY = 0x01,
10527+ GR_STATUS_INIT = 0x00 // disabled state
10528+};
10529+
10530+/* Begin ACL declarations */
10531+
10532+/* Role flags */
10533+
10534+enum {
10535+ GR_ROLE_USER = 0x0001,
10536+ GR_ROLE_GROUP = 0x0002,
10537+ GR_ROLE_DEFAULT = 0x0004,
10538+ GR_ROLE_SPECIAL = 0x0008,
10539+ GR_ROLE_AUTH = 0x0010,
10540+ GR_ROLE_NOPW = 0x0020,
10541+ GR_ROLE_GOD = 0x0040,
10542+ GR_ROLE_LEARN = 0x0080,
10543+ GR_ROLE_TPE = 0x0100
10544+};
10545+
10546+/* ACL Subject and Object mode flags */
10547+enum {
10548+ GR_DELETED = 0x00000080
10549+};
10550+
10551+/* ACL Object-only mode flags */
10552+enum {
10553+ GR_READ = 0x00000001,
10554+ GR_APPEND = 0x00000002,
10555+ GR_WRITE = 0x00000004,
10556+ GR_EXEC = 0x00000008,
10557+ GR_FIND = 0x00000010,
10558+ GR_INHERIT = 0x00000040,
10559+ GR_PTRACERD = 0x00000100,
10560+ GR_SETID = 0x00000200,
10561+ GR_CREATE = 0x00000400,
10562+ GR_DELETE = 0x00000800,
10563+ GR_NOPTRACE = 0x00001000,
10564+ GR_AUDIT_READ = 0x00002000,
10565+ GR_AUDIT_APPEND = 0x00004000,
10566+ GR_AUDIT_WRITE = 0x00008000,
10567+ GR_AUDIT_EXEC = 0x00010000,
10568+ GR_AUDIT_FIND = 0x00020000,
10569+ GR_AUDIT_INHERIT= 0x00040000,
10570+ GR_AUDIT_SETID = 0x00080000,
10571+ GR_AUDIT_CREATE = 0x00100000,
10572+ GR_AUDIT_DELETE = 0x00200000,
10573+ GR_SUPPRESS = 0x00400000,
10574+ GR_NOLEARN = 0x00800000
10575+};
10576+
10577+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
10578+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
10579+ GR_AUDIT_CREATE | GR_AUDIT_DELETE)
10580+
10581+/* ACL subject-only mode flags */
10582+enum {
10583+ GR_KILL = 0x00000001,
10584+ GR_VIEW = 0x00000002,
10585+ GR_PROTECTED = 0x00000100,
10586+ GR_LEARN = 0x00000200,
10587+ GR_OVERRIDE = 0x00000400,
10588+ /* just a placeholder, this mode is only used in userspace */
10589+ GR_DUMMY = 0x00000800,
10590+ GR_PAXPAGE = 0x00001000,
10591+ GR_PAXSEGM = 0x00002000,
10592+ GR_PAXGCC = 0x00004000,
10593+ GR_PAXRANDMMAP = 0x00008000,
10594+ GR_PAXRANDEXEC = 0x00010000,
10595+ GR_PAXMPROTECT = 0x00020000,
10596+ GR_PROTSHM = 0x00040000,
10597+ GR_KILLPROC = 0x00080000,
10598+ GR_KILLIPPROC = 0x00100000,
10599+ /* just a placeholder, this mode is only used in userspace */
10600+ GR_NOTROJAN = 0x00200000,
10601+ GR_PROTPROCFD = 0x00400000,
10602+ GR_PROCACCT = 0x00800000,
10603+ GR_RELAXPTRACE = 0x01000000,
10604+ GR_NESTED = 0x02000000
10605+};
10606+
10607+enum {
10608+ GR_ID_USER = 0x01,
10609+ GR_ID_GROUP = 0x02,
10610+};
10611+
10612+enum {
10613+ GR_ID_ALLOW = 0x01,
10614+ GR_ID_DENY = 0x02,
10615+};
10616+
10617+#define GR_CRASH_RES 11
10618+#define GR_UIDTABLE_MAX 500
10619+
10620+/* begin resource learning section */
10621+enum {
10622+ GR_RLIM_CPU_BUMP = 60,
10623+ GR_RLIM_FSIZE_BUMP = 50000,
10624+ GR_RLIM_DATA_BUMP = 10000,
10625+ GR_RLIM_STACK_BUMP = 1000,
10626+ GR_RLIM_CORE_BUMP = 10000,
10627+ GR_RLIM_RSS_BUMP = 500000,
10628+ GR_RLIM_NPROC_BUMP = 1,
10629+ GR_RLIM_NOFILE_BUMP = 5,
10630+ GR_RLIM_MEMLOCK_BUMP = 50000,
10631+ GR_RLIM_AS_BUMP = 500000,
10632+ GR_RLIM_LOCKS_BUMP = 2
10633+};
10634+
10635+#endif
10636diff -uNr linux-2.6.7-rc1.orig/include/linux/grinternal.h linux-2.6.7-rc1/include/linux/grinternal.h
10637--- linux-2.6.7-rc1.orig/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100
10638+++ linux-2.6.7-rc1/include/linux/grinternal.h 2004-05-25 14:33:59.344338616 +0200
806c2378 10639@@ -0,0 +1,200 @@
1db5cd70
PS
10640+#ifndef __GRINTERNAL_H
10641+#define __GRINTERNAL_H
10642+
10643+#ifdef CONFIG_GRKERNSEC
10644+
10645+#include <linux/fs.h>
10646+#include <linux/grdefs.h>
10647+#include <linux/grmsg.h>
10648+
10649+extern void gr_add_learn_entry(const char *fmt, ...);
10650+extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
10651+ const struct vfsmount *mnt);
10652+extern __u32 gr_check_create(const struct dentry *new_dentry,
10653+ const struct dentry *parent,
10654+ const struct vfsmount *mnt, const __u32 mode);
10655+extern int gr_check_protected_task(const struct task_struct *task);
10656+extern __u32 to_gr_audit(const __u32 reqmode);
10657+extern int gr_set_acls(const int type);
10658+
10659+extern void gr_handle_alertkill(void);
10660+extern char *gr_to_filename(const struct dentry *dentry,
10661+ const struct vfsmount *mnt);
10662+extern char *gr_to_filename1(const struct dentry *dentry,
10663+ const struct vfsmount *mnt);
10664+extern char *gr_to_filename2(const struct dentry *dentry,
10665+ const struct vfsmount *mnt);
10666+extern char *gr_to_filename3(const struct dentry *dentry,
10667+ const struct vfsmount *mnt);
10668+
10669+extern int grsec_enable_link;
10670+extern int grsec_enable_fifo;
10671+extern int grsec_enable_execve;
10672+extern int grsec_enable_forkbomb;
10673+extern int grsec_forkbomb_gid;
10674+extern int grsec_forkbomb_sec;
10675+extern int grsec_forkbomb_max;
10676+extern int grsec_enable_execlog;
10677+extern int grsec_enable_signal;
10678+extern int grsec_enable_forkfail;
10679+extern int grsec_enable_time;
10680+extern int grsec_enable_chroot_shmat;
10681+extern int grsec_enable_chroot_findtask;
10682+extern int grsec_enable_chroot_mount;
10683+extern int grsec_enable_chroot_double;
10684+extern int grsec_enable_chroot_pivot;
10685+extern int grsec_enable_chroot_chdir;
10686+extern int grsec_enable_chroot_chmod;
10687+extern int grsec_enable_chroot_mknod;
10688+extern int grsec_enable_chroot_fchdir;
10689+extern int grsec_enable_chroot_nice;
10690+extern int grsec_enable_chroot_execlog;
10691+extern int grsec_enable_chroot_caps;
10692+extern int grsec_enable_chroot_sysctl;
10693+extern int grsec_enable_chroot_unix;
10694+extern int grsec_enable_tpe;
10695+extern int grsec_tpe_gid;
10696+extern int grsec_enable_tpe_all;
10697+extern int grsec_enable_sidcaps;
10698+extern int grsec_enable_randpid;
10699+extern int grsec_enable_socket_all;
10700+extern int grsec_socket_all_gid;
10701+extern int grsec_enable_socket_client;
10702+extern int grsec_socket_client_gid;
10703+extern int grsec_enable_socket_server;
10704+extern int grsec_socket_server_gid;
10705+extern int grsec_audit_gid;
10706+extern int grsec_enable_group;
10707+extern int grsec_enable_audit_ipc;
1db5cd70
PS
10708+extern int grsec_enable_mount;
10709+extern int grsec_enable_chdir;
10710+extern int grsec_lock;
10711+
10712+extern struct task_struct *child_reaper;
10713+
10714+extern spinlock_t grsec_alert_lock;
10715+extern unsigned long grsec_alert_wtime;
10716+extern unsigned long grsec_alert_fyet;
10717+
10718+extern spinlock_t grsec_alertgood_lock;
10719+extern unsigned long grsec_alertgood_wtime;
10720+extern unsigned long grsec_alertgood_fyet;
10721+
10722+extern spinlock_t grsec_audit_lock;
10723+
10724+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
10725+ gr_to_filename2(tsk->exec_file->f_dentry, \
10726+ tsk->exec_file->f_vfsmnt) : "/")
10727+
10728+#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
10729+ gr_to_filename3(tsk->parent->exec_file->f_dentry, \
10730+ tsk->parent->exec_file->f_vfsmnt) : "/")
10731+
10732+#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
10733+ gr_to_filename(tsk->exec_file->f_dentry, \
10734+ tsk->exec_file->f_vfsmnt) : "/")
10735+
10736+#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
10737+ gr_to_filename1(tsk->parent->exec_file->f_dentry, \
10738+ tsk->parent->exec_file->f_vfsmnt) : "/")
10739+
10740+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && \
10741+ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
10742+ child_reaper->fs->root->d_inode->i_sb->s_dev) || \
10743+ (tsk_a->fs->root->d_inode->i_ino != \
10744+ child_reaper->fs->root->d_inode->i_ino)))
10745+
10746+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_sb->s_dev == \
10747+ tsk_b->fs->root->d_inode->i_sb->s_dev) && \
10748+ (tsk_a->fs->root->d_inode->i_ino == \
10749+ tsk_b->fs->root->d_inode->i_ino))
10750+
10751+#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
10752+ current->pid, current->uid, \
10753+ current->euid, current->gid, current->egid, \
10754+ gr_parent_task_fullpath(current), \
10755+ current->parent->comm, current->parent->pid, \
10756+ current->parent->uid, current->parent->euid, \
10757+ current->parent->gid, current->parent->egid
10758+
10759+#define GR_CHROOT_CAPS ( \
10760+ CAP_TO_MASK(CAP_FOWNER) | \
10761+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
10762+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
10763+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
10764+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
10765+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
10766+ CAP_TO_MASK(CAP_IPC_OWNER))
10767+
10768+#define security_alert_good(normal_msg,args...) \
10769+({ \
10770+ spin_lock(&grsec_alertgood_lock); \
10771+ \
10772+ if (!grsec_alertgood_wtime || get_seconds() - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME) { \
10773+ grsec_alertgood_wtime = get_seconds(); grsec_alertgood_fyet = 0; \
10774+ if (current->curr_ip) \
10775+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10776+ else \
10777+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10778+ } else if((get_seconds() - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
10779+ grsec_alertgood_fyet++; \
10780+ if (current->curr_ip) \
10781+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10782+ else \
10783+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10784+ } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
10785+ grsec_alertgood_wtime = get_seconds(); grsec_alertgood_fyet++; \
10786+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
10787+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
10788+ } \
10789+ \
10790+ spin_unlock(&grsec_alertgood_lock); \
10791+})
10792+
10793+#define security_alert(normal_msg,args...) \
10794+({ \
10795+ spin_lock(&grsec_alert_lock); \
10796+ \
10797+ if (!grsec_alert_wtime || get_seconds() - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME) { \
10798+ grsec_alert_wtime = get_seconds(); grsec_alert_fyet = 0; \
10799+ if (current->curr_ip) \
10800+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10801+ else \
10802+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10803+ } else if((get_seconds() - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
10804+ grsec_alert_fyet++; \
10805+ if (current->curr_ip) \
10806+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10807+ else \
10808+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10809+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
10810+ grsec_alert_wtime = get_seconds(); grsec_alert_fyet++; \
10811+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
10812+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
10813+ } \
10814+ \
10815+ gr_handle_alertkill(); \
10816+ spin_unlock(&grsec_alert_lock); \
10817+})
10818+
10819+#define security_audit(normal_msg,args...) \
10820+({ \
10821+ spin_lock(&grsec_audit_lock); \
10822+ if (current->curr_ip) \
10823+ printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
10824+ NIPQUAD(current->curr_ip) , ## args); \
10825+ else \
10826+ printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
10827+ spin_unlock(&grsec_audit_lock); \
10828+})
10829+
10830+#define security_learn(normal_msg,args...) \
10831+({ \
10832+ preempt_disable(); \
10833+ gr_add_learn_entry(normal_msg "\n", ## args); \
10834+ preempt_enable(); \
10835+})
10836+
10837+#endif
10838+
10839+#endif
10840diff -uNr linux-2.6.7-rc1.orig/include/linux/grmsg.h linux-2.6.7-rc1/include/linux/grmsg.h
10841--- linux-2.6.7-rc1.orig/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100
10842+++ linux-2.6.7-rc1/include/linux/grmsg.h 2004-05-25 14:33:59.347338160 +0200
806c2378 10843@@ -0,0 +1,107 @@
1db5cd70
PS
10844+#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"
10845+#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"
10846+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
10847+#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
10848+#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
10849+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
10850+#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
10851+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
10852+#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
10853+#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
10854+#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
10855+#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
10856+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
10857+#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"
10858+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
10859+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
10860+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
10861+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
10862+#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
10863+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
10864+#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
10865+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
10866+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
10867+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
10868+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
10869+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
10870+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
10871+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
10872+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
10873+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
10874+#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
10875+#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
10876+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
10877+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
10878+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution for %lu seconds"
10879+#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
10880+#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
10881+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
10882+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
10883+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
10884+#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
10885+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
10886+#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
10887+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
10888+#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
10889+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
10890+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
10891+#define GR_INITF_ACL_MSG "init_variables() failed %s"
10892+#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"
10893+#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
10894+#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
10895+#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
10896+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
10897+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
10898+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
10899+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
10900+#define GR_ENABLE_ACL_MSG "Loaded %s"
10901+#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
10902+#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
10903+#define GR_RELOAD_ACL_MSG "Reloaded %s"
10904+#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
10905+#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
10906+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
10907+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
10908+#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
10909+#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
10910+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
10911+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
10912+#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
10913+#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
10914+#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
10915+#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
10916+#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
10917+#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
10918+#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
10919+#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
10920+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
10921+#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
10922+#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
10923+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
10924+#define GR_TIME_MSG "time set by " DEFAULTSECMSG
10925+#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
10926+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
10927+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
10928+#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG
10929+#define GR_SOCK2_MSG "attempted socket(%d,%.16s,%.16s) by " DEFAULTSECMSG
10930+#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
10931+#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
10932+#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
10933+#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
10934+#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"
10935+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
10936+#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
10937+#define GR_USRCHANGE_ACL_MSG "change to uid %d denied for " DEFAULTSECMSG
10938+#define GR_GRPCHANGE_ACL_MSG "change to gid %d denied for " DEFAULTSECMSG
10939+#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
10940+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
10941+#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
10942+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
10943+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
10944+#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
10945+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
10946+#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
10947+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
10948+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
10949+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
10950+#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
1db5cd70
PS
10951diff -uNr linux-2.6.7-rc1.orig/include/linux/grsecurity.h linux-2.6.7-rc1/include/linux/grsecurity.h
10952--- linux-2.6.7-rc1.orig/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100
10953+++ linux-2.6.7-rc1/include/linux/grsecurity.h 2004-05-25 14:33:59.349337856 +0200
806c2378 10954@@ -0,0 +1,187 @@
1db5cd70
PS
10955+#ifndef GR_SECURITY_H
10956+#define GR_SECURITY_H
10957+#include <linux/fs.h>
10958+#include <linux/binfmts.h>
10959+
10960+extern int gr_check_user_change(int real, int effective, int fs);
10961+extern int gr_check_group_change(int real, int effective, int fs);
10962+
10963+extern void gr_add_to_task_ip_table(struct task_struct *p);
10964+extern void gr_del_task_from_ip_table(struct task_struct *p);
10965+
10966+extern int gr_pid_is_chrooted(const struct task_struct *p);
10967+extern int gr_handle_chroot_nice(void);
10968+extern int gr_handle_chroot_sysctl(const int op);
10969+extern int gr_handle_chroot_capset(const struct task_struct *target);
10970+extern int gr_handle_chroot_setpriority(struct task_struct *p,
10971+ const int niceval);
10972+extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
10973+extern int gr_handle_chroot_chroot(const struct dentry *dentry,
10974+ const struct vfsmount *mnt);
10975+extern void gr_handle_chroot_caps(struct task_struct *task);
10976+extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
10977+extern int gr_handle_chroot_chmod(const struct dentry *dentry,
10978+ const struct vfsmount *mnt, const int mode);
10979+extern int gr_handle_chroot_mknod(const struct dentry *dentry,
10980+ const struct vfsmount *mnt, const int mode);
10981+extern int gr_handle_chroot_mount(const struct dentry *dentry,
10982+ const struct vfsmount *mnt,
10983+ const char *dev_name);
10984+extern int gr_handle_chroot_pivot(void);
10985+extern int gr_handle_chroot_unix(const pid_t pid);
10986+
10987+extern int gr_handle_rawio(const struct inode *inode);
10988+extern int gr_handle_nproc(void);
10989+
10990+extern void gr_handle_ioperm(void);
10991+extern void gr_handle_iopl(void);
10992+
10993+extern int gr_tpe_allow(const struct file *file);
10994+
10995+extern int gr_random_pid(void);
10996+
10997+extern void gr_log_forkfail(const int retval);
10998+extern void gr_log_timechange(void);
10999+extern void gr_log_signal(const int sig, const struct task_struct *t);
11000+extern void gr_log_chdir(const struct dentry *dentry,
11001+ const struct vfsmount *mnt);
11002+extern void gr_log_chroot_exec(const struct dentry *dentry,
11003+ const struct vfsmount *mnt);
11004+extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
11005+extern void gr_log_remount(const char *devname, const int retval);
11006+extern void gr_log_unmount(const char *devname, const int retval);
11007+extern void gr_log_mount(const char *from, const char *to, const int retval);
11008+extern void gr_log_msgget(const int ret, const int msgflg);
11009+extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
11010+extern void gr_log_semget(const int err, const int semflg);
11011+extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
11012+extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
11013+extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
1db5cd70
PS
11014+
11015+extern int gr_handle_follow_link(const struct inode *parent,
11016+ const struct inode *inode,
11017+ const struct dentry *dentry,
11018+ const struct vfsmount *mnt);
11019+extern int gr_handle_fifo(const struct dentry *dentry,
11020+ const struct vfsmount *mnt,
11021+ const struct dentry *dir, const int flag,
11022+ const int acc_mode);
11023+extern int gr_handle_hardlink(const struct dentry *dentry,
11024+ const struct vfsmount *mnt,
11025+ struct inode *inode,
11026+ const int mode, const char *to);
11027+
11028+extern int gr_task_is_capable(struct task_struct *task, const int cap);
11029+extern int gr_is_capable_nolog(const int cap);
11030+extern void gr_learn_resource(const struct task_struct *task, const int limit,
11031+ const unsigned long wanted, const int gt);
11032+extern void gr_copy_label(struct task_struct *tsk);
11033+extern void gr_handle_crash(struct task_struct *task, const int sig);
11034+extern int gr_handle_signal(const struct task_struct *p, const int sig);
11035+extern int gr_check_crash_uid(const uid_t uid);
11036+extern int gr_check_protected_task(const struct task_struct *task);
11037+extern int gr_acl_handle_mmap(const struct file *file,
11038+ const unsigned long prot);
11039+extern int gr_acl_handle_mprotect(const struct file *file,
11040+ const unsigned long prot);
11041+extern int gr_check_hidden_task(const struct task_struct *tsk);
11042+extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
11043+ const struct vfsmount *mnt);
11044+extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
11045+ const struct vfsmount *mnt);
11046+extern __u32 gr_acl_handle_access(const struct dentry *dentry,
11047+ const struct vfsmount *mnt, const int fmode);
11048+extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
11049+ const struct vfsmount *mnt, mode_t mode);
11050+extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
11051+ const struct vfsmount *mnt, mode_t mode);
11052+extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
11053+ const struct vfsmount *mnt);
11054+extern int gr_handle_ptrace_exec(const struct dentry *dentry,
11055+ const struct vfsmount *mnt);
11056+extern int gr_handle_ptrace(struct task_struct *task, const long request);
11057+extern int gr_handle_proc_ptrace(struct task_struct *task);
11058+extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
11059+extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
11060+ const struct vfsmount *mnt);
11061+extern int gr_check_crash_exec(const struct file *filp);
11062+extern int gr_acl_is_enabled(void);
11063+extern void gr_set_kernel_label(struct task_struct *task);
11064+extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
11065+ const gid_t gid);
11066+extern void gr_set_proc_label(const struct dentry *dentry,
11067+ const struct vfsmount *mnt);
11068+extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
11069+ const struct vfsmount *mnt);
11070+extern __u32 gr_acl_handle_open(const struct dentry *dentry,
11071+ const struct vfsmount *mnt, const int fmode);
11072+extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
11073+ const struct dentry *p_dentry,
11074+ const struct vfsmount *p_mnt, const int fmode,
11075+ const int imode);
11076+extern void gr_handle_create(const struct dentry *dentry,
11077+ const struct vfsmount *mnt);
11078+extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
11079+ const struct dentry *parent_dentry,
11080+ const struct vfsmount *parent_mnt,
11081+ const int mode);
11082+extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
11083+ const struct dentry *parent_dentry,
11084+ const struct vfsmount *parent_mnt);
11085+extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
11086+ const struct vfsmount *mnt);
11087+extern void gr_handle_delete(const ino_t ino, const dev_t dev);
11088+extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
11089+ const struct vfsmount *mnt);
11090+extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
11091+ const struct dentry *parent_dentry,
11092+ const struct vfsmount *parent_mnt,
11093+ const char *from);
11094+extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
11095+ const struct dentry *parent_dentry,
11096+ const struct vfsmount *parent_mnt,
11097+ const struct dentry *old_dentry,
11098+ const struct vfsmount *old_mnt, const char *to);
11099+extern int gr_acl_handle_rename(struct dentry *new_dentry,
11100+ struct dentry *parent_dentry,
11101+ const struct vfsmount *parent_mnt,
11102+ struct dentry *old_dentry,
11103+ struct inode *old_parent_inode,
11104+ struct vfsmount *old_mnt, const char *newname);
11105+extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
11106+ struct dentry *old_dentry,
11107+ struct dentry *new_dentry,
11108+ struct vfsmount *mnt, const __u8 replace);
11109+extern __u32 gr_check_link(const struct dentry *new_dentry,
11110+ const struct dentry *parent_dentry,
11111+ const struct vfsmount *parent_mnt,
11112+ const struct dentry *old_dentry,
11113+ const struct vfsmount *old_mnt);
11114+extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
11115+ const struct vfsmount *mnt, const ino_t ino);
11116+extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
11117+ const struct vfsmount *mnt);
11118+extern void gr_acl_handle_exit(void);
11119+extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
11120+extern int gr_acl_handle_procpidmem(const struct task_struct *task);
11121+extern __u32 gr_cap_rtnetlink(void);
11122+
11123+#ifdef CONFIG_GRKERNSEC
11124+extern void gr_handle_mem_write(void);
11125+extern void gr_handle_kmem_write(void);
11126+extern void gr_handle_open_port(void);
11127+extern int gr_handle_mem_mmap(const unsigned long offset,
11128+ struct vm_area_struct *vma);
11129+
11130+extern __u16 ip_randomid(void);
11131+extern __u32 ip_randomisn(void);
11132+extern unsigned long get_random_long(void);
11133+
11134+extern int grsec_enable_dmesg;
11135+extern int grsec_enable_randid;
11136+extern int grsec_enable_randisn;
11137+extern int grsec_enable_randsrc;
11138+extern int grsec_enable_randrpc;
11139+#endif
11140+
11141+#endif
1db5cd70
PS
11142diff -uNr linux-2.6.7-rc1.orig/include/linux/proc_fs.h linux-2.6.7-rc1/include/linux/proc_fs.h
11143--- linux-2.6.7-rc1.orig/include/linux/proc_fs.h 2004-05-23 07:55:03.000000000 +0200
11144+++ linux-2.6.7-rc1/include/linux/proc_fs.h 2004-05-25 14:33:59.376333752 +0200
11145@@ -221,7 +221,7 @@
11146
11147 #endif /* CONFIG_PROC_FS */
11148
11149-#if !defined(CONFIG_PROC_FS)
11150+#if !defined(CONFIG_PROC_FS) || !defined(CONFIG_PROC_KCORE)
11151 static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
11152 {
11153 }
1db5cd70 11154diff -uNr linux-2.6.7-rc1.orig/include/linux/sched.h linux-2.6.7-rc1/include/linux/sched.h
2359ff29
PS
11155--- linux-2.6.7-rc2/include/linux/sched.h.orig 2004-06-02 23:31:55.729266024 +0200
11156+++ linux-2.6.7-rc2/include/linux/sched.h 2004-06-02 23:34:05.803491736 +0200
1db5cd70
PS
11157@@ -31,6 +31,7 @@
11158 #include <linux/percpu.h>
11159
11160 struct exec_domain;
11161+struct linux_binprm;
dd62ee14 11162
11163 /*
11164 * cloning flags:
2359ff29 11165@@ -518,6 +519,21 @@
1db5cd70
PS
11166 struct mempolicy *mempolicy;
11167 short il_next; /* could be shared with used_math */
11168 #endif
11169+#ifdef CONFIG_GRKERNSEC
11170+ /* grsecurity */
11171+ struct acl_subject_label *acl;
11172+ struct acl_role_label *role;
11173+ struct file *exec_file;
11174+ u32 curr_ip;
11175+ u32 gr_saddr;
11176+ u32 gr_daddr;
11177+ u16 gr_sport;
11178+ u16 gr_dport;
11179+ u16 acl_role_id;
11180+ u8 acl_sp_role:1;
11181+ u8 used_accept:1;
11182+ u8 is_writable:1;
11183+#endif
11184 };
11185
11186 static inline pid_t process_group(struct task_struct *tsk)
2359ff29 11187@@ -816,14 +832,29 @@
1db5cd70
PS
11188 : on_sig_stack(sp) ? SS_ONSTACK : 0);
11189 }
11190
11191+extern int gr_task_is_capable(struct task_struct *task, const int cap);
11192+extern int gr_is_capable_nolog(const int cap);
11193
11194 #ifdef CONFIG_SECURITY
11195 /* code is in security.c */
11196 extern int capable(int cap);
11197+static inline int capable_nolog(int cap)
11198+{
11199+ return capable(cap);
11200+}
11201 #else
11202 static inline int capable(int cap)
11203 {
11204- if (cap_raised(current->cap_effective, cap)) {
11205+ if (cap_raised(current->cap_effective, cap) && gr_task_is_capable(current, cap)) {
11206+ current->flags |= PF_SUPERPRIV;
11207+ return 1;
11208+ }
11209+ return 0;
11210+}
11211+
11212+static inline int capable_nolog(int cap)
11213+{
11214+ if (cap_raised(current->cap_effective, cap) && gr_is_capable_nolog(cap)) {
11215 current->flags |= PF_SUPERPRIV;
11216 return 1;
11217 }
11218diff -uNr linux-2.6.7-rc1.orig/include/linux/shm.h linux-2.6.7-rc1/include/linux/shm.h
11219--- linux-2.6.7-rc1.orig/include/linux/shm.h 2004-05-23 07:54:29.000000000 +0200
11220+++ linux-2.6.7-rc1/include/linux/shm.h 2004-05-25 14:33:59.412328280 +0200
11221@@ -84,6 +84,10 @@
11222 time_t shm_ctim;
11223 pid_t shm_cprid;
11224 pid_t shm_lprid;
11225+#ifdef CONFIG_GRKERNSEC
11226+ time_t shm_createtime;
11227+ pid_t shm_lapid;
11228+#endif
11229 };
11230
11231 /* shm_mode upper byte flags */
11232diff -uNr linux-2.6.7-rc1.orig/include/linux/sysctl.h linux-2.6.7-rc1/include/linux/sysctl.h
11233--- linux-2.6.7-rc1.orig/include/linux/sysctl.h 2004-05-25 14:25:39.000000000 +0200
11234+++ linux-2.6.7-rc1/include/linux/sysctl.h 2004-05-25 14:33:59.418327368 +0200
11235@@ -133,6 +133,7 @@
11236 KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */
11237 KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
11238 KERN_HZ_TIMER=65, /* int: hz timer on or off */
11239+ KERN_GRSECURITY=68, /* grsecurity */
11240 };
11241
11242
11243diff -uNr linux-2.6.7-rc1.orig/include/net/ip.h linux-2.6.7-rc1/include/net/ip.h
11244--- linux-2.6.7-rc1.orig/include/net/ip.h 2004-05-25 14:25:40.000000000 +0200
11245+++ linux-2.6.7-rc1/include/net/ip.h 2004-05-25 14:33:59.430325544 +0200
78638fc5 11246@@ -34,6 +34,11 @@
1db5cd70 11247 #include <net/arp.h>
78638fc5 11248 #include <net/snmp.h>
1db5cd70
PS
11249
11250+#ifdef CONFIG_GRKERNSEC_RANDID
11251+extern int grsec_enable_randid;
11252+extern __u16 ip_randomid(void);
11253+#endif
11254+
78638fc5
AM
11255 struct sock;
11256
11257 struct inet_skb_parm
1db5cd70
PS
11258@@ -191,6 +196,13 @@
11259
11260 static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
11261 {
11262+
11263+#ifdef CONFIG_GRKERNSEC_RANDID
11264+ if (grsec_enable_randid)
11265+ iph->id = htons(ip_randomid());
11266+ else
11267+#endif
11268+
11269 if (iph->frag_off & htons(IP_DF)) {
11270 /* This is only to work around buggy Windows95/2000
11271 * VJ compression implementations. If the ID field
1db5cd70
PS
11272diff -uNr linux-2.6.7-rc1.orig/init/Kconfig linux-2.6.7-rc1/init/Kconfig
11273--- linux-2.6.7-rc1.orig/init/Kconfig 2004-05-23 07:54:30.000000000 +0200
11274+++ linux-2.6.7-rc1/init/Kconfig 2004-05-25 14:33:59.434324936 +0200
11275@@ -230,6 +230,7 @@
11276 config KALLSYMS
11277 bool "Load all symbols for debugging/kksymoops" if EMBEDDED
11278 default y
11279+ depends on !GRKERNSEC_HIDESYM
11280 help
11281 Say Y here to let the kernel print out symbolic crash information and
11282 symbolic stack backtraces. This increases the size of the kernel
11283diff -uNr linux-2.6.7-rc1.orig/init/main.c linux-2.6.7-rc1/init/main.c
11284--- linux-2.6.7-rc1.orig/init/main.c 2004-05-23 07:53:46.000000000 +0200
11285+++ linux-2.6.7-rc1/init/main.c 2004-05-25 14:33:59.440324024 +0200
11286@@ -91,6 +91,7 @@
11287 extern void populate_rootfs(void);
11288 extern void driver_init(void);
11289 extern void prepare_namespace(void);
11290+extern void grsecurity_init(void);
11291
11292 #ifdef CONFIG_TC
11293 extern void tc_init(void);
11294@@ -638,6 +639,7 @@
11295 else
11296 prepare_namespace();
11297
11298+ grsecurity_init();
11299 /*
11300 * Ok, we have completed the initial bootup, and
11301 * we're essentially up and running. Get rid of the
11302diff -uNr linux-2.6.7-rc1.orig/ipc/msg.c linux-2.6.7-rc1/ipc/msg.c
11303--- linux-2.6.7-rc1.orig/ipc/msg.c 2004-05-23 07:53:30.000000000 +0200
11304+++ linux-2.6.7-rc1/ipc/msg.c 2004-05-25 14:33:59.445323264 +0200
11305@@ -24,6 +24,7 @@
11306 #include <linux/list.h>
11307 #include <linux/security.h>
11308 #include <linux/sched.h>
11309+#include <linux/grsecurity.h>
11310 #include <asm/current.h>
11311 #include <asm/uaccess.h>
11312 #include "util.h"
11313@@ -226,6 +227,9 @@
11314 msg_unlock(msq);
11315 }
11316 up(&msg_ids.sem);
11317+
11318+ gr_log_msgget(ret, msgflg);
11319+
11320 return ret;
11321 }
11322
11323@@ -475,6 +479,8 @@
11324 break;
11325 }
11326 case IPC_RMID:
11327+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
11328+
11329 freeque (msq, msqid);
11330 break;
11331 }
11332diff -uNr linux-2.6.7-rc1.orig/ipc/sem.c linux-2.6.7-rc1/ipc/sem.c
11333--- linux-2.6.7-rc1.orig/ipc/sem.c 2004-05-23 07:53:57.000000000 +0200
11334+++ linux-2.6.7-rc1/ipc/sem.c 2004-05-25 14:33:59.448322808 +0200
11335@@ -71,6 +71,7 @@
11336 #include <linux/time.h>
11337 #include <linux/smp_lock.h>
11338 #include <linux/security.h>
11339+#include <linux/grsecurity.h>
11340 #include <asm/uaccess.h>
11341 #include "util.h"
11342
11343@@ -238,6 +239,9 @@
11344 }
11345
11346 up(&sem_ids.sem);
11347+
11348+ gr_log_semget(err, semflg);
11349+
11350 return err;
11351 }
11352
11353@@ -804,6 +808,8 @@
11354
11355 switch(cmd){
11356 case IPC_RMID:
11357+ gr_log_semrm(ipcp->uid, ipcp->cuid);
11358+
11359 freeary(sma, semid);
11360 err = 0;
11361 break;
11362diff -uNr linux-2.6.7-rc1.orig/ipc/shm.c linux-2.6.7-rc1/ipc/shm.c
11363--- linux-2.6.7-rc1.orig/ipc/shm.c 2004-05-23 07:54:17.000000000 +0200
11364+++ linux-2.6.7-rc1/ipc/shm.c 2004-05-25 14:33:59.460320984 +0200
11365@@ -26,6 +26,7 @@
11366 #include <linux/proc_fs.h>
11367 #include <linux/shmem_fs.h>
11368 #include <linux/security.h>
11369+#include <linux/grsecurity.h>
11370 #include <asm/uaccess.h>
11371
11372 #include "util.h"
11373@@ -50,6 +51,14 @@
11374 static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
11375 #endif
11376
11377+#ifdef CONFIG_GRKERNSEC
11378+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
11379+ const time_t shm_createtime, const uid_t cuid,
11380+ const int shmid);
11381+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
11382+ const time_t shm_createtime);
11383+#endif
11384+
11385 size_t shm_ctlmax = SHMMAX;
11386 size_t shm_ctlall = SHMALL;
11387 int shm_ctlmni = SHMMNI;
11388@@ -217,6 +226,9 @@
11389 shp->shm_lprid = 0;
11390 shp->shm_atim = shp->shm_dtim = 0;
11391 shp->shm_ctim = get_seconds();
11392+#ifdef CONFIG_GRKERNSEC
11393+ shp->shm_createtime = get_seconds();
11394+#endif
11395 shp->shm_segsz = size;
11396 shp->shm_nattch = 0;
11397 shp->id = shm_buildid(id,shp->shm_perm.seq);
11398@@ -271,6 +283,8 @@
11399 }
11400 up(&shm_ids.sem);
11401
11402+ gr_log_shmget(err, shmflg, size);
11403+
11404 return err;
11405 }
11406
11407@@ -569,6 +583,8 @@
11408 if (err)
11409 goto out_unlock_up;
11410
11411+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
11412+
11413 if (shp->shm_nattch){
11414 shp->shm_flags |= SHM_DEST;
11415 /* Do not find it any more */
11416@@ -707,9 +723,27 @@
11417 return err;
11418 }
11419
11420+#ifdef CONFIG_GRKERNSEC
11421+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
11422+ shp->shm_perm.cuid, shmid)) {
11423+ shm_unlock(shp);
11424+ return -EACCES;
11425+ }
11426+
11427+ if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
11428+ shm_unlock(shp);
11429+ return -EACCES;
11430+ }
11431+#endif
11432+
11433 file = shp->shm_file;
11434 size = i_size_read(file->f_dentry->d_inode);
11435 shp->shm_nattch++;
11436+
11437+#ifdef CONFIG_GRKERNSEC
11438+ shp->shm_lapid = current->pid;
11439+#endif
11440+
11441 shm_unlock(shp);
11442
11443 down_write(&current->mm->mmap_sem);
11444diff -uNr linux-2.6.7-rc1.orig/kernel/capability.c linux-2.6.7-rc1/kernel/capability.c
11445--- linux-2.6.7-rc1.orig/kernel/capability.c 2004-05-23 07:54:22.000000000 +0200
11446+++ linux-2.6.7-rc1/kernel/capability.c 2004-05-25 14:33:59.462320680 +0200
11447@@ -10,6 +10,7 @@
11448 #include <linux/mm.h>
11449 #include <linux/module.h>
11450 #include <linux/security.h>
11451+#include <linux/grsecurity.h>
11452 #include <asm/uaccess.h>
11453
11454 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
11455@@ -168,6 +169,11 @@
11456 } else
11457 target = current;
11458
11459+ if (gr_handle_chroot_capset(target)) {
11460+ ret = -ESRCH;
11461+ goto out;
11462+ }
11463+
11464 ret = -EPERM;
11465
11466 if (security_capset_check(target, &effective, &inheritable, &permitted))
11467diff -uNr linux-2.6.7-rc1.orig/kernel/configs.c linux-2.6.7-rc1/kernel/configs.c
11468--- linux-2.6.7-rc1.orig/kernel/configs.c 2004-05-23 07:53:57.000000000 +0200
11469+++ linux-2.6.7-rc1/kernel/configs.c 2004-05-25 14:33:59.465320224 +0200
11470@@ -78,8 +78,16 @@
11471 struct proc_dir_entry *entry;
11472
11473 /* create the current config file */
11474+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11475+#ifdef CONFIG_GRKERNSEC_PROC_USER
11476+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
11477+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11478+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
11479+#endif
11480+#else
11481 entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
11482 &proc_root);
11483+#endif
11484 if (!entry)
11485 return -ENOMEM;
11486
11487diff -uNr linux-2.6.7-rc1.orig/kernel/exit.c linux-2.6.7-rc1/kernel/exit.c
11488--- linux-2.6.7-rc1.orig/kernel/exit.c 2004-05-23 07:54:43.000000000 +0200
11489+++ linux-2.6.7-rc1/kernel/exit.c 2004-05-25 14:33:59.468319768 +0200
11490@@ -23,6 +23,7 @@
11491 #include <linux/mount.h>
11492 #include <linux/proc_fs.h>
11493 #include <linux/mempolicy.h>
11494+#include <linux/grsecurity.h>
11495
11496 #include <asm/uaccess.h>
11497 #include <asm/unistd.h>
11498@@ -233,6 +234,13 @@
11499 {
11500 write_lock_irq(&tasklist_lock);
11501
11502+#ifdef CONFIG_GRKERNSEC
11503+ if (current->exec_file) {
11504+ fput(current->exec_file);
11505+ current->exec_file = NULL;
11506+ }
11507+#endif
11508+
11509 ptrace_unlink(current);
11510 /* Reparent to init */
11511 REMOVE_LINKS(current);
11512@@ -240,6 +248,8 @@
11513 current->real_parent = child_reaper;
11514 SET_LINKS(current);
11515
11516+ gr_set_kernel_label(current);
11517+
11518 /* Set the exit signal to SIGCHLD so we signal init on exit */
11519 current->exit_signal = SIGCHLD;
11520
11521@@ -334,6 +344,15 @@
11522 vsnprintf(current->comm, sizeof(current->comm), name, args);
11523 va_end(args);
11524
11525+#ifdef CONFIG_GRKERNSEC
11526+ if (current->exec_file) {
11527+ fput(current->exec_file);
11528+ current->exec_file = NULL;
11529+ }
11530+#endif
11531+
11532+ gr_set_kernel_label(current);
11533+
11534 /*
11535 * If we were started as result of loading a module, close all of the
11536 * user space pages. We don't need them, and if we didn't close them
11537@@ -785,6 +804,11 @@
11538 }
11539
11540 acct_process(code);
11541+
11542+ gr_acl_handle_psacct(tsk, code);
11543+ gr_acl_handle_exit();
11544+ gr_del_task_from_ip_table(tsk);
11545+
11546 __exit_mm(tsk);
11547
11548 exit_sem(tsk);
11549diff -uNr linux-2.6.7-rc1.orig/kernel/fork.c linux-2.6.7-rc1/kernel/fork.c
11550--- linux-2.6.7-rc1.orig/kernel/fork.c 2004-05-25 14:25:38.000000000 +0200
11551+++ linux-2.6.7-rc1/kernel/fork.c 2004-05-25 14:33:59.472319160 +0200
11552@@ -36,6 +36,7 @@
11553 #include <linux/mount.h>
11554 #include <linux/audit.h>
11555 #include <linux/rmap.h>
11556+#include <linux/grsecurity.h>
11557
11558 #include <asm/pgtable.h>
11559 #include <asm/pgalloc.h>
11560@@ -279,7 +280,7 @@
11561 mm->locked_vm = 0;
11562 mm->mmap = NULL;
11563 mm->mmap_cache = NULL;
11564- mm->free_area_cache = TASK_UNMAPPED_BASE;
11565+ mm->free_area_cache = oldmm->free_area_cache;
11566 mm->map_count = 0;
11567 mm->rss = 0;
11568 cpus_clear(mm->cpu_vm_mask);
11569@@ -901,6 +902,9 @@
11570 goto fork_out;
11571
11572 retval = -EAGAIN;
11573+
11574+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
11575+
11576 if (atomic_read(&p->user->processes) >=
11577 p->rlim[RLIMIT_NPROC].rlim_cur) {
11578 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
11579@@ -997,6 +1001,8 @@
11580 if (retval)
11581 goto bad_fork_cleanup_namespace;
11582
11583+ gr_copy_label(p);
11584+
11585 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
11586 /*
11587 * Clear TID on mm_release()?
11588@@ -1138,6 +1144,9 @@
11589 free_uid(p->user);
11590 bad_fork_free:
11591 free_task(p);
11592+
11593+ gr_log_forkfail(retval);
11594+
11595 goto fork_out;
11596 }
11597
11598diff -uNr linux-2.6.7-rc1.orig/kernel/kallsyms.c linux-2.6.7-rc1/kernel/kallsyms.c
11599--- linux-2.6.7-rc1.orig/kernel/kallsyms.c 2004-05-23 07:55:01.000000000 +0200
11600+++ linux-2.6.7-rc1/kernel/kallsyms.c 2004-05-25 14:33:59.474318856 +0200
11601@@ -313,7 +313,15 @@
11602 {
11603 struct proc_dir_entry *entry;
11604
11605+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11606+#ifdef CONFIG_GRKERNSEC_PROC_USER
11607+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
11608+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11609+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
11610+#endif
11611+#else
11612 entry = create_proc_entry("kallsyms", 0444, NULL);
11613+#endif
11614 if (entry)
11615 entry->proc_fops = &kallsyms_operations;
11616 return 0;
11617diff -uNr linux-2.6.7-rc1.orig/kernel/pid.c linux-2.6.7-rc1/kernel/pid.c
11618--- linux-2.6.7-rc1.orig/kernel/pid.c 2004-05-23 07:54:20.000000000 +0200
11619+++ linux-2.6.7-rc1/kernel/pid.c 2004-05-25 14:33:59.477318400 +0200
11620@@ -25,6 +25,7 @@
11621 #include <linux/init.h>
11622 #include <linux/bootmem.h>
11623 #include <linux/hash.h>
11624+#include <linux/grsecurity.h>
11625
11626 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
11627 static struct list_head *pid_hash[PIDTYPE_MAX];
11628@@ -99,10 +100,12 @@
11629
11630 int alloc_pidmap(void)
11631 {
11632- int pid, offset, max_steps = PIDMAP_ENTRIES + 1;
11633+ int pid = 0, offset, max_steps = PIDMAP_ENTRIES + 1;
11634 pidmap_t *map;
11635
11636- pid = last_pid + 1;
11637+ pid = gr_random_pid();
11638+ if (!pid)
11639+ pid = last_pid + 1;
11640 if (pid >= pid_max)
11641 pid = RESERVED_PIDS;
11642
11643@@ -225,10 +228,16 @@
11644 task_t *find_task_by_pid(int nr)
11645 {
11646 struct pid *pid = find_pid(PIDTYPE_PID, nr);
11647+ struct task_struct *task = NULL;
11648
11649 if (!pid)
11650 return NULL;
11651- return pid_task(pid->task_list.next, PIDTYPE_PID);
11652+ task = pid_task(pid->task_list.next, PIDTYPE_PID);
11653+
11654+ if (gr_pid_is_chrooted(task))
11655+ return NULL;
11656+
11657+ return task;
11658 }
11659
11660 EXPORT_SYMBOL(find_task_by_pid);
11661diff -uNr linux-2.6.7-rc1.orig/kernel/printk.c linux-2.6.7-rc1/kernel/printk.c
11662--- linux-2.6.7-rc1.orig/kernel/printk.c 2004-05-23 07:55:02.000000000 +0200
11663+++ linux-2.6.7-rc1/kernel/printk.c 2004-05-25 14:33:59.481317792 +0200
11664@@ -30,6 +30,7 @@
11665 #include <linux/smp.h>
11666 #include <linux/security.h>
11667 #include <linux/bootmem.h>
11668+#include <linux/grsecurity.h>
11669
11670 #include <asm/uaccess.h>
11671
11672@@ -249,6 +250,11 @@
11673 char c;
11674 int error = 0;
11675
11676+#ifdef CONFIG_GRKERNSEC_DMESG
11677+ if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
11678+ return -EPERM;
11679+#endif
11680+
11681 error = security_syslog(type);
11682 if (error)
11683 return error;
11684diff -uNr linux-2.6.7-rc1.orig/kernel/resource.c linux-2.6.7-rc1/kernel/resource.c
11685--- linux-2.6.7-rc1.orig/kernel/resource.c 2004-05-23 07:54:22.000000000 +0200
11686+++ linux-2.6.7-rc1/kernel/resource.c 2004-05-25 14:33:59.483317488 +0200
11687@@ -134,10 +134,27 @@
11688 {
11689 struct proc_dir_entry *entry;
11690
11691+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11692+#ifdef CONFIG_GRKERNSEC_PROC_USER
11693+ entry = create_proc_entry("ioports", S_IRUSR, NULL);
11694+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11695+ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
11696+#endif
11697+#else
11698 entry = create_proc_entry("ioports", 0, NULL);
11699+#endif
11700 if (entry)
11701 entry->proc_fops = &proc_ioports_operations;
11702+
11703+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11704+#ifdef CONFIG_GRKERNSEC_PROC_USER
11705+ entry = create_proc_entry("iomem", S_IRUSR, NULL);
11706+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11707+ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
11708+#endif
11709+#else
11710 entry = create_proc_entry("iomem", 0, NULL);
11711+#endif
11712 if (entry)
11713 entry->proc_fops = &proc_iomem_operations;
11714 return 0;
11715diff -uNr linux-2.6.7-rc1.orig/kernel/sched.c linux-2.6.7-rc1/kernel/sched.c
11716--- linux-2.6.7-rc1.orig/kernel/sched.c 2004-05-23 07:54:30.000000000 +0200
11717+++ linux-2.6.7-rc1/kernel/sched.c 2004-05-25 14:33:59.504314296 +0200
11718@@ -40,6 +40,7 @@
11719 #include <linux/cpu.h>
11720 #include <linux/percpu.h>
11721 #include <linux/kthread.h>
11722+#include <linux/grsecurity.h>
11723
e228341c
PS
11724 #ifdef CONFIG_NUMA
11725 #define cpu_to_node_mask(cpu) node_to_cpumask(cpu_to_node(cpu))
11726@@ -2159,6 +2160,8 @@
11727 }
11728 #endif
11729
11730+void __sched_text_start(void) {}
11731+
11732 /*
11733 * schedule() is the main scheduler function.
11734 */
11735@@ -2538,6 +2541,8 @@
1db5cd70 11736
e228341c
PS
11737 EXPORT_SYMBOL(sleep_on_timeout);
11738
11739+void __sched_text_end(void) {}
11740+
11741 void set_user_nice(task_t *p, long nice)
11742 {
11743 unsigned long flags;
11744@@ -2611,6 +2616,8 @@
1db5cd70
PS
11745 return -EPERM;
11746 if (increment < -40)
11747 increment = -40;
11748+ if (gr_handle_chroot_nice())
11749+ return -EPERM;
11750 }
11751 if (increment > 40)
11752 increment = 40;
e228341c
PS
11753@@ -3868,8 +3875,6 @@
11754
11755 int in_sched_functions(unsigned long addr)
11756 {
11757- /* Linker adds these: start and end of __sched functions */
11758- extern char __sched_text_start[], __sched_text_end[];
11759 return addr >= (unsigned long)__sched_text_start
11760 && addr < (unsigned long)__sched_text_end;
11761 }
1db5cd70
PS
11762diff -uNr linux-2.6.7-rc1.orig/kernel/signal.c linux-2.6.7-rc1/kernel/signal.c
11763--- linux-2.6.7-rc1.orig/kernel/signal.c 2004-05-23 07:53:57.000000000 +0200
11764+++ linux-2.6.7-rc1/kernel/signal.c 2004-05-25 14:33:59.518312168 +0200
11765@@ -21,6 +21,7 @@
11766 #include <linux/binfmts.h>
11767 #include <linux/security.h>
11768 #include <linux/ptrace.h>
11769+#include <linux/grsecurity.h>
11770 #include <asm/param.h>
11771 #include <asm/uaccess.h>
11772 #include <asm/unistd.h>
11773@@ -770,11 +771,13 @@
11774 (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
11775
11776
11777-static int
11778+int
11779 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
11780 {
11781 int ret = 0;
11782
11783+ gr_log_signal(sig, t);
11784+
11785 if (!irqs_disabled())
11786 BUG();
11787 #ifdef CONFIG_SMP
11788@@ -825,6 +828,8 @@
11789 ret = specific_send_sig_info(sig, info, t);
11790 spin_unlock_irqrestore(&t->sighand->siglock, flags);
11791
11792+ gr_handle_crash(t, sig);
11793+
11794 return ret;
11795 }
11796
dd62ee14 11797@@ -1086,10 +1086,14 @@
1db5cd70 11798
dd62ee14 11799 success = 0;
11800 retval = -ESRCH;
11801- for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
11802- int err = group_send_sig_info(sig, info, p);
11803- success |= !err;
11804- retval = err;
11805+ if (gr_handle_signal(p,sig))
5768ba12 11806+ retval = -EPERM;
dd62ee14 11807+ else {
11808+ for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
11809+ int err = group_send_sig_info(sig, info, p);
11810+ success |= !err;
11811+ retval = err;
11812+ }
1db5cd70 11813 }
dd62ee14 11814 return success ? 0 : retval;
1db5cd70
PS
11815 }
11816@@ -1143,8 +1153,12 @@
11817 read_lock(&tasklist_lock);
11818 p = find_task_by_pid(pid);
11819 error = -ESRCH;
11820- if (p)
11821- error = group_send_sig_info(sig, info, p);
11822+ if (p) {
11823+ if (gr_handle_signal(p, sig))
11824+ error = -EPERM;
11825+ else
11826+ error = group_send_sig_info(sig, info, p);
11827+ }
11828 read_unlock(&tasklist_lock);
11829 return error;
11830 }
11831@@ -1168,10 +1182,14 @@
11832 read_lock(&tasklist_lock);
11833 for_each_process(p) {
11834 if (p->pid > 1 && p->tgid != current->tgid) {
11835- int err = group_send_sig_info(sig, info, p);
11836- ++count;
11837- if (err != -EPERM)
11838- retval = err;
11839+ if (gr_handle_signal(p, sig))
11840+ retval = -EPERM;
11841+ else {
11842+ int err = group_send_sig_info(sig, info, p);
11843+ ++count;
11844+ if (err != -EPERM)
11845+ retval = err;
11846+ }
11847 }
11848 }
11849 read_unlock(&tasklist_lock);
11850diff -uNr linux-2.6.7-rc1.orig/kernel/sys.c linux-2.6.7-rc1/kernel/sys.c
11851--- linux-2.6.7-rc1.orig/kernel/sys.c 2004-05-23 07:53:34.000000000 +0200
11852+++ linux-2.6.7-rc1/kernel/sys.c 2004-05-25 14:33:59.529310496 +0200
11853@@ -23,6 +23,7 @@
11854 #include <linux/security.h>
11855 #include <linux/dcookies.h>
11856 #include <linux/suspend.h>
11857+#include <linux/grsecurity.h>
11858
11859 #include <asm/uaccess.h>
11860 #include <asm/io.h>
11861@@ -293,6 +294,12 @@
11862 error = -EACCES;
11863 goto out;
11864 }
11865+
11866+ if (gr_handle_chroot_setpriority(p, niceval)) {
11867+ error = -ESRCH;
11868+ goto out;
11869+ }
11870+
11871 no_nice = security_task_setnice(p, niceval);
11872 if (no_nice) {
11873 error = no_nice;
11874@@ -597,6 +604,9 @@
11875 if (rgid != (gid_t) -1 ||
11876 (egid != (gid_t) -1 && egid != old_rgid))
11877 current->sgid = new_egid;
11878+
11879+ gr_set_role_label(current, current->uid, new_rgid);
11880+
11881 current->fsgid = new_egid;
11882 current->egid = new_egid;
11883 current->gid = new_rgid;
11884@@ -624,6 +634,9 @@
11885 current->mm->dumpable=0;
11886 wmb();
11887 }
11888+
11889+ gr_set_role_label(current, current->uid, gid);
11890+
11891 current->gid = current->egid = current->sgid = current->fsgid = gid;
11892 }
11893 else if ((gid == current->gid) || (gid == current->sgid))
11894@@ -662,6 +675,9 @@
11895 current->mm->dumpable = 0;
11896 wmb();
11897 }
11898+
11899+ gr_set_role_label(current, new_ruid, current->gid);
11900+
11901 current->uid = new_ruid;
11902 return 0;
11903 }
11904@@ -762,6 +778,9 @@
11905 } else if ((uid != current->uid) && (uid != new_suid))
11906 return -EPERM;
11907
11908+ if (gr_check_crash_uid(uid))
11909+ return -EPERM;
11910+
11911 if (old_euid != uid)
11912 {
11913 current->mm->dumpable = 0;
11914@@ -861,8 +880,10 @@
11915 current->egid = egid;
11916 }
11917 current->fsgid = current->egid;
11918- if (rgid != (gid_t) -1)
11919+ if (rgid != (gid_t) -1) {
11920+ gr_set_role_label(current, current->uid, rgid);
11921 current->gid = rgid;
11922+ }
11923 if (sgid != (gid_t) -1)
11924 current->sgid = sgid;
11925 return 0;
11926diff -uNr linux-2.6.7-rc1.orig/kernel/sysctl.c linux-2.6.7-rc1/kernel/sysctl.c
11927--- linux-2.6.7-rc1.orig/kernel/sysctl.c 2004-05-25 14:25:41.000000000 +0200
11928+++ linux-2.6.7-rc1/kernel/sysctl.c 2004-05-25 14:33:59.538309128 +0200
11929@@ -46,6 +46,14 @@
11930 #endif
11931
11932 #if defined(CONFIG_SYSCTL)
11933+#include <linux/grsecurity.h>
11934+#include <linux/grinternal.h>
11935+
11936+extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
11937+ const void *newval);
11938+extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
11939+ const int op);
11940+extern int gr_handle_chroot_sysctl(const int op);
11941
11942 /* External variables not in a header file. */
11943 extern int panic_timeout;
49166ac6 11944@@ -145,6 +153,7 @@
1db5cd70
PS
11945 #ifdef CONFIG_UNIX98_PTYS
11946 extern ctl_table pty_table[];
11947 #endif
11948+extern ctl_table grsecurity_table[];
1db5cd70
PS
11949
11950 /* /proc declarations: */
11951
49166ac6 11952@@ -639,6 +648,14 @@
1db5cd70
PS
11953 .mode = 0444,
11954 .proc_handler = &proc_dointvec,
11955 },
11956+#ifdef CONFIG_GRKERNSEC_SYSCTL
11957+ {
11958+ .ctl_name = KERN_GRSECURITY,
11959+ .procname = "grsecurity",
11960+ .mode = 0500,
11961+ .child = grsecurity_table,
11962+ },
11963+#endif
11964 { .ctl_name = 0 }
11965 };
11966
49166ac6 11967@@ -1000,6 +1017,10 @@
1db5cd70
PS
11968 static inline int ctl_perm(ctl_table *table, int op)
11969 {
11970 int error;
11971+ if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
11972+ return -EACCES;
11973+ if (gr_handle_chroot_sysctl(op))
11974+ return -EACCES;
11975 error = security_sysctl(table, op);
11976 if (error)
11977 return error;
49166ac6 11978@@ -1036,6 +1057,10 @@
1db5cd70
PS
11979 table = table->child;
11980 goto repeat;
11981 }
11982+
11983+ if (!gr_handle_sysctl(table, oldval, newval))
11984+ return -EACCES;
11985+
11986 error = do_sysctl_strategy(table, name, nlen,
11987 oldval, oldlenp,
11988 newval, newlen, context);
11989diff -uNr linux-2.6.7-rc1.orig/kernel/time.c linux-2.6.7-rc1/kernel/time.c
11990--- linux-2.6.7-rc1.orig/kernel/time.c 2004-05-23 07:53:46.000000000 +0200
11991+++ linux-2.6.7-rc1/kernel/time.c 2004-05-25 14:33:59.550307304 +0200
11992@@ -28,6 +28,7 @@
11993 #include <linux/timex.h>
11994 #include <linux/errno.h>
11995 #include <linux/smp_lock.h>
11996+#include <linux/grsecurity.h>
11997 #include <asm/uaccess.h>
11998 #include <asm/unistd.h>
11999
12000@@ -82,6 +83,9 @@
12001
12002 tv.tv_nsec = 0;
12003 do_settimeofday(&tv);
12004+
12005+ gr_log_timechange();
12006+
12007 return 0;
12008 }
12009
12010@@ -183,6 +187,8 @@
12011 return -EFAULT;
12012 }
12013
12014+ gr_log_timechange();
12015+
12016 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
12017 }
12018
12019diff -uNr linux-2.6.7-rc1.orig/kernel/timer.c linux-2.6.7-rc1/kernel/timer.c
12020--- linux-2.6.7-rc1.orig/kernel/timer.c 2004-05-23 07:54:42.000000000 +0200
12021+++ linux-2.6.7-rc1/kernel/timer.c 2004-05-25 14:33:59.555306544 +0200
12022@@ -31,6 +31,7 @@
12023 #include <linux/time.h>
12024 #include <linux/jiffies.h>
12025 #include <linux/cpu.h>
12026+#include <linux/grsecurity.h>
12027
12028 #include <asm/uaccess.h>
12029 #include <asm/unistd.h>
12030@@ -792,6 +793,9 @@
12031
12032 psecs = (p->utime += user);
12033 psecs += (p->stime += system);
12034+
12035+ gr_learn_resource(p, RLIMIT_CPU, psecs / HZ, 1);
12036+
12037 if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
12038 /* Send SIGXCPU every second.. */
12039 if (!(psecs % HZ))
12040diff -uNr linux-2.6.7-rc1.orig/mm/filemap.c linux-2.6.7-rc1/mm/filemap.c
12041--- linux-2.6.7-rc1.orig/mm/filemap.c 2004-05-23 07:53:57.000000000 +0200
12042+++ linux-2.6.7-rc1/mm/filemap.c 2004-05-25 14:33:59.561305632 +0200
12043@@ -27,6 +27,8 @@
12044 #include <linux/pagevec.h>
12045 #include <linux/blkdev.h>
12046 #include <linux/security.h>
12047+#include <linux/grsecurity.h>
12048+
12049 /*
12050 * This is needed for the following functions:
12051 * - try_to_release_page
12052@@ -1721,6 +1723,7 @@
12053 *pos = i_size_read(inode);
12054
12055 if (limit != RLIM_INFINITY) {
12056+ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
12057 if (*pos >= limit) {
12058 send_sig(SIGXFSZ, current, 0);
12059 return -EFBIG;
12060diff -uNr linux-2.6.7-rc1.orig/mm/memory.c linux-2.6.7-rc1/mm/memory.c
12061--- linux-2.6.7-rc1.orig/mm/memory.c 2004-05-23 07:54:09.000000000 +0200
12062+++ linux-2.6.7-rc1/mm/memory.c 2004-05-25 14:33:59.568304568 +0200
12063@@ -46,6 +46,7 @@
12064 #include <linux/rmap.h>
12065 #include <linux/module.h>
12066 #include <linux/init.h>
12067+#include <linux/grsecurity.h>
12068
12069 #include <asm/pgalloc.h>
12070 #include <asm/uaccess.h>
12071@@ -1220,6 +1221,7 @@
12072
12073 do_expand:
12074 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
12075+ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
12076 if (limit != RLIM_INFINITY && offset > limit)
12077 goto out_sig;
12078 if (offset > inode->i_sb->s_maxbytes)
12079diff -uNr linux-2.6.7-rc1.orig/mm/mlock.c linux-2.6.7-rc1/mm/mlock.c
12080--- linux-2.6.7-rc1.orig/mm/mlock.c 2004-05-23 07:53:32.000000000 +0200
12081+++ linux-2.6.7-rc1/mm/mlock.c 2004-05-25 14:33:59.574303656 +0200
49166ac6 12082@@ -8,6 +8,7 @@
1db5cd70
PS
12083 #include <linux/mman.h>
12084 #include <linux/mm.h>
1db5cd70 12085
49166ac6 12086+#include <linux/grsecurity.h>
1db5cd70
PS
12087
12088 static int mlock_fixup(struct vm_area_struct * vma,
12089 unsigned long start, unsigned long end, unsigned int newflags)
49166ac6 12090@@ -68,6 +69,9 @@
1db5cd70
PS
12091 return -EINVAL;
12092 if (end == start)
12093 return 0;
1db5cd70
PS
12094+ if (end > TASK_SIZE)
12095+ return -EINVAL;
12096+
12097 vma = find_vma(current->mm, start);
12098 if (!vma || vma->vm_start > start)
12099 return -ENOMEM;
49166ac6 12100@@ -118,6 +122,7 @@
1db5cd70
PS
12101 lock_limit >>= PAGE_SHIFT;
12102
12103 /* check against resource limits */
12104+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
12105 if (locked <= lock_limit)
12106 error = do_mlock(start, len, 1);
12107 up_write(&current->mm->mmap_sem);
49166ac6 12108@@ -154,6 +159,9 @@
1db5cd70
PS
12109 for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
12110 unsigned int newflags;
12111
1db5cd70
PS
12112+ if (vma->vm_end > TASK_SIZE)
12113+ break;
12114+
12115 newflags = vma->vm_flags | VM_LOCKED;
12116 if (!(flags & MCL_CURRENT))
12117 newflags &= ~VM_LOCKED;
49166ac6 12118@@ -177,6 +185,7 @@
1db5cd70
PS
12119 lock_limit >>= PAGE_SHIFT;
12120
12121 ret = -ENOMEM;
12122+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
12123 if (current->mm->total_vm <= lock_limit)
12124 ret = do_mlockall(flags);
12125 out:
12126diff -uNr linux-2.6.7-rc1.orig/mm/mmap.c linux-2.6.7-rc1/mm/mmap.c
2359ff29
PS
12127--- linux-2.6.7-rc2/mm/mmap.c.orig 2004-06-02 23:45:34.377812528 +0200
12128+++ linux-2.6.7-rc2/mm/mmap.c 2004-06-02 23:54:52.740928432 +0200
1db5cd70
PS
12129@@ -23,6 +23,7 @@
12130 #include <linux/mount.h>
12131 #include <linux/mempolicy.h>
12132 #include <linux/rmap.h>
12133+#include <linux/grsecurity.h>
12134
12135 #include <asm/uaccess.h>
12136 #include <asm/pgalloc.h>
12137@@ -137,6 +138,7 @@
12138
12139 /* Check against rlimit.. */
12140 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
12141+ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
12142 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
12143 goto out;
12144
2359ff29 12145@@ -781,6 +786,7 @@
1db5cd70
PS
12146 if (vm_flags & VM_LOCKED) {
12147 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
12148 locked += len;
12149+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
12150 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
12151 return -EAGAIN;
12152 }
2359ff29 12153@@ -839,6 +845,9 @@
1db5cd70
PS
12154 if (error)
12155 return error;
12156
12157+ if (!gr_acl_handle_mmap(file, prot))
12158+ return -EACCES;
12159+
12160 /* Clear old maps */
12161 error = -ENOMEM;
12162 munmap_back:
2359ff29 12163@@ -850,6 +859,7 @@
1db5cd70
PS
12164 }
12165
12166 /* Check against address space limit. */
12167+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
12168 if ((mm->total_vm << PAGE_SHIFT) + len
12169 > current->rlim[RLIMIT_AS].rlim_cur)
12170 return -ENOMEM;
2359ff29 12171@@ -1197,9 +1210,17 @@
1db5cd70
PS
12172 return -ENOMEM;
12173 }
12174
12175+ gr_learn_resource(current, RLIMIT_STACK, address - vma->vm_start, 1);
12176+ gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
12177+ if (vma->vm_flags & VM_LOCKED)
12178+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
12179+
dd62ee14 12180 if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
1db5cd70
PS
12181 ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
12182- current->rlim[RLIMIT_AS].rlim_cur) {
12183+ current->rlim[RLIMIT_AS].rlim_cur ||
12184+ ((vma->vm_flags & VM_LOCKED) &&
12185+ ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
12186+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
12187 anon_vma_unlock(vma);
12188 vm_unacct_memory(grow);
12189 return -ENOMEM;
2359ff29 12190@@ -1258,9 +1279,17 @@
1db5cd70
PS
12191 return -ENOMEM;
12192 }
2359ff29 12193
1db5cd70
PS
12194+ gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address, 1);
12195+ gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
12196+ if (vma->vm_flags & VM_LOCKED)
12197+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
12198+
dd62ee14 12199 if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
1db5cd70
PS
12200 ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
12201- current->rlim[RLIMIT_AS].rlim_cur) {
12202+ current->rlim[RLIMIT_AS].rlim_cur ||
12203+ ((vma->vm_flags & VM_LOCKED) &&
12204+ ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
12205+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
12206 anon_vma_unlock(vma);
12207 vm_unacct_memory(grow);
12208 return -ENOMEM;
2359ff29 12209@@ -1623,6 +1655,7 @@
1db5cd70
PS
12210 if (mm->def_flags & VM_LOCKED) {
12211 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
12212 locked += len;
12213+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
12214 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
12215 return -EAGAIN;
12216 }
2359ff29 12217@@ -1639,6 +1672,7 @@
1db5cd70
PS
12218 }
12219
12220 /* Check against address space limits *after* clearing old maps... */
12221+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
12222 if ((mm->total_vm << PAGE_SHIFT) + len
12223 > current->rlim[RLIMIT_AS].rlim_cur)
12224 return -ENOMEM;
1db5cd70
PS
12225diff -uNr linux-2.6.7-rc1.orig/mm/mprotect.c linux-2.6.7-rc1/mm/mprotect.c
12226--- linux-2.6.7-rc1.orig/mm/mprotect.c 2004-05-23 07:55:03.000000000 +0200
12227+++ linux-2.6.7-rc1/mm/mprotect.c 2004-05-25 14:33:59.581302592 +0200
12228@@ -17,6 +17,7 @@
12229 #include <linux/highmem.h>
12230 #include <linux/security.h>
12231 #include <linux/mempolicy.h>
12232+#include <linux/grsecurity.h>
12233
12234 #include <asm/uaccess.h>
12235 #include <asm/pgalloc.h>
12236@@ -202,6 +203,10 @@
12237 end = start + len;
12238 if (end < start)
12239 return -ENOMEM;
12240+
12241+ if (end > TASK_SIZE)
12242+ return -EINVAL;
12243+
12244 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
12245 return -EINVAL;
12246 if (end == start)
12247@@ -236,6 +241,11 @@
12248 if (start > vma->vm_start)
12249 prev = vma;
12250
12251+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
12252+ error = -EACCES;
12253+ goto out;
12254+ }
12255+
12256 for (nstart = start ; ; ) {
12257 unsigned int newflags;
12258
12259diff -uNr linux-2.6.7-rc1.orig/mm/mremap.c linux-2.6.7-rc1/mm/mremap.c
12260--- linux-2.6.7-rc1.orig/mm/mremap.c 2004-05-23 07:54:19.000000000 +0200
12261+++ linux-2.6.7-rc1/mm/mremap.c 2004-05-25 14:33:59.584302136 +0200
49166ac6 12262@@ -267,6 +267,10 @@
1db5cd70
PS
12263 if (!new_len)
12264 goto out;
12265
1db5cd70
PS
12266+ if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
12267+ old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
12268+ goto out;
12269+
12270 /* new_addr is only valid if MREMAP_FIXED is specified */
12271 if (flags & MREMAP_FIXED) {
12272 if (new_addr & ~PAGE_MASK)
12273diff -uNr linux-2.6.7-rc1.orig/net/ipv4/af_inet.c linux-2.6.7-rc1/net/ipv4/af_inet.c
12274--- linux-2.6.7-rc1.orig/net/ipv4/af_inet.c 2004-05-23 07:53:35.000000000 +0200
12275+++ linux-2.6.7-rc1/net/ipv4/af_inet.c 2004-05-25 14:33:59.595300464 +0200
12276@@ -87,6 +87,7 @@
12277 #include <linux/init.h>
12278 #include <linux/poll.h>
12279 #include <linux/netfilter_ipv4.h>
12280+#include <linux/grsecurity.h>
12281
12282 #include <asm/uaccess.h>
12283 #include <asm/system.h>
12284@@ -387,7 +388,12 @@
12285 else
12286 inet->pmtudisc = IP_PMTUDISC_WANT;
12287
12288- inet->id = 0;
12289+#ifdef CONFIG_GRKERNSEC_RANDID
12290+ if (grsec_enable_randid)
12291+ inet->id = htons(ip_randomid());
12292+ else
12293+#endif
12294+ inet->id = 0;
12295
12296 sock_init_data(sock, sk);
12297 sk_set_owner(sk, THIS_MODULE);
12298diff -uNr linux-2.6.7-rc1.orig/net/ipv4/ip_output.c linux-2.6.7-rc1/net/ipv4/ip_output.c
12299--- linux-2.6.7-rc1.orig/net/ipv4/ip_output.c 2004-05-25 14:25:40.000000000 +0200
12300+++ linux-2.6.7-rc1/net/ipv4/ip_output.c 2004-05-25 14:33:59.600299704 +0200
12301@@ -64,6 +64,7 @@
12302 #include <linux/proc_fs.h>
12303 #include <linux/stat.h>
12304 #include <linux/init.h>
12305+#include <linux/grsecurity.h>
12306
12307 #include <net/snmp.h>
12308 #include <net/ip.h>
12309@@ -1180,6 +1181,12 @@
12310 iph->tos = inet->tos;
12311 iph->tot_len = htons(skb->len);
12312 iph->frag_off = df;
12313+
12314+#ifdef CONFIG_GRKERNSEC_RANDID
12315+ if (grsec_enable_randid)
12316+ iph->id = htons(ip_randomid());
12317+ else
12318+#endif
12319 if (!df) {
12320 __ip_select_ident(iph, &rt->u.dst, 0);
12321 } else {
12322diff -uNr linux-2.6.7-rc1.orig/net/ipv4/netfilter/ipt_stealth.c linux-2.6.7-rc1/net/ipv4/netfilter/ipt_stealth.c
12323--- linux-2.6.7-rc1.orig/net/ipv4/netfilter/ipt_stealth.c 1970-01-01 01:00:00.000000000 +0100
12324+++ linux-2.6.7-rc1/net/ipv4/netfilter/ipt_stealth.c 2004-05-25 14:33:59.610298184 +0200
12325@@ -0,0 +1,112 @@
12326+/* Kernel module to add stealth support.
12327+ *
12328+ * Copyright (C) 2002 Brad Spengler <spender@grsecurity.net>
12329+ *
12330+ */
12331+
12332+#include <linux/kernel.h>
12333+#include <linux/module.h>
12334+#include <linux/skbuff.h>
12335+#include <linux/net.h>
12336+#include <linux/sched.h>
12337+#include <linux/inet.h>
12338+#include <linux/stddef.h>
12339+
12340+#include <net/ip.h>
12341+#include <net/sock.h>
12342+#include <net/tcp.h>
12343+#include <net/udp.h>
12344+#include <net/route.h>
12345+#include <net/inet_common.h>
12346+
12347+#include <linux/netfilter_ipv4/ip_tables.h>
12348+
12349+MODULE_LICENSE("GPL");
12350+
12351+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
12352+
12353+static int
12354+match(const struct sk_buff *skb,
12355+ const struct net_device *in,
12356+ const struct net_device *out,
12357+ const void *matchinfo,
12358+ int offset,
12359+ int *hotdrop)
12360+{
12361+ struct iphdr *ip = skb->nh.iph;
12362+ struct tcphdr th;
12363+ struct udphdr uh;
12364+ struct sock *sk = NULL;
12365+
12366+ if (!ip || offset) return 0;
12367+
12368+ switch(ip->protocol) {
12369+ case IPPROTO_TCP:
12370+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
12371+ *hotdrop = 1;
12372+ return 0;
12373+ }
12374+ if (!(th.syn && !th.ack)) return 0;
12375+ sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);
12376+ break;
12377+ case IPPROTO_UDP:
12378+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
12379+ *hotdrop = 1;
12380+ return 0;
12381+ }
12382+ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
12383+ break;
12384+ default:
12385+ return 0;
12386+ }
12387+
12388+ if(!sk) // port is being listened on, match this
12389+ return 1;
12390+ else {
12391+ sock_put(sk);
12392+ return 0;
12393+ }
12394+}
12395+
12396+/* Called when user tries to insert an entry of this type. */
12397+static int
12398+checkentry(const char *tablename,
12399+ const struct ipt_ip *ip,
12400+ void *matchinfo,
12401+ unsigned int matchsize,
12402+ unsigned int hook_mask)
12403+{
12404+ if (matchsize != IPT_ALIGN(0))
12405+ return 0;
12406+
12407+ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
12408+ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
12409+ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
12410+ return 1;
12411+
12412+ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
12413+
12414+ return 0;
12415+}
12416+
12417+
12418+static struct ipt_match stealth_match = {
12419+ .name = "stealth",
12420+ .match = &match,
12421+ .checkentry = &checkentry,
12422+ .destroy = NULL,
12423+ .me = THIS_MODULE
12424+};
12425+
12426+static int __init init(void)
12427+{
12428+ return ipt_register_match(&stealth_match);
12429+}
12430+
12431+static void __exit fini(void)
12432+{
12433+ ipt_unregister_match(&stealth_match);
12434+}
12435+
12436+module_init(init);
12437+module_exit(fini);
12438diff -uNr linux-2.6.7-rc1.orig/net/ipv4/netfilter/Kconfig linux-2.6.7-rc1/net/ipv4/netfilter/Kconfig
12439--- linux-2.6.7-rc1.orig/net/ipv4/netfilter/Kconfig 2004-05-25 14:25:41.000000000 +0200
12440+++ linux-2.6.7-rc1/net/ipv4/netfilter/Kconfig 2004-05-25 14:33:59.604299096 +0200
12441@@ -241,6 +241,21 @@
12442
12443 To compile it as a module, choose M here. If unsure, say N.
12444
12445+config IP_NF_MATCH_STEALTH
12446+ tristate "stealth match support"
12447+ depends on IP_NF_IPTABLES
12448+ help
12449+ Enabling this option will drop all syn packets coming to unserved tcp
12450+ ports as well as all packets coming to unserved udp ports. If you
12451+ are using your system to route any type of packets (ie. via NAT)
12452+ you should put this module at the end of your ruleset, since it will
12453+ drop packets that aren't going to ports that are listening on your
12454+ machine itself, it doesn't take into account that the packet might be
12455+ destined for someone on your internal network if you're using NAT for
12456+ instance.
12457+
12458+ To compile it as a module, choose M here. If unsure, say N.
12459+
12460 config IP_NF_MATCH_HELPER
12461 tristate "Helper match support"
12462 depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
12463diff -uNr linux-2.6.7-rc1.orig/net/ipv4/netfilter/Makefile linux-2.6.7-rc1/net/ipv4/netfilter/Makefile
12464--- linux-2.6.7-rc1.orig/net/ipv4/netfilter/Makefile 2004-05-25 14:25:41.000000000 +0200
12465+++ linux-2.6.7-rc1/net/ipv4/netfilter/Makefile 2004-05-25 14:33:59.608298488 +0200
12466@@ -140,6 +140,8 @@
12467 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
12468 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
12469
12470+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
12471+
12472 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
12473 obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
12474
12475diff -uNr linux-2.6.7-rc1.orig/net/ipv4/tcp_ipv4.c linux-2.6.7-rc1/net/ipv4/tcp_ipv4.c
12476--- linux-2.6.7-rc1.orig/net/ipv4/tcp_ipv4.c 2004-05-25 14:25:40.000000000 +0200
12477+++ linux-2.6.7-rc1/net/ipv4/tcp_ipv4.c 2004-05-25 14:33:59.615297424 +0200
12478@@ -62,6 +62,7 @@
12479 #include <linux/jhash.h>
12480 #include <linux/init.h>
12481 #include <linux/times.h>
12482+#include <linux/grsecurity.h>
12483
12484 #include <net/icmp.h>
12485 #include <net/tcp.h>
12486@@ -224,9 +225,16 @@
12487 spin_lock(&tcp_portalloc_lock);
12488 rover = tcp_port_rover;
12489 do {
12490- rover++;
12491- if (rover < low || rover > high)
12492- rover = low;
12493+#ifdef CONFIG_GRKERNSEC_RANDSRC
12494+ if (grsec_enable_randsrc && (high > low)) {
12495+ rover = low + (get_random_long() % (high - low));
12496+ } else
12497+#endif
12498+ {
12499+ rover++;
12500+ if (rover < low || rover > high)
12501+ rover = low;
12502+ }
12503 head = &tcp_bhash[tcp_bhashfn(rover)];
12504 spin_lock(&head->lock);
12505 tb_for_each(tb, node, &head->chain)
12506@@ -537,6 +545,11 @@
12507
12508 static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
12509 {
12510+#ifdef CONFIG_GRKERNSEC_RANDISN
12511+ if (likely(grsec_enable_randisn))
12512+ return ip_randomisn();
12513+ else
12514+#endif
12515 return secure_tcp_sequence_number(skb->nh.iph->daddr,
12516 skb->nh.iph->saddr,
12517 skb->h.th->dest,
12518@@ -671,10 +684,17 @@
12519 rover = tcp_port_rover;
12520
12521 do {
12522- rover++;
12523- if ((rover < low) || (rover > high))
12524- rover = low;
12525- head = &tcp_bhash[tcp_bhashfn(rover)];
12526+#ifdef CONFIG_GRKERNSEC_RANDSRC
12527+ if (grsec_enable_randsrc && (high > low)) {
12528+ rover = low + (get_random_long() % (high - low));
12529+ } else
12530+#endif
12531+ {
12532+ rover++;
12533+ if ((rover < low) || (rover > high))
12534+ rover = low;
12535+ }
12536+ head = &tcp_bhash[tcp_bhashfn(rover)];
12537 spin_lock(&head->lock);
12538
12539 /* Does not bother with rcv_saddr checks,
12540@@ -724,6 +744,15 @@
12541 }
12542 spin_unlock(&head->lock);
12543
12544+#ifdef CONFIG_GRKERNSEC
12545+ gr_del_task_from_ip_table(current);
12546+ current->gr_saddr = inet_sk(sk)->rcv_saddr;
12547+ current->gr_daddr = inet_sk(sk)->daddr;
12548+ current->gr_sport = inet_sk(sk)->sport;
12549+ current->gr_dport = inet_sk(sk)->dport;
12550+ gr_add_to_task_ip_table(current);
12551+#endif
12552+
12553 if (tw) {
12554 tcp_tw_deschedule(tw);
12555 tcp_tw_put(tw);
12556@@ -843,13 +872,24 @@
12557 tcp_v4_setup_caps(sk, &rt->u.dst);
12558 tp->ext2_header_len = rt->u.dst.header_len;
12559
12560- if (!tp->write_seq)
12561+ if (!tp->write_seq) {
12562+#ifdef CONFIG_GRKERNSEC_RANDISN
12563+ if (likely(grsec_enable_randisn))
12564+ tp->write_seq = ip_randomisn();
12565+ else
12566+#endif
12567 tp->write_seq = secure_tcp_sequence_number(inet->saddr,
12568 inet->daddr,
12569 inet->sport,
12570 usin->sin_port);
12571+ }
12572
12573- inet->id = tp->write_seq ^ jiffies;
12574+#ifdef CONFIG_GRKERNSEC_RANDID
12575+ if (grsec_enable_randid)
12576+ inet->id = htons(ip_randomid());
12577+ else
12578+#endif
12579+ inet->id = tp->write_seq ^ jiffies;
12580
12581 err = tcp_connect(sk);
12582 rt = NULL;
12583@@ -1593,7 +1633,13 @@
12584 if (newinet->opt)
12585 newtp->ext_header_len = newinet->opt->optlen;
12586 newtp->ext2_header_len = dst->header_len;
12587- newinet->id = newtp->write_seq ^ jiffies;
12588+
12589+#ifdef CONFIG_GRKERNSEC_RANDID
12590+ if (grsec_enable_randid)
12591+ newinet->id = htons(ip_randomid());
12592+ else
12593+#endif
12594+ newinet->id = newtp->write_seq ^ jiffies;
12595
12596 tcp_sync_mss(newsk, dst_pmtu(dst));
12597 newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
12598diff -uNr linux-2.6.7-rc1.orig/net/ipv4/udp.c linux-2.6.7-rc1/net/ipv4/udp.c
12599--- linux-2.6.7-rc1.orig/net/ipv4/udp.c 2004-05-25 14:25:40.000000000 +0200
12600+++ linux-2.6.7-rc1/net/ipv4/udp.c 2004-05-25 14:33:59.619296816 +0200
12601@@ -100,6 +100,7 @@
12602 #include <linux/skbuff.h>
12603 #include <linux/proc_fs.h>
12604 #include <linux/seq_file.h>
12605+#include <linux/grsecurity.h>
12606 #include <net/sock.h>
12607 #include <net/udp.h>
12608 #include <net/icmp.h>
12609@@ -108,6 +109,12 @@
12610 #include <net/checksum.h>
12611 #include <net/xfrm.h>
12612
12613+extern int gr_search_udp_recvmsg(const struct sock *sk,
12614+ const struct sk_buff *skb);
12615+extern int gr_search_udp_sendmsg(const struct sock *sk,
12616+ const struct sockaddr_in *addr);
12617+
12618+
12619 /*
12620 * Snmp MIB for the UDP layer
12621 */
12622@@ -538,9 +545,16 @@
12623 dport = usin->sin_port;
12624 if (dport == 0)
12625 return -EINVAL;
12626+
12627+ if (!gr_search_udp_sendmsg(sk, usin))
12628+ return -EPERM;
12629 } else {
12630 if (sk->sk_state != TCP_ESTABLISHED)
12631 return -EDESTADDRREQ;
12632+
12633+ if (!gr_search_udp_sendmsg(sk, NULL))
12634+ return -EPERM;
12635+
12636 daddr = inet->daddr;
12637 dport = inet->dport;
12638 /* Open fast path for connected socket.
12639@@ -792,7 +806,12 @@
12640 if (!skb)
12641 goto out;
12642
12643- copied = skb->len - sizeof(struct udphdr);
12644+ if (!gr_search_udp_recvmsg(sk, skb)) {
12645+ err = -EPERM;
12646+ goto out_free;
12647+ }
12648+
12649+ copied = skb->len - sizeof(struct udphdr);
12650 if (copied > len) {
12651 copied = len;
12652 msg->msg_flags |= MSG_TRUNC;
12653@@ -901,7 +920,12 @@
12654 inet->daddr = rt->rt_dst;
12655 inet->dport = usin->sin_port;
12656 sk->sk_state = TCP_ESTABLISHED;
12657- inet->id = jiffies;
12658+#ifdef CONFIG_GRKERNSEC_RANDID
12659+ if (grsec_enable_randid)
12660+ inet->id = htons(ip_randomid());
12661+ else
12662+#endif
12663+ inet->id = jiffies;
12664
12665 sk_dst_set(sk, &rt->u.dst);
12666 return(0);
12667diff -uNr linux-2.6.7-rc1.orig/net/socket.c linux-2.6.7-rc1/net/socket.c
12668--- linux-2.6.7-rc1.orig/net/socket.c 2004-05-23 07:53:57.000000000 +0200
12669+++ linux-2.6.7-rc1/net/socket.c 2004-05-25 14:33:59.634294536 +0200
12670@@ -81,6 +81,7 @@
12671 #include <linux/syscalls.h>
12672 #include <linux/compat.h>
12673 #include <linux/kmod.h>
12674+#include <linux/in.h>
12675
12676 #ifdef CONFIG_NET_RADIO
12677 #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
12678@@ -94,6 +95,18 @@
12679 #include <net/sock.h>
12680 #include <linux/netfilter.h>
12681
12682+extern void gr_attach_curr_ip(const struct sock *sk);
12683+extern int gr_handle_sock_all(const int family, const int type,
12684+ const int protocol);
12685+extern int gr_handle_sock_server(const struct sockaddr *sck);
12686+extern int gr_handle_sock_client(const struct sockaddr *sck);
12687+extern int gr_search_connect(const struct socket * sock,
12688+ const struct sockaddr_in * addr);
12689+extern int gr_search_bind(const struct socket * sock,
12690+ const struct sockaddr_in * addr);
12691+extern int gr_search_socket(const int domain, const int type,
12692+ const int protocol);
12693+
12694 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
12695 static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
12696 size_t size, loff_t pos);
12697@@ -897,6 +910,7 @@
12698 printk(KERN_DEBUG "sock_close: NULL inode\n");
12699 return 0;
12700 }
12701+
12702 sock_fasync(-1, filp, 0);
12703 sock_release(SOCKET_I(inode));
12704 return 0;
12705@@ -1126,6 +1140,16 @@
12706 int retval;
12707 struct socket *sock;
12708
12709+ if(!gr_search_socket(family, type, protocol)) {
12710+ retval = -EACCES;
12711+ goto out;
12712+ }
12713+
12714+ if (gr_handle_sock_all(family, type, protocol)) {
12715+ retval = -EACCES;
12716+ goto out;
12717+ }
12718+
12719 retval = sock_create(family, type, protocol, &sock);
12720 if (retval < 0)
12721 goto out;
12722@@ -1221,11 +1245,23 @@
12723 {
12724 struct socket *sock;
12725 char address[MAX_SOCK_ADDR];
12726+ struct sockaddr *sck;
12727 int err;
12728
12729 if((sock = sockfd_lookup(fd,&err))!=NULL)
12730 {
12731 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
12732+ sck = (struct sockaddr *)address;
12733+ if (!gr_search_bind(sock, (struct sockaddr_in *)sck)) {
12734+ sockfd_put(sock);
12735+ return -EACCES;
12736+ }
12737+
12738+ if (gr_handle_sock_server(sck)) {
12739+ sockfd_put(sock);
12740+ return -EACCES;
12741+ }
12742+
12743 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
12744 if (err) {
12745 sockfd_put(sock);
12746@@ -1328,6 +1364,7 @@
12747 goto out_release;
12748
12749 security_socket_post_accept(sock, newsock);
12750+ gr_attach_curr_ip(newsock->sk);
12751
12752 out_put:
12753 sockfd_put(sock);
12754@@ -1355,6 +1392,7 @@
12755 {
12756 struct socket *sock;
12757 char address[MAX_SOCK_ADDR];
12758+ struct sockaddr *sck;
12759 int err;
12760
12761 sock = sockfd_lookup(fd, &err);
12762@@ -1364,6 +1402,18 @@
12763 if (err < 0)
12764 goto out_put;
12765
12766+ sck = (struct sockaddr *)address;
12767+
12768+ if (!gr_search_connect(sock, (struct sockaddr_in *)sck)) {
12769+ err = -EACCES;
12770+ goto out_put;
12771+ }
12772+
12773+ if (gr_handle_sock_client(sck)) {
12774+ err = -EACCES;
12775+ goto out_put;
12776+ }
12777+
12778 err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
12779 if (err)
12780 goto out_put;
12781@@ -1617,6 +1667,7 @@
12782 err=sock->ops->shutdown(sock, how);
12783 sockfd_put(sock);
12784 }
12785+
12786 return err;
12787 }
12788
12789diff -uNr linux-2.6.7-rc1.orig/net/sunrpc/xprt.c linux-2.6.7-rc1/net/sunrpc/xprt.c
12790--- linux-2.6.7-rc1.orig/net/sunrpc/xprt.c 2004-05-23 07:54:22.000000000 +0200
12791+++ linux-2.6.7-rc1/net/sunrpc/xprt.c 2004-05-25 14:33:59.644293016 +0200
12792@@ -58,6 +58,7 @@
12793 #include <linux/file.h>
12794 #include <linux/workqueue.h>
12795 #include <linux/random.h>
12796+#include <linux/grsecurity.h>
12797
12798 #include <net/sock.h>
12799 #include <net/checksum.h>
12800@@ -1337,6 +1338,12 @@
12801 */
12802 static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
12803 {
12804+
12805+#ifdef CONFIG_GRKERNSEC_RANDRPC
12806+ if (grsec_enable_randrpc)
12807+ return (u32) get_random_long();
12808+#endif
12809+
12810 return xprt->xid++;
12811 }
12812
12813diff -uNr linux-2.6.7-rc1.orig/net/unix/af_unix.c linux-2.6.7-rc1/net/unix/af_unix.c
12814--- linux-2.6.7-rc1.orig/net/unix/af_unix.c 2004-05-23 07:54:22.000000000 +0200
12815+++ linux-2.6.7-rc1/net/unix/af_unix.c 2004-05-25 14:33:59.653291648 +0200
12816@@ -118,6 +118,7 @@
12817 #include <linux/mount.h>
12818 #include <net/checksum.h>
12819 #include <linux/security.h>
12820+#include <linux/grsecurity.h>
12821
12822 int sysctl_unix_max_dgram_qlen = 10;
12823
12824@@ -681,6 +682,11 @@
12825 if (err)
12826 goto put_fail;
12827
12828+ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
12829+ err = -EACCES;
12830+ goto put_fail;
12831+ }
12832+
12833 err = -ECONNREFUSED;
12834 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
12835 goto put_fail;
12836@@ -704,6 +710,13 @@
12837 if (u) {
12838 struct dentry *dentry;
12839 dentry = unix_sk(u)->dentry;
12840+
12841+ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
12842+ err = -EPERM;
12843+ sock_put(u);
12844+ goto fail;
12845+ }
12846+
12847 if (dentry)
12848 touch_atime(unix_sk(u)->mnt, dentry);
12849 } else
12850@@ -803,9 +816,18 @@
12851 */
12852 mode = S_IFSOCK |
12853 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
12854+
12855+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
12856+ err = -EACCES;
12857+ goto out_mknod_dput;
12858+ }
12859+
12860 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
12861 if (err)
12862 goto out_mknod_dput;
12863+
12864+ gr_handle_create(dentry, nd.mnt);
12865+
12866 up(&nd.dentry->d_inode->i_sem);
12867 dput(nd.dentry);
12868 nd.dentry = dentry;
12869@@ -823,6 +845,10 @@
12870 goto out_unlock;
12871 }
12872
12873+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12874+ sk->sk_peercred.pid = current->pid;
12875+#endif
12876+
12877 list = &unix_socket_table[addr->hash];
12878 } else {
12879 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
3aa50353
PS
12880diff -uNr linux-2.6.7-rc1.orig/security/Kconfig linux-2.6.7-rc1/security/Kconfig
12881--- linux-2.6.7-rc1.orig/security/Kconfig 2004-05-23 07:54:23.000000000 +0200
12882+++ linux-2.6.7-rc1/security/Kconfig 2004-05-26 01:02:26.341672392 +0200
12883@@ -2,6 +2,8 @@
12884 # Security configuration
12885 #
12886
12887+source grsecurity/Kconfig
12888+
12889 menu "Security options"
12890
12891 config SECURITY
1db5cd70
PS
12892diff -uNr linux-2.6.7-rc1.orig/security/commoncap.c linux-2.6.7-rc1/security/commoncap.c
12893--- linux-2.6.7-rc1.orig/security/commoncap.c 2004-05-23 07:53:57.000000000 +0200
12894+++ linux-2.6.7-rc1/security/commoncap.c 2004-05-25 14:33:59.657291040 +0200
12895@@ -27,7 +27,7 @@
12896 int cap_capable (struct task_struct *tsk, int cap)
12897 {
12898 /* Derived from include/linux/sched.h:capable. */
12899- if (cap_raised (tsk->cap_effective, cap))
12900+ if (cap_raised (tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
12901 return 0;
12902 else
12903 return -EPERM;
12904@@ -37,7 +37,7 @@
12905 {
12906 /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
12907 if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
12908- !capable (CAP_SYS_PTRACE))
12909+ !capable_nolog (CAP_SYS_PTRACE))
12910 return -EPERM;
12911 else
12912 return 0;
12913@@ -334,7 +334,7 @@
12914 /*
12915 * Leave the last 3% for root
12916 */
12917- if (!capable(CAP_SYS_ADMIN))
12918+ if (!capable_nolog(CAP_SYS_ADMIN))
12919 free -= free / 32;
12920
12921 if (free > pages)
12922@@ -345,7 +345,7 @@
12923 * only call if we're about to fail.
12924 */
12925 n = nr_free_pages();
12926- if (!capable(CAP_SYS_ADMIN))
12927+ if (!capable_nolog(CAP_SYS_ADMIN))
12928 n -= n / 32;
12929 free += n;
12930
12931diff -uNr linux-2.6.7-rc1.orig/security/security.c linux-2.6.7-rc1/security/security.c
12932--- linux-2.6.7-rc1.orig/security/security.c 2004-05-23 07:53:30.000000000 +0200
12933+++ linux-2.6.7-rc1/security/security.c 2004-05-25 14:33:59.659290736 +0200
12934@@ -206,4 +206,5 @@
12935 EXPORT_SYMBOL_GPL(mod_reg_security);
12936 EXPORT_SYMBOL_GPL(mod_unreg_security);
12937 EXPORT_SYMBOL(capable);
12938+EXPORT_SYMBOL(capable_nolog);
12939 EXPORT_SYMBOL(security_ops);
dbb7f4ea
PS
12940diff -uNr linux-2.6.7-rc1.orig/Makefile linux-2.6.7-rc1/Makefile
12941--- linux-2.6.7-rc1.orig/Makefile 2004-05-26 00:38:42.000000000 +0200
12942+++ linux-2.6.7-rc1/Makefile 2004-05-26 01:23:28.424806592 +0200
12943@@ -484,7 +484,7 @@
12944
12945
12946 ifeq ($(KBUILD_EXTMOD),)
12947-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/
12948+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/
12949
12950 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
12951 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
This page took 3.597706 seconds and 4 git commands to generate.