]> git.pld-linux.org Git - packages/kernel.git/blame - linux-grsecurity-1.8-2.4.7.patch
run depmod before geninitrd and rc-boot
[packages/kernel.git] / linux-grsecurity-1.8-2.4.7.patch
CommitLineData
119f9537
JR
1diff -urN linux/Documentation/Configure.help linux.grsec/Documentation/Configure.help
2--- linux/Documentation/Configure.help Sun Sep 30 01:30:58 2001
3+++ linux.grsec/Documentation/Configure.help Sun Sep 30 01:54:18 2001
4@@ -18157,6 +18157,361 @@
5 boards supported by this driver, and for further information
6 on the use of this driver.
7
8+Non-executable Stack
9+CONFIG_GRKERNSEC_STACK
10+ If you say Y here, your system will not allow execution of
11+ code on the stack, making buffer overflow exploitation more difficult.
12+ Exploits will have to dabble in more obscure methods of
13+ exploitation(bss,got,heap..)
14+
15+Gcc trampoline support
16+CONFIG_GRKERNSEC_STACK_GCC
17+ If you say Y here, the system will support trampoline code along
18+ with the stack protection. If you do not have any programs on
19+ your system that require this (glibc 2.0 users must say YES to
20+ this option) you may say no here.
21+
22+PaX protection
23+CONFIG_GRKERNSEC_PAX
24+ By design the IA-32 architecture does not allow for protecting
25+ memory pages against execution, i.e. if a page is readable (such
26+ as the stack or heap) it is also executable. There is a well
27+ known exploit technique that makes use of this fact and a common
28+ programming mistake where an attacker can introduce executable
29+ code of his choice somewhere in the attacked program's memory
30+ (typically the stack or the heap) and then execute it. If the
31+ attacked program was running with different (typically higher)
32+ privileges than that of the attacker, then he can elevate his
33+ own privilege level (e.g. get a root shell, write to files for
34+ which he does not have write access to, etc).
35+
36+ Since the implementation is software based, it comes with a
37+ performance impact, you should evaluate your system carefully
38+ before deciding to use this feature on production systems.
39+
40+ Enabling this feature will enforce the non-executable flag on
41+ memory pages thereby making it harder to execute 'foreign' code
42+ in a program. This will also break programs that rely on the
43+ old behaviour and expect that dynamically allocated memory via
44+ the malloc() family of functions is executable (which it is not).
45+ Notable examples are the XFree86 4.x server, the java runtime
46+ and wine.
47+
48+ NOTE: you can use the 'chpax' utility to enable/disable this
49+ feature on a per file basis.
50+
51+Emulate trampolines
52+CONFIG_GRKERNSEC_PAX_EMUTRAMP
53+ There are some programs and libraries that for one reason or
54+ another attempt to execute special small code snippets from
55+ non-executable memory pages. Most notable examples are the
56+ signal handler return code generated by the kernel itself and
57+ the GCC trampolines.
58+
59+ If you enabled CONFIG_PAX_PAGEEXEC then such programs will no
60+ longer work under your kernel. As a remedy you can say Y here
61+ and use the 'chpax' utility to enable trampoline emulation for
62+ the affected programs yet still have the protection provided by
63+ CONFIG_PAX_PAGEEXEC. Alternatively you can say N here and use
64+ the 'chpax' utility to disable CONFIG_PAX_PAGEEXEC for the
65+ affected files.
66+
67+ NOTE: enabling this feature *may* open up a loophole in the
68+ protection provided by CONFIG_PAX_PAGEEXEC that an attacker
69+ could abuse. Therefore the best solution is to not have any
70+ files on your system that would require this option. This can
71+ be achieved by not using libc5 (which relies on the kernel
72+ signal handler return code) and not using or rewriting programs
73+ that make use of the nested function implementation of GCC.
74+ Skilled users can just fix GCC itself so that it implements
75+ nested function calls in a way that does not interfere with PaX.
76+
77+Restrict mprotect()
78+CONFIG_GRKERNSEC_PAX_MPROTECT
79+ Enabling this option will prevent programs from changing the
80+ executable status of memory pages that were not originally
81+ created as executable. The kernel will also prevent programs
82+ from making read-only executable pages writable again.
83+
84+ You should say Y here to complete the protection provided by
85+ the enforcement of the PAGE_EXEC flag (CONFIG_PAX_PAGEEXEC).
86+
87+ NOTE: you can use the 'chpax' utility to enable/disable this
88+ feature on a per file basis.
89+
90+Randomize mmap() base
91+CONFIG_GRKERNSEC_PAX_RANDMMAP
92+ By saying Y here the kernel will somewhat randomize the address
93+ space of programs at each execution (the top of the stack, the
94+ base address for mmap() requests that do not specify one themselves
95+ and the base address of dynamic ELF executables).
96+
97+ As a result all dynamically loaded libraries will appear at random
98+ addresses and therefore be harder to exploit by a technique where
99+ an attacker attempts to execute library code for his purposes
100+ (e.g. spawn a shell from an exploited program that is running at
101+ an elevated privilege level).
102+
103+ Furthermore, if a program is relinked as a dynamic ELF file, its
104+ base address will be randomized as well, completing the full
105+ randomization of the address space. Attacking such programs becomes
106+ a guess game.
107+
108+ It is strongly recommended to say Y here even if CONFIG_PAX_PAGEEXEC
109+ is not enabled as address space randomization has negligible impact
110+ on performance yet it provides a very effective protection.
111+
112+ NOTE: you can use the 'chpax' utility to enable/disable this
113+ feature on a per file basis.
114+
115+
116+Proc Restrictions
117+CONFIG_GRKERNSEC_PROC
118+ If you say Y here, the permissions of the /proc filesystem
119+ will be altered to enhance system security and privacy. Depending
120+ upon the options you choose, you can either restrict users to see
121+ only the processes they themselves run, or choose a group that can
122+ not see all processes, but can view other proc entries that would
123+ normally be restricted to the user. If you're running identd as
124+ a non-root user, you will have to run it as the group you specify here.
125+
126+Linking restrictions
127+CONFIG_GRKERNSEC_LINK
128+ If you say Y here, /tmp race exploits will be prevented, since users
129+ will no longer be able to follow symlinks owned by other users in
130+ world-writeable +t directories (i.e. /tmp), unless the owner of the
131+ symlink is the owner of the directory. users will also not be
132+ able to hardlink to files they do not own.
133+
134+FIFO restrictions
135+CONFIG_GRKERNSEC_FIFO
136+ If you say Y here, users will not be able to write to FIFOs they don't
137+ own in world-writeable +t directories (i.e. /tmp), unless the owner of
138+ the FIFO is the same owner of the directory it's held in.
139+
140+Secure file descriptors
141+CONFIG_GRKERNSEC_FD
142+ If you say Y here, set*id binaries will be protected from data spoofing
143+ attacks (eg. making a program read /etc/shadow). The patches do this
144+ by opening up /dev/null to any of the stdin, stdout, stderr file descriptors
145+ for set*id binaries that are open and run by a user that is not the owner
146+ of the file.
147+
148+Exec process limiting
149+CONFIG_GRKERNSEC_EXECVE
150+ If you say Y here, users with a resource limit on processes will
151+ have the value checked during execve() calls. The current system
152+ only checks the system limit during fork() calls.
153+
154+Fork-bombing protection
155+CONFIG_GRKERNSEC_FORKBOMB
156+ If you say Y here, you will be able to configure a group to add to users
157+ on your system that you want to be unable to fork-bomb the system.
158+ You will be able to specify a maximum process limit for the user and
159+ set a rate limit for all forks under their uid. (Fork-bombing is a
160+ tactic used by attackers that can be enacted in two ways, (1) loading
161+ up thousands of processes until the system can't take any more (this
162+ method can be stopped outside of the kernel with PAM, however we place
163+ protection for it in the kernel to be more complete and reduce overhead),
164+ and (2), by forking processes at a rapid rate, and then killing them
165+ off, which cannot be protected against in the same way at tactic 1)
166+ The rate limit is specified in forks allowed per second. Set this
167+ limit low enough to stop tactic 2, but high enough to allow for
168+ normal operation.
169+
170+Exec logging
171+CONFIG_GRKERNSEC_EXECLOG
172+ If you say Y here, all execve() calls will be logged (since the
173+ other exec*() calls are frontends to execve(), all execution
174+ will be logged). Useful for shell-servers that like to keep track
175+ of their users.
176+ WARNING: This option when enabled will produce a LOT of logs, especially
177+ on an active system.
178+
179+Set*id logging
180+CONFIG_GRKERNSEC_SUID
181+ If you say Y here, all set*id() calls will be logged. Such information
182+ could be useful when detecting a possible intrusion attempt.
183+
184+Signal logging
185+CONFIG_GRKERNSEC_SIGNAL
186+ If you say Y here, certain important signals will be logged, such as
187+ SIGSEGV, which will as a result inform you of when a error in a program
188+ occured, which in some cases could mean a possible exploit attempt.
189+
190+BSD-style coredumps
191+CONFIG_GRKERNSEC_COREDUMP
192+ If you say Y here, linux will use a style similar to BSD for
193+ coredumps, core.processname. Not a security feature, just
194+ a useful one.
195+
196+Fork failure logging
197+CONFIG_GRKERNSEC_FORKFAIL
198+ If you say Y here, all failed fork() attempts will be logged.
199+ This could suggest a fork bomb, or someone attempting to overstep
200+ their process limit.
201+
202+Time change logging
203+CONFIG_GRKERNSEC_TIME
204+ If you say Y here, any changes of the system clock will be logged.
205+
206+Secure keymap loading
207+CONFIG_GRKERNSEC_KBMAP
208+ If you say Y here, KDSKBENT and KDSKBSENT ioctl calls being
209+ called by unprivileged users will be denied. If you answer N,
210+ everyone will be able to modify keyboard bindings.
211+
212+ Saying N makes hacking root account easier for anyone who
213+ has access to the console.
214+
215+Enhanced network randomness
216+CONFIG_GRKERNSEC_RANDNET
217+ If you say Y here, the functions controlling the randomness
218+ of the Linux IP stack will be enhanced to decrease the chances
219+ of being able to predict certain packets that require some
220+ amount of randomness.
221+
222+Chroot jail restrictions
223+CONFIG_GRKERNSEC_CHROOT
224+ If you say Y here, processes in a chrooted jail will be much more
225+ difficult to break out of. It stops most generic ways of breaking
226+ a chroot jail. Adding in chroot jail restrictions adds these
227+ protective measures to the kernel:
228+ No mknod()
229+ No ptracing
230+ No fchmod +s or chmod +s (usually used to create a rootshell)
231+ No double chroots
232+ Restricted signal sending to other processes
233+ No mounting or remounting of devices
234+ Enforced chdir("/") on all chroots
235+
236+Log all execs within a jail
237+CONFIG_GRKERNSEC_CHROOT_EXECLOG
238+ If you say Y here, all executions inside a chroot jail will be logged to
239+ syslog.
240+
241+Chroot jail capability restrictions
242+CONFIG_GRKERNSEC_CHROOT_CAPS
243+ If you say Y here, the capabilities on all root processes within a
244+ chroot jail will be lowered to stop module insertion, raw i/o,
245+ system and net admin tasks, transferring capabilities, and
246+ tty configuration tasks. This is left an option because it breaks
247+ some apps (glftpd) Disable this if your chrooted apps are having
248+ problems.
249+
250+Trusted path execution
251+CONFIG_GRKERNSEC_TPE
252+ If you say Y here, you will be able to choose a gid to add to the
253+ supplementary groups of users you want to mark as "untrusted."
254+ These users will not be able to execute any files that are not in
255+ root-owned directories writeable only by root.
256+
257+Partially restrict non-root users
258+CONFIG_GRKERNSEC_TPE_ALL
259+ If you say Y here, All other non-root users will only be allowed to
260+ execute files in directories they own that are not group or
261+ world-writeable, or in directories owned by root and writeable only by
262+ root.
263+
264+Trusted path execution glibc protection
265+CONFIG_GRKERNSEC_TPE_GLIBC
266+ If you say Y here, all non-root users will not be able to execute
267+ any files while glibc specific environment variables such as
268+ LD_PRELOAD are set, which could be used to evade the trusted
269+ path execution protection. It also protects against evasion
270+ through /lib/ld-2.* It is recommended you say Y here also.
271+
272+Randomized PIDs
273+CONFIG_GRKERNSEC_RANDPID
274+ If you say Y here, all PIDs created on the system will be
275+ pseudo-randomly generated. This is extremely effective along
276+ with the /proc restrictions to disallow an attacker from guessing
277+ pids of daemons, etc. PIDs are also used in some cases as part
278+ of a naming system for temporary files, so this option would keep
279+ those filenames from being predicted as well. We also use code
280+ to make sure that PID numbers aren't reused too soon.
281+
282+Randomized IP IDs
283+CONFIG_GRKERNSEC_RANDID
284+ If you say Y here, all the id field on all outgoing packets
285+ will be randomized. This hinders os fingerprinters and
286+ keeps your machine from being used as a bounce for an untraceable
287+ portscan. Ids are used for fragmented packets, fragments belonging
288+ to the same packet have the same id. By default linux only
289+ increments the id value on each packet sent to an individual host.
290+ I've replaced the usage of all the other ip generation routines with
291+ my own for speed. I generate random data for 64 packets at once and
292+ distribute them as needed. I also keep track of the last 32 packets
293+ so that we don't create two packets with the same ids too soon,
294+ which would cause problems if the packets were fragmented and had
295+ to be reassembled.
296+ This option will make your system more OpenBSD-ish ;)
297+
298+Randomized TCP source ports
299+CONFIG_GRKERNSEC_RANDSRC
300+ If you say Y here, situations where a source port is generated on the
301+ fly for the TCP protocol (ie. with connect() ) will be altered so that
302+ the source port is generated at random, instead of a simple incrementing
303+ algorithm.
304+
305+Altered Ping IDs
306+CONFIG_GRKERNSEC_RANDPING
307+ If you say Y here, the way Linux handles echo replies will be changed
308+ so that the reply uses an ID equal to the ID of the echo request.
309+ This will help in confusing OS detection.
310+
311+Randomized TTL
312+CONFIG_GRKERNSEC_RANDTTL
313+ If you say Y here, your TTL (time to live) for packets will be set at
314+ random, with a base level you specify, to further confuse OS detection.
315+ The default base level for this option is set to the Linux default.
316+
317+Socket restrictions
318+CONFIG_GRKERNSEC_SOCKET
319+ If you say Y here, you will be able to choose from several options.
320+ If you assign a GID on your system and add it to the supplementary
321+ groups of users you want to restrict socket access to, this patch
322+ will do one of three things, based on the option(s) you choose.
323+ Deny all socket access: keeps users from connecting to other hosts
324+ from the machine or running servers from the machine
325+ Deny all client sockets: keeps users from connecting to other machines
326+ only
327+ Deny all server sockets: keeps users from running servers on the machine
328+ You should change the GID's from the default to what you have set up on
329+ your system.
330+
331+Stealth network enhancements
332+CONFIG_GRKERNSEC_STEALTH
333+ If you say Y here, you will enable several enhancements that will
334+ improve your system's protection against portscans.
335+ Enabling these options and filtering all open ports should make
336+ your machine very hard to detect, while not interfering with (most)
337+ normal operation. Enabling the UDP stealth options is known to slow
338+ down SSH connection times, and may also interfere with other protocols
339+ as well. All the stealth options break RFC, so there's always the
340+ possibility that it might affect how certain network applications react
341+ to your system.
342+
343+Sysctl support
344+CONFIG_GRKERNSEC_SYSCTL
345+ If you say Y here, you will be able to change the options that
346+ grsecurity runs with at bootup, without having to recompile your
347+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
348+ to enable (1) or disable (0) various features. They can only be set
349+ once per boot for security reasons. All features are enabled by default.
350+ Please note that this option could reduce the effectiveness
351+ of the added security of this patch if an ACL system is not put in
352+ place. Your init scripts should be read-only, and root should not have
353+ access to adding modules or performing raw i/o operations. All options
354+ should be set at startup, so that they cannot be set again. *THIS IS
355+ EXTREMELY IMPORTANT*
356+
357+Oblivion ACL System
358+CONFIG_OBV_PROC
359+ If you say Y here, you enable the Access Control List system for
360+ grsecurity called Oblivion. You will need to run obvadm setup
361+ to set your password and create your config files.
362+
363 #
364 # ARM options
365 #
366diff -urN linux/arch/alpha/config.in linux.grsec/arch/alpha/config.in
367--- linux/arch/alpha/config.in Sun Sep 30 01:30:50 2001
368+++ linux.grsec/arch/alpha/config.in Sun Sep 30 01:54:18 2001
369@@ -368,3 +368,12 @@
370 bool 'Legacy kernel start address' CONFIG_ALPHA_LEGACY_START_ADDRESS
371
372 endmenu
373+
374+mainmenu_option next_comment
375+comment 'Grsecurity'
376+bool 'Grsecurity' CONFIG_GRKERNSEC
377+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
378+ source grsecurity/Config.in
379+fi
380+endmenu
381+
382diff -urN linux/arch/arm/config.in linux.grsec/arch/arm/config.in
383--- linux/arch/arm/config.in Sun Sep 30 01:30:50 2001
384+++ linux.grsec/arch/arm/config.in Sun Sep 30 01:54:18 2001
385@@ -504,3 +504,12 @@
386 dep_bool ' Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
387 dep_bool ' kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
388 endmenu
389+
390+mainmenu_option next_comment
391+comment 'Grsecurity'
392+bool 'Grsecurity' CONFIG_GRKERNSEC
393+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
394+ source grsecurity/Config.in
395+fi
396+endmenu
397+
398diff -urN linux/arch/cris/config.in linux.grsec/arch/cris/config.in
399--- linux/arch/cris/config.in Wed Jul 4 20:50:38 2001
400+++ linux.grsec/arch/cris/config.in Sun Sep 30 01:54:18 2001
401@@ -240,3 +240,12 @@
402 int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
403 fi
404 endmenu
405+
406+mainmenu_option next_comment
407+comment 'Grsecurity'
408+bool 'Grsecurity' CONFIG_GRKERNSEC
409+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
410+ source grsecurity/Config.in
411+fi
412+endmenu
413+
414diff -urN linux/arch/i386/config.in linux.grsec/arch/i386/config.in
415--- linux/arch/i386/config.in Sun Sep 30 01:30:59 2001
416+++ linux.grsec/arch/i386/config.in Sun Sep 30 01:54:18 2001
417@@ -405,3 +405,12 @@
418 fi
419 bool 'Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
420 endmenu
421+
422+mainmenu_option next_comment
423+comment 'Grsecurity'
424+bool 'Grsecurity' CONFIG_GRKERNSEC
425+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
426+ source grsecurity/Config.in
427+fi
428+endmenu
429+
430diff -urN linux/arch/i386/kernel/entry.S linux.grsec/arch/i386/kernel/entry.S
431--- linux/arch/i386/kernel/entry.S Sun Sep 30 01:30:54 2001
432+++ linux.grsec/arch/i386/kernel/entry.S Sun Sep 30 01:54:18 2001
433@@ -46,6 +46,7 @@
434 #include <asm/segment.h>
435 #define ASSEMBLY
436 #include <asm/smp.h>
437+#include <asm/page.h>
438
439 EBX = 0x00
440 ECX = 0x04
441@@ -410,8 +411,51 @@
442 #endif
443
444 ENTRY(page_fault)
445+#ifdef CONFIG_GRKERNSEC_PAX
446+ pushl $ SYMBOL_NAME(pax_do_page_fault)
447+ pushl %ds
448+ pushl %eax
449+ xorl %eax,%eax
450+ pushl %ebp
451+ pushl %edi
452+ pushl %esi
453+ pushl %edx
454+ decl %eax # eax = -1
455+ pushl %ecx
456+ pushl %ebx
457+ cld
458+ movl %es,%ecx
459+ movl ORIG_EAX(%esp), %esi # get the error code
460+ movl ES(%esp), %edi # get the function address
461+ movl %eax, ORIG_EAX(%esp)
462+ movl %ecx, ES(%esp)
463+ movl %esp,%edx
464+ pushl %esi # push the error code
465+ pushl %edx # push the pt_regs pointer
466+ movl $(__KERNEL_DS),%edx
467+ movl %edx,%ds
468+ movl %edx,%es
469+ GET_CURRENT(%ebx)
470+ call *%edi
471+ addl $8,%esp
472+ decl %eax
473+ jnz ret_from_exception
474+
475+ popl %ebx
476+ popl %ecx
477+ popl %edx
478+ popl %esi
479+ popl %edi
480+ popl %ebp
481+ popl %eax
482+ popl %ds
483+ popl %es
484+ addl $4,%esp
485+ jmp system_call
486+#else
487 pushl $ SYMBOL_NAME(do_page_fault)
488 jmp error_code
489+#endif
490
491 ENTRY(machine_check)
492 pushl $0
493diff -urN linux/arch/i386/kernel/head.S linux.grsec/arch/i386/kernel/head.S
494--- linux/arch/i386/kernel/head.S Wed Jun 20 20:00:53 2001
495+++ linux.grsec/arch/i386/kernel/head.S Sun Sep 30 01:54:18 2001
496@@ -433,7 +433,11 @@
497 .quad 0x0000000000000000 /* not used */
498 .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */
499 .quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */
500+#ifdef CONFIG_GRKERNSEC_STACK
501+ .quad 0x00cbfa000000f7ff /* 0x23 user 3GB-8MB code at 0 */
502+#else
503 .quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */
504+#endif
505 .quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */
506 .quad 0x0000000000000000 /* not used */
507 .quad 0x0000000000000000 /* not used */
508diff -urN linux/arch/i386/kernel/process.c linux.grsec/arch/i386/kernel/process.c
509--- linux/arch/i386/kernel/process.c Sun Sep 30 01:30:54 2001
510+++ linux.grsec/arch/i386/kernel/process.c Sun Sep 30 01:54:18 2001
511@@ -50,6 +50,7 @@
512
513 #include <linux/irq.h>
514
515+
516 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
517
518 int hlt_counter;
519@@ -736,7 +737,7 @@
520 {
521 int error;
522 char * filename;
523-
524+
525 filename = getname((char *) regs.ebx);
526 error = PTR_ERR(filename);
527 if (IS_ERR(filename))
528diff -urN linux/arch/i386/kernel/ptrace.c linux.grsec/arch/i386/kernel/ptrace.c
529--- linux/arch/i386/kernel/ptrace.c Fri Jul 20 21:39:55 2001
530+++ linux.grsec/arch/i386/kernel/ptrace.c Sun Sep 30 01:54:18 2001
531@@ -20,7 +20,10 @@
532 #include <asm/processor.h>
533 #include <asm/i387.h>
534 #include <asm/debugreg.h>
535-
536+#ifdef CONFIG_GRKERNSEC_CHROOT
537+#include <linux/grsecurity.h>
538+extern struct task_struct *child_reaper;
539+#endif
540 /*
541 * does not yet catch signals sent when the child dies.
542 * in exit.c or in signal.c.
543@@ -177,6 +180,29 @@
544 }
545 if (child->p_pptr != current)
546 goto out_tsk;
547+
548+#ifdef CONFIG_GRKERNSEC_CHROOT
549+ if(grsec_enable_chroot &&
550+ !( (current->fs->root->d_inode->i_dev ==
551+ child_reaper->fs->root->d_inode->i_dev) &&
552+ (current->fs->root->d_inode->i_ino ==
553+ child_reaper->fs->root->d_inode->i_ino) ) &&
554+ !( (current->fs->root->d_inode->i_dev ==
555+ child->fs->root->d_inode->i_dev) &&
556+ (current->fs->root->d_inode->i_ino ==
557+ child->fs->root->d_inode->i_ino) ) ) {
558+ security_alert("denied ptrace of process(%.16s:%d) within chroot() jail "
559+ "(%.32s:%lu) by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), "
560+ "UID (%d), EUID(%d)","ptrace from chroot()",
561+ child->comm,child->pid,kdevname(current->fs->root->d_inode->i_dev),
562+ current->fs->root->d_inode->i_ino, current->comm, current->pid,
563+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
564+ current->p_pptr->uid,current->p_pptr->euid);
565+ goto out_tsk;
566+ }
567+#endif
568+
569+
570 switch (request) {
571 /* when I and D space are separate, these will need to be fixed. */
572 case PTRACE_PEEKTEXT: /* read word at location addr. */
573diff -urN linux/arch/i386/kernel/signal.c linux.grsec/arch/i386/kernel/signal.c
574--- linux/arch/i386/kernel/signal.c Wed Jul 4 23:41:33 2001
575+++ linux.grsec/arch/i386/kernel/signal.c Sun Sep 30 01:54:18 2001
576@@ -7,6 +7,7 @@
577 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
578 */
579
580+#include <linux/config.h>
581 #include <linux/sched.h>
582 #include <linux/mm.h>
583 #include <linux/smp.h>
584@@ -23,6 +24,10 @@
585 #include <asm/uaccess.h>
586 #include <asm/i387.h>
587
588+#ifdef CONFIG_GRKERNSEC_STACK
589+#include <linux/grsecurity.h>
590+#endif
591+
592 #define DEBUG_SIG 0
593
594 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
595@@ -420,11 +425,15 @@
596 if (ka->sa.sa_flags & SA_RESTORER) {
597 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
598 } else {
599+#ifdef CONFIG_GRKERNSEC_STACK
600+ err |= __put_user(MAGIC_SIGRETURN, &frame->pretcode);
601+#else
602 err |= __put_user(frame->retcode, &frame->pretcode);
603 /* This is popl %eax ; movl $,%eax ; int $0x80 */
604 err |= __put_user(0xb858, (short *)(frame->retcode+0));
605 err |= __put_user(__NR_sigreturn, (int *)(frame->retcode+2));
606 err |= __put_user(0x80cd, (short *)(frame->retcode+6));
607+#endif
608 }
609
610 if (err)
611@@ -495,11 +504,15 @@
612 if (ka->sa.sa_flags & SA_RESTORER) {
613 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
614 } else {
615+#ifdef CONFIG_GRKERNSEC_STACK
616+ err |= __put_user(MAGIC_RT_SIGRETURN, &frame->pretcode);
617+#else
618 err |= __put_user(frame->retcode, &frame->pretcode);
619 /* This is movl $,%eax ; int $0x80 */
620 err |= __put_user(0xb8, (char *)(frame->retcode+0));
621 err |= __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1));
622 err |= __put_user(0x80cd, (short *)(frame->retcode+5));
623+#endif
624 }
625
626 if (err)
627@@ -556,6 +569,18 @@
628 regs->eip -= 2;
629 }
630 }
631+
632+#ifdef CONFIG_GRKERNSEC_PAX
633+ /* PaX: clean up as our trace attempt became obsolete */
634+ if ((current->flags & PF_PAX_PAGEEXEC) && (current->ptrace & PT_PAX_TRACE)) {
635+ if (!(current->ptrace & PT_PAX_OLDTF)) {
636+ regs->eflags &= ~TF_MASK;
637+ }
638+ current->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
639+ current->thread.pax_faults.eip = 0;
640+ current->thread.pax_faults.count = 0;
641+ }
642+#endif
643
644 /* Set up the stack frame */
645 if (ka->sa.sa_flags & SA_SIGINFO)
646diff -urN linux/arch/i386/kernel/traps.c linux.grsec/arch/i386/kernel/traps.c
647--- linux/arch/i386/kernel/traps.c Sun Sep 30 01:30:54 2001
648+++ linux.grsec/arch/i386/kernel/traps.c Sun Sep 30 01:54:18 2001
649@@ -52,6 +52,10 @@
650
651 #include <linux/irq.h>
652
653+#ifdef CONFIG_GRKERNSEC_STACK
654+#include <linux/grsecurity.h>
655+#endif
656+
657 asmlinkage int system_call(void);
658 #if defined(CONFIG_KDB)
659 asmlinkage int kdb_call(void);
660@@ -489,15 +493,185 @@
661 DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
662 DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
663 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
664-
665+#if defined(CONFIG_GRKERNSEC_STACK) && defined(CONFIG_GRKERNSEC_STACK_GCC)
666+static unsigned long *get_reg(struct pt_regs *regs, unsigned char regnum)
667+{
668+ switch (regnum) {
669+ case 0: return &regs->eax;
670+ case 1: return &regs->ecx;
671+ case 2: return &regs->edx;
672+ case 3: return &regs->ebx;
673+ case 4: return &regs->esp;
674+ case 5: return &regs->ebp;
675+ case 6: return &regs->esi;
676+ case 7: return &regs->edi;
677+ }
678+ return NULL;
679+}
680+static unsigned long get_modrm(struct pt_regs *regs, int *err)
681+{
682+ unsigned char modrm, sib;
683+ signed char rel8;
684+ unsigned long rel32;
685+ int size, regnum, scale;
686+ unsigned long index, base, addr, value;
687+
688+ *err |= __get_user(modrm, (unsigned char *)(regs->eip + 1));
689+ size = 2;
690+ regnum = modrm & 7;
691+ addr = *get_reg(regs, regnum);
692+ if (regnum == 4 && (modrm & 0xC0) != 0xC0) {
693+ *err |= __get_user(sib, (unsigned char *)(regs->eip + 2));
694+ size = 3;
695+ scale = sib >> 6;
696+ index = *get_reg(regs, (sib >> 3) & 7);
697+ base = *get_reg(regs, sib & 7);
698+ addr = base + (index << scale);
699+ }
700+
701+ switch (modrm & 0xC0) {
702+ case 0x00:
703+ if (regnum == 5) {
704+ *err |= __get_user(addr,
705+ (unsigned long *)(regs->eip + 2));
706+ size = 6;
707+ }
708+ *err |= __get_user(value, (unsigned long *)addr);
709+ break;
710+
711+ case 0x40:
712+ *err |= __get_user(rel8, (signed char *)(regs->eip + size));
713+ size++;
714+ addr += rel8;
715+ *err |= __get_user(value, (unsigned long *)addr);
716+ break;
717+
718+ case 0x80:
719+ *err |= __get_user(rel32, (unsigned long *)(regs->eip + size));
720+ size += 4;
721+ addr += rel32;
722+ *err |= __get_user(value, (unsigned long *)addr);
723+ break;
724+
725+ case 0xC0:
726+ default:
727+ value = addr;
728+ }
729+
730+ if (*err) return 0;
731+ regs->eip += size;
732+ return value;
733+}
734+#endif
735 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
736 {
737+#ifdef CONFIG_GRKERNSEC_STACK
738+ unsigned long addr;
739+#ifdef CONFIG_GRKERNSEC_STACK_GCC
740+ unsigned char insn;
741+ int err, count;
742+#endif
743+#endif
744 if (regs->eflags & VM_MASK)
745 goto gp_in_vm86;
746
747 if (!(regs->xcs & 3))
748 goto gp_in_kernel;
749-
750+#ifdef CONFIG_GRKERNSEC_STACK
751+/* Check if it was return from a signal handler */
752+ if ((regs->xcs & 0xFFFF) == __USER_CS)
753+ if (*(unsigned char *)regs->eip == 0xC3)
754+ if (!__get_user(addr, (unsigned long *)regs->esp)) {
755+ if ((addr & 0xFFFFFFFE) == MAGIC_SIGRETURN) {
756+/* Call sys_sigreturn() or sys_rt_sigreturn() to restore the context */
757+ regs->esp += 8;
758+ __asm__("movl %3,%%esi\n\t"
759+ "subl %1,%%esp\n\t"
760+ "movl %2,%%ecx\n\t"
761+ "movl %%esp,%%edi\n\t"
762+ "rep; movsl\n\t"
763+ "testl $1,%4\n\t"
764+ "jnz 1f\n\t"
765+ "call sys_sigreturn\n\t"
766+ "leal %3,%%edi\n\t"
767+ "jmp 2f\n\t"
768+ "1:\n\t"
769+ "call sys_rt_sigreturn\n\t"
770+ "leal %3,%%edi\n\t"
771+ "2:\n\t"
772+ "addl %1,%%edi\n\t"
773+ "movl %%esp,%%esi\n\t"
774+ "movl %2,%%ecx\n\t"
775+ "movl (%%edi),%%edi\n\t"
776+ "rep; movsl\n\t"
777+ "movl %%esi,%%esp"
778+ :
779+/* %eax is returned separately */
780+ "=a" (regs->eax)
781+ :
782+ "i" (sizeof(*regs)),
783+ "i" (sizeof(*regs) >> 2),
784+ "m" (regs),
785+ "r" (addr)
786+ :
787+ "cx", "dx", "si", "di", "cc", "memory");
788+ return;
789+ }
790+/*
791+ * * Check if we're returning to the stack area, which is only likely to happen
792+ * * when attempting to exploit a buffer overflow.
793+ * */
794+ if ((addr & 0xFF800000) == 0xBF800000 ||
795+ (addr >= PAGE_OFFSET - _STK_LIM && addr < PAGE_OFFSET))
796+ security_alert("return onto stack by (%.16s:%d), UID(%d), EUID (%d), parent (%.16s:%d), UID(%d), EUID (%d)",
797+ "returns onto stack",
798+ current->comm,current->pid,current->uid,
799+ current->euid,current->p_pptr->comm,current->p_pptr->pid,
800+ current->p_pptr->uid,current->p_pptr->euid);
801+ }
802+
803+#ifdef CONFIG_GRKERNSEC_STACK_GCC
804+/* Check if it could have been a trampoline call */
805+ if ((regs->xcs & 0xFFFF) == __USER_CS)
806+ if (*(unsigned char *)regs->eip == 0xFF)
807+ if (!__get_user(insn, (unsigned char *)(regs->eip + 1)))
808+ if ((insn & 0x38) == 0x10 && insn != 0xD4) { /* call mod r/m */
809+/* First, emulate the call */
810+ err = 0;
811+ addr = get_modrm(regs, &err);
812+ if (!err) {
813+ regs->esp -= 4;
814+ err = __put_user(regs->eip, (unsigned long *)regs->esp);
815+ regs->eip = addr;
816+ }
817+/* Then, start emulating the trampoline itself */
818+ count = 0;
819+ while (!err && !__get_user(insn, (unsigned char *)regs->eip++))
820+ if ((insn & 0xF8) == 0xB8) { /* movl imm32,%reg */
821+/* We only have 8 GP registers, no reason to initialize one twice */
822+ if (count++ >= 8) break;
823+ err |= __get_user(addr, (unsigned long *)regs->eip);
824+ regs->eip += 4;
825+ *get_reg(regs, insn & 7) = addr;
826+ } else
827+ if (insn == 0xFF) {
828+ err |= __get_user(insn, (unsigned char *)regs->eip);
829+ if ((insn & 0xF8) == 0xE0) { /* jmp *%reg */
830+ regs->eip = *get_reg(regs, insn & 7);
831+ if (err) break; else return;
832+ }
833+ break;
834+ } else
835+ if (insn == 0xE9) { /* jmp rel32 */
836+ err |= __get_user(addr, (unsigned long *)regs->eip);
837+ if (err) break;
838+ regs->eip += 4 + addr;
839+ return;
840+ } else
841+ break;
842+ }
843+#endif
844+#endif
845 current->thread.error_code = error_code;
846 current->thread.trap_no = 13;
847 force_sig(SIGSEGV, current);
848@@ -720,6 +894,10 @@
849 inb(0x71); /* dummy */
850 }
851
852+#ifdef CONFIG_GRKERNSEC_PAX
853+void pax_handle_ptes(struct task_struct *tsk);
854+#endif
855+
856 /*
857 * Our handling of the processor debug registers is non-trivial.
858 * We do not clear them on entry and exit from the kernel. Therefore
859@@ -759,6 +937,23 @@
860 return;
861 #endif
862
863+#ifdef CONFIG_GRKERNSEC_PAX
864+ /* PaX: clean up */
865+ /* PaX: clean up */
866+ if ((tsk->flags & PF_PAX_PAGEEXEC) && (condition & DR_STEP) && (tsk->ptrace & PT_PAX_TRACE)) {
867+ tsk->ptrace &= ~PT_PAX_TRACE;
868+ pax_handle_ptes(tsk);
869+ if (!(tsk->ptrace & PT_PAX_KEEPTF) && !(tsk->ptrace & PT_PAX_OLDTF))
870+ regs->eflags &= ~TF_MASK;
871+ tsk->ptrace &= ~PT_PAX_KEEPTF;
872+ if (!(tsk->ptrace & PT_PAX_OLDTF)) {
873+ condition &= ~DR_STEP;
874+ if (!(condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)))
875+ return;
876+ }
877+ tsk->ptrace &= ~PT_PAX_OLDTF;
878+ }
879+#endif
880 /* Mask out spurious debug traps due to lazy DR7 setting */
881 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
882 if (!tsk->thread.debugreg[7])
883diff -urN linux/arch/i386/mm/fault.c linux.grsec/arch/i386/mm/fault.c
884--- linux/arch/i386/mm/fault.c Tue May 15 09:16:51 2001
885+++ linux.grsec/arch/i386/mm/fault.c Sun Sep 30 01:55:48 2001
886@@ -4,6 +4,7 @@
887 * Copyright (C) 1995 Linus Torvalds
888 */
889
890+#include <linux/config.h>
891 #include <linux/signal.h>
892 #include <linux/sched.h>
893 #include <linux/kernel.h>
894@@ -17,6 +18,9 @@
895 #include <linux/smp_lock.h>
896 #include <linux/interrupt.h>
897 #include <linux/init.h>
898+#ifdef CONFIG_GRKERNSEC_PAX
899+#include <linux/unistd.h>
900+#endif
901
902 #include <asm/system.h>
903 #include <asm/uaccess.h>
904@@ -103,23 +107,31 @@
905 * bit 1 == 0 means read, 1 means write
906 * bit 2 == 0 means kernel, 1 means user-mode
907 */
908+#ifdef CONFIG_GRKERNSEC_PAX
909+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
910+#else
911 asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
912+#endif
913 {
914 struct task_struct *tsk;
915 struct mm_struct *mm;
916 struct vm_area_struct * vma;
917+#ifndef CONFIG_GRKERNSEC_PAX
918 unsigned long address;
919+#endif
920 unsigned long page;
921 unsigned long fixup;
922 int write;
923 siginfo_t info;
924
925+#ifndef CONFIG_GRKERNSEC_PAX
926 /* get the address */
927 __asm__("movl %%cr2,%0":"=r" (address));
928
929 /* It's safe to allow irq's after cr2 has been saved */
930 if (regs->eflags & X86_EFLAGS_IF)
931 local_irq_enable();
932+#endif
933
934 tsk = current;
935
936@@ -177,21 +189,37 @@
937 good_area:
938 info.si_code = SEGV_ACCERR;
939 write = 0;
940+#ifdef CONFIG_GRKERNSEC_PAX
941+ switch (error_code & 7) {
942+#else
943 switch (error_code & 3) {
944+#endif
945 default: /* 3: write, present */
946 #ifdef TEST_VERIFY_AREA
947 if (regs->cs == KERNEL_CS)
948 printk("WP fault at %08lx\n", regs->eip);
949 #endif
950 /* fall through */
951+#ifdef CONFIG_GRKERNSEC_PAX
952+ case 7: /* PaX: write, present, some protection violation */
953+#endif
954 case 2: /* write, not present */
955+#ifdef CONFIG_GRKERNSEC_PAX
956+ case 6:
957+#endif
958 if (!(vma->vm_flags & VM_WRITE))
959 goto bad_area;
960 write++;
961 break;
962 case 1: /* read, present */
963 goto bad_area;
964+#ifdef CONFIG_GRKERNSEC_PAX
965+ case 5: /* PaX: read, present, protection violation */
966+#endif
967 case 0: /* read, not present */
968+#ifdef CONFIG_GRKERNSEC_PAX
969+ case 4:
970+#endif
971 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
972 goto bad_area;
973 }
974@@ -358,3 +386,440 @@
975 return;
976 }
977 }
978+#ifdef CONFIG_GRKERNSEC_PAX
979+/* PaX: called with the page_table_lock spinlock held */
980+static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
981+{
982+ pgd_t *pgd;
983+ pmd_t *pmd;
984+
985+ pgd = pgd_offset(mm, address);
986+ if (!pgd || !pgd_present(*pgd))
987+ return 0;
988+ pmd = pmd_offset(pgd, address);
989+ if (!pmd || !pmd_present(*pmd))
990+ return 0;
991+ return pte_offset(pmd, address);
992+}
993+
994+/*
995+ * PaX: decide what to do with offenders
996+ *
997+ * returns 0 when access should be allowed
998+ * 1 when task should be killed
999+ * 2 when sigreturn trampoline was detected
1000+ * 3 when rt_sigreturn trampoline was detected
1001+ * 4 when gcc trampoline was detected
1002+ */
1003+static int pax_handle_read_fault(struct pt_regs *regs, unsigned long address)
1004+{
1005+ static unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
1006+ int err;
1007+
1008+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1009+ if (!(current->flags & PF_PAX_EMUTRAMP))
1010+ return 1;
1011+ { /* PaX: sigreturn emulation */
1012+ unsigned char pop, mov;
1013+ unsigned short sys;
1014+ unsigned long nr;
1015+
1016+ err = __get_user(pop, (unsigned char *)(regs->eip));
1017+ err |= __get_user(mov, (unsigned char *)(regs->eip + 1));
1018+ err |= __get_user(nr, (unsigned long *)(regs->eip + 2));
1019+ err |= __get_user(sys, (unsigned short *)(regs->eip + 6));
1020+
1021+ if (!err) {
1022+ if (pop == 0x58 &&
1023+ mov == 0xb8 &&
1024+ nr == __NR_sigreturn &&
1025+ sys == 0x80cd)
1026+ {
1027+ regs->esp += 4;
1028+ regs->eax = nr;
1029+ regs->eip += 8;
1030+ return 2;
1031+ }
1032+ }
1033+ }
1034+
1035+ { /* PaX: rt_sigreturn emulation */
1036+ unsigned char mov;
1037+ unsigned short sys;
1038+ unsigned long nr;
1039+
1040+ err = __get_user(mov, (unsigned char *)(regs->eip));
1041+ err |= __get_user(nr, (unsigned long *)(regs->eip + 1));
1042+ err |= __get_user(sys, (unsigned short *)(regs->eip + 5));
1043+
1044+ if (!err) {
1045+ if (mov == 0xb8 &&
1046+ nr == __NR_rt_sigreturn &&
1047+ sys == 0x80cd)
1048+ {
1049+ regs->eax = nr;
1050+ regs->eip += 7;
1051+ return 3;
1052+ }
1053+ }
1054+ }
1055+
1056+ { /* PaX: gcc trampoline emulation #1 */
1057+ unsigned char mov1, mov2;
1058+ unsigned short jmp;
1059+ unsigned long addr1, addr2, ret;
1060+
1061+ err = __get_user(mov1, (unsigned char *)(regs->eip));
1062+ err |= __get_user(addr1, (unsigned long *)(regs->eip + 1));
1063+ err |= __get_user(mov2, (unsigned char *)(regs->eip + 5));
1064+ err |= __get_user(addr2, (unsigned long *)(regs->eip + 6));
1065+ err |= __get_user(jmp, (unsigned short *)(regs->eip + 10));
1066+ err |= __get_user(ret, (unsigned long *)(regs->esp));
1067+
1068+ if (!err) {
1069+ unsigned short call;
1070+
1071+ err = __get_user(call, (unsigned short *)(ret-2));
1072+ if (!err) {
1073+ if ((mov1 & 0xF8) == 0xB8 &&
1074+ (mov2 & 0xF8) == 0xB8 &&
1075+ (mov1 & 0x07) != (mov2 & 0x07) &&
1076+ (jmp & 0xF8FF) == 0xE0FF &&
1077+ (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
1078+ (call & 0xF8FF) == 0xD0FF &&
1079+ (regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]]))
1080+ {
1081+ ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
1082+ ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
1083+ regs->eip = addr2;
1084+ return 4;
1085+ }
1086+ }
1087+ }
1088+ }
1089+
1090+ { /* PaX: gcc trampoline emulation #2 */
1091+ unsigned char mov, jmp;
1092+ unsigned long addr1, addr2, ret;
1093+
1094+ err = __get_user(mov, (unsigned char *)(regs->eip));
1095+ err |= __get_user(addr1, (unsigned long *)(regs->eip + 1));
1096+ err |= __get_user(jmp, (unsigned char *)(regs->eip + 5));
1097+ err |= __get_user(addr2, (unsigned long *)(regs->eip + 6));
1098+ err |= __get_user(ret, (unsigned long *)(regs->esp));
1099+
1100+ if (!err) {
1101+ unsigned short call;
1102+
1103+ err = __get_user(call, (unsigned short *)(ret-2));
1104+ if (!err) {
1105+ if ((mov & 0xF8) == 0xB8 &&
1106+ jmp == 0xE9 &&
1107+ (call & 0xF8FF) == 0xD0FF &&
1108+ (regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]]))
1109+ {
1110+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1111+ regs->eip += addr2 + 10;
1112+ return 4;
1113+ }
1114+ }
1115+ }
1116+ }
1117+#endif
1118+
1119+ return 1; /* PaX in action */
1120+}
1121+
1122+static int pax_handle_opcode(struct task_struct *tsk, struct pt_regs *regs)
1123+{
1124+ unsigned long opsize = 1;
1125+ unsigned long opsize_override = 0;
1126+ unsigned long i;
1127+
1128+ if (regs->eflags & TF_MASK)
1129+ tsk->ptrace |= PT_PAX_OLDTF;
1130+ else
1131+ tsk->ptrace &= ~PT_PAX_OLDTF;
1132+ tsk->ptrace &= ~PT_PAX_KEEPTF;
1133+
1134+ for (i=0; i<15; i++) {
1135+ unsigned char opcode;
1136+ if (__get_user(opcode, (unsigned char*)(regs->eip+i)))
1137+ break;
1138+ switch (opcode) {
1139+ case 0x26:
1140+ case 0x2E:
1141+ case 0x36:
1142+ case 0x3E:
1143+ case 0x64:
1144+ case 0x65:
1145+ case 0x67:
1146+ case 0xF0:
1147+ case 0xF2:
1148+ case 0xF3:
1149+ break;
1150+
1151+ case 0x66:
1152+ opsize_override = 1;
1153+ break;
1154+
1155+ case 0x9C: /* PUSHF */
1156+ if (opsize ^ opsize_override) {
1157+ __put_user(regs->eflags & 0x00FCFFFFul, (unsigned long*)(regs->esp-4));
1158+ regs->esp -= 4;
1159+ } else {
1160+ __put_user(regs->eflags, (unsigned short*)(regs->esp-2));
1161+ regs->esp -= 2;
1162+ }
1163+ regs->eip += i + 1;
1164+ return 1;
1165+
1166+ case 0x9D: /* POPF */
1167+ case 0xCF: /* IRET */
1168+ tsk->ptrace |= PT_PAX_KEEPTF;
1169+ return 0;
1170+
1171+ default:
1172+ return 0;
1173+ }
1174+ }
1175+ return 0;
1176+}
1177+
1178+static inline void pax_handle_pte(struct mm_struct *mm, unsigned long address)
1179+{
1180+ pte_t *pte;
1181+ pte = pax_get_pte(mm, address);
1182+ if (pte) {
1183+ set_pte(pte, pte_exprotect(*pte));
1184+ __flush_tlb_one(address);
1185+ }
1186+}
1187+
1188+#define PAX_SPIN_COUNT 256
1189+
1190+void pax_handle_ptes(struct task_struct *tsk)
1191+{
1192+ struct mm_struct *mm;
1193+
1194+ mm = tsk->mm;
1195+ spin_lock(&mm->page_table_lock);
1196+ switch (tsk->thread.pax_faults.count) {
1197+ default:
1198+ printk(KERN_ERR "PAX: wtf: %s:%d, %ld\n", tsk->comm, tsk->pid, tsk->thread.pax_faults.count);
1199+ break;
1200+
1201+ case PAX_SPIN_COUNT+4:
1202+ pax_handle_pte(mm, tsk->thread.pax_faults.addresses[3]);
1203+
1204+ case PAX_SPIN_COUNT+3:
1205+ pax_handle_pte(mm, tsk->thread.pax_faults.addresses[2]);
1206+
1207+ case PAX_SPIN_COUNT+2:
1208+ pax_handle_pte(mm, tsk->thread.pax_faults.addresses[1]);
1209+
1210+ case PAX_SPIN_COUNT+1:
1211+ pax_handle_pte(mm, tsk->thread.pax_faults.addresses[0]);
1212+ }
1213+ spin_unlock(&mm->page_table_lock);
1214+ tsk->thread.pax_faults.eip = 0;
1215+ tsk->thread.pax_faults.count = 0;
1216+}
1217+
1218+/*
1219+ * PaX: handle the extra page faults or pass it down to the original handler
1220+ *
1221+ * returns 0 when nothing special was detected
1222+ * 1 when sigreturn trampoline (syscall) has to be emulated
1223+ */
1224+asmlinkage int pax_do_page_fault(struct pt_regs *regs, unsigned long error_code)
1225+{
1226+ struct task_struct *tsk = current;
1227+ struct mm_struct *mm = current->mm;
1228+ unsigned long address;
1229+ pte_t *pte;
1230+ unsigned char pte_mask = _PAGE_ACCESSED | _PAGE_USER;
1231+ int ret;
1232+ unsigned long i;
1233+
1234+ __asm__("movl %%cr2,%0":"=r" (address));
1235+
1236+ /* It's safe to allow irq's after cr2 has been saved */
1237+ if (regs->eflags & X86_EFLAGS_IF)
1238+ local_irq_enable();
1239+
1240+ if ((error_code & 5) != 5 || address >= TASK_SIZE || regs->xcs != __USER_CS || (VM_MASK & regs->eflags))
1241+ goto chain;
1242+
1243+ /* PaX: it's our fault, let's handle it if we can */
1244+
1245+ if (error_code == 7) {
1246+ pte_mask |= _PAGE_DIRTY;
1247+ /* PaX: take a look at read faults before acquiring any locks */
1248+ } else if (regs->eip == address) { /* read/instruction fetch attempt from a protected page in user mode */
1249+ ret = pax_handle_read_fault(regs, address);
1250+ switch (ret) {
1251+ case 4:
1252+ tsk->thread.pax_faults.eip = 0;
1253+ tsk->thread.pax_faults.count = 0;
1254+ return 0;
1255+
1256+ case 3:
1257+ case 2:
1258+ tsk->thread.pax_faults.eip = 0;
1259+ tsk->thread.pax_faults.count = 0;
1260+ return 1;
1261+
1262+ default:
1263+ case 1: {
1264+ char* buffer = (char*)__get_free_page(GFP_KERNEL);
1265+ char* path=NULL;
1266+
1267+ if (buffer) {
1268+ struct vm_area_struct* vma;
1269+
1270+ down_read(&mm->mmap_sem);
1271+ vma = mm->mmap;
1272+ while (vma) {
1273+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
1274+ break;
1275+ }
1276+ vma = vma->vm_next;
1277+ }
1278+ if (vma)
1279+ path = d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt, buffer, PAGE_SIZE);
1280+ up_read(&mm->mmap_sem);
1281+ }
1282+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, EIP: %08lX, ESP: %08lX\n", path, tsk->comm, tsk->pid, regs->eip, regs->esp);
1283+ if (buffer) free_page((unsigned long)buffer);
1284+ printk(KERN_ERR "PAX: bytes at EIP: ");
1285+ for (i = 0; i < 20; i++) {
1286+ unsigned char c;
1287+ if (__get_user(c, (unsigned char*)(regs->eip+i))) {
1288+ printk("<invalid address>.");
1289+ break;
1290+ }
1291+ printk("%02x ", c);
1292+ }
1293+ printk("\n");
1294+
1295+ tsk->thread.pax_faults.eip = 0;
1296+ tsk->thread.pax_faults.count = 0;
1297+ tsk->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
1298+ regs->eflags &= ~TF_MASK;
1299+ tsk->thread.cr2 = address;
1300+ tsk->thread.error_code = error_code;
1301+ tsk->thread.trap_no = 14;
1302+ force_sig(SIGKILL,tsk);
1303+ return 0;
1304+ }
1305+
1306+ case 0:
1307+ }
1308+ }
1309+
1310+ spin_lock(&mm->page_table_lock);
1311+ pte = pax_get_pte(mm, address);
1312+ if (!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte)) {
1313+ spin_unlock(&mm->page_table_lock);
1314+ goto chain;
1315+ }
1316+
1317+ if ((error_code == 7) && !pte_write(*pte)) { /* write attempt to a protected page in user mode */
1318+ spin_unlock(&mm->page_table_lock);
1319+ goto chain;
1320+ }
1321+
1322+ /*
1323+ * PaX: fill DTLB with user rights and retry
1324+ */
1325+ if (regs->eip != tsk->thread.pax_faults.eip) { /* detect DTLB trashing */
1326+ tsk->thread.pax_faults.eip = regs->eip;
1327+ tsk->thread.pax_faults.count = 0;
1328+
1329+pax_emu:
1330+ __asm__ __volatile__ (
1331+ "orb %2,%1\n"
1332+ "invlpg %0\n"
1333+ "testb $0,%0\n"
1334+ "xorb %3,%1\n"
1335+ :
1336+ : "m" (*(char*)address), "m" (*(char*)pte) , "r" (pte_mask) , "i" (_PAGE_USER)
1337+ : "memory", "cc");
1338+ spin_unlock(&mm->page_table_lock);
1339+ return 0;
1340+ }
1341+
1342+ if (tsk->thread.pax_faults.count < PAX_SPIN_COUNT) {
1343+ ++tsk->thread.pax_faults.count;
1344+ goto pax_emu;
1345+ }
1346+ spin_unlock(&mm->page_table_lock);
1347+
1348+ if (tsk->thread.pax_faults.count == PAX_SPIN_COUNT) {
1349+ if (pax_handle_opcode(tsk, regs)) {
1350+ tsk->thread.pax_faults.eip = 0;
1351+ tsk->thread.pax_faults.count = 0;
1352+ tsk->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
1353+ return 0;
1354+ } else {
1355+ ++tsk->thread.pax_faults.count;
1356+ }
1357+ }
1358+
1359+ if (tsk->thread.pax_faults.count > PAX_SPIN_COUNT+1+3) {
1360+ printk(KERN_ERR "PAX: preventing DoS: %s:%d, EIP: %08lX, ESP: %08lX\n", tsk->comm, tsk->pid, regs->eip, regs->esp);
1361+ printk(KERN_ERR "PAX: bytes at EIP: ");
1362+ for (i = 0; i < 20; i++) {
1363+ unsigned char c;
1364+ if (__get_user(c, (unsigned char*)(regs->eip+i))) {
1365+ printk("<invalid address>.");
1366+ break;
1367+ }
1368+ printk("%02x ", c);
1369+ }
1370+ printk("\n");
1371+
1372+ tsk->thread.pax_faults.eip = 0;
1373+ tsk->thread.pax_faults.count = 0;
1374+ tsk->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
1375+ regs->eflags &= ~TF_MASK;
1376+ tsk->thread.cr2 = address;
1377+ tsk->thread.error_code = error_code;
1378+ tsk->thread.trap_no = 14;
1379+ force_sig(SIGKILL,tsk);
1380+ return 0;
1381+ }
1382+
1383+ spin_lock(&mm->page_table_lock);
1384+ pte = pax_get_pte(mm, address);
1385+ if (pte) {
1386+ set_pte(pte, pte_mkexec(*pte));
1387+ __flush_tlb_one(address);
1388+ tsk->thread.pax_faults.addresses[tsk->thread.pax_faults.count-PAX_SPIN_COUNT-1] = address;
1389+ ++tsk->thread.pax_faults.count;
1390+ }
1391+ spin_unlock(&mm->page_table_lock);
1392+ tsk->ptrace |= PT_PAX_TRACE;
1393+ regs->eflags |= TF_MASK;
1394+
1395+#if 0
1396+ if (tsk->thread.pax_faults.count > PAX_SPIN_COUNT+1+1) {
1397+ printk(KERN_ERR "PAX: DTLB trashing, level %ld: %s:%d,"
1398+ "EIP: %08lX, ESP: %08lX, cr2: %08lX\n",
1399+ tsk->thread.pax_faults.count - (PAX_SPIN_COUNT+1),
1400+ tsk->comm, tsk->pid, regs->eip, regs->esp, address);
1401+ printk(KERN_ERR "PAX: DTLB trashing, %08lX, %08lX, %08lX\n",
1402+ tsk->thread.pax_faults.addresses[0],
1403+ tsk->thread.pax_faults.addresses[1],
1404+ tsk->thread.pax_faults.addresses[2]);
1405+ }
1406+#endif
1407+ return 0;
1408+
1409+chain:
1410+ do_page_fault(regs, error_code, address);
1411+ return 0;
1412+}
1413+#endif
1414+
1415diff -urN linux/arch/i386/mm/init.c linux.grsec/arch/i386/mm/init.c
1416--- linux/arch/i386/mm/init.c Sat Apr 21 01:15:20 2001
1417+++ linux.grsec/arch/i386/mm/init.c Sun Sep 30 01:54:18 2001
1418@@ -397,7 +397,11 @@
1419 pmd = pmd_offset(pgd, vaddr);
1420 pte = pte_offset(pmd, vaddr);
1421 old_pte = *pte;
1422+#ifdef CONFIG_GRKERNSEC_PAX
1423+ *pte = mk_pte_phys(0, PAGE_READONLY_EXEC);
1424+#else
1425 *pte = mk_pte_phys(0, PAGE_READONLY);
1426+#endif
1427 local_flush_tlb();
1428
1429 boot_cpu_data.wp_works_ok = do_test_wp_bit(vaddr);
1430diff -urN linux/arch/ia64/config.in linux.grsec/arch/ia64/config.in
1431--- linux/arch/ia64/config.in Wed Apr 18 02:19:24 2001
1432+++ linux.grsec/arch/ia64/config.in Sun Sep 30 01:54:18 2001
1433@@ -281,3 +281,12 @@
1434 bool 'Disable VHPT' CONFIG_DISABLE_VHPT
1435
1436 endmenu
1437+
1438+mainmenu_option next_comment
1439+comment 'Grsecurity'
1440+bool 'Grsecurity' CONFIG_GRKERNSEC
1441+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1442+ source grsecurity/Config.in
1443+fi
1444+endmenu
1445+
1446diff -urN linux/arch/m68k/config.in linux.grsec/arch/m68k/config.in
1447--- linux/arch/m68k/config.in Sun Sep 30 01:30:50 2001
1448+++ linux.grsec/arch/m68k/config.in Sun Sep 30 01:54:18 2001
1449@@ -548,3 +548,12 @@
1450 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
1451 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
1452 endmenu
1453+
1454+mainmenu_option next_comment
1455+comment 'Grsecurity'
1456+bool 'Grsecurity' CONFIG_GRKERNSEC
1457+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1458+ source grsecurity/Config.in
1459+fi
1460+endmenu
1461+
1462diff -urN linux/arch/mips/config.in linux.grsec/arch/mips/config.in
1463--- linux/arch/mips/config.in Sun Sep 30 01:30:50 2001
1464+++ linux.grsec/arch/mips/config.in Sun Sep 30 01:54:18 2001
1465@@ -509,3 +509,12 @@
1466 bool 'Run uncached' CONFIG_MIPS_UNCACHED
1467 fi
1468 endmenu
1469+
1470+mainmenu_option next_comment
1471+comment 'Grsecurity'
1472+bool 'Grsecurity' CONFIG_GRKERNSEC
1473+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1474+ source grsecurity/Config.in
1475+fi
1476+endmenu
1477+
1478diff -urN linux/arch/mips64/config.in linux.grsec/arch/mips64/config.in
1479--- linux/arch/mips64/config.in Wed Jul 4 20:50:39 2001
1480+++ linux.grsec/arch/mips64/config.in Sun Sep 30 01:54:18 2001
1481@@ -274,3 +274,12 @@
1482 bool 'Run uncached' CONFIG_MIPS_UNCACHED
1483 fi
1484 endmenu
1485+
1486+mainmenu_option next_comment
1487+comment 'Grsecurity'
1488+bool 'Grsecurity' CONFIG_GRKERNSEC
1489+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1490+ source grsecurity/Config.in
1491+fi
1492+endmenu
1493+
1494diff -urN linux/arch/parisc/config.in linux.grsec/arch/parisc/config.in
1495--- linux/arch/parisc/config.in Wed Apr 18 02:19:25 2001
1496+++ linux.grsec/arch/parisc/config.in Sun Sep 30 01:54:18 2001
1497@@ -208,3 +208,11 @@
1498 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
1499 endmenu
1500
1501+mainmenu_option next_comment
1502+comment 'Grsecurity'
1503+bool 'Grsecurity' CONFIG_GRKERNSEC
1504+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1505+ source grsecurity/Config.in
1506+fi
1507+endmenu
1508+
1509diff -urN linux/arch/ppc/config.in linux.grsec/arch/ppc/config.in
1510--- linux/arch/ppc/config.in Sun Sep 30 01:30:50 2001
1511+++ linux.grsec/arch/ppc/config.in Sun Sep 30 01:54:18 2001
1512@@ -379,3 +379,12 @@
1513 bool 'Include kgdb kernel debugger' CONFIG_KGDB
1514 bool 'Include xmon kernel debugger' CONFIG_XMON
1515 endmenu
1516+
1517+mainmenu_option next_comment
1518+comment 'Grsecurity'
1519+bool 'Grsecurity' CONFIG_GRKERNSEC
1520+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1521+ source grsecurity/Config.in
1522+fi
1523+endmenu
1524+
1525diff -urN linux/arch/s390/config.in linux.grsec/arch/s390/config.in
1526--- linux/arch/s390/config.in Wed Apr 18 02:19:25 2001
1527+++ linux.grsec/arch/s390/config.in Sun Sep 30 01:54:19 2001
1528@@ -70,3 +70,11 @@
1529 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
1530 endmenu
1531
1532+mainmenu_option next_comment
1533+comment 'Grsecurity'
1534+bool 'Grsecurity' CONFIG_GRKERNSEC
1535+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1536+ source grsecurity/Config.in
1537+fi
1538+endmenu
1539+
1540diff -urN linux/arch/s390x/config.in linux.grsec/arch/s390x/config.in
1541--- linux/arch/s390x/config.in Wed Apr 18 02:19:25 2001
1542+++ linux.grsec/arch/s390x/config.in Sun Sep 30 01:54:19 2001
1543@@ -74,3 +74,11 @@
1544 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
1545 endmenu
1546
1547+mainmenu_option next_comment
1548+comment 'Grsecurity'
1549+bool 'Grsecurity' CONFIG_GRKERNSEC
1550+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1551+ source grsecurity/Config.in
1552+fi
1553+endmenu
1554+
1555diff -urN linux/arch/sh/config.in linux.grsec/arch/sh/config.in
1556--- linux/arch/sh/config.in Wed Jun 27 22:55:29 2001
1557+++ linux.grsec/arch/sh/config.in Sun Sep 30 01:54:19 2001
1558@@ -326,3 +326,12 @@
1559 bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
1560 fi
1561 endmenu
1562+
1563+mainmenu_option next_comment
1564+comment 'Grsecurity'
1565+bool 'Grsecurity' CONFIG_GRKERNSEC
1566+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1567+ source grsecurity/Config.in
1568+fi
1569+endmenu
1570+
1571diff -urN linux/arch/sparc/config.in linux.grsec/arch/sparc/config.in
1572--- linux/arch/sparc/config.in Sun Sep 30 01:30:52 2001
1573+++ linux.grsec/arch/sparc/config.in Sun Sep 30 01:54:19 2001
1574@@ -274,3 +274,12 @@
1575
1576 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
1577 endmenu
1578+
1579+mainmenu_option next_comment
1580+comment 'Grsecurity'
1581+bool 'Grsecurity' CONFIG_GRKERNSEC
1582+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1583+ source grsecurity/Config.in
1584+fi
1585+endmenu
1586+
1587diff -urN linux/arch/sparc64/config.in linux.grsec/arch/sparc64/config.in
1588--- linux/arch/sparc64/config.in Sun Sep 30 01:30:50 2001
1589+++ linux.grsec/arch/sparc64/config.in Sun Sep 30 01:54:19 2001
1590@@ -289,3 +289,12 @@
1591 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
1592 #bool 'ECache flush trap support at ta 0x72' CONFIG_EC_FLUSH_TRAP
1593 endmenu
1594+
1595+mainmenu_option next_comment
1596+comment 'Grsecurity'
1597+bool 'Grsecurity' CONFIG_GRKERNSEC
1598+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1599+ source grsecurity/Config.in
1600+fi
1601+endmenu
1602+
1603diff -urN linux/drivers/char/mem.c linux.grsec/drivers/char/mem.c
1604--- linux/drivers/char/mem.c Wed Jul 11 01:07:46 2001
1605+++ linux.grsec/drivers/char/mem.c Sun Sep 30 01:54:19 2001
1606@@ -205,9 +205,20 @@
1607 /*
1608 * Don't dump addresses that are not real memory to a core file.
1609 */
1610+#ifdef CONFIG_GRKERNSEC_PAX
1611+ if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) {
1612+#else
1613 if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
1614+#endif
1615 vma->vm_flags |= VM_IO;
1616-
1617+#ifdef CONFIG_GRKERNSEC_PAX
1618+ /* it turned out to be device memory (eg. video RAM), don't apply PaX */
1619+ if (!(vma->vm_flags & VM_EXEC)) {
1620+ vma->vm_flags |= VM_EXEC | VM_MAYEXEC;
1621+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
1622+ }
1623+ }
1624+#endif
1625 if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
1626 vma->vm_page_prot))
1627 return -EAGAIN;
1628@@ -368,8 +379,11 @@
1629 count = size;
1630
1631 zap_page_range(mm, addr, count);
1632+#ifdef CONFIG_GRKERNSEC_PAX
1633+ zeromap_page_range(addr, count, vma->vm_page_prot);
1634+#else
1635 zeromap_page_range(addr, count, PAGE_COPY);
1636-
1637+#endif
1638 size -= count;
1639 buf += count;
1640 addr += count;
1641diff -urN linux/drivers/char/random.c linux.grsec/drivers/char/random.c
1642--- linux/drivers/char/random.c Mon Jul 2 22:56:41 2001
1643+++ linux.grsec/drivers/char/random.c Sun Sep 30 01:54:19 2001
1644@@ -253,6 +253,12 @@
1645 /*
1646 * Configuration information
1647 */
1648+#ifdef CONFIG_GRKERNSEC_RANDNET
1649+#include <linux/grsecurity.h>
1650+#define DEFAULT_POOL_SIZE_RANDNET 4096
1651+#define SECONDARY_POOL_SIZE_RANDNET 1024
1652+#define BATCH_ENTROPY_SIZE_RANDNET 2048
1653+#endif
1654 #define DEFAULT_POOL_SIZE 512
1655 #define SECONDARY_POOL_SIZE 128
1656 #define BATCH_ENTROPY_SIZE 256
1657@@ -380,8 +386,13 @@
1658 /*
1659 * Static global variables
1660 */
1661+#ifdef CONFIG_GRKERNSEC_RANDPID
1662+struct entropy_store *random_state; /* The default global store */
1663+struct entropy_store *sec_random_state; /* secondary store */
1664+#else
1665 static struct entropy_store *random_state; /* The default global store */
1666 static struct entropy_store *sec_random_state; /* secondary store */
1667+#endif
1668 static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
1669 static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
1670
1671@@ -1383,11 +1394,23 @@
1672 {
1673 int i;
1674
1675- if (create_entropy_store(DEFAULT_POOL_SIZE, &random_state))
1676+ if (create_entropy_store(
1677+#ifdef CONFIG_GRKERNSEC_RANDNET
1678+ grsec_enable_randnet?DEFAULT_POOL_SIZE_RANDNET:
1679+#endif
1680+ DEFAULT_POOL_SIZE, &random_state))
1681 return; /* Error, return */
1682- if (batch_entropy_init(BATCH_ENTROPY_SIZE, random_state))
1683+ if (batch_entropy_init(
1684+#ifdef CONFIG_GRKERNSEC_RANDNET
1685+ grsec_enable_randnet?BATCH_ENTROPY_SIZE_RANDNET:
1686+#endif
1687+ BATCH_ENTROPY_SIZE, random_state))
1688 return; /* Error, return */
1689- if (create_entropy_store(SECONDARY_POOL_SIZE, &sec_random_state))
1690+ if (create_entropy_store(
1691+#ifdef CONFIG_GRKERNSEC_RANDNET
1692+ grsec_enable_randnet?SECONDARY_POOL_SIZE_RANDNET:
1693+#endif
1694+ SECONDARY_POOL_SIZE, &sec_random_state))
1695 return; /* Error, return */
1696 clear_entropy_store(random_state);
1697 clear_entropy_store(sec_random_state);
1698diff -urN linux/drivers/char/vt.c linux.grsec/drivers/char/vt.c
1699--- linux/drivers/char/vt.c Fri Feb 9 20:30:22 2001
1700+++ linux.grsec/drivers/char/vt.c Sun Sep 30 01:54:19 2001
1701@@ -40,6 +40,10 @@
1702 #include <asm/vc_ioctl.h>
1703 #endif /* CONFIG_FB_COMPAT_XPMAC */
1704
1705+#ifdef CONFIG_GRKERNSEC_KBMAP
1706+#include <linux/grsecurity.h>
1707+#endif
1708+
1709 char vt_dont_switch;
1710 extern struct tty_driver console_driver;
1711
1712@@ -174,7 +178,11 @@
1713 val = (i ? K_HOLE : K_NOSUCHMAP);
1714 return put_user(val, &user_kbe->kb_value);
1715 case KDSKBENT:
1716+#ifdef CONFIG_GRKERNSEC_KBMAP
1717+ if (!perm || (grsec_enable_kbmap && !suser()))
1718+#else
1719 if (!perm)
1720+#endif
1721 return -EPERM;
1722 if (!i && v == K_NOSUCHMAP) {
1723 /* disallocate map */
1724@@ -293,7 +301,11 @@
1725 put_user('\0', q);
1726 return ((p && *p) ? -EOVERFLOW : 0);
1727 case KDSKBSENT:
1728+#ifdef CONFIG_GRKERNSEC_KBMAP
1729+ if (!perm || (grsec_enable_kbmap && !suser()))
1730+#else
1731 if (!perm)
1732+#endif
1733 return -EPERM;
1734
1735 q = func_table[i];
1736diff -urN linux/drivers/ieee1394/video1394.c linux.grsec/drivers/ieee1394/video1394.c
1737--- linux/drivers/ieee1394/video1394.c Fri Jul 20 02:48:16 2001
1738+++ linux.grsec/drivers/ieee1394/video1394.c Sun Sep 30 01:54:19 2001
1739@@ -794,7 +794,11 @@
1740 pos=(unsigned long) d->buf;
1741 while (size > 0) {
1742 page = kvirt_to_pa(pos);
1743+#ifdef CONFIG_GRKERNSEC_PAX
1744+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
1745+#else
1746 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1747+#endif
1748 return -EAGAIN;
1749 start+=PAGE_SIZE;
1750 pos+=PAGE_SIZE;
1751diff -urN linux/drivers/media/video/bttv-driver.c linux.grsec/drivers/media/video/bttv-driver.c
1752--- linux/drivers/media/video/bttv-driver.c Tue Jul 17 00:13:32 2001
1753+++ linux.grsec/drivers/media/video/bttv-driver.c Sun Sep 30 01:54:19 2001
1754@@ -2037,7 +2037,11 @@
1755 pos=(unsigned long) btv->fbuffer;
1756 while (size > 0) {
1757 page = kvirt_to_pa(pos);
1758+#ifdef CONFIG_GRKERNSEC_PAX
1759+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
1760+#else
1761 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1762+#endif
1763 return -EAGAIN;
1764 start+=PAGE_SIZE;
1765 pos+=PAGE_SIZE;
1766diff -urN linux/drivers/media/video/cpia.c linux.grsec/drivers/media/video/cpia.c
1767--- linux/drivers/media/video/cpia.c Sun May 20 02:43:06 2001
1768+++ linux.grsec/drivers/media/video/cpia.c Sun Sep 30 01:54:19 2001
1769@@ -3004,7 +3004,11 @@
1770 pos = (unsigned long)(cam->frame_buf);
1771 while (size > 0) {
1772 page = kvirt_to_pa(pos);
1773+#ifdef CONFIG_GRKERNSEC_PAX
1774+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC)) {
1775+#else
1776 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
1777+#endif
1778 up(&cam->busy_lock);
1779 return -EAGAIN;
1780 }
1781diff -urN linux/drivers/media/video/meye.c linux.grsec/drivers/media/video/meye.c
1782--- linux/drivers/media/video/meye.c Wed Jul 4 23:41:33 2001
1783+++ linux.grsec/drivers/media/video/meye.c Sun Sep 30 01:54:19 2001
1784@@ -1267,7 +1267,11 @@
1785
1786 while (size > 0) {
1787 page = kvirt_to_pa(pos);
1788+#ifdef CONFIG_GRKERNSEC_PAX
1789+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC)) {
1790+#else
1791 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
1792+#endif
1793 up(&meye.lock);
1794 return -EAGAIN;
1795 }
1796diff -urN linux/drivers/media/video/planb.c linux.grsec/drivers/media/video/planb.c
1797--- linux/drivers/media/video/planb.c Thu Jun 28 02:10:55 2001
1798+++ linux.grsec/drivers/media/video/planb.c Sun Sep 30 01:54:19 2001
1799@@ -2001,7 +2001,11 @@
1800 }
1801 for (i = 0; i < pb->rawbuf_size; i++) {
1802 if (remap_page_range(start, virt_to_phys((void *)pb->rawbuf[i]),
1803+#ifdef CONFIG_GRKERNSEC_PAX
1804+ PAGE_SIZE, PAGE_SHARED_EXEC))
1805+#else
1806 PAGE_SIZE, PAGE_SHARED))
1807+#endif
1808 return -EAGAIN;
1809 start += PAGE_SIZE;
1810 if (size <= PAGE_SIZE)
1811diff -urN linux/drivers/media/video/zr36067.c linux.grsec/drivers/media/video/zr36067.c
1812--- linux/drivers/media/video/zr36067.c Wed Jul 4 23:41:33 2001
1813+++ linux.grsec/drivers/media/video/zr36067.c Sun Sep 30 01:54:19 2001
1814@@ -4312,7 +4312,11 @@
1815 frag_tab[2 * j];
1816 page = virt_to_phys(bus_to_virt(pos)); /* should just be pos on i386 */
1817 if (remap_page_range
1818+#ifdef CONFIG_GRKERNSEC_PAX
1819+ (start, page, todo, PAGE_SHARED_EXEC)) {
1820+#else
1821 (start, page, todo, PAGE_SHARED)) {
1822+#endif
1823 printk(KERN_ERR
1824 "%s: zoran_mmap(V4L): remap_page_range failed\n",
1825 zr->name);
1826@@ -4353,7 +4357,11 @@
1827 ("V4L remap page range %d 0x%lx %ld to 0x%lx\n",
1828 i, page, todo, start));
1829 if (remap_page_range
1830+#ifdef CONFIG_GRKERNSEC_PAX
1831+ (start, page, todo, PAGE_SHARED_EXEC)) {
1832+#else
1833 (start, page, todo, PAGE_SHARED)) {
1834+#endif
1835 printk(KERN_ERR
1836 "%s: zoran_mmap(V4L): remap_page_range failed\n",
1837 zr->name);
1838diff -urN linux/drivers/media/video/zr36120.c linux.grsec/drivers/media/video/zr36120.c
1839--- linux/drivers/media/video/zr36120.c Tue Jul 17 00:13:32 2001
1840+++ linux.grsec/drivers/media/video/zr36120.c Sun Sep 30 01:54:19 2001
1841@@ -1475,7 +1475,11 @@
1842 pos = (unsigned long)ztv->fbuffer;
1843 while (size>0) {
1844 unsigned long page = virt_to_phys((void*)pos);
1845+#ifdef CONFIG_GRKERNSEC_PAX
1846+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
1847+#else
1848 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1849+#endif
1850 return -EAGAIN;
1851 start += PAGE_SIZE;
1852 pos += PAGE_SIZE;
1853diff -urN linux/drivers/usb/ibmcam.c linux.grsec/drivers/usb/ibmcam.c
1854--- linux/drivers/usb/ibmcam.c Wed Jun 13 00:53:37 2001
1855+++ linux.grsec/drivers/usb/ibmcam.c Sun Sep 30 01:54:19 2001
1856@@ -2841,7 +2841,11 @@
1857 pos = (unsigned long)ibmcam->fbuf;
1858 while (size > 0) {
1859 page = kvirt_to_pa(pos);
1860+#ifdef CONFIG_GRKERNSEC_PAX
1861+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
1862+#else
1863 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1864+#endif
1865 return -EAGAIN;
1866
1867 start += PAGE_SIZE;
1868diff -urN linux/drivers/usb/ov511.c linux.grsec/drivers/usb/ov511.c
1869--- linux/drivers/usb/ov511.c Tue Jul 17 00:13:32 2001
1870+++ linux.grsec/drivers/usb/ov511.c Sun Sep 30 01:54:19 2001
1871@@ -2756,7 +2756,11 @@
1872 pos = (unsigned long)ov511->fbuf;
1873 while (size > 0) {
1874 page = kvirt_to_pa(pos);
1875+#ifdef CONFIG_GRKERNSEC_PAX
1876+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
1877+#else
1878 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1879+#endif
1880 return -EAGAIN;
1881 start += PAGE_SIZE;
1882 pos += PAGE_SIZE;
1883diff -urN linux/drivers/usb/pwc-if.c linux.grsec/drivers/usb/pwc-if.c
1884--- linux/drivers/usb/pwc-if.c Thu Jun 21 02:42:09 2001
1885+++ linux.grsec/drivers/usb/pwc-if.c Sun Sep 30 01:54:19 2001
1886@@ -1511,7 +1511,11 @@
1887 pos = (unsigned long)pdev->image_data;
1888 while (size > 0) {
1889 page = kvirt_to_pa(pos);
1890+#ifdef CONFIG_GRKERNSEC_PAX
1891+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
1892+#else
1893 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1894+#endif
1895 return -EAGAIN;
1896
1897 start += PAGE_SIZE;
1898diff -urN linux/drivers/usb/se401.c linux.grsec/drivers/usb/se401.c
1899--- linux/drivers/usb/se401.c Mon Jul 2 22:56:41 2001
1900+++ linux.grsec/drivers/usb/se401.c Sun Sep 30 01:54:19 2001
1901@@ -1388,7 +1388,11 @@
1902 pos = (unsigned long)se401->fbuf;
1903 while (size > 0) {
1904 page = kvirt_to_pa(pos);
1905+#ifdef CONFIG_GRKERNSEC_PAX
1906+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC)) {
1907+#else
1908 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
1909+#endif
1910 up(&se401->lock);
1911 return -EAGAIN;
1912 }
1913diff -urN linux/fs/binfmt_aout.c linux.grsec/fs/binfmt_aout.c
1914--- linux/fs/binfmt_aout.c Fri Jul 20 05:33:38 2001
1915+++ linux.grsec/fs/binfmt_aout.c Sun Sep 30 01:54:20 2001
1916@@ -5,6 +5,7 @@
1917 */
1918
1919 #include <linux/module.h>
1920+#include <linux/config.h>
1921
1922 #include <linux/sched.h>
1923 #include <linux/kernel.h>
1924@@ -29,6 +30,10 @@
1925 #include <asm/uaccess.h>
1926 #include <asm/pgalloc.h>
1927
1928+#ifdef CONFIG_GRKERNSEC_STACK
1929+#include <linux/grsecurity.h>
1930+#endif
1931+
1932 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
1933 static int load_aout_library(struct file*);
1934 static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
1935@@ -305,6 +310,25 @@
1936 current->mm->mmap = NULL;
1937 compute_creds(bprm);
1938 current->flags &= ~PF_FORKNOEXEC;
1939+#ifdef CONFIG_GRKERNSEC_STACK
1940+ if (N_FLAGS(ex) & F_STACKEXEC) current->flags |= PF_STACKEXEC;
1941+#endif
1942+
1943+#ifdef CONFIG_GRKERNSEC_PAX
1944+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC))
1945+ current->flags |= PF_PAX_PAGEEXEC;
1946+#endif
1947+
1948+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
1949+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
1950+ current->flags |= PF_PAX_EMUTRAMP;
1951+#endif
1952+
1953+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
1954+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
1955+ current->flags |= PF_PAX_MPROTECT;
1956+#endif
1957+
1958 #ifdef __sparc__
1959 if (N_MAGIC(ex) == NMAGIC) {
1960 loff_t pos = fd_offset;
1961@@ -391,7 +415,11 @@
1962
1963 down_write(&current->mm->mmap_sem);
1964 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
1965+#ifdef CONFIG_GRKERNSEC_PAX
1966+ PROT_READ | PROT_WRITE,
1967+#else
1968 PROT_READ | PROT_WRITE | PROT_EXEC,
1969+#endif
1970 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
1971 fd_offset + ex.a_text);
1972 up_write(&current->mm->mmap_sem);
1973diff -urN linux/fs/binfmt_elf.c linux.grsec/fs/binfmt_elf.c
1974--- linux/fs/binfmt_elf.c Sun Sep 30 01:30:59 2001
1975+++ linux.grsec/fs/binfmt_elf.c Sun Sep 30 01:54:20 2001
1976@@ -10,7 +10,7 @@
1977 */
1978
1979 #include <linux/module.h>
1980-
1981+#include <linux/config.h>
1982 #include <linux/fs.h>
1983 #include <linux/stat.h>
1984 #include <linux/sched.h>
1985@@ -31,6 +31,9 @@
1986 #include <linux/init.h>
1987 #include <linux/highuid.h>
1988 #include <linux/smp_lock.h>
1989+#ifdef CONFIG_GRKERNSEC_PAX
1990+#include <linux/random.h>
1991+#endif
1992
1993 #include <asm/uaccess.h>
1994 #include <asm/param.h>
1995@@ -40,6 +43,10 @@
1996
1997 #include <linux/elf.h>
1998
1999+#ifdef CONFIG_GRKERNSEC_STACK
2000+#include <linux/grsecurity.h>
2001+#endif
2002+
2003 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
2004 static int load_elf_library(struct file*);
2005 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
2006@@ -71,7 +78,10 @@
2007 #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
2008 #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))
2009
2010-static struct linux_binfmt elf_format = {
2011+#ifndef CONFIG_GRKERNSEC_STACK
2012+static
2013+#endif
2014+struct linux_binfmt elf_format = {
2015 NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
2016 };
2017
2018@@ -133,6 +143,11 @@
2019 } else
2020 u_platform = p;
2021
2022+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2023+ if (current->flags & PF_PAX_RANDMMAP)
2024+ u_platform -= (current->mm->delta_stack & ~PAGE_MASK);
2025+#endif
2026+
2027 /*
2028 * Force 16 byte _final_ alignment here for generality.
2029 */
2030@@ -559,7 +574,48 @@
2031 current->mm->end_data = 0;
2032 current->mm->end_code = 0;
2033 current->mm->mmap = NULL;
2034+#ifdef CONFIG_GRKERNSEC_PAX
2035+ current->mm->delta_mmap = 0;
2036+ current->mm->delta_exec = 0;
2037+ current->mm->delta_stack = 0;
2038+#endif
2039 current->flags &= ~PF_FORKNOEXEC;
2040+#ifdef CONFIG_GRKERNSEC_STACK
2041+ if (elf_ex.e_flags & EF_STACKEXEC)
2042+ current->flags |= PF_STACKEXEC;
2043+#endif
2044+
2045+#ifdef CONFIG_GRKERNSEC_PAX
2046+ if (!(elf_ex.e_flags & EF_PAX_PAGEEXEC))
2047+ current->flags |= PF_PAX_PAGEEXEC;
2048+#endif
2049+
2050+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2051+ if (elf_ex.e_flags & EF_PAX_EMUTRAMP)
2052+ current->flags |= PF_PAX_EMUTRAMP;
2053+#endif
2054+
2055+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
2056+ if (!(elf_ex.e_flags & EF_PAX_MPROTECT))
2057+ current->flags |= PF_PAX_MPROTECT;
2058+#endif
2059+
2060+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2061+ if (!(elf_ex.e_flags & EF_PAX_RANDMMAP)) {
2062+ unsigned short delta;
2063+ current->flags |= PF_PAX_RANDMMAP;
2064+
2065+ get_random_bytes(&delta, sizeof(delta));
2066+ current->mm->delta_mmap = (unsigned long)delta << PAGE_SHIFT;
2067+
2068+ get_random_bytes(&delta, sizeof(delta));
2069+ current->mm->delta_exec = (unsigned long)delta << PAGE_SHIFT;
2070+
2071+ get_random_bytes(&delta, sizeof(delta));
2072+ current->mm->delta_stack = (unsigned long)delta << 4;
2073+ }
2074+#endif
2075+
2076 elf_entry = (unsigned long) elf_ex.e_entry;
2077
2078 /* Do this so that we can load the interpreter, if need be. We will
2079@@ -596,6 +652,13 @@
2080 base, as well as whatever program they might try to exec. This
2081 is because the brk will follow the loader, and is not movable. */
2082 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
2083+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2084+ /* PaX: randomize base address at the default exe base if requested */
2085+ if (current->flags | PF_PAX_RANDMMAP) {
2086+ load_bias = ELF_PAGESTART(0x08048000 - vaddr + current->mm->delta_exec);
2087+ }
2088+#endif
2089+
2090 }
2091
2092 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
2093diff -urN linux/fs/exec.c linux.grsec/fs/exec.c
2094--- linux/fs/exec.c Fri Jul 20 05:32:54 2001
2095+++ linux.grsec/fs/exec.c Sun Sep 30 01:55:22 2001
2096@@ -45,6 +45,25 @@
2097 #include <linux/kmod.h>
2098 #endif
2099
2100+#ifdef CONFIG_OBV_PROC
2101+#include <linux/obvext.h>
2102+#endif
2103+
2104+
2105+#ifdef CONFIG_GRKERNSEC_FD
2106+#include <linux/major.h>
2107+#endif
2108+
2109+#if defined(CONFIG_GRKERNSEC_FD) || defined(CONFIG_GRKERNSEC_EXECVE) ||\
2110+ defined(CONFIG_GRKERNSEC_COREDUMP)||defined(CONFIG_GRKERNSEC_TPE) ||\
2111+ defined(CONFIG_GRKERNSEC_CHROOT_EXECLOG) || defined(CONFIG_GRKERNSEC_STACK)
2112+#include <linux/grsecurity.h>
2113+#endif
2114+
2115+#ifdef CONFIG_GRKERNSEC_CHROOT
2116+extern struct task_struct *child_reaper;
2117+#endif
2118+
2119 static struct linux_binfmt *formats;
2120 static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
2121
2122@@ -276,7 +295,12 @@
2123 goto out;
2124 flush_dcache_page(page);
2125 flush_page_to_ram(page);
2126+#ifdef CONFIG_GRKERNSEC_PAX
2127+ set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page,
2128+ (tsk->flags & PF_PAX_PAGEEXEC)?PAGE_COPY_NOEXEC:PAGE_COPY_EXEC))));
2129+#else
2130 set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
2131+#endif
2132 tsk->mm->rss++;
2133 spin_unlock(&tsk->mm->page_table_lock);
2134
2135@@ -297,6 +321,12 @@
2136
2137 stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
2138
2139+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2140+ if (current->flags & PF_PAX_RANDMMAP)
2141+ stack_base = PAGE_MASK & (stack_base - current->mm->delta_stack);
2142+
2143+#endif
2144+
2145 bprm->p += stack_base;
2146 if (bprm->loader)
2147 bprm->loader += stack_base;
2148@@ -310,9 +340,15 @@
2149 {
2150 mpnt->vm_mm = current->mm;
2151 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
2152+#ifdef CONFIG_GRKERNSEC_PAX
2153+ mpnt->vm_end = stack_base + MAX_ARG_PAGES*PAGE_SIZE;
2154+ mpnt->vm_page_prot = (current->flags & PF_PAX_PAGEEXEC)?PAGE_COPY_NOEXEC:PAGE_COPY_EXEC;
2155+ mpnt->vm_flags = (current->flags & PF_PAX_PAGEEXEC)?VM_STACK_FLAGS:(VM_STACK_FLAGS|VM_EXEC|VM_MAYEXEC);
2156+#else
2157 mpnt->vm_end = STACK_TOP;
2158 mpnt->vm_page_prot = PAGE_COPY;
2159 mpnt->vm_flags = VM_STACK_FLAGS;
2160+#endif
2161 mpnt->vm_ops = NULL;
2162 mpnt->vm_pgoff = 0;
2163 mpnt->vm_file = NULL;
2164@@ -468,6 +504,65 @@
2165 if (atomic_dec_and_test(&oldsig->count))
2166 kmem_cache_free(sigact_cachep, oldsig);
2167 }
2168+#ifdef CONFIG_GRKERNSEC_FD
2169+static inline int tweak_fd_open_null(struct linux_binprm *bprm)
2170+{
2171+ struct inode *i;
2172+ struct dentry *d;
2173+ struct file *f;
2174+
2175+ if(!(i = get_empty_inode()))
2176+ return -ENOMEM;
2177+ if(!(d = dget(d_alloc_root(i)))){
2178+ iput(i);
2179+ return -ENOMEM;
2180+ }
2181+ if(!(f = get_empty_filp())){
2182+ dput(d);
2183+ iput(i);
2184+ return -ENFILE;
2185+ }
2186+ i->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
2187+ i->i_uid = current->fsuid;
2188+ i->i_gid = current->fsgid;
2189+ i->i_rdev = MKDEV(MEM_MAJOR,3);
2190+ i->i_blksize = PAGE_SIZE;
2191+ i->i_blocks = 0;
2192+ i->i_atime = i->i_mtime = i->i_ctime = CURRENT_TIME;
2193+ i->i_op = &page_symlink_inode_operations;
2194+ i->i_state = I_DIRTY;
2195+ f->f_flags = O_RDWR;
2196+ f->f_mode = FMODE_READ | FMODE_WRITE;
2197+ f->f_dentry = d;
2198+ f->f_pos = 0;
2199+ f->f_reada = 0;
2200+ chrdev_open(i,f);
2201+ bprm->tweak_fd_null = f;
2202+ return 0;
2203+}
2204+
2205+static int tweak_fd_0_1_2(struct linux_binprm *bprm)
2206+{
2207+ int fd,new,retval;
2208+ struct file *f;
2209+ f = bprm->tweak_fd_null;
2210+ for(fd=0;fd<=2;fd++){
2211+ if(current->files->fd[fd]) continue;
2212+ if((new = get_unused_fd()) != fd) {
2213+ if(new >= 0) put_unused_fd(new);
2214+ return -EMFILE;
2215+ }
2216+ if(f)
2217+ atomic_inc(&f->f_count);
2218+ else
2219+ if((retval = tweak_fd_open_null(bprm)))
2220+ return retval;
2221+ fd_install(fd,bprm->tweak_fd_null);
2222+ bprm->tweak_fd_mask |= 1 << fd;
2223+ }
2224+ return 0;
2225+}
2226+#endif
2227
2228 /*
2229 * These functions flushes out all traces of the currently running executable
2230@@ -558,6 +653,25 @@
2231 current->comm[i++] = ch;
2232 }
2233 current->comm[i] = '\0';
2234+#ifdef CONFIG_GRKERNSEC_STACK
2235+ current->flags &= ~PF_STACKEXEC;
2236+#endif
2237+
2238+#ifdef CONFIG_GRKERNSEC_PAX
2239+ current->flags &= ~PF_PAX_PAGEEXEC;
2240+#endif
2241+
2242+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
2243+ current->flags &= ~PF_PAX_EMUTRAMP;
2244+#endif
2245+
2246+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
2247+ current->flags &= ~PF_PAX_MPROTECT;
2248+#endif
2249+
2250+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
2251+ current->flags &= ~PF_PAX_RANDMMAP;
2252+#endif
2253
2254 flush_thread();
2255
2256@@ -574,7 +688,10 @@
2257
2258 flush_signal_handlers(current);
2259 flush_old_files(current->files);
2260-
2261+#ifdef CONFIG_GRKERNSEC_FD
2262+ if(grsec_enable_fd && bprm->priv_change)
2263+ return tweak_fd_0_1_2(bprm);
2264+#endif
2265 return 0;
2266
2267 mmap_failed:
2268@@ -604,6 +721,9 @@
2269 {
2270 int mode;
2271 struct inode * inode = bprm->file->f_dentry->d_inode;
2272+#ifdef CONFIG_GRKERNSEC_FD
2273+ if (grsec_enable_fd) bprm->priv_change = 0;
2274+#endif
2275
2276 mode = inode->i_mode;
2277 /* Huh? We had already checked for MAY_EXEC, WTF do we check this? */
2278@@ -617,8 +737,16 @@
2279
2280 if(!IS_NOSUID(inode)) {
2281 /* Set-uid? */
2282- if (mode & S_ISUID)
2283- bprm->e_uid = inode->i_uid;
2284+#ifdef CONFIG_GRKERNSEC_FD
2285+ if (mode & S_ISUID){
2286+ bprm->e_uid = inode->i_uid;
2287+ if(grsec_enable_fd && (bprm->e_uid != current->euid))
2288+ bprm->priv_change = 1;
2289+ }
2290+#else
2291+ if (mode & S_ISUID)
2292+ bprm->e_uid = inode->i_uid;
2293+#endif
2294
2295 /* Set-gid? */
2296 /*
2297@@ -626,9 +754,17 @@
2298 * is a candidate for mandatory locking, not a setgid
2299 * executable.
2300 */
2301- if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
2302- bprm->e_gid = inode->i_gid;
2303- }
2304+#ifdef CONFIG_GRKERNSEC_FD
2305+ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)){
2306+ bprm->e_gid = inode->i_gid;
2307+ if(grsec_enable_fd && !in_group_p(bprm->e_gid))
2308+ bprm->priv_change = 1;
2309+ }
2310+#else
2311+ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
2312+ bprm->e_gid = inode->i_gid;
2313+#endif
2314+}
2315
2316 /* We don't have VFS support for capabilities yet */
2317 cap_clear(bprm->cap_inheritable);
2318@@ -648,10 +784,10 @@
2319 cap_set_full(bprm->cap_inheritable);
2320 cap_set_full(bprm->cap_permitted);
2321 }
2322- if (bprm->e_uid == 0)
2323+
2324+ if (bprm->e_uid == 0)
2325 cap_set_full(bprm->cap_effective);
2326 }
2327-
2328 memset(bprm->buf,0,BINPRM_BUF_SIZE);
2329 return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
2330 }
2331@@ -699,6 +835,9 @@
2332 current->cap_permitted);
2333 }
2334 }
2335+#ifdef CONFIG_GRKERNSEC_FD
2336+ if (grsec_enable_fd) tweak_fd_0_1_2(bprm);
2337+#endif
2338 do_unlock = 1;
2339 }
2340
2341@@ -847,6 +986,39 @@
2342 struct file *file;
2343 int retval;
2344 int i;
2345+#ifdef CONFIG_GRKERNSEC_EXECLOG
2346+ int x;
2347+ char *grargs;
2348+ char grarg[68];
2349+#endif
2350+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
2351+ if(grsec_enable_chroot_execlog &&
2352+ !( (current->fs->root->d_inode->i_dev ==
2353+ child_reaper->fs->root->d_inode->i_dev) &&
2354+ (current->fs->root->d_inode->i_ino ==
2355+ child_reaper->fs->root->d_inode->i_ino) ) ) {
2356+ security_alert("exec of %.64s within chroot() jail (%.32s:%lu) by process (%.16s:%d), "
2357+ "UID (%d), EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d)",
2358+ "execs from chroot()",filename,kdevname(current->fs->root->d_inode->i_dev),
2359+ current->fs->root->d_inode->i_ino,current->comm,current->pid,
2360+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
2361+ current->p_pptr->uid,current->p_pptr->euid);
2362+ }
2363+#endif
2364+#ifdef CONFIG_GRKERNSEC_EXECVE
2365+ if(grsec_enable_execve && current->user)
2366+ if(atomic_read(&current->user->processes) > current->rlim[RLIMIT_NPROC].rlim_cur)
2367+ {
2368+ security_alert("Attempt to overstep process limit by (%.16s:%d), "
2369+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)",
2370+ "proc limit overstep",
2371+ current->comm,current->pid,current->uid,
2372+ current->euid,current->p_pptr->comm,
2373+ current->p_pptr->pid,current->p_pptr->uid,
2374+ current->p_pptr->euid);
2375+ return -EAGAIN;
2376+ }
2377+#endif
2378
2379 file = open_exec(filename);
2380
2381@@ -854,6 +1026,94 @@
2382 if (IS_ERR(file))
2383 return retval;
2384
2385+#ifdef CONFIG_GRKERNSEC_TPE
2386+if (grsec_enable_tpe) {
2387+#ifdef CONFIG_GRKERNSEC_TPE_GLIBC
2388+if (grsec_enable_tpe_glibc) {
2389+#ifdef CONFIG_GRKERNSEC_TPE_ALL
2390+if(grsec_enable_tpe_all?current->uid:in_group_p(grsec_tpe_gid)){
2391+#else
2392+if(in_group_p(grsec_tpe_gid)){
2393+#endif
2394+ char **envpp=envp,*envpt;
2395+ while(*envpp){
2396+ envpt=*envpp;
2397+ if((*envpt == 'L') && (*(envpt + 1) == 'D') &&
2398+ (*(envpt + 2) == '_') && strchr(envpt,'=')){
2399+ security_alert("denied exec of %.32s by (%.16s:%d), UID (%d), "
2400+ "EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d) reason: "
2401+ "malicious environment","denied execs",
2402+ filename,current->comm,current->pid,current->uid,current->euid,
2403+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
2404+ current->p_pptr->euid);
2405+ dput(file->f_dentry);
2406+ return -EACCES;
2407+ }
2408+ *envpp=*++envpp;
2409+ }
2410+ if(!strncmp(file->f_dentry->d_name.name,"ld-2.",5) &&
2411+ !strncmp(file->f_dentry->d_parent->d_name.name,"lib",3)){
2412+ security_alert("denied exec of %.32s by (%.16s:%d), UID (%d), "
2413+ "EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d) reason: "
2414+ "tried to bypass via ld","denied execs",
2415+ filename,current->comm,current->pid,current->uid,current->euid,
2416+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
2417+ current->p_pptr->euid);
2418+ dput(file->f_dentry);
2419+ return -EACCES;
2420+ }
2421+}
2422+}
2423+#endif
2424+if((current->uid) &&
2425+ ((file->f_dentry->d_parent->d_inode->i_uid) ||
2426+ (!(file->f_dentry->d_parent->d_inode->i_uid) &&
2427+ ((file->f_dentry->d_parent->d_inode->i_mode & S_IWGRP) ||
2428+ (file->f_dentry->d_parent->d_inode->i_mode & S_IWOTH)))) &&
2429+ (in_group_p(grsec_tpe_gid))){
2430+security_alert("denied exec of %.32s by (%.16s:%d), UID (%d), "
2431+ "EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d) reason: "
2432+ "untrusted","denied execs",
2433+ filename,current->comm,current->pid,current->uid,current->euid,
2434+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
2435+ current->p_pptr->euid);
2436+ dput(file->f_dentry);
2437+ return -EACCES;
2438+}
2439+#ifdef CONFIG_GRKERNSEC_TPE_ALL
2440+else if(grsec_enable_tpe_all &&
2441+ (current->uid) && !(((!(file->f_dentry->d_parent->d_inode->i_uid) &&
2442+ !(file->f_dentry->d_parent->d_inode->i_mode & S_IWGRP) &&
2443+ !(file->f_dentry->d_parent->d_inode->i_mode & S_IWOTH)) ||
2444+ ((file->f_dentry->d_parent->d_inode->i_uid == current->uid) &&
2445+ !(file->f_dentry->d_parent->d_inode->i_mode & S_IWGRP) &&
2446+ !(file->f_dentry->d_parent->d_inode->i_mode & S_IWOTH))))){
2447+security_alert("denied exec of %.32s by (%.16s:%d), UID (%d), "
2448+ "EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d) reason:"
2449+ " untrusted","denied execs",
2450+ filename,current->comm,current->pid,current->uid,current->euid,
2451+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
2452+ current->p_pptr->euid);
2453+ dput(file->f_dentry);
2454+ return -EACCES;
2455+}
2456+#endif
2457+}
2458+#endif
2459+
2460+#ifdef CONFIG_OBV_PROC
2461+if( ( (obv_search(file->f_dentry,OBV_EXEC,file->f_vfsmnt)) == OBV_DENY) ) {
2462+ obv_seclog("denying execution of %.1024s by (%.16s:%d), "
2463+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2464+ filename,current->comm,current->pid,current->uid,
2465+ current->euid,current->p_pptr->comm,
2466+ current->p_pptr->pid,current->p_pptr->uid,
2467+ current->p_pptr->euid);
2468+ fput(file);
2469+ return -EPERM;
2470+}
2471+#endif
2472+
2473 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
2474 memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
2475
2476@@ -867,13 +1127,37 @@
2477 fput(file);
2478 return bprm.argc;
2479 }
2480+#ifdef CONFIG_GRKERNSEC_EXECLOG
2481+ if (grsec_enable_execlog) {
2482+ for(x=0;x<sizeof(grarg);x++)
2483+ grarg[x]='\0';
2484+ for(x=0;x<bprm.argc;x++) {
2485+ if((strlen(argv[x]) + strlen(grarg) + 2) < sizeof(grarg)) {
2486+ grargs=strcat(grarg,argv[x]);
2487+ if(x<bprm.argc-1)
2488+ grargs=strcat(grarg," ");
2489+ }
2490+ }
2491+ printk(KERN_INFO "grsecurity: exec of (%.68s) by (%.16s:%d), "
2492+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2493+ grarg,current->comm,current->pid,current->uid,
2494+ current->euid,current->p_pptr->comm,
2495+ current->p_pptr->pid,current->p_pptr->uid,
2496+ current->p_pptr->euid);
2497+ }
2498+#endif
2499
2500 if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) {
2501 allow_write_access(file);
2502 fput(file);
2503 return bprm.envc;
2504 }
2505-
2506+#ifdef CONFIG_GRKERNSEC_FD
2507+ if (grsec_enable_fd) {
2508+ bprm.tweak_fd_mask = 0;
2509+ bprm.tweak_fd_null = NULL;
2510+ }
2511+#endif
2512 retval = prepare_binprm(&bprm);
2513 if (retval < 0)
2514 goto out;
2515@@ -892,9 +1176,19 @@
2516 goto out;
2517
2518 retval = search_binary_handler(&bprm,regs);
2519- if (retval >= 0)
2520+ if (retval >= 0) {
2521+#ifdef CONFIG_OBV_PROC
2522+ if(obv_set_proc_acl(file->f_dentry,current,filename,file->f_vfsmnt)) {
2523+ obv_seclog("could not set acl for %ld %d\n",
2524+ file->f_dentry->d_inode->i_ino,
2525+ file->f_dentry->d_inode->i_dev);
2526+ goto out;
2527+ }
2528+#endif
2529+
2530 /* execve success */
2531 return retval;
2532+ }
2533
2534 out:
2535 /* Something went wrong, return the inode and free the argument pages*/
2536@@ -907,7 +1201,13 @@
2537 if (page)
2538 __free_page(page);
2539 }
2540-
2541+#ifdef CONFIG_GRKERNSEC_FD
2542+ if(grsec_enable_fd && bprm.tweak_fd_mask) {
2543+ for(i=0;i<=2;i++)
2544+ if(bprm.tweak_fd_mask & (1 << i))
2545+ (void)sys_close(i);
2546+ }
2547+#endif
2548 return retval;
2549 }
2550
2551@@ -940,8 +1240,11 @@
2552 goto fail;
2553
2554 memcpy(corename,"core.", 5);
2555-#if 0
2556- memcpy(corename+5,current->comm,sizeof(current->comm));
2557+#ifdef CONFIG_GRKERNSEC_COREDUMP
2558+ if(grsec_enable_coredump)
2559+ memcpy(corename+5,current->comm,sizeof(current->comm));
2560+ else
2561+ corename[4] = '\0';
2562 #else
2563 corename[4] = '\0';
2564 #endif
2565@@ -960,7 +1263,11 @@
2566 goto close_fail;
2567 if (!file->f_op->write)
2568 goto close_fail;
2569+#ifdef CONFIG_OBV_PROC
2570+ if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
2571+#else
2572 if (do_truncate(file->f_dentry, 0) != 0)
2573+#endif
2574 goto close_fail;
2575
2576 down_read(&current->mm->mmap_sem);
2577diff -urN linux/fs/namei.c linux.grsec/fs/namei.c
2578--- linux/fs/namei.c Sun Sep 30 01:30:55 2001
2579+++ linux.grsec/fs/namei.c Sun Sep 30 01:54:20 2001
2580@@ -25,8 +25,21 @@
2581 #include <asm/namei.h>
2582 #include <asm/uaccess.h>
2583
2584+#if defined(CONFIG_GRKERNSEC_LINK) || defined(CONFIG_GRKERNSEC_FIFO) ||\
2585+ defined(CONFIG_GRKERNSEC_CHROOT)
2586+#include <linux/grsecurity.h>
2587+#endif
2588+
2589+#ifdef CONFIG_OBV_PROC
2590+#include <linux/obvext.h>
2591+#endif
2592+
2593 #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
2594
2595+#ifdef CONFIG_GRKERNSEC_CHROOT
2596+extern struct task_struct *child_reaper;
2597+#endif
2598+
2599 /* [Feb-1997 T. Schoebel-Theuer]
2600 * Fundamental changes in the pathname lookup mechanisms (namei)
2601 * were necessary because of omirr. The reason is that omirr needs
2602@@ -309,6 +322,27 @@
2603 if (current->link_count >= 8)
2604 goto loop;
2605 current->link_count++;
2606+#ifdef CONFIG_GRKERNSEC_LINK
2607+ if(grsec_enable_link && S_ISLNK(dentry->d_inode->i_mode) &&
2608+ (dentry->d_parent->d_inode->i_mode & S_ISVTX) &&
2609+ dentry->d_parent->d_inode->i_uid != dentry->d_inode->i_uid &&
2610+ (dentry->d_parent->d_inode->i_mode & S_IWOTH) &&
2611+ current->fsuid != dentry->d_inode->i_uid) {
2612+ security_alert("not following symlink (%.30s/%.30s) of [%.32s]:%lu owned by %d.%d "
2613+ "by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), "
2614+ "UID (%d), EUID (%d)","symlinks not followed",
2615+ dentry->d_parent->d_name.name,
2616+ dentry->d_name.name,
2617+ kdevname(dentry->d_inode->i_dev),
2618+ dentry->d_inode->i_ino,
2619+ dentry->d_inode->i_uid,
2620+ dentry->d_inode->i_gid,current->comm,
2621+ current->pid,current->uid,current->euid,
2622+ current->p_pptr->comm,current->p_pptr->pid,
2623+ current->p_pptr->uid,current->p_pptr->euid);
2624+ return -EACCES;
2625+ }
2626+#endif
2627 UPDATE_ATIME(dentry->d_inode);
2628 err = dentry->d_inode->i_op->follow_link(dentry, nd);
2629 current->link_count--;
2630@@ -589,6 +623,24 @@
2631 else if (this.len == 2 && this.name[1] == '.')
2632 nd->last_type = LAST_DOTDOT;
2633 return_base:
2634+#ifdef CONFIG_OBV_PROC
2635+ if(nd->dentry)
2636+ if( ( (obv_check_hidden(nd->dentry,nd->mnt)) == OBV_DENY) ) {
2637+ obv_seclog("attempt to access hidden file "
2638+ "with inode %ld dev %d by (%.16s:%d), "
2639+ "UID(%d), EUID(%d), parent (%.16s:%d), "
2640+ "UID(%d), EUID(%d)\n",
2641+ nd->dentry->d_inode->i_ino,
2642+ nd->dentry->d_inode->i_dev,
2643+ current->comm,current->pid,current->uid,
2644+ current->euid,current->p_pptr->comm,
2645+ current->p_pptr->pid,current->p_pptr->uid,
2646+ current->p_pptr->euid);
2647+ err = -ENOENT; /*Fake that its not there*/
2648+ goto out_dput;
2649+ }
2650+#endif
2651+
2652 return 0;
2653 out_dput:
2654 dput(dentry);
2655@@ -930,6 +982,62 @@
2656 struct dentry *dentry;
2657 struct dentry *dir;
2658 int count = 0;
2659+#ifdef CONFIG_OBV_PROC
2660+ int tmp;
2661+ if(nd->flags) {
2662+ nd->flags = 0;
2663+ if(path_init(pathname,lookup_flags(flag)|LOOKUP_PARENT,nd))
2664+ error = path_walk(pathname,nd);
2665+ if(error) return error;
2666+ } else {
2667+ if(path_init(pathname,lookup_flags(flag),nd))
2668+ error = path_walk(pathname,nd);
2669+ if(error) return error;
2670+ }
2671+ if( (tmp = (flag&O_ACCMODE)) > 0) {
2672+ if(tmp & FMODE_READ ) {
2673+ if( (obv_search(nd->dentry,OBV_READ,nd->mnt)) == OBV_DENY) {
2674+ obv_seclog("attempt to open %.1024s read-only "
2675+ "by (%.16s:%d), UID(%d), EUID(%d), parent "
2676+ "(%.16s:%d), UID(%d), EUID(%d)\n",pathname,
2677+ current->comm,current->pid,current->uid,
2678+ current->euid,current->p_pptr->comm,
2679+ current->p_pptr->pid,current->p_pptr->uid,
2680+ current->p_pptr->euid);
2681+ error = -EPERM;
2682+ goto exit;
2683+ }
2684+ }
2685+ else if(flag & O_APPEND) {
2686+ if( (obv_search(nd->dentry,OBV_APPEND,nd->mnt)) == OBV_DENY) {
2687+ obv_seclog("attempt to open %.1024s "
2688+ "append-only by (%.16s:%d), UID(%d), "
2689+ "EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2690+ pathname,current->comm,current->pid,current->uid,
2691+ current->euid,current->p_pptr->comm,
2692+ current->p_pptr->pid,current->p_pptr->uid,
2693+ current->p_pptr->euid);
2694+ error = -EPERM;
2695+ goto exit;
2696+ }
2697+ }
2698+ if(tmp & FMODE_WRITE && (!(flag & O_APPEND))) { /* its write*/
2699+ if( ( (obv_search(nd->dentry,OBV_WRITE,nd->mnt)) == OBV_DENY) ) {
2700+ obv_seclog("attempt to open %.1024s "
2701+ "for writing by (%.16s:%d), UID(%d), "
2702+ "EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2703+ pathname,current->comm,current->pid,current->uid,
2704+ current->euid,current->p_pptr->comm,
2705+ current->p_pptr->pid,current->p_pptr->uid,
2706+ current->p_pptr->euid);
2707+ error = -EPERM;
2708+ goto exit;
2709+ }
2710+ }
2711+ }
2712+ path_release(nd);
2713+#endif
2714+
2715
2716 acc_mode = ACC_MODE(flag);
2717
2718@@ -1032,12 +1140,32 @@
2719 error = permission(inode,acc_mode);
2720 if (error)
2721 goto exit;
2722-
2723 /*
2724 * FIFO's, sockets and device files are special: they don't
2725 * actually live on the filesystem itself, and as such you
2726 * can write to them even if the filesystem is read-only.
2727 */
2728+#ifdef CONFIG_GRKERNSEC_FIFO
2729+ if (grsec_enable_fifo &&
2730+ S_ISFIFO(inode->i_mode) && !(flag & O_EXCL) &&
2731+ (dentry->d_parent->d_inode->i_mode & S_ISVTX) &&
2732+ inode->i_uid != dentry->d_parent->d_inode->i_uid &&
2733+ current->fsuid != inode->i_uid) {
2734+ if (!permission(inode, acc_mode))
2735+ security_alert("denied writing FIFO (%.32s/%.32s) of %d.%d "
2736+ "by (%.16s:%d), UID(%d), EUID(%d), parent "
2737+ "(%.16s:%d), UID(%d), EUID(%d)",
2738+ "writes into a FIFO denied",dentry->d_parent->d_name.name,dentry->d_name.name,
2739+ inode->i_uid, inode->i_gid,
2740+ current->comm,current->pid,
2741+ current->uid, current->euid,
2742+ current->p_pptr->comm,
2743+ current->p_pptr->pid,current->p_pptr->uid,
2744+ current->p_pptr->euid);
2745+ error = -EACCES;
2746+ goto exit;
2747+ }
2748+#endif
2749 if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
2750 flag &= ~O_TRUNC;
2751 } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
2752@@ -1081,7 +1209,11 @@
2753 if (!error) {
2754 DQUOT_INIT(inode);
2755
2756+#ifdef CONFIG_OBV_PROC
2757+ error = do_truncate(dentry,0,nd->mnt);
2758+#else
2759 error = do_truncate(dentry, 0);
2760+#endif
2761 }
2762 put_write_access(inode);
2763 if (error)
2764@@ -1112,6 +1244,29 @@
2765 * stored in nd->last.name and we will have to putname() it when we
2766 * are done. Procfs-like symlinks just set LAST_BIND.
2767 */
2768+#ifdef CONFIG_GRKERNSEC_LINK
2769+ if(grsec_enable_link && S_ISLNK(dentry->d_inode->i_mode) &&
2770+ (dentry->d_parent->d_inode->i_mode & S_ISVTX) &&
2771+ dentry->d_parent->d_inode->i_uid != dentry->d_inode->i_uid &&
2772+ (dentry->d_parent->d_inode->i_mode & S_IWOTH) &&
2773+ current->fsuid != dentry->d_inode->i_uid) {
2774+ security_alert("not following symlink (%.30s/%.30s) [%.32s]:%lu of %d.%d "
2775+ "by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), "
2776+ "UID (%d), EUID (%d)","symlinks not followed",
2777+ dentry->d_parent->d_name.name,
2778+ dentry->d_name.name,
2779+ kdevname(dentry->d_inode->i_dev),
2780+ dentry->d_inode->i_ino,
2781+ dentry->d_inode->i_uid,
2782+ dentry->d_inode->i_gid,current->comm,
2783+ current->pid,current->uid,current->euid,
2784+ current->p_pptr->comm,current->p_pptr->pid,
2785+ current->p_pptr->uid,current->p_pptr->euid);
2786+ error = -EACCES;
2787+ goto exit;
2788+ }
2789+#endif
2790+
2791 UPDATE_ATIME(dentry->d_inode);
2792 error = dentry->d_inode->i_op->follow_link(dentry, nd);
2793 dput(dentry);
2794@@ -1195,7 +1350,9 @@
2795 char * tmp;
2796 struct dentry * dentry;
2797 struct nameidata nd;
2798-
2799+#ifdef CONFIG_GRKERNSEC_CHROOT
2800+ char grdevmode;
2801+#endif
2802 if (S_ISDIR(mode))
2803 return -EPERM;
2804 tmp = getname(filename);
2805@@ -1212,6 +1369,50 @@
2806 if (!IS_POSIX_ACL(nd.dentry->d_inode))
2807 mode &= ~current->fs->umask;
2808 if (!IS_ERR(dentry)) {
2809+#ifdef CONFIG_GRKERNSEC_CHROOT
2810+ if (grsec_enable_chroot && !S_ISFIFO(mode)) {
2811+ if(!( (current->fs->root->d_inode->i_dev ==
2812+ child_reaper->fs->root->d_inode->i_dev) &&
2813+ (current->fs->root->d_inode->i_ino ==
2814+ child_reaper->fs->root->d_inode->i_ino) ) ) {
2815+ switch (mode & S_IFMT) {
2816+ case S_IFREG: grdevmode = 'r'; break;
2817+ case S_IFCHR: grdevmode = 'c'; break;
2818+ case S_IFBLK: grdevmode = 'b'; break;
2819+ case S_IFSOCK: grdevmode = 's'; break;
2820+ default: grdevmode = 'u';
2821+ }
2822+ security_alert("refused attempt to mknod(%c:%.32s) (%.30s) from chroot() jail (%s:%lu) "
2823+ "owned by %d %d by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), UID "
2824+ "(%d), EUID (%d)","chroot() mknods denied",grdevmode,kdevname(dev),tmp,
2825+ kdevname(current->fs->root->d_inode->i_dev),current->fs->root->d_inode->i_ino,
2826+ current->fs->root->d_inode->i_uid,current->fs->root->d_inode->i_gid,
2827+ current->comm,current->pid,current->uid,current->euid,current->p_pptr->comm,
2828+ current->p_pptr->pid,current->p_pptr->uid,current->p_pptr->euid);
2829+ dput(dentry);
2830+ error = -EPERM;
2831+ goto out;
2832+ }
2833+ }
2834+#endif
2835+#ifdef CONFIG_OBV_PROC
2836+ if( ( (obv_search(nd.dentry,OBV_WRITE,nd.mnt)) == OBV_DENY) ) {
2837+ obv_seclog("attempt to mknod %.1024s (dev %d) by (%.16s:%d), "
2838+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2839+ filename,dev,current->comm,current->pid,current->uid,
2840+ current->euid,current->p_pptr->comm,
2841+ current->p_pptr->pid,current->p_pptr->uid,
2842+ current->p_pptr->euid);
2843+ dput(dentry);
2844+ path_release(&nd);
2845+ error = -EPERM;
2846+ goto out;
2847+ }
2848+#endif
2849+
2850+
2851+
2852+
2853 switch (mode & S_IFMT) {
2854 case 0: case S_IFREG:
2855 error = vfs_create(nd.dentry->d_inode,dentry,mode);
2856@@ -1279,9 +1480,26 @@
2857 dentry = lookup_create(&nd, 1);
2858 error = PTR_ERR(dentry);
2859 if (!IS_ERR(dentry)) {
2860+#ifdef CONFIG_OBV_PROC
2861+ error = 0;
2862+ if( ( ((obv_search(nd.dentry,OBV_WRITE,nd.mnt)) == OBV_DENY))){
2863+ obv_seclog("attempt to mkdir %.1024s by (%.16s:%d), "
2864+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2865+ pathname,current->comm,current->pid,current->uid,
2866+ current->euid,current->p_pptr->comm,
2867+ current->p_pptr->pid,current->p_pptr->uid,
2868+ current->p_pptr->euid);
2869+ error = -EPERM;
2870+ }
2871+ if(!error) {
2872+#endif
2873+
2874 if (!IS_POSIX_ACL(nd.dentry->d_inode))
2875 mode &= ~current->fs->umask;
2876 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
2877+#ifdef CONFIG_OBV_PROC
2878+ }
2879+#endif
2880 dput(dentry);
2881 }
2882 up(&nd.dentry->d_inode->i_sem);
2883@@ -1388,7 +1606,20 @@
2884 dentry = lookup_hash(&nd.last, nd.dentry);
2885 error = PTR_ERR(dentry);
2886 if (!IS_ERR(dentry)) {
2887- error = vfs_rmdir(nd.dentry->d_inode, dentry);
2888+#ifdef CONFIG_OBV_PROC
2889+ error = 0;
2890+ if( ( (obv_search(nd.dentry,OBV_WRITE,nd.mnt)) == OBV_DENY)) {
2891+ obv_seclog("attempt to rmdir %.1024s by (%.16s:%d), "
2892+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2893+ pathname,current->comm,current->pid,current->uid,
2894+ current->euid,current->p_pptr->comm,
2895+ current->p_pptr->pid,current->p_pptr->uid,
2896+ current->p_pptr->euid);
2897+ error = -EPERM;
2898+ }
2899+ if(!error)
2900+#endif
2901+ error = vfs_rmdir(nd.dentry->d_inode, dentry);
2902 dput(dentry);
2903 }
2904 up(&nd.dentry->d_inode->i_sem);
2905@@ -1451,7 +1682,21 @@
2906 /* Why not before? Because we want correct error value */
2907 if (nd.last.name[nd.last.len])
2908 goto slashes;
2909- error = vfs_unlink(nd.dentry->d_inode, dentry);
2910+#ifdef CONFIG_OBV_PROC
2911+ error = 0;
2912+ if( ( (obv_search(dentry,OBV_WRITE, nd.mnt)) == OBV_DENY)) {
2913+ obv_seclog("attempt to unlink %.1024s by (%.16s:%d), "
2914+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
2915+ name,current->comm,current->pid,current->uid,
2916+ current->euid,current->p_pptr->comm,
2917+ current->p_pptr->pid,current->p_pptr->uid,
2918+ current->p_pptr->euid);
2919+ error = -EPERM;
2920+ }
2921+ if(!error)
2922+#endif
2923+
2924+ error = vfs_unlink(nd.dentry->d_inode, dentry);
2925 exit2:
2926 dput(dentry);
2927 }
2928@@ -1508,6 +1753,19 @@
2929 if (!IS_ERR(to)) {
2930 struct dentry *dentry;
2931 struct nameidata nd;
2932+#ifdef CONFIG_OBV_PROC
2933+ struct nameidata old_nd;
2934+ if(path_init(from,LOOKUP_POSITIVE|LOOKUP_FOLLOW,&old_nd))
2935+ if(path_walk(from,&old_nd)) {
2936+#ifdef CONFIG_OBV_DEBUG
2937+ printk("Error looking up %s\n",from);
2938+#endif
2939+
2940+ path_release(&old_nd);
2941+ return -EROFS;
2942+ }
2943+#endif
2944+
2945
2946 if (path_init(to, LOOKUP_PARENT, &nd))
2947 error = path_walk(to, &nd);
2948@@ -1516,7 +1774,24 @@
2949 dentry = lookup_create(&nd, 0);
2950 error = PTR_ERR(dentry);
2951 if (!IS_ERR(dentry)) {
2952- error = vfs_symlink(nd.dentry->d_inode, dentry, from);
2953+#ifdef CONFIG_OBV_PROC
2954+ error = 0;
2955+ if( obv_search(old_nd.dentry,OBV_WRITE,old_nd.mnt) == OBV_DENY || obv_search(nd.dentry,OBV_WRITE,nd.mnt) == OBV_DENY) {
2956+ obv_seclog("attempt to symlink %.1024s "
2957+ "to %.1024s by (%.16s:%d), UID(%d), "
2958+ "EUID(%d), parent (%.16s:%d), UID(%d) "
2959+ "EUID(%d)\n",oldname,newname,
2960+ current->comm,current->pid,current->uid,
2961+ current->euid,current->p_pptr->comm,
2962+ current->p_pptr->pid,current->p_pptr->uid,
2963+ current->p_pptr->euid);
2964+ error = -EPERM;
2965+ }
2966+ path_release(&old_nd);
2967+ if(!error)
2968+#endif
2969+
2970+ error = vfs_symlink(nd.dentry->d_inode, dentry, from);
2971 dput(dentry);
2972 }
2973 up(&nd.dentry->d_inode->i_sem);
2974@@ -1607,7 +1882,44 @@
2975 new_dentry = lookup_create(&nd, 0);
2976 error = PTR_ERR(new_dentry);
2977 if (!IS_ERR(new_dentry)) {
2978- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
2979+#ifdef CONFIG_GRKERNSEC_LINK
2980+ if(grsec_enable_link) {
2981+ error = -EPERM;
2982+ if(current->fsuid != old_nd.dentry->d_inode->i_uid &&
2983+ (!S_ISREG(old_nd.dentry->d_inode->i_mode) ||
2984+ (old_nd.dentry->d_inode->i_mode & S_ISUID) ||
2985+ ((old_nd.dentry->d_inode->i_mode & (S_ISGID | S_IXGRP)) ==
2986+ (S_ISGID | S_IXGRP)) || (error = permission(old_nd.dentry->d_inode,
2987+ MAY_READ | MAY_WRITE))) && !capable(CAP_FOWNER) && current->uid) {
2988+ security_alert("denied hardlink of %.30s (owned by %d.%d) to %.30s for (%.16s:%d),"
2989+ " UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)",
2990+ "denied hardlinks",oldname,old_nd.dentry->d_inode->i_uid,
2991+ old_nd.dentry->d_inode->i_gid,newname,current->comm,current->pid,current->uid,
2992+ current->euid,current->p_pptr->comm,current->p_pptr->pid,
2993+ current->p_pptr->uid,current->p_pptr->euid);
2994+ } else {
2995+#endif
2996+#ifdef CONFIG_OBV_PROC
2997+ error = 0;
2998+ if( obv_search(old_nd.dentry,OBV_WRITE,old_nd.mnt) == OBV_DENY || obv_search(nd.dentry,OBV_WRITE,nd.mnt) == OBV_DENY) {
2999+ obv_seclog("attempt to link %.1024s to %.1024s "
3000+ "by (%.16s:%d), UID(%d), "
3001+ "EUID(%d), parent (%.16s:%d), UID(%d) "
3002+ "EUID(%d)\n",oldname,newname,
3003+ current->comm,current->pid,current->uid,
3004+ current->euid,current->p_pptr->comm,
3005+ current->p_pptr->pid,current->p_pptr->uid,
3006+ current->p_pptr->euid);
3007+ error = -EPERM;
3008+ }
3009+ if(!error)
3010+#endif
3011+
3012+ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
3013+#ifdef CONFIG_GRKERNSEC_LINK
3014+ }
3015+ }
3016+#endif
3017 dput(new_dentry);
3018 }
3019 up(&nd.dentry->d_inode->i_sem);
3020@@ -1844,11 +2156,30 @@
3021 error = PTR_ERR(new_dentry);
3022 if (IS_ERR(new_dentry))
3023 goto exit4;
3024+#ifdef CONFIG_OBV_PROC
3025+ error = 0;
3026+ if( obv_search(old_dir,OBV_WRITE,oldnd.mnt) == OBV_DENY || obv_search(new_dir,OBV_WRITE,newnd.mnt) == OBV_DENY) {
3027+ obv_seclog("attempt to rename %.1024s to %.1024s "
3028+ "by (%.16s:%d), UID(%d), "
3029+ "EUID(%d), parent (%.16s:%d), UID(%d) "
3030+ "EUID(%d)\n",oldname,newname,
3031+ current->comm,current->pid,current->uid,
3032+ current->euid,current->p_pptr->comm,
3033+ current->p_pptr->pid,current->p_pptr->uid,
3034+ current->p_pptr->euid);
3035+ error = -EPERM;
3036+ }
3037+ if(!error) {
3038+#endif
3039
3040- lock_kernel();
3041- error = vfs_rename(old_dir->d_inode, old_dentry,
3042- new_dir->d_inode, new_dentry);
3043- unlock_kernel();
3044+
3045+ lock_kernel();
3046+ error = vfs_rename(old_dir->d_inode, old_dentry,
3047+ new_dir->d_inode, new_dentry);
3048+ unlock_kernel();
3049+#ifdef CONFIG_OBV_PROC
3050+ }
3051+#endif
3052
3053 dput(new_dentry);
3054 exit4:
3055diff -urN linux/fs/open.c linux.grsec/fs/open.c
3056--- linux/fs/open.c Sun Sep 30 01:30:53 2001
3057+++ linux.grsec/fs/open.c Sun Sep 30 01:54:20 2001
3058@@ -17,8 +17,35 @@
3059
3060 #include <asm/uaccess.h>
3061
3062+#if defined(CONFIG_GRKERNSEC_CHROOT)||\
3063+ defined(CONFIG_GRKERNSEC_CHROOT_CAPS)
3064+#include <linux/grsecurity.h>
3065+#endif
3066+
3067+#ifdef CONFIG_OBV_PROC
3068+#include <linux/obvext.h>
3069+#endif
3070+
3071 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
3072
3073+#ifdef CONFIG_GRKERNSEC_CHROOT
3074+extern struct task_struct *child_reaper;
3075+#endif
3076+
3077+#ifdef CONFIG_OBV_PROC
3078+static int conv_flags(int p) {
3079+ int retval = LOOKUP_FOLLOW;
3080+ if(p & O_NOFOLLOW)
3081+ retval &= ~LOOKUP_FOLLOW;
3082+ if( (p & (O_CREAT|O_EXCL)) == (O_CREAT | O_EXCL))
3083+ retval &= ~LOOKUP_FOLLOW;
3084+ if(p & O_DIRECTORY)
3085+ retval |= LOOKUP_DIRECTORY;
3086+ return retval;
3087+}
3088+#endif
3089+
3090+
3091 int vfs_statfs(struct super_block *sb, struct statfs *buf)
3092 {
3093 int retval = -ENODEV;
3094@@ -70,7 +97,11 @@
3095 return error;
3096 }
3097
3098+#ifdef CONFIG_OBV_PROC
3099+int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
3100+#else
3101 int do_truncate(struct dentry *dentry, loff_t length)
3102+#endif
3103 {
3104 struct inode *inode = dentry->d_inode;
3105 int error;
3106@@ -80,6 +111,22 @@
3107 if (length < 0)
3108 return -EINVAL;
3109
3110+#ifdef CONFIG_OBV_PROC
3111+ if( ( (obv_search(dentry,OBV_WRITE,mnt)) == OBV_DENY)) {
3112+ obv_seclog("attempted to truncate file with inode %ld dev "
3113+ "%d by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
3114+ "UID(%d),EUID(%d)\n",dentry->d_inode->i_ino,
3115+ dentry->d_inode->i_dev,
3116+ current->comm,current->pid,current->uid,
3117+ current->euid,current->p_pptr->comm,
3118+ current->p_pptr->pid,current->p_pptr->uid,
3119+ current->p_pptr->euid);
3120+ dput(dentry);
3121+ return -EPERM;
3122+ }
3123+#endif
3124+
3125+
3126 down(&inode->i_sem);
3127 down_write(&inode->i_truncate_sem);
3128 newattrs.ia_size = length;
3129@@ -135,7 +182,11 @@
3130 error = locks_verify_truncate(inode, NULL, length);
3131 if (!error) {
3132 DQUOT_INIT(inode);
3133+#ifdef CONFIG_OBV_PROC
3134+ error = do_truncate(nd.dentry, length, nd.mnt);
3135+#else
3136 error = do_truncate(nd.dentry, length);
3137+#endif
3138 }
3139 put_write_access(inode);
3140
3141@@ -175,7 +226,11 @@
3142
3143 error = locks_verify_truncate(inode, file, length);
3144 if (!error)
3145+#ifdef CONFIG_OBV_PROC
3146+ error = do_truncate(dentry, length, file->f_vfsmnt);
3147+#else
3148 error = do_truncate(dentry, length);
3149+#endif
3150 out_putf:
3151 fput(file);
3152 out:
3153@@ -229,6 +284,23 @@
3154 if (IS_RDONLY(inode))
3155 goto dput_and_out;
3156
3157+#ifdef CONFIG_OBV_PROC
3158+ if( ( (obv_search(nd.dentry,OBV_WRITE,nd.mnt)) == OBV_DENY)) {
3159+ obv_seclog("attempted to change access time for file"
3160+ "with inode %ld dev "
3161+ "%d by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
3162+ "UID(%d),EUID(%d)\n",nd.dentry->d_inode->i_ino,
3163+ nd.dentry->d_inode->i_dev,
3164+ current->comm,current->pid,current->uid,
3165+ current->euid,current->p_pptr->comm,
3166+ current->p_pptr->pid,current->p_pptr->uid,
3167+ current->p_pptr->euid);
3168+ path_release(&nd);
3169+ return -EPERM;
3170+ }
3171+#endif
3172+
3173+
3174 /* Don't worry, the checks are done in inode_change_ok() */
3175 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
3176 if (times) {
3177@@ -274,6 +346,23 @@
3178 if (IS_RDONLY(inode))
3179 goto dput_and_out;
3180
3181+#ifdef CONFIG_OBV_PROC
3182+ if( ( (obv_search(nd.dentry,OBV_WRITE,nd.mnt)) == OBV_DENY)) {
3183+ obv_seclog("attempted to change access time for file with"
3184+ "inode %ld dev "
3185+ "%d by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
3186+ "UID(%d),EUID(%d)\n",nd.dentry->d_inode->i_ino,
3187+ nd.dentry->d_inode->i_dev,
3188+ current->comm,current->pid,current->uid,
3189+ current->euid,current->p_pptr->comm,
3190+ current->p_pptr->pid,current->p_pptr->uid,
3191+ current->p_pptr->euid);
3192+ path_release(&nd);
3193+ return -EPERM;
3194+ }
3195+#endif
3196+
3197+
3198 /* Don't worry, the checks are done in inode_change_ok() */
3199 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
3200 if (utimes) {
3201@@ -325,6 +414,21 @@
3202
3203 res = user_path_walk(filename, &nd);
3204 if (!res) {
3205+#ifdef CONFIG_OBV_PROC
3206+ if( ( (obv_search(nd.dentry,OBV_WRITE,nd.mnt)) == OBV_DENY)) {
3207+ obv_seclog("attempted to access file with inode %ld dev "
3208+ "%d by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
3209+ "UID(%d),EUID(%d)\n",nd.dentry->d_inode->i_ino,
3210+ nd.dentry->d_inode->i_dev,
3211+ current->comm,current->pid,current->uid,
3212+ current->euid,current->p_pptr->comm,
3213+ current->p_pptr->pid,current->p_pptr->uid,
3214+ current->p_pptr->euid);
3215+ path_release(&nd);
3216+ res = -EPERM;
3217+ }
3218+#endif
3219+
3220 res = permission(nd.dentry->d_inode, mode);
3221 /* SuS v2 requires we report a read only fs too */
3222 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
3223@@ -362,6 +466,21 @@
3224 if (error)
3225 goto dput_and_out;
3226
3227+#ifdef CONFIG_OBV_PROC
3228+ if( ( (obv_search(nd.dentry,OBV_READ,nd.mnt)) == OBV_DENY)) {
3229+ obv_seclog("Attempted to chdir to directory with inode %ld dev "
3230+ "%d by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
3231+ "UID(%d),EUID(%d)\n",nd.dentry->d_inode->i_ino,
3232+ nd.dentry->d_inode->i_dev,
3233+ current->comm,current->pid,current->uid,
3234+ current->euid,current->p_pptr->comm,
3235+ current->p_pptr->pid,current->p_pptr->uid,
3236+ current->p_pptr->euid);
3237+ error = -EPERM;
3238+ goto dput_and_out;
3239+ }
3240+#endif
3241+
3242 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
3243
3244 dput_and_out:
3245@@ -392,6 +511,21 @@
3246 goto out_putf;
3247
3248 error = permission(inode, MAY_EXEC);
3249+
3250+#ifdef CONFIG_OBV_PROC
3251+ if( ( (obv_search(file->f_dentry,OBV_WRITE,file->f_vfsmnt)) == OBV_DENY)) {
3252+ obv_seclog("attempted to truncate file with inode %ld dev "
3253+ "%d by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
3254+ "UID(%d), EUID(%d)\n",file->f_dentry->d_inode->i_ino,
3255+ file->f_dentry->d_inode->i_dev,
3256+ current->comm,current->pid,current->uid,
3257+ current->euid,current->p_pptr->comm,
3258+ current->p_pptr->pid,current->p_pptr->uid,
3259+ current->p_pptr->euid);
3260+ error = -EPERM;
3261+ }
3262+#endif
3263+
3264 if (!error)
3265 set_fs_pwd(current->fs, mnt, dentry);
3266 out_putf:
3267@@ -423,11 +557,46 @@
3268 goto dput_and_out;
3269
3270 error = -EPERM;
3271- if (!capable(CAP_SYS_CHROOT))
3272- goto dput_and_out;
3273+ if (!capable(CAP_SYS_CHROOT))
3274+ goto dput_and_out;
3275+#ifdef CONFIG_GRKERNSEC_CHROOT
3276+ if(grsec_enable_chroot &&
3277+ !( (current->fs->root->d_inode->i_dev ==
3278+ child_reaper->fs->root->d_inode->i_dev) &&
3279+ (current->fs->root->d_inode->i_ino ==
3280+ child_reaper->fs->root->d_inode->i_ino) ) ) {
3281+ security_alert("denied attempt to chroot() from (%.32s:%lu) to (%.30s)"
3282+ ", process (%.16s:%d), UID (%d), EUID (%d), parent "
3283+ "(%16s:%d), UID (%d), EUID (%d)", "double chroot() denied",
3284+ kdevname(current->fs->root->d_inode->i_dev),current->fs->root->d_inode->i_ino,name,
3285+ current->comm,current->pid,current->uid,current->euid,
3286+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
3287+ current->p_pptr->euid);
3288+ goto dput_and_out;
3289+ }
3290+#endif
3291
3292 set_fs_root(current->fs, nd.mnt, nd.dentry);
3293 set_fs_altroot();
3294+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
3295+ if(grsec_enable_chroot_caps && current->pid && current->pid > 1) {
3296+ cap_lower(current->cap_permitted,CAP_FOWNER & CAP_SETPCAP & CAP_LINUX_IMMUTABLE &
3297+ CAP_NET_ADMIN & CAP_SYS_MODULE & CAP_SYS_RAWIO & CAP_SYS_PACCT &
3298+ CAP_SYS_ADMIN & CAP_SYS_BOOT & CAP_SYS_RESOURCE & CAP_SYS_TIME &
3299+ CAP_SYS_TTY_CONFIG);
3300+ cap_lower(current->cap_inheritable,CAP_FOWNER & CAP_SETPCAP & CAP_LINUX_IMMUTABLE &
3301+ CAP_NET_ADMIN & CAP_SYS_MODULE & CAP_SYS_RAWIO & CAP_SYS_PACCT &
3302+ CAP_SYS_ADMIN & CAP_SYS_BOOT & CAP_SYS_RESOURCE & CAP_SYS_TIME &
3303+ CAP_SYS_TTY_CONFIG);
3304+ cap_lower(current->cap_effective,CAP_FOWNER & CAP_SETPCAP & CAP_LINUX_IMMUTABLE &
3305+ CAP_NET_ADMIN & CAP_SYS_MODULE & CAP_SYS_RAWIO & CAP_SYS_PACCT &
3306+ CAP_SYS_ADMIN & CAP_SYS_BOOT & CAP_SYS_RESOURCE & CAP_SYS_TIME &
3307+ CAP_SYS_TTY_CONFIG);
3308+ }
3309+#endif
3310+#ifdef CONFIG_GRKERNSEC_CHROOT
3311+ if (grsec_enable_chroot) sys_chdir("/");
3312+#endif
3313 error = 0;
3314 dput_and_out:
3315 path_release(&nd);
3316@@ -456,8 +625,46 @@
3317 err = -EPERM;
3318 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
3319 goto out_putf;
3320+
3321+#ifdef CONFIG_OBV_PROC
3322+ if( ( (obv_search(dentry,OBV_WRITE,file->f_vfsmnt)) == OBV_DENY)) {
3323+ obv_seclog("Attempt to fchmod program with inode %ld dev %d "
3324+ "by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
3325+ "UID(%d),EUID(%d)\n",dentry->d_inode->i_ino,
3326+ dentry->d_inode->i_dev,
3327+ current->comm,current->pid,current->uid,
3328+ current->euid,current->p_pptr->comm,
3329+ current->p_pptr->pid,current->p_pptr->uid,
3330+ current->p_pptr->euid);
3331+
3332+ err = -EPERM;
3333+ goto out_putf;
3334+ }
3335+#endif
3336+
3337 if (mode == (mode_t) -1)
3338 mode = inode->i_mode;
3339+#ifdef CONFIG_GRKERNSEC_CHROOT
3340+ if(grsec_enable_chroot && ((mode & S_ISUID) || (mode & S_ISGID))) {
3341+ if(!( (current->fs->root->d_inode->i_dev ==
3342+ child_reaper->fs->root->d_inode->i_dev) &&
3343+ (current->fs->root->d_inode->i_ino ==
3344+ child_reaper->fs->root->d_inode->i_ino) ) ) {
3345+
3346+ security_alert("denied attempt to fchmod() +s (%.32s:%lu) owned by %d.%d to mode 0%07o "
3347+ "from chroot() jail (%.32s:%lu) of %d.%d by (%.16s:%d), UID (%d), "
3348+ "EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d)","denied fchmod() +s in chroot()",
3349+ kdevname(inode->i_dev),inode->i_ino,inode->i_uid,inode->i_gid,mode,
3350+ kdevname(current->fs->root->d_inode->i_dev),current->fs->root->d_inode->i_ino,
3351+ current->fs->root->d_inode->i_uid,current->fs->root->d_inode->i_gid,
3352+ current->comm,current->pid,current->uid,current->euid,
3353+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
3354+ current->p_pptr->euid);
3355+ err = -EPERM;
3356+ goto out_putf;
3357+ }
3358+ }
3359+#endif
3360 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
3361 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
3362 err = notify_change(dentry, &newattrs);
3363@@ -488,8 +695,43 @@
3364 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
3365 goto dput_and_out;
3366
3367+#ifdef CONFIG_OBV_PROC
3368+ if( ( (obv_search(nd.dentry,OBV_WRITE,nd.mnt)) == OBV_DENY)) {
3369+ obv_seclog("Attempt to chmod file %1024s by (%.16s:%d), "
3370+ "UID(%d), EUID(%d), parent (%.16s:%d), "
3371+ "UID(%d),EUID(%d)\n",filename,
3372+ current->comm,current->pid,current->uid,
3373+ current->euid,current->p_pptr->comm,
3374+ current->p_pptr->pid,current->p_pptr->uid,
3375+ current->p_pptr->euid);
3376+ error = -EPERM;
3377+ goto dput_and_out;
3378+ }
3379+#endif
3380+
3381+
3382 if (mode == (mode_t) -1)
3383 mode = inode->i_mode;
3384+#ifdef CONFIG_GRKERNSEC_CHROOT
3385+ if (grsec_enable_chroot && ((mode & S_ISUID) || (mode & S_ISGID))) {
3386+ if(!( (current->fs->root->d_inode->i_dev ==
3387+ child_reaper->fs->root->d_inode->i_dev) &&
3388+ (current->fs->root->d_inode->i_ino ==
3389+ child_reaper->fs->root->d_inode->i_ino) ) ) {
3390+ security_alert("denied attempt to chmod() +s (%.32s:%lu) (%.30s) owned by %d.%d to mode 0%07o "
3391+ "from chroot() jail (%.32s:%lu) of %d.%d by (%.16s:%d), UID (%d), "
3392+ "EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d)","denied fchmod() +s in chroot()",
3393+ kdevname(inode->i_dev),inode->i_ino,filename,inode->i_uid,inode->i_gid,
3394+ mode,kdevname(current->fs->root->d_inode->i_dev),
3395+ current->fs->root->d_inode->i_ino,current->fs->root->d_inode->i_uid,
3396+ current->fs->root->d_inode->i_gid,current->comm,current->pid,
3397+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
3398+ current->p_pptr->uid,current->p_pptr->euid);
3399+ error = -EPERM;
3400+ goto dput_and_out;
3401+ }
3402+ }
3403+#endif
3404 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
3405 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
3406 error = notify_change(nd.dentry, &newattrs);
3407@@ -500,7 +742,7 @@
3408 return error;
3409 }
3410
3411-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
3412+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
3413 {
3414 struct inode * inode;
3415 int error;
3416@@ -514,9 +756,36 @@
3417 error = -EROFS;
3418 if (IS_RDONLY(inode))
3419 goto out;
3420+#ifdef CONFIG_GRKERNSEC_NOEXEC
3421+ if(in_group_p(CONFIG_GRKERNSEC_NOEXEC_GID) &&
3422+ (group == CONFIG_GRKERNSEC_NOEXEC_GID)){
3423+ security_alert("denied chown of %.32s by (%.16s:%d), UID(%d), "
3424+ "EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d) reason: tried to "
3425+ "bypass noexec","denied noexec chowns",dentry->d_name.name,current->comm,
3426+ current->pid,current->uid,current->euid,current->p_pptr->comm,
3427+ current->p_pptr->pid,current->p_pptr->uid,current->p_pptr->euid);
3428+ return -EPERM;
3429+ }
3430+#endif
3431+
3432 error = -EPERM;
3433 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
3434 goto out;
3435+#ifdef CONFIG_OBV_PROC
3436+ if( ( (obv_search(dentry,OBV_WRITE,mnt)) == OBV_DENY)) {
3437+ obv_seclog("Attempt to chown file with inode %ld dev %d "
3438+ "to %d.%d by (%.16s:%d), UID(%d), EUID(%d), parent "
3439+ "(%.16s:%d), UID(%d), EUID(%d)\n",
3440+ dentry->d_inode->i_ino,dentry->d_inode->i_dev,user,group,
3441+ current->comm,current->pid,current->uid,
3442+ current->euid,current->p_pptr->comm,
3443+ current->p_pptr->pid,current->p_pptr->uid,
3444+ current->p_pptr->euid);
3445+ dput(dentry);
3446+ return -EPERM;
3447+ }
3448+#endif
3449+
3450 if (user == (uid_t) -1)
3451 user = inode->i_uid;
3452 if (group == (gid_t) -1)
3453@@ -567,7 +836,7 @@
3454
3455 error = user_path_walk(filename, &nd);
3456 if (!error) {
3457- error = chown_common(nd.dentry, user, group);
3458+ error = chown_common(nd.dentry, user, group, nd.mnt);
3459 path_release(&nd);
3460 }
3461 return error;
3462@@ -580,7 +849,7 @@
3463
3464 error = user_path_walk_link(filename, &nd);
3465 if (!error) {
3466- error = chown_common(nd.dentry, user, group);
3467+ error = chown_common(nd.dentry, user, group, nd.mnt);
3468 path_release(&nd);
3469 }
3470 return error;
3471@@ -594,7 +863,7 @@
3472
3473 file = fget(fd);
3474 if (file) {
3475- error = chown_common(file->f_dentry, user, group);
3476+ error = chown_common(file->f_dentry, user, group, file->f_vfsmnt);
3477 fput(file);
3478 }
3479 return error;
3480@@ -618,12 +887,30 @@
3481 {
3482 int namei_flags, error;
3483 struct nameidata nd;
3484+#ifdef CONFIG_OBV_PROC
3485+ struct nameidata obv;
3486+#endif
3487
3488 namei_flags = flags;
3489 if ((namei_flags+1) & O_ACCMODE)
3490 namei_flags++;
3491 if (namei_flags & O_TRUNC)
3492 namei_flags |= 2;
3493+
3494+#ifdef CONFIG_OBV_PROC
3495+ error = 0;
3496+ if(path_init(filename,conv_flags(namei_flags),&obv))
3497+ error = path_walk(filename,&obv);
3498+ if(error) goto out;
3499+ if(!obv.dentry->d_inode)
3500+ nd.flags = 1;
3501+ else
3502+ nd.flags = 0;
3503+ path_release(&obv);
3504+out:
3505+
3506+#endif
3507+
3508
3509 error = open_namei(filename, namei_flags, mode, &nd);
3510 if (!error)
3511diff -urN linux/fs/proc/base.c linux.grsec/fs/proc/base.c
3512--- linux/fs/proc/base.c Sun Sep 30 01:30:59 2001
3513+++ linux.grsec/fs/proc/base.c Sun Sep 30 01:54:20 2001
3514@@ -24,6 +24,10 @@
3515 #include <linux/file.h>
3516 #include <linux/string.h>
3517
3518+#ifdef CONFIG_OBV_PROC
3519+#include <linux/obvext.h>
3520+#endif
3521+
3522 /*
3523 * For hysterical raisins we keep the same inumbers as in the old procfs.
3524 * Feel free to change the macro below - just keep the range distinct from
3525@@ -566,6 +570,25 @@
3526 static struct pid_entry base_stuff[] = {
3527 E(PROC_PID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
3528 E(PROC_PID_ENVIRON, "environ", S_IFREG|S_IRUSR),
3529+#ifdef CONFIG_GRKERNSEC_PROC_USER
3530+ E(PROC_PID_STATUS, "status", S_IFREG|S_IRUSR),
3531+ E(PROC_PID_CMDLINE, "cmdline", S_IFREG|S_IRUSR),
3532+ E(PROC_PID_STAT, "stat", S_IFREG|S_IRUSR),
3533+ E(PROC_PID_STATM, "statm", S_IFREG|S_IRUSR),
3534+#ifdef CONFIG_SMP
3535+ E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUSR),
3536+#endif
3537+ E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUSR),
3538+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
3539+ E(PROC_PID_STATUS, "status", S_IFREG|S_IRUSR|S_IRGRP),
3540+ E(PROC_PID_CMDLINE, "cmdline", S_IFREG|S_IRUSR|S_IRGRP),
3541+ E(PROC_PID_STAT, "stat", S_IFREG|S_IRUSR|S_IRGRP),
3542+ E(PROC_PID_STATM, "statm", S_IFREG|S_IRUSR|S_IRGRP),
3543+#ifdef CONFIG_SMP
3544+ E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUSR|S_IRGRP),
3545+#endif
3546+ E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUSR|S_IRGRP),
3547+#else
3548 E(PROC_PID_STATUS, "status", S_IFREG|S_IRUGO),
3549 E(PROC_PID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
3550 E(PROC_PID_STAT, "stat", S_IFREG|S_IRUGO),
3551@@ -575,6 +598,7 @@
3552 E(PROC_PID_CPUS_ALLOWED, "cpus_allowed", S_IFREG|S_IRUGO|S_IWUSR),
3553 #endif
3554 E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUGO),
3555+#endif
3556 E(PROC_PID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
3557 E(PROC_PID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
3558 E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO),
3559@@ -726,7 +750,11 @@
3560 inode->i_gid = 0;
3561 if (ino == PROC_PID_INO || task_dumpable(task)) {
3562 inode->i_uid = task->euid;
3563+#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
3564 inode->i_gid = task->egid;
3565+#else
3566+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
3567+#endif
3568 }
3569
3570 out:
3571@@ -1034,13 +1062,26 @@
3572 if (!task)
3573 goto out;
3574
3575+#ifdef CONFIG_OBV_PROC
3576+ if(task->obvacl)
3577+ if(obv_check_hidden_proc(task))
3578+ goto out;
3579+#endif
3580+
3581+
3582 inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
3583
3584 free_task_struct(task);
3585
3586 if (!inode)
3587 goto out;
3588+#ifdef CONFIG_GRKERNSEC_PROC_USER
3589+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
3590+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
3591+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
3592+#else
3593 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
3594+#endif
3595 inode->i_op = &proc_base_inode_operations;
3596 inode->i_fop = &proc_base_operations;
3597 inode->i_nlink = 3;
3598@@ -1082,6 +1123,12 @@
3599 continue;
3600 if (--index >= 0)
3601 continue;
3602+#ifdef CONFIG_OBV_PROC
3603+ if(p->obvacl)
3604+ if(obv_check_hidden_proc(p))
3605+ continue;
3606+#endif
3607+
3608 pids[nr_pids] = pid;
3609 nr_pids++;
3610 if (nr_pids >= PROC_MAXPIDS)
3611diff -urN linux/fs/proc/inode.c linux.grsec/fs/proc/inode.c
3612--- linux/fs/proc/inode.c Wed Apr 18 08:16:39 2001
3613+++ linux.grsec/fs/proc/inode.c Sun Sep 30 01:54:20 2001
3614@@ -152,7 +152,11 @@
3615 if (de->mode) {
3616 inode->i_mode = de->mode;
3617 inode->i_uid = de->uid;
3618+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
3619+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
3620+#else
3621 inode->i_gid = de->gid;
3622+#endif
3623 }
3624 if (de->size)
3625 inode->i_size = de->size;
3626diff -urN linux/fs/read_write.c linux.grsec/fs/read_write.c
3627--- linux/fs/read_write.c Tue Apr 17 23:36:44 2001
3628+++ linux.grsec/fs/read_write.c Sun Sep 30 01:54:20 2001
3629@@ -14,6 +14,11 @@
3630
3631 #include <asm/uaccess.h>
3632
3633+#ifdef CONFIG_OBV_PROC
3634+#include <linux/obvext.h>
3635+#endif
3636+
3637+
3638 struct file_operations generic_ro_fops = {
3639 read: generic_file_read,
3640 mmap: generic_file_mmap,
3641@@ -124,6 +129,21 @@
3642 file = fget(fd);
3643 if (file) {
3644 if (file->f_mode & FMODE_READ) {
3645+#ifdef CONFIG_OBV_PROC
3646+ if( (file->f_dentry->d_inode) && (S_ISBLK(file->f_dentry->d_inode->i_mode)) && (!capable(CAP_SYS_RAWIO))) {
3647+ obv_seclog("Attempt to read from block file "
3648+ "with inode %ld dev %d by (%.16s:%d), "
3649+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
3650+ file->f_dentry->d_inode->i_ino,file->f_dentry->d_inode->i_dev,
3651+ current->comm,current->pid,current->uid,
3652+ current->euid,current->p_pptr->comm,
3653+ current->p_pptr->pid,current->p_pptr->uid,
3654+ current->p_pptr->euid);
3655+ fput(file);
3656+ return -EPERM;
3657+ }
3658+#endif
3659+
3660 ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
3661 file, file->f_pos, count);
3662 if (!ret) {
3663@@ -151,6 +171,21 @@
3664 if (file) {
3665 if (file->f_mode & FMODE_WRITE) {
3666 struct inode *inode = file->f_dentry->d_inode;
3667+#ifdef CONFIG_OBV_PROC
3668+ if( (inode != NULL) && (S_ISBLK(inode->i_mode)) && (!capable(CAP_SYS_RAWIO))) {
3669+ obv_seclog("Attempt to write to block file "
3670+ "with inode %ld dev %d by (%.16s:%d), "
3671+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), EUID(%d)\n",
3672+ inode->i_ino,inode->i_dev,
3673+ current->comm,current->pid,current->uid,
3674+ current->euid,current->p_pptr->comm,
3675+ current->p_pptr->pid,current->p_pptr->uid,
3676+ current->p_pptr->euid);
3677+ fput(file);
3678+ return -EPERM;
3679+ }
3680+#endif
3681+
3682 ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
3683 file->f_pos, count);
3684 if (!ret) {
3685diff -urN linux/fs/readdir.c linux.grsec/fs/readdir.c
3686--- linux/fs/readdir.c Mon Dec 11 22:45:42 2000
3687+++ linux.grsec/fs/readdir.c Sun Sep 30 01:54:20 2001
3688@@ -13,6 +13,10 @@
3689
3690 #include <asm/uaccess.h>
3691
3692+#ifdef CONFIG_OBV_PROC
3693+#include <linux/obvext.h>
3694+#endif
3695+
3696 int vfs_readdir(struct file *file, filldir_t filler, void *buf)
3697 {
3698 struct inode *inode = file->f_dentry->d_inode;
3699@@ -120,6 +124,10 @@
3700 struct readdir_callback {
3701 struct old_linux_dirent * dirent;
3702 int count;
3703+#ifdef CONFIG_OBV_PROC
3704+ struct dentry *dentry;
3705+ struct vfsmount *mnt;
3706+#endif
3707 };
3708
3709 static int fillonedir(void * __buf, const char * name, int namlen, off_t offset,
3710@@ -127,9 +135,30 @@
3711 {
3712 struct readdir_callback * buf = (struct readdir_callback *) __buf;
3713 struct old_linux_dirent * dirent;
3714+#ifdef CONFIG_OBV_PROC
3715+ ino_t old_ino;
3716+#endif
3717
3718 if (buf->count)
3719 return -EINVAL;
3720+#ifdef CONFIG_OBV_PROC
3721+ if(buf->dentry && buf->dentry->d_inode) {
3722+ old_ino = buf->dentry->d_inode->i_ino;
3723+ //down(&buf->dentry->d_inode->i_sem);
3724+ buf->dentry->d_inode->i_ino = ino;
3725+#ifdef CONFIG_OBV_PROC
3726+ printk("Guess what: %ld %d is about to get a readdir check\n",buf->dentry->d_inode->i_ino,buf->dentry->d_inode->i_dev);
3727+#endif
3728+ if( obv_check_hidden(buf->dentry,buf->mnt) == OBV_DENY) {
3729+ buf->dentry->d_inode->i_ino = old_ino;
3730+ //up(&buf->dentry->d_inode->i_sem);
3731+ return 0;
3732+ }
3733+ //up(&buf->dentry->d_inode->i_sem);
3734+ buf->dentry->d_inode->i_ino = ino;
3735+ }
3736+#endif
3737+
3738 buf->count++;
3739 dirent = buf->dirent;
3740 put_user(ino, &dirent->d_ino);
3741@@ -153,6 +182,10 @@
3742
3743 buf.count = 0;
3744 buf.dirent = dirent;
3745+#ifdef CONFIG_OBV_PROC
3746+ buf.dentry = file->f_dentry;
3747+ buf.mnt = file->f_vfsmnt;
3748+#endif
3749
3750 error = vfs_readdir(file, fillonedir, &buf);
3751 if (error >= 0)
3752@@ -181,6 +214,10 @@
3753 struct linux_dirent * previous;
3754 int count;
3755 int error;
3756+#ifdef CONFIG_OBV_PROC
3757+ struct dentry *dentry;
3758+ struct vfsmount *mnt;
3759+#endif
3760 };
3761
3762 static int filldir(void * __buf, const char * name, int namlen, off_t offset,
3763@@ -189,10 +226,30 @@
3764 struct linux_dirent * dirent;
3765 struct getdents_callback * buf = (struct getdents_callback *) __buf;
3766 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
3767+#ifdef CONFIG_OBV_PROC
3768+ ino_t old_ino;
3769+#endif
3770
3771 buf->error = -EINVAL; /* only used if we fail.. */
3772 if (reclen > buf->count)
3773 return -EINVAL;
3774+#ifdef CONFIG_OBV_PROC
3775+ if(buf->dentry && buf->dentry->d_inode) {
3776+ old_ino = buf->dentry->d_inode->i_ino;
3777+ //down(&buf->dentry->d_inode->i_sem);
3778+ buf->dentry->d_inode->i_ino = ino;
3779+#ifdef CONFIG_OBV_DEBUG
3780+ printk("Guess what: %ld %d is about to get a readdir check\n",buf->dentry->d_inode->i_ino,buf->dentry->d_inode->i_dev);
3781+#endif
3782+ if( obv_check_hidden(buf->dentry,buf->mnt) == OBV_DENY) {
3783+ buf->dentry->d_inode->i_ino = old_ino;
3784+ //up(&buf->dentry->d_inode->i_sem);
3785+ return 0;
3786+ }
3787+ buf->dentry->d_inode->i_ino = old_ino;
3788+ //up(&buf->dentry->d_inode->i_sem);
3789+ }
3790+#endif
3791 dirent = buf->previous;
3792 if (dirent)
3793 put_user(offset, &dirent->d_off);
3794@@ -224,6 +281,10 @@
3795 buf.previous = NULL;
3796 buf.count = count;
3797 buf.error = 0;
3798+#ifdef CONFIG_OBV_PROC
3799+ buf.dentry = file->f_dentry;
3800+ buf.mnt = file->f_vfsmnt;
3801+#endif
3802
3803 error = vfs_readdir(file, filldir, &buf);
3804 if (error < 0)
3805@@ -259,6 +320,10 @@
3806 struct linux_dirent64 * previous;
3807 int count;
3808 int error;
3809+#ifdef CONFIG_OBV_PROC
3810+ struct dentry *dentry;
3811+ struct vfsmount *mnt;
3812+#endif
3813 };
3814
3815 static int filldir64(void * __buf, const char * name, int namlen, off_t offset,
3816@@ -267,10 +332,30 @@
3817 struct linux_dirent64 * dirent, d;
3818 struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
3819 int reclen = ROUND_UP64(NAME_OFFSET(dirent) + namlen + 1);
3820-
3821+
3822+#ifdef CONFIG_OBV_PROC
3823+ ino_t old_ino;
3824+#endif
3825 buf->error = -EINVAL; /* only used if we fail.. */
3826 if (reclen > buf->count)
3827 return -EINVAL;
3828+#ifdef CONFIG_OBV_PROC
3829+ if(buf->dentry && buf->dentry->d_inode) {
3830+ old_ino = buf->dentry->d_inode->i_ino;
3831+ //down(&buf->dentry->d_inode->i_sem);
3832+ buf->dentry->d_inode->i_ino = ino;
3833+ if((obv_check_hidden(buf->dentry,buf->mnt)) == OBV_DENY) {
3834+ buf->dentry->d_inode->i_ino = old_ino;
3835+ // up(&buf->dentry->d_inode->i_sem);
3836+ return 0;
3837+ }
3838+ buf->dentry->d_inode->i_ino = old_ino;
3839+ //up(&buf->dentry->d_inode->i_sem);
3840+ }
3841+#endif
3842+
3843+
3844+
3845 dirent = buf->previous;
3846 if (dirent) {
3847 d.d_off = offset;
3848@@ -307,6 +392,11 @@
3849 buf.previous = NULL;
3850 buf.count = count;
3851 buf.error = 0;
3852+#ifdef CONFIG_OBV_PROC
3853+ buf.mnt = file->f_vfsmnt;
3854+ buf.dentry = file->f_dentry;
3855+#endif
3856+
3857
3858 error = vfs_readdir(file, filldir64, &buf);
3859 if (error < 0)
3860diff -urN linux/fs/super.c linux.grsec/fs/super.c
3861--- linux/fs/super.c Sun Sep 30 01:30:55 2001
3862+++ linux.grsec/fs/super.c Sun Sep 30 01:54:20 2001
3863@@ -42,6 +42,12 @@
3864 #define __NO_VERSION__
3865 #include <linux/module.h>
3866
3867+#ifdef CONFIG_GRKERNSEC_CHROOT
3868+#include <linux/sched.h>
3869+#include <linux/grsecurity.h>
3870+extern struct task_struct *child_reaper;
3871+#endif
3872+
3873 /*
3874 * We use a semaphore to synchronize all mount/umount
3875 * activity - imagine the mess if we have a race between
3876@@ -1422,6 +1428,27 @@
3877 retval = path_walk(dir_name, &nd);
3878 if (retval)
3879 return retval;
3880+
3881+#ifdef CONFIG_GRKERNSEC_CHROOT
3882+ if (grsec_enable_chroot &&
3883+ !( (current->fs->root->d_inode->i_dev ==
3884+ child_reaper->fs->root->d_inode->i_dev) &&
3885+ (current->fs->root->d_inode->i_ino ==
3886+ child_reaper->fs->root->d_inode->i_ino) ) ) {
3887+ security_alert("denied attempt to mount (%.30s) as %.64s from chroot() jail (%.32s:%lu) "
3888+ "of %d.%d by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), "
3889+ "UID (%d), EUID (%d)","denied mounts in chroot()",dev_name,dir_name,
3890+ kdevname(current->fs->root->d_inode->i_dev),
3891+ current->fs->root->d_inode->i_ino,current->fs->root->d_inode->i_uid,
3892+ current->fs->root->d_inode->i_gid,current->comm,current->pid,
3893+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
3894+ current->p_pptr->uid,current->p_pptr->euid);
3895+ retval = -EPERM;
3896+ path_release(&nd);
3897+ return retval;
3898+ }
3899+#endif
3900+
3901
3902 if (flags & MS_REMOUNT)
3903 retval = do_remount(&nd, flags&~MS_REMOUNT,
3904diff -urN linux/grsecurity/Config.in linux.grsec/grsecurity/Config.in
3905--- linux/grsecurity/Config.in Thu Jan 1 01:00:00 1970
3906+++ linux.grsec/grsecurity/Config.in Sun Sep 30 01:54:20 2001
3907@@ -0,0 +1,124 @@
3908+mainmenu_option next_comment
3909+comment 'Buffer Overflow Protection'
3910+if [ "$CONFIG_X86" != "n" ]; then
3911+if [ "$CONFIG_GRKERNSEC_PAX" != "y" ]; then
3912+bool 'Openwall non-executable stack' CONFIG_GRKERNSEC_STACK
3913+if [ "$CONFIG_GRKERNSEC_STACK" != "n" ]; then
3914+bool ' Gcc trampoline support' CONFIG_GRKERNSEC_STACK_GCC
3915+fi
3916+fi
3917+if [ "$CONFIG_GRKERNSEC_STACK" != "y" ]; then
3918+bool 'PaX protection' CONFIG_GRKERNSEC_PAX
3919+if [ "$CONFIG_GRKERNSEC_PAX" = "y" ]; then
3920+ bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
3921+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
3922+ bool ' Randomize mmap() base' CONFIG_GRKERNSEC_PAX_RANDMMAP
3923+fi
3924+fi
3925+fi
3926+endmenu
3927+mainmenu_option next_comment
3928+comment 'Access Control Lists'
3929+bool 'Enable Oblivion Process Management' CONFIG_OBV_PROC
3930+if [ "$CONFIG_OBV_PROC" = "y" ]; then
3931+ int 'Maximum Number of Oblivion Rulesets for Files, Processes' CONFIG_OBV_MAX_RULESET 256
3932+ int 'Seconds in between Oblivion log messages(minimum)' CONFIG_OBV_FLOODTIME 3
3933+ choice 'Default ruleset for programs without acls' \
3934+ "Deny CONFIG_OBV_DEF_DENY \
3935+ Allow CONFIG_OBV_DEF_ALLOW \
3936+ Deny_if_running_as_root CONFIG_OBV_DEF_DENY_ROOT " Allow
3937+ bool 'Enable Oblivion Debugging Messages' CONFIG_OBV_DEBUG
3938+ string 'Path to obvadm' CONFIG_OBVADM_PATH "/sbin/obvadm"
3939+ int 'Maximum tries before password lockout' CONFIG_OBV_MAXTRIES 3
3940+ int 'Time to wait after max password tries, in seconds' CONFIG_OBV_TIMEOUT 30
3941+fi
3942+endmenu
3943+mainmenu_option next_comment
3944+comment 'Filesystem Protections'
3945+bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC
3946+if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then
3947+bool ' Restrict to user only' CONFIG_GRKERNSEC_PROC_USER
3948+if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then
3949+bool ' Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP
3950+if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
3951+int ' GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001
3952+fi
3953+fi
3954+fi
3955+bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK
3956+bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO
3957+bool 'Secure file descriptors' CONFIG_GRKERNSEC_FD
3958+bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT
3959+if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then
3960+bool ' Log execs within jail' CONFIG_GRKERNSEC_CHROOT_EXECLOG
3961+bool ' Capability restrictions' CONFIG_GRKERNSEC_CHROOT_CAPS
3962+fi
3963+bool 'Secure keymap loading' CONFIG_GRKERNSEC_KBMAP
3964+endmenu
3965+mainmenu_option next_comment
3966+comment 'Security Logging'
3967+bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG
3968+bool 'Set*id logging' CONFIG_GRKERNSEC_SUID
3969+bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL
3970+bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL
3971+bool 'Time change logging' CONFIG_GRKERNSEC_TIME
3972+endmenu
3973+mainmenu_option next_comment
3974+comment 'Executable Protections'
3975+bool 'Exec process limiting' CONFIG_GRKERNSEC_EXECVE
3976+bool 'Fork-bomb protection' CONFIG_GRKERNSEC_FORKBOMB
3977+if [ "$CONFIG_GRKERNSEC_FORKBOMB" != "n" ]; then
3978+int ' GID for restricted users' CONFIG_GRKERNSEC_FORKBOMB_GID 1006
3979+int ' Forks allowed per second' CONFIG_GRKERNSEC_FORKBOMB_SEC 40
3980+int ' Maximum processes allowed' CONFIG_GRKERNSEC_FORKBOMB_MAX 20
3981+fi
3982+bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE
3983+if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then
3984+bool ' Glibc protection' CONFIG_GRKERNSEC_TPE_GLIBC
3985+bool ' Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
3986+int ' GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
3987+fi
3988+endmenu
3989+mainmenu_option next_comment
3990+comment 'Network Protections'
3991+bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID
3992+bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID
3993+bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC
3994+bool 'Altered Ping IDs' CONFIG_GRKERNSEC_RANDPING
3995+bool 'Randomized TTL' CONFIG_GRKERNSEC_RANDTTL
3996+if [ "$CONFIG_GRKERNSEC_RANDTTL" != "n" ]; then
3997+int ' TTL starting point:' CONFIG_GRKERNSEC_RANDTTL_THRESH 64
3998+fi
3999+bool 'Enhanced network randomness' CONFIG_GRKERNSEC_RANDNET
4000+bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET
4001+if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then
4002+bool ' Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL
4003+if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then
4004+int ' GID to deny all sockets for:' CONFIG_GRKERNSEC_ALL_GID 1004
4005+fi
4006+bool ' Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT
4007+if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then
4008+int ' GID to deny client sockets for:' CONFIG_GRKERNSEC_CLIENT_GID 1003
4009+fi
4010+bool ' Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER
4011+if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then
4012+int ' GID to deny server sockets for:' CONFIG_GRKERNSEC_SERVER_GID 1002
4013+fi
4014+fi
4015+bool 'Stealth networking' CONFIG_GRKERNSEC_STEALTH
4016+if [ "$CONFIG_GRKERNSEC_STEALTH" != "n" ]; then
4017+bool ' Do not send Connection Resets' CONFIG_GRKERNSEC_STEALTH_RST
4018+bool ' Do not reply to UDP with ICMP unreachables' CONFIG_GRKERNSEC_STEALTH_UDP
4019+bool ' Do not reply to ICMP requests' CONFIG_GRKERNSEC_STEALTH_ICMP
4020+bool ' Do not reply to IGMP requests' CONFIG_GRKERNSEC_STEALTH_IGMP
4021+bool ' Drop packets with illegitimate flags' CONFIG_GRKERNSEC_STEALTH_FLAGS
4022+fi
4023+endmenu
4024+mainmenu_option next_comment
4025+comment 'Sysctl support'
4026+bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL
4027+endmenu
4028+mainmenu_option next_comment
4029+comment 'Miscellaneous Enhancements'
4030+bool 'BSD-style coredumps' CONFIG_GRKERNSEC_COREDUMP
4031+endmenu
4032diff -urN linux/include/asm-i386/a.out.h linux.grsec/include/asm-i386/a.out.h
4033--- linux/include/asm-i386/a.out.h Fri Jun 16 20:33:06 1995
4034+++ linux.grsec/include/asm-i386/a.out.h Sun Sep 30 01:54:20 2001
4035@@ -18,9 +18,11 @@
4036 #define N_SYMSIZE(a) ((a).a_syms)
4037
4038 #ifdef __KERNEL__
4039-
4040+#ifdef CONFIG_GRKERNSEC_STACK
4041+#define STACK_TOP ((current->flags & PF_STACKEXEC) ? TASK_SIZE - _STK_LIM : TASK_SIZE)
4042+#else
4043 #define STACK_TOP TASK_SIZE
4044-
4045+#endif
4046 #endif
4047
4048 #endif /* __A_OUT_GNU_H__ */
4049diff -urN linux/include/asm-i386/pgtable.h linux.grsec/include/asm-i386/pgtable.h
4050--- linux/include/asm-i386/pgtable.h Fri Jul 20 21:52:18 2001
4051+++ linux.grsec/include/asm-i386/pgtable.h Sun Sep 30 01:54:20 2001
4052@@ -180,9 +180,19 @@
4053 #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
4054
4055 #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
4056+#ifdef CONFIG_GRKERNSEC_PAX
4057+#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW |_PAGE_USER |_PAGE_ACCESSED)
4058+#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
4059+#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
4060+
4061+#define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
4062+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
4063+#define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
4064+#else
4065 #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
4066 #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
4067 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
4068+#endif
4069
4070 #define __PAGE_KERNEL \
4071 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
4072@@ -216,6 +226,15 @@
4073 * This is the closest we can get..
4074 */
4075 #define __P000 PAGE_NONE
4076+#ifdef CONFIG_GRKERNSEC_PAX
4077+#define __P001 PAGE_READONLY_NOEXEC
4078+#define __P010 PAGE_COPY_NOEXEC
4079+#define __P011 PAGE_COPY_NOEXEC
4080+#define __P100 PAGE_READONLY_EXEC
4081+#define __P101 PAGE_READONLY_EXEC
4082+#define __P110 PAGE_COPY_EXEC
4083+#define __P111 PAGE_COPY_EXEC
4084+#else
4085 #define __P001 PAGE_READONLY
4086 #define __P010 PAGE_COPY
4087 #define __P011 PAGE_COPY
4088@@ -223,8 +242,18 @@
4089 #define __P101 PAGE_READONLY
4090 #define __P110 PAGE_COPY
4091 #define __P111 PAGE_COPY
4092+#endif
4093
4094 #define __S000 PAGE_NONE
4095+#ifdef CONFIG_GRKERNSEC_PAX
4096+#define __S001 PAGE_READONLY_NOEXEC
4097+#define __S010 PAGE_SHARED_NOEXEC
4098+#define __S011 PAGE_SHARED_NOEXEC
4099+#define __S100 PAGE_READONLY_EXEC
4100+#define __S101 PAGE_READONLY_EXEC
4101+#define __S110 PAGE_SHARED_EXEC
4102+#define __S111 PAGE_SHARED_EXEC
4103+#else
4104 #define __S001 PAGE_READONLY
4105 #define __S010 PAGE_SHARED
4106 #define __S011 PAGE_SHARED
4107@@ -232,6 +261,7 @@
4108 #define __S101 PAGE_READONLY
4109 #define __S110 PAGE_SHARED
4110 #define __S111 PAGE_SHARED
4111+#endif
4112
4113 /*
4114 * Define this if things work differently on an i386 and an i486:
4115diff -urN linux/include/asm-i386/processor.h linux.grsec/include/asm-i386/processor.h
4116--- linux/include/asm-i386/processor.h Fri Jul 20 21:52:18 2001
4117+++ linux.grsec/include/asm-i386/processor.h Sun Sep 30 01:54:20 2001
4118@@ -264,12 +264,24 @@
4119 * User space process size: 3GB (default).
4120 */
4121 #define TASK_SIZE (PAGE_OFFSET)
4122-
4123+#ifdef CONFIG_GRKERNSEC_STACK
4124+#define MAGIC_SIGRETURN (PAGE_OFFSET + 0xDE0000)
4125+#define MAGIC_RT_SIGRETURN (PAGE_OFFSET + 0xDE0001)
4126+#endif
4127 /* This decides where the kernel will search for a free chunk of vm
4128 * space during mmap's.
4129 */
4130+#ifdef CONFIG_GRKERNSEC_STACK
4131+extern struct linux_binfmt elf_format;
4132+#define TASK_UNMAPPED_BASE(size) ( \
4133+ current->binfmt == &elf_format && \
4134+ !(current->flags & PF_STACKEXEC) && \
4135+ (size) < 0x00ef0000UL \
4136+ ? 0x00110000UL \
4137+ : TASK_SIZE / 3 )
4138+#else
4139 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
4140-
4141+#endif
4142 /*
4143 * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
4144 */
4145@@ -360,6 +372,14 @@
4146 unsigned long __cacheline_filler[5];
4147 };
4148
4149+#ifdef CONFIG_GRKERNSEC_PAX
4150+struct pax_fault_info {
4151+ unsigned long eip;
4152+ unsigned long addresses[4];
4153+ unsigned long count;
4154+};
4155+#endif
4156+
4157 struct thread_struct {
4158 unsigned long esp0;
4159 unsigned long eip;
4160@@ -370,6 +390,11 @@
4161 unsigned long debugreg[8]; /* %%db0-7 debug registers */
4162 /* fault info */
4163 unsigned long cr2, trap_no, error_code;
4164+#ifdef CONFIG_GRKERNSEC_PAX
4165+/* PaX fault info */
4166+ struct pax_fault_info pax_faults;
4167+#endif
4168+
4169 /* floating point info */
4170 union i387_union i387;
4171 /* virtual 86 mode info */
4172diff -urN linux/include/linux/a.out.h linux.grsec/include/linux/a.out.h
4173--- linux/include/linux/a.out.h Fri Jul 20 21:52:18 2001
4174+++ linux.grsec/include/linux/a.out.h Sun Sep 30 01:54:20 2001
4175@@ -37,6 +37,14 @@
4176 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
4177 };
4178
4179+#ifdef CONFIG_GRKERNSEC_PAX
4180+/* Constants for the N_FLAGS field */
4181+#define F_PAX_PAGEEXEC 1 /* Enforce PAGE_EXEC */
4182+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
4183+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
4184+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
4185+#endif
4186+
4187 #if !defined (N_MAGIC)
4188 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
4189 #endif
4190@@ -56,7 +64,9 @@
4191 #define N_SET_FLAGS(exec, flags) \
4192 ((exec).a_info = \
4193 ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
4194-
4195+#ifdef CONFIG_GRKERNSEC_STACK
4196+#define F_STACKEXEC 1
4197+#endif
4198 /* Code indicating object file or impure executable. */
4199 #define OMAGIC 0407
4200 /* Code indicating pure executable. */
4201diff -urN linux/include/linux/binfmts.h linux.grsec/include/linux/binfmts.h
4202--- linux/include/linux/binfmts.h Fri Jul 20 21:52:18 2001
4203+++ linux.grsec/include/linux/binfmts.h Sun Sep 30 01:54:20 2001
4204@@ -1,6 +1,7 @@
4205 #ifndef _LINUX_BINFMTS_H
4206 #define _LINUX_BINFMTS_H
4207
4208+#include <linux/config.h>
4209 #include <linux/ptrace.h>
4210 #include <linux/capability.h>
4211
4212@@ -30,6 +31,11 @@
4213 int argc, envc;
4214 char * filename; /* Name of binary */
4215 unsigned long loader, exec;
4216+#ifdef CONFIG_GRKERNSEC_FD
4217+ int priv_change;
4218+ int tweak_fd_mask;
4219+ struct file *tweak_fd_null;
4220+#endif
4221 };
4222
4223 /*
4224diff -urN linux/include/linux/elf.h linux.grsec/include/linux/elf.h
4225--- linux/include/linux/elf.h Sun Sep 30 01:30:57 2001
4226+++ linux.grsec/include/linux/elf.h Sun Sep 30 01:54:20 2001
4227@@ -85,7 +85,9 @@
4228 * up with a final number.
4229 */
4230 #define EM_ALPHA 0x9026
4231-
4232+#ifdef CONFIG_GRKERNSEC_STACK
4233+#define EF_STACKEXEC 1
4234+#endif
4235 /*
4236 * This is the old interim value for S/390 architecture
4237 */
4238@@ -254,6 +256,13 @@
4239 #define R_MIPS_LOVENDOR 100
4240 #define R_MIPS_HIVENDOR 127
4241
4242+#ifdef CONFIG_GRKERNSEC_PAX
4243+/* Constants for the e_flags field */
4244+#define EF_PAX_PAGEEXEC 1 /* 0: Enforce PAGE_EXEC */
4245+#define EF_PAX_EMUTRAMP 2 /* 0: Emulate trampolines */
4246+#define EF_PAX_MPROTECT 4 /* 0: Restrict mprotect() */
4247+#define EF_PAX_RANDMMAP 8 /* 0: Randomize mmap() base */
4248+#endif
4249
4250 /*
4251 * Sparc ELF relocation types
4252diff -urN linux/include/linux/fs.h linux.grsec/include/linux/fs.h
4253--- linux/include/linux/fs.h Sun Sep 30 01:30:57 2001
4254+++ linux.grsec/include/linux/fs.h Sun Sep 30 01:54:20 2001
4255@@ -1048,7 +1048,11 @@
4256
4257 asmlinkage long sys_open(const char *, int, int);
4258 asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */
4259+#ifdef CONFIG_OBV_PROC
4260+extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
4261+#else
4262 extern int do_truncate(struct dentry *, loff_t start);
4263+#endif
4264
4265 extern struct file *filp_open(const char *, int, int);
4266 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
4267diff -urN linux/include/linux/grsecurity.h linux.grsec/include/linux/grsecurity.h
4268--- linux/include/linux/grsecurity.h Thu Jan 1 01:00:00 1970
4269+++ linux.grsec/include/linux/grsecurity.h Sun Sep 30 01:54:20 2001
4270@@ -0,0 +1,41 @@
4271+extern int grsec_enable_link;
4272+extern int grsec_enable_fifo;
4273+extern int grsec_enable_fd;
4274+extern int grsec_enable_execve;
4275+extern int grsec_enable_forkbomb;
4276+extern int grsec_forkbomb_gid;
4277+extern int grsec_forkbomb_sec;
4278+extern int grsec_forkbomb_max;
4279+extern int grsec_enable_execlog;
4280+extern int grsec_enable_suid;
4281+extern int grsec_enable_signal;
4282+extern int grsec_enable_coredump;
4283+extern int grsec_enable_forkfail;
4284+extern int grsec_enable_time;
4285+extern int grsec_enable_kbmap;
4286+extern int grsec_enable_randnet;
4287+extern int grsec_enable_chroot;
4288+extern int grsec_enable_chroot_execlog;
4289+extern int grsec_enable_chroot_caps;
4290+extern int grsec_enable_tpe;
4291+extern int grsec_tpe_gid;
4292+extern int grsec_enable_tpe_glibc;
4293+extern int grsec_enable_tpe_all;
4294+extern int grsec_enable_sidcaps;
4295+extern int grsec_enable_randpid;
4296+extern int grsec_enable_randid;
4297+extern int grsec_enable_randsrc;
4298+extern int grsec_enable_randping;
4299+extern int grsec_enable_randttl;
4300+extern int grsec_randttl_thresh;
4301+extern int grsec_enable_socket_all;
4302+extern int grsec_socket_all_gid;
4303+extern int grsec_enable_socket_client;
4304+extern int grsec_socket_client_gid;
4305+extern int grsec_enable_socket_server;
4306+extern int grsec_socket_server_gid;
4307+extern int grsec_enable_stealth_rst;
4308+extern int grsec_enable_stealth_udp;
4309+extern int grsec_enable_stealth_icmp;
4310+extern int grsec_enable_stealth_igmp;
4311+extern int grsec_enable_stealth_flags;
4312diff -urN linux/include/linux/kernel.h linux.grsec/include/linux/kernel.h
4313--- linux/include/linux/kernel.h Tue Jun 12 20:51:43 2001
4314+++ linux.grsec/include/linux/kernel.h Sun Sep 30 01:57:33 2001
4315@@ -59,8 +59,12 @@
4316 extern long simple_strtol(const char *,char **,unsigned int);
4317 extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
4318 extern long long simple_strtoll(const char *,char **,unsigned int);
4319-extern int sprintf(char * buf, const char * fmt, ...);
4320-extern int vsprintf(char *buf, const char *, va_list);
4321+extern int sprintf(char * buf, const char * fmt, ...)
4322+ __attribute__ ((format (printf,2,3)));
4323+extern int vsprintf(char *buf, const char *, va_list)
4324+ __attribute__ ((format (printf,2,0)));
4325+extern int _vsnprintf(char *buf, int n, const char *, va_list)
4326+ __attribute__ ((format (printf,3,0)));
4327 extern int get_option(char **str, int *pint);
4328 extern char *get_options(char *str, int nints, int *ints);
4329 extern unsigned long long memparse(char *ptr, char **retptr);
4330@@ -105,6 +109,47 @@
4331 ((unsigned char *)&addr)[1], \
4332 ((unsigned char *)&addr)[2], \
4333 ((unsigned char *)&addr)[3]
4334+#ifndef CONFIG_OBV_DEBUG
4335+#define obv_seclog(default_msg, args...) \
4336+({ \
4337+ static unsigned long msg_time = 0, getting_messages = 0; \
4338+ static spinlock_t oblivion_lock = SPIN_LOCK_UNLOCKED; \
4339+ \
4340+ spin_lock(&oblivion_lock); \
4341+ \
4342+ if((!msg_time) || (jiffies - msg_time > CONFIG_OBV_FLOODTIME * HZ)) { \
4343+ getting_messages = 1; \
4344+ msg_time = jiffies; \
4345+ printk(KERN_INFO "oblivion: " default_msg "\n", ##args ); \
4346+ } else if(getting_messages) { \
4347+ msg_time = jiffies; \
4348+ getting_messages = 0; \
4349+ printk(KERN_ALERT "Flooded with msgs. Logging disabled for %i seconds \n", CONFIG_OBV_FLOODTIME); \
4350+ \
4351+ } \
4352+ spin_unlock(&oblivion_lock); \
4353+})
4354+#else
4355+#define obv_seclog(msg,args...) printk(KERN_INFO "oblivion " msg "\n", ##args);
4356+#endif
4357+
4358+#define security_alert(normal_msg,flood_msg,args...) \
4359+({ \
4360+ static unsigned long warning_time = 0, no_flood_yet = 0; \
4361+ static spinlock_t security_alert_lock = SPIN_LOCK_UNLOCKED; \
4362+ \
4363+ spin_lock(&security_alert_lock); \
4364+ if(!warning_time || jiffies - warning_time > 30 * HZ) { \
4365+ warning_time = jiffies; no_flood_yet = 1; \
4366+ printk(KERN_ALERT "grsecurity: " normal_msg "\n", ## args); \
4367+ } else if (no_flood_yet) { \
4368+ warning_time = jiffies; no_flood_yet = 0; \
4369+ printk(KERN_ALERT "grsecurity: more " flood_msg \
4370+ ", logging disabled for 30 seconds\n"); \
4371+ } \
4372+ \
4373+ spin_unlock(&security_alert_lock); \
4374+})
4375
4376 #define HIPQUAD(addr) \
4377 ((unsigned char *)&addr)[3], \
4378diff -urN linux/include/linux/mm.h linux.grsec/include/linux/mm.h
4379--- linux/include/linux/mm.h Sun Sep 30 01:30:58 2001
4380+++ linux.grsec/include/linux/mm.h Sun Sep 30 01:54:20 2001
4381@@ -104,7 +104,11 @@
4382 #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
4383 #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
4384
4385+#ifdef CONFIG_GRKERNSEC_PAX
4386+#define VM_STACK_FLAGS 0x00000133
4387+#else
4388 #define VM_STACK_FLAGS 0x00000177
4389+#endif
4390
4391 #define VM_READHINTMASK (VM_SEQ_READ | VM_RAND_READ)
4392 #define VM_ClearReadHint(v) (v)->vm_flags &= ~VM_READHINTMASK
4393diff -urN linux/include/linux/oblivion.h linux.grsec/include/linux/oblivion.h
4394--- linux/include/linux/oblivion.h Thu Jan 1 01:00:00 1970
4395+++ linux.grsec/include/linux/oblivion.h Sun Sep 30 01:54:20 2001
4396@@ -0,0 +1,145 @@
4397+
4398+#include <linux/obvdefs.h>
4399+
4400+/* * * * * * * * * * * * * * * * * * * * *
4401+ * Oblivion kernel Modification
4402+ * Main header file
4403+ * Purpose: define most Oblivion data structures
4404+ * * * * * * * * * * * * * * * * * * * * */
4405+
4406+#define OBV_VERSION "oblivion v1.0"
4407+
4408+#define OBV_SHUTDOWN_MODE 0
4409+#define OBV_ENABLE_MODE 1
4410+#define OBV_CHCAPS_MODE 2
4411+#define OBV_AUTH_MODE 3
4412+#define OBV_GOD_MODE 4
4413+
4414+/* required headers: <linux/kdev_t.h>, <linux/types.h> */
4415+
4416+/* I need to include linux/fs.h in oblivion.c and it would be
4417+ * overkill to include kdev_t.h twice(once here and once in fs.h)
4418+ * so I just did the other necessary header inclusion before including oblivion.h*/
4419+
4420+
4421+
4422+#define OBV_MAX_PW_LEN 129
4423+#define OBV_SHASUM_SIZE 20
4424+#define OBV_MAX_EXTRA_LEN 1025
4425+
4426+/* Begin Data Structures */
4427+struct obv_pw {
4428+ char pw[OBV_MAX_PW_LEN];
4429+ char extra[OBV_MAX_EXTRA_LEN];
4430+ __u8 sum[OBV_SHASUM_SIZE]; /* 160-bit SHA hash of the password*/
4431+ __u8 mode; /* On/Off/Restart(Restart is not ready yet..*/
4432+};
4433+
4434+struct obv_sum {
4435+ __u8 sum[OBV_SHASUM_SIZE];
4436+ ino_t file_inode;
4437+ kdev_t file_dev;
4438+};
4439+
4440+struct obv_sum_db {
4441+ struct obv_sum *db;
4442+ int max_ref;
4443+};
4444+
4445+
4446+struct obv_file_acl {
4447+ ino_t file_inode;
4448+ kdev_t file_dev;
4449+ __u32 mode;
4450+};
4451+
4452+/* When sorting/searching, we can effectively search obv_file_acl and obv_acl structures since their identifying information(inodes/devs) are the same name and their size, due to the above padding, is also the same*/
4453+
4454+struct obv_file_db {
4455+ struct obv_file_acl *db;
4456+ int max_ref;
4457+};
4458+
4459+
4460+/* information about r/w/x info for a file by a process */
4461+/* Uses a (balanced )binary tree for its implementation...ideas are welcome for
4462+ * a more efficient way however=)*/
4463+
4464+struct obv_proc_acl {
4465+ ino_t file_inode;
4466+ kdev_t file_dev;
4467+ /* to do rules like /tmp * set the dir /tmp rw .. best solution I can find*/
4468+ __u16 mode;
4469+ /* you may consider the file inode, file_dev, and mode to(combined) be the key */
4470+ struct obv_proc_acl *left;
4471+ struct obv_proc_acl *right;
4472+ __u16 height; /* used for avl rebalancing*/
4473+};
4474+
4475+
4476+
4477+/* information about a process */
4478+struct obv_acl {
4479+ ino_t file_inode;
4480+ kdev_t file_dev;
4481+ __u8 mode;
4482+ kernel_cap_t file_caps; /* capability set*/
4483+ struct obv_proc_acl *tree;
4484+};
4485+
4486+/* database - contains process ACLs */
4487+struct obv_proc_db {
4488+ struct obv_acl *db;
4489+ int max_ref;
4490+};
4491+
4492+/* Temporary storage--see kernel/oblivion.c */
4493+struct obv_temp {
4494+ ino_t file_inode;
4495+ kdev_t file_dev;
4496+ __u16 mode;
4497+};
4498+/* Begin Capabilities subsection */
4499+
4500+#define CONFIG_OBV_MAX_CAP 30
4501+
4502+struct obv_cap {
4503+ char * capname;
4504+ kernel_cap_t capval;
4505+};
4506+
4507+struct obv_cap_list {
4508+ struct obv_cap table[CONFIG_OBV_MAX_CAP];
4509+};
4510+/* End Capabilities subsection */
4511+/* End Data Structures */
4512+
4513+/* Begin SHA hash section */
4514+#define SHA1HANDSOFF /* Copies data before messing with it. */
4515+
4516+struct SHA1_CTX {
4517+ unsigned long state[5];
4518+ unsigned long count[2];
4519+ unsigned char buffer[64];
4520+};
4521+
4522+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
4523+
4524+/* blk0() and blk() perform the initial expand. */
4525+/* I got the idea of expanding during the round function from SSLeay */
4526+#ifdef __LITTLE_ENDIAN
4527+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
4528+ |(rol(block->l[i],8)&0x00FF00FF))
4529+#else
4530+#define blk0(i) block->l[i]
4531+#endif /* __LITTLE_ENDIAN */
4532+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
4533+ ^block->l[(i+2)&15]^block->l[i&15],1))
4534+
4535+ /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
4536+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
4537+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
4538+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
4539+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
4540+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
4541+/* End SHA hash section */
4542diff -urN linux/include/linux/obvcipher.h linux.grsec/include/linux/obvcipher.h
4543--- linux/include/linux/obvcipher.h Thu Jan 1 01:00:00 1970
4544+++ linux.grsec/include/linux/obvcipher.h Sun Sep 30 01:54:20 2001
4545@@ -0,0 +1,4 @@
4546+extern void SHA1Init(struct SHA1_CTX *context);
4547+extern void SHA1Update(struct SHA1_CTX *context, unsigned char *data,unsigned int len);
4548+extern void SHA1Final(unsigned char digest[20],struct SHA1_CTX *context);
4549+extern int obv_chkpw(struct obv_pw *entry);
4550diff -urN linux/include/linux/obvdefs.h linux.grsec/include/linux/obvdefs.h
4551--- linux/include/linux/obvdefs.h Thu Jan 1 01:00:00 1970
4552+++ linux.grsec/include/linux/obvdefs.h Sun Sep 30 01:54:20 2001
4553@@ -0,0 +1,78 @@
4554+
4555+/* Begin Status/Return value declarations */
4556+
4557+#define OBV_ALLOW 1
4558+#define OBV_NOTFOUND -1
4559+#define OBV_DENY 0
4560+
4561+#define OBV_LOADING 0x01
4562+#define OBV_DISABLED 0x02
4563+#define OBV_READY 0x04
4564+#define OBV_1ST 0x08
4565+/* Debugging mode*/
4566+#define OBV_TESTING 0x080
4567+
4568+#ifdef CONFIG_OBV_DEF_DENY
4569+#define OBV_DEFAULT OBV_DENY
4570+#endif
4571+#ifdef CONFIG_OBV_DEF_DENY_ROOT
4572+#define OBV_DEFAULT !(current->euid) ? OBV_DENY : OBV_ALLOW;
4573+#endif
4574+#ifdef CONFIG_OBV_DEF_ALLOW
4575+#define OBV_DEFAULT OBV_ALLOW
4576+#endif
4577+
4578+/* End Status declarations */
4579+
4580+
4581+
4582+
4583+/* Begin ACL declarations */
4584+#define OBV_READ 0x01
4585+#define OBV_APPEND 0x02
4586+#define OBV_WRITE 0x04
4587+#define OBV_EXEC 0x08
4588+#define OBV_HIDDEN 0x10
4589+#define OBV_OVERRIDE 0x20 /* Override File ACL, useful for proc only*/
4590+#define OBV_PROTECTED 0x40
4591+
4592+/* Standard stuff done, on to File ACL stuff */
4593+
4594+#define OBV_FILE_READ OBV_READ
4595+#define OBV_FILE_APPEND OBV_APPEND
4596+#define OBV_FILE_WRITE (OBV_WRITE | OBV_APPEND)
4597+#define OBV_FILE_EXEC OBV_EXEC
4598+#define OBV_FILE_HIDDEN OBV_HIDDEN
4599+
4600+
4601+#define OBV_PROC_READ OBV_READ
4602+#define OBV_PROC_APPEND OBV_APPEND
4603+#define OBV_PROC_WRITE (OBV_WRITE|OBV_APPEND); /* write access implies append access*/
4604+#define OBV_PROC_EXEC OBV_EXEC
4605+#define OBV_PROC_ACCESS OBV_HIDDEN
4606+#define OBV_PROC_OVERRIDE OBV_OVERRIDE
4607+#define OBV_PROC_IGN_DEFAULT OBV_IGN_DEFAULT
4608+#define OBV_PROC_HIDDEN OBV_HIDDEN /* Hidden, unkillable(except by init) process. Good for hiding your IDSes / logging daemons:)*/
4609+#define OBV_PROC_PROTECTED OBV_PROTECTED
4610+
4611+/* Begin TODO */
4612+#define OBV_REQSUM 0x200 /* Require program to have SHAsum in database*/
4613+#define OBV_INHERIT 0x400 /* Children inherit parent's process acls*/
4614+#define OBV_AUTH 0x100 /* Require secondary authentication before execution*/
4615+#define OBV_FILE_REQSUM OBV_REQSUM
4616+#define OBV_FILE_AUTH OBV_AUTH
4617+#define OBV_PROC_REQSUM OBV_REQSUM
4618+#define OBV_PROC_INHERIT OBV_INHERIT
4619+#define OBV_PROC_AUTH OBV_AUTH
4620+/* End TODO */
4621+
4622+#define OBV_PROC_EXTRA (OBV_PROC_OVERRIDE|OBV_PROC_REQSUM|OBV_PROC_INHERIT|OBV_PROC_AUTH)
4623+/* Extra things that must be checked after a search*/
4624+
4625+#define OBV_FILE_EXTRA (OBV_FILE_REQSUM|OBV_FILE_AUTH)
4626+#define OBV_RW (OBV_READ|OBV_WRITE)
4627+#define OBV_RX (OBV_READ|OBV_EXEC)
4628+#define OBV_RWX (OBV_READ|OBV_WRITE|OBV_EXEC)
4629+
4630+/* End ACL Declarations */
4631+
4632diff -urN linux/include/linux/obvext.h linux.grsec/include/linux/obvext.h
4633--- linux/include/linux/obvext.h Thu Jan 1 01:00:00 1970
4634+++ linux.grsec/include/linux/obvext.h Sun Sep 30 01:54:20 2001
4635@@ -0,0 +1,17 @@
4636+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4637+ * Oblivion external header
4638+ * Used for sections of the kernel that must access oblivion
4639+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
4640+
4641+#include <linux/dcache.h>
4642+#include <linux/sysctl.h>
4643+#include <linux/obvdefs.h>
4644+
4645+extern int obv_status;
4646+extern int obv_disable;
4647+extern int obv_check_hidden(struct dentry *dentry, struct vfsmount *mnt);
4648+extern int obv_search(struct dentry *dentry, __u16 mode, struct vfsmount *mnt);
4649+extern int obv_set_proc_acl(struct dentry *dentry,struct task_struct *tsk,char *filename, struct vfsmount *mnt);
4650+extern int obv_check_hidden_proc(struct task_struct *tsk);
4651+extern int obv_check_protected(struct task_struct *tsk);
4652+extern int obv_proc_handler(ctl_table *table,int write, struct file *filp, void *buffer, size_t *lenp);
4653diff -urN linux/include/linux/sched.h linux.grsec/include/linux/sched.h
4654--- linux/include/linux/sched.h Sun Sep 30 01:30:53 2001
4655+++ linux.grsec/include/linux/sched.h Sun Sep 30 01:56:59 2001
4656@@ -27,6 +27,10 @@
4657 #include <linux/securebits.h>
4658 #include <linux/fs_struct.h>
4659
4660+#ifdef CONFIG_OBV_PROC
4661+struct obv_acl;
4662+#endif
4663+
4664 /*
4665 * cloning flags:
4666 */
4667@@ -225,7 +229,12 @@
4668 unsigned long def_flags;
4669 unsigned long cpu_vm_mask;
4670 unsigned long swap_address;
4671-
4672+#ifdef CONFIG_GRKERNSEC_PAX
4673+ unsigned long delta_mmap; /* PaX: randomized offset */
4674+ unsigned long delta_exec; /* PaX: randomized offset */
4675+ unsigned long delta_stack; /* PaX: randomized offset */
4676+#endif
4677+
4678 unsigned dumpable:1;
4679
4680 /* Architecture-specific MM context */
4681@@ -404,6 +413,10 @@
4682
4683 /* journalling filesystem info */
4684 void *journal_info;
4685+#ifdef CONFIG_OBV_PROC
4686+ struct obv_acl *obvacl;
4687+#endif
4688+
4689 };
4690
4691 /*
4692@@ -421,6 +434,11 @@
4693
4694 #define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */
4695
4696+#define PF_PAX_PAGEEXEC 0x01000000 /* PaX: Enforce PAGE_EXEC */
4697+#define PF_PAX_EMUTRAMP 0x02000000 /* PaX: Emulate trampolines */
4698+#define PF_PAX_MPROTECT 0x04000000 /* PaX: Restrict mprotect() */
4699+#define PF_PAX_RANDMMAP 0x08000000 /* PaX: Randomize mmap() base */
4700+
4701 /*
4702 * Ptrace flags
4703 */
4704@@ -428,7 +446,17 @@
4705 #define PT_PTRACED 0x00000001
4706 #define PT_TRACESYS 0x00000002
4707 #define PT_DTRACE 0x00000004 /* delayed trace (used on m68k, i386) */
4708+#ifdef CONFIG_GRKERNSEC_STACK
4709+#define PF_STACKEXEC 0x01000000
4710+#endif
4711 #define PT_TRACESYSGOOD 0x00000008
4712+
4713+#ifdef CONFIG_GRKERNSEC_PAX
4714+/* PaX: for handling DTLB trashing */
4715+#define PT_PAX_TRACE 0x00000020
4716+#define PT_PAX_KEEPTF 0x00000040
4717+#define PT_PAX_OLDTF 0x00000080
4718+#endif
4719
4720 /*
4721 * Limit the stack by to some sane default: root can always
4722diff -urN linux/include/linux/sysctl.h linux.grsec/include/linux/sysctl.h
4723--- linux/include/linux/sysctl.h Sun Sep 30 01:30:58 2001
4724+++ linux.grsec/include/linux/sysctl.h Sun Sep 30 01:59:05 2001
4725@@ -121,6 +121,8 @@
4726 KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */
4727 KERN_NMI_WATCHDOG=52, /* int: nmi_watchdog on/off */
4728 KERN_KDB=53, /* int: kdb on/off */
4729+ KERN_GRSECURITY=68, /* grsecurity */
4730+ KERN_OBV = 69, /* struct obv_pw, controls oblivion*/
4731 };
4732
4733
4734diff -urN linux/include/net/inetpeer.h linux.grsec/include/net/inetpeer.h
4735--- linux/include/net/inetpeer.h Fri Jul 20 21:52:19 2001
4736+++ linux.grsec/include/net/inetpeer.h Sun Sep 30 01:54:20 2001
4737@@ -14,6 +14,9 @@
4738 #include <linux/sched.h>
4739 #include <linux/spinlock.h>
4740 #include <asm/atomic.h>
4741+#ifdef CONFIG_GRKERNSEC_RANDID
4742+#include <linux/random.h>
4743+#endif
4744
4745 struct inet_peer
4746 {
4747@@ -58,7 +61,9 @@
4748 __u16 id;
4749
4750 spin_lock_bh(&inet_peer_idlock);
4751- id = p->ip_id_count++;
4752+#ifdef CONFIG_GRKERNSEC_RANDID
4753+ get_random_bytes(&id,(sizeof(id) / 2));
4754+#endif
4755 spin_unlock_bh(&inet_peer_idlock);
4756 return id;
4757 }
4758diff -urN linux/include/net/ip.h linux.grsec/include/net/ip.h
4759--- linux/include/net/ip.h Fri Jul 20 21:53:07 2001
4760+++ linux.grsec/include/net/ip.h Sun Sep 30 01:54:20 2001
4761@@ -31,6 +31,9 @@
4762 #include <linux/in_route.h>
4763 #include <net/route.h>
4764 #include <net/arp.h>
4765+#ifdef CONFIG_GRKERNSEC_RANDID
4766+#include <linux/random.h>
4767+#endif
4768
4769 #ifndef _SNMP_H
4770 #include <net/snmp.h>
4771@@ -196,7 +199,11 @@
4772 * does not change, they drop every other packet in
4773 * a TCP stream using header compression.
4774 */
4775+#ifdef CONFIG_GRKERNSEC_RANDID
4776+ get_random_bytes(&iph->id,(sizeof(iph->id) / 2));
4777+#else
4778 iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
4779+#endif
4780 } else
4781 __ip_select_ident(iph, dst);
4782 }
4783diff -urN linux/init/main.c linux.grsec/init/main.c
4784--- linux/init/main.c Sun Sep 30 01:30:58 2001
4785+++ linux.grsec/init/main.c Sun Sep 30 01:54:20 2001
4786@@ -74,6 +74,12 @@
4787 #include <linux/kdb.h>
4788 #endif
4789
4790+#ifdef CONFIG_OBV_PROC
4791+#include <linux/obvext.h>
4792+#endif
4793+
4794+
4795+
4796 /*
4797 * Versions of gcc older than that listed below may actually compile
4798 * and link okay, but the end product can have subtle run time bugs.
4799@@ -113,6 +119,12 @@
4800 extern void ipc_init(void);
4801 #endif
4802
4803+#ifdef CONFIG_OBV_PROC
4804+static __init int obv_setup(char *line);
4805+#endif
4806+
4807+
4808+
4809 /*
4810 * Boot command-line arguments
4811 */
4812@@ -307,6 +319,19 @@
4813 }
4814
4815 __setup("root=", root_dev_setup);
4816+
4817+#ifdef CONFIG_OBV_PROC
4818+static int __init obv_setup(char *str)
4819+{
4820+#ifdef CONFIG_OBV_DEBUG
4821+ obv_seclog("Obv got %.3s at startup\n",str);
4822+#endif
4823+ if(*str == '0') obv_disable = 1;
4824+ return 1;
4825+}
4826+__setup("oblivion=",obv_setup);
4827+#endif
4828+
4829
4830 static int __init checksetup(char *line)
4831 {
4832diff -urN linux/kernel/Makefile linux.grsec/kernel/Makefile
4833--- linux/kernel/Makefile Sun Sep 30 01:30:58 2001
4834+++ linux.grsec/kernel/Makefile Sun Sep 30 01:54:20 2001
4835@@ -20,6 +20,7 @@
4836 obj-$(CONFIG_MODULES) += ksyms.o
4837 obj-$(CONFIG_PM) += pm.o
4838 obj-$(CONFIG_KALLSYMS) += kallsyms.o
4839+obj-$(CONFIG_OBV_PROC) += oblivion.o obvqsort.o obvhash.o
4840
4841 ifneq ($(CONFIG_IA64),y)
4842 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
4843diff -urN linux/kernel/exit.c linux.grsec/kernel/exit.c
4844--- linux/kernel/exit.c Fri May 4 23:44:06 2001
4845+++ linux.grsec/kernel/exit.c Sun Sep 30 01:54:20 2001
4846@@ -18,6 +18,15 @@
4847 #include <asm/pgtable.h>
4848 #include <asm/mmu_context.h>
4849
4850+#ifdef CONFIG_GRKERNSEC_RANDPID
4851+#include <linux/grsecurity.h>
4852+#endif
4853+
4854+#ifdef CONFIG_OBV_PROC
4855+extern void obv_exit(struct task_struct *tsk);
4856+#endif
4857+
4858+
4859 extern void sem_exit (void);
4860 extern struct task_struct *child_reaper;
4861
4862@@ -419,7 +428,10 @@
4863 }
4864 write_unlock_irq(&tasklist_lock);
4865 }
4866-
4867+#ifdef CONFIG_GRKERNSEC_RANDPID
4868+pid_t last_pids[64];
4869+int cur_n_pids;
4870+#endif
4871 NORET_TYPE void do_exit(long code)
4872 {
4873 struct task_struct *tsk = current;
4874@@ -437,9 +449,18 @@
4875 #ifdef CONFIG_BSD_PROCESS_ACCT
4876 acct_process(code);
4877 #endif
4878+#ifdef CONFIG_OBV_PROC
4879+ obv_exit(tsk);
4880+#endif
4881 __exit_mm(tsk);
4882
4883 lock_kernel();
4884+#ifdef CONFIG_GRKERNSEC_RANDPID
4885+ if(grsec_enable_randpid){
4886+ last_pids[cur_n_pids++] = tsk -> pid;
4887+ cur_n_pids &= 63;
4888+ }
4889+#endif
4890 sem_exit();
4891 __exit_files(tsk);
4892 __exit_fs(tsk);
4893diff -urN linux/kernel/fork.c linux.grsec/kernel/fork.c
4894--- linux/kernel/fork.c Wed Jul 18 03:23:28 2001
4895+++ linux.grsec/kernel/fork.c Sun Sep 30 02:01:52 2001
4896@@ -19,12 +19,29 @@
4897 #include <linux/module.h>
4898 #include <linux/vmalloc.h>
4899 #include <linux/completion.h>
4900+#ifdef CONFIG_GRKERNSEC_RANDPID
4901+#include <linux/random.h>
4902+#endif
4903+
4904+#if defined(CONFIG_GRKERNSEC_FORKFAIL)||defined(CONFIG_GRKERNSEC_RANDPID) \
4905+ || defined(CONFIG_GRKERNSEC_FORKBOMB)
4906+#include <linux/grsecurity.h>
4907+#endif
4908
4909 #include <asm/pgtable.h>
4910 #include <asm/pgalloc.h>
4911 #include <asm/uaccess.h>
4912 #include <asm/mmu_context.h>
4913
4914+#ifdef CONFIG_OBV_PROC
4915+#include <linux/oblivion.h>
4916+#endif
4917+
4918+#ifdef CONFIG_GRKERNSEC_RANDPID
4919+extern struct entropy_store *random_state;
4920+extern struct entropy_store *sec_random_state;
4921+#endif
4922+
4923 /* The idle threads do not count.. */
4924 int nr_threads;
4925 int nr_running;
4926@@ -35,6 +52,13 @@
4927
4928 struct task_struct *pidhash[PIDHASH_SZ];
4929
4930+#ifdef CONFIG_OBV_PROC
4931+static __inline__ int obv_copy_acl(struct task_struct *tsk) {
4932+ tsk->obvacl = current->obvacl;
4933+ return 0;
4934+}
4935+#endif
4936+
4937 void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
4938 {
4939 unsigned long flags;
4940@@ -80,9 +104,18 @@
4941 /* Protects next_safe and last_pid. */
4942 spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED;
4943
4944+#ifdef CONFIG_GRKERNSEC_RANDPID
4945+extern pid_t last_pids[64];
4946+extern int cur_n_pids;
4947+#endif
4948+
4949 static int get_pid(unsigned long flags)
4950 {
4951 static int next_safe = PID_MAX;
4952+#ifdef CONFIG_GRKERNSEC_RANDPID
4953+ int loops;
4954+#endif
4955+
4956 struct task_struct *p;
4957
4958 if (flags & CLONE_PID)
4959@@ -90,31 +123,69 @@
4960
4961 spin_lock(&lastpid_lock);
4962 if((++last_pid) & 0xffff8000) {
4963+#ifdef CONFIG_GRKERNSEC_RANDPID
4964+ if(!grsec_enable_randpid)
4965+#endif
4966 last_pid = 300; /* Skip daemons etc. */
4967 goto inside;
4968 }
4969- if(last_pid >= next_safe) {
4970+ if(last_pid >=
4971+#ifdef CONFIG_GRKERNSEC_RANDPID
4972+ grsec_enable_randpid?2:
4973+#endif
4974+ next_safe) {
4975 inside:
4976+#ifdef CONFIG_GRKERNSEC_RANDPID
4977+ if(!grsec_enable_randpid)
4978+#endif
4979 next_safe = PID_MAX;
4980 read_lock(&tasklist_lock);
4981 repeat:
4982+#ifdef CONFIG_GRKERNSEC_RANDPID
4983+ if (grsec_enable_randpid) {
4984+ if((random_state) || (sec_random_state)){
4985+ do {
4986+ get_random_bytes(&last_pid, sizeof(last_pid));
4987+ last_pid %= PID_MAX;
4988+ if(last_pid < 0)
4989+ last_pid-=(2 * last_pid);
4990+ } while (last_pid < 1);
4991+ } else
4992+ last_pid = 1+((xtime.tv_usec * total_forks) % PID_MAX);
4993+ for(loops=0;loops<64;loops++){
4994+ if(last_pids[loops] == last_pid)
4995+ goto repeat;
4996+ }
4997+ }
4998+#endif
4999+
5000 for_each_task(p) {
5001 if(p->pid == last_pid ||
5002 p->pgrp == last_pid ||
5003 p->session == last_pid) {
5004- if(++last_pid >= next_safe) {
5005+ if(
5006+#ifdef CONFIG_GRKERNSEC_RANDPID
5007+ !grsec_enable_randpid &&
5008+#endif
5009+ ++last_pid >= next_safe) {
5010 if(last_pid & 0xffff8000)
5011 last_pid = 300;
5012 next_safe = PID_MAX;
5013 }
5014 goto repeat;
5015 }
5016+#ifdef CONFIG_GRKERNSEC_RANDPID
5017+ if(!grsec_enable_randpid){
5018+#endif
5019 if(p->pid > last_pid && next_safe > p->pid)
5020 next_safe = p->pid;
5021 if(p->pgrp > last_pid && next_safe > p->pgrp)
5022 next_safe = p->pgrp;
5023 if(p->session > last_pid && next_safe > p->session)
5024 next_safe = p->session;
5025+#ifdef CONFIG_GRKERNSEC_RANDPID
5026+ }
5027+#endif
5028 }
5029 read_unlock(&tasklist_lock);
5030 }
5031@@ -534,6 +605,7 @@
5032 return 0;
5033 }
5034
5035+
5036 static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
5037 {
5038 unsigned long new_flags = p->flags;
5039@@ -560,7 +632,11 @@
5040 int retval;
5041 struct task_struct *p;
5042 struct completion vfork;
5043-
5044+#ifdef CONFIG_GRKERNSEC_FORKBOMB
5045+ int sec_forks = 0;
5046+ int user_tasks = 0;
5047+ unsigned long curr_time = jiffies;
5048+#endif
5049 retval = -EPERM;
5050
5051 /*
5052@@ -583,6 +659,42 @@
5053 if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur)
5054 goto bad_fork_free;
5055
5056+#ifdef CONFIG_GRKERNSEC_FORKBOMB
5057+if(grsec_enable_forkbomb) {
5058+if(in_group_p(grsec_forkbomb_gid)){
5059+ read_lock(&tasklist_lock);
5060+ for_each_task(p)
5061+ {
5062+ if ((p->uid) == current->uid)
5063+ {
5064+ user_tasks++;
5065+ if ( (curr_time - (p->start_time)) <= 100)
5066+ sec_forks++;
5067+ }
5068+ }
5069+ read_unlock(&tasklist_lock);
5070+
5071+ if (user_tasks >= grsec_forkbomb_max){
5072+ security_alert("max process limit reached with (%s:%d) by UID (%d), "
5073+ "EUID (%d), parent (%s:%d), UID (%d), EUID (%d)","max proc limits "
5074+ "reached",
5075+ current->comm,current->pid,current->uid,
5076+ current->euid, current->p_pptr->comm,current->p_pptr->pid,
5077+ current->p_pptr->uid,current->p_pptr->euid);
5078+ goto bad_fork_free;
5079+ } else if (sec_forks >= grsec_forkbomb_sec){
5080+ security_alert("fork rate-limit reached with (%s:%d) by UID (%d), "
5081+ "EUID (%d), parent (%s:%d), UID (%d), EUID (%d)","fork rate-limits "
5082+ "reached",
5083+ current->comm,current->pid,current->uid,
5084+ current->euid, current->p_pptr->comm,current->p_pptr->pid,
5085+ current->p_pptr->uid,current->p_pptr->euid);
5086+ goto bad_fork_free;
5087+ }
5088+}
5089+}
5090+#endif
5091+
5092 atomic_inc(&p->user->__count);
5093 atomic_inc(&p->user->processes);
5094
5095@@ -654,6 +766,11 @@
5096 goto bad_fork_cleanup_fs;
5097 if (copy_mm(clone_flags, p))
5098 goto bad_fork_cleanup_sighand;
5099+#ifdef CONFIG_OBV_PROC
5100+ if (obv_copy_acl(p))
5101+ goto bad_fork_cleanup_sighand;
5102+#endif
5103+
5104 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
5105 if (retval)
5106 goto bad_fork_cleanup_mm;
5107@@ -740,6 +857,13 @@
5108 free_uid(p->user);
5109 bad_fork_free:
5110 free_task_struct(p);
5111+#ifdef CONFIG_GRKERNSEC_FORKFAIL
5112+ if(grsec_enable_forkfail)
5113+ security_alert("failed fork with errno %d by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), "
5114+ "UID (%d), EUID (%d)","failed forks",retval,current->comm,current->pid,
5115+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
5116+ current->p_pptr->uid,current->p_pptr->euid);
5117+#endif
5118 goto fork_out;
5119 }
5120
5121diff -urN linux/kernel/oblivion.c linux.grsec/kernel/oblivion.c
5122--- linux/kernel/oblivion.c Thu Jan 1 01:00:00 1970
5123+++ linux.grsec/kernel/oblivion.c Sun Sep 30 01:54:20 2001
5124@@ -0,0 +1,1357 @@
5125+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5126+ * Oblivion: A Security-Enhancing Linux Kernel Modification
5127+ * Author: Michael Dalton
5128+ * E-Mail: shadowrye@linux.com
5129+ * Information: This modification is designed to give
5130+ * fine-tuned control over processes, to prevent
5131+ * the damage of buffer overflows by disallowing them to run or
5132+ * write to anything that is abnormal. It also protects files from
5133+ * access by unauthorized programs(read only/append only/hidden modes)
5134+ * and has capability management features.
5135+ *
5136+ * Modifications
5137+ * 4-20-2001 - Began development of OPM .3
5138+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5139+
5140+/* Access Layers */
5141+
5142+
5143+/* Files -
5144+ * file database -> file info
5145+ */
5146+
5147+/* Process
5148+ * process database -> process entry (and capabilities) -> process file access rights
5149+ */
5150+
5151+#include <linux/kernel.h>
5152+#include <linux/mm.h>
5153+#include <linux/ctype.h>
5154+#include <asm/uaccess.h>
5155+#include <asm/errno.h>
5156+#include <linux/file.h>
5157+#include <linux/fs.h>
5158+#include <linux/slab.h>
5159+#include <linux/types.h>
5160+#include <linux/capability.h>
5161+#include <linux/sched.h>
5162+#include <linux/oblivion.h>
5163+#include <linux/obvcipher.h>
5164+#include <linux/sysctl.h>
5165+
5166+#define OBV_SET_AUTH 1
5167+#define OBV_SET_INHERIT 2
5168+#define OBV_SET_PROC 3
5169+
5170+#define CONFIG_OBV_PROCACL_CONF "/etc/obv/proc.acl"
5171+#define CONFIG_OBV_FILEACL_CONF "/etc/obv/file.acl"
5172+#define CONFIG_OBV_SUM_CONF "/etc/obv/sum.db"
5173+#define CONFIG_OBV_PW_CONF "/etc/obv/pw"
5174+#define CONFIG_OBVADM_ACL CONFIG_OBVADM_PATH ## " fx"
5175+#define CONFIG_GODMODE_ACL "/ frwxoi"
5176+/* i.e. this would become "/sbin/obvadm x" for executable access only to
5177+ * /sbin/obvadm (and find it if its hidden) */
5178+
5179+#define obv_empty_tree (struct obv_proc_acl *) NULL
5180+
5181+#define obv_heightof(tree) ( (tree == obv_empty_tree) ? 0 : (tree->height) )
5182+
5183+#define INIT_CAP_TABLE(table) \
5184+table[0].capname = "CAP_CHOWN";\
5185+table[0].capval = CAP_CHOWN; \
5186+table[1].capname = "CAP_DAC_OVERRIDE"; \
5187+table[1].capval = CAP_DAC_OVERRIDE; \
5188+table[2].capname = "CAP_DAC_READ_SEARCH"; \
5189+table[2].capval = CAP_DAC_READ_SEARCH; \
5190+table[3].capname = "CAP_FOWNER"; \
5191+table[3].capval = CAP_FOWNER; \
5192+table[4].capname = "CAP_FSETID"; \
5193+table[4].capval = CAP_FSETID; \
5194+table[5].capname = "CAP_FS_MASK"; \
5195+table[5].capval = CAP_FS_MASK; \
5196+table[6].capname = "CAP_KILL"; \
5197+table[6].capval = CAP_KILL; \
5198+table[7].capname = "CAP_SETGID"; \
5199+table[7].capval = CAP_SETGID; \
5200+table[8].capname = "CAP_SETUID"; \
5201+table[8].capval = CAP_SETUID; \
5202+table[9].capname = "CAP_SETPCAP"; \
5203+table[9].capval = CAP_SETPCAP; \
5204+table[10].capname = "CAP_LINUX_IMMUTABLE"; \
5205+table[10].capval = CAP_LINUX_IMMUTABLE; \
5206+table[11].capname = "CAP_NET_BIND_SERVICE"; \
5207+table[11].capval = CAP_NET_BIND_SERVICE; \
5208+table[12].capname = "CAP_NET_BROADCAST"; \
5209+table[12].capval = CAP_NET_BROADCAST;\
5210+table[13].capname = "CAP_NET_ADMIN"; \
5211+table[13].capval = CAP_NET_ADMIN; \
5212+table[14].capname = "CAP_NET_RAW"; \
5213+table[14].capval = CAP_NET_RAW; \
5214+table[15].capname = "CAP_IPC_LOCK"; \
5215+table[15].capval = CAP_IPC_LOCK; \
5216+table[16].capname = "CAP_IPC_OWNER"; \
5217+table[16].capval = CAP_IPC_OWNER; \
5218+table[17].capname = "CAP_SYS_MODULE"; \
5219+table[17].capval = CAP_SYS_MODULE; \
5220+table[18].capname = "CAP_SYS_RAWIO"; \
5221+table[18].capval = CAP_SYS_RAWIO; \
5222+table[19].capname = "CAP_SYS_CHROOT"; \
5223+table[19].capval = CAP_SYS_CHROOT; \
5224+table[20].capname = "CAP_SYS_PTRACE"; \
5225+table[20].capval = CAP_SYS_PTRACE; \
5226+table[21].capname = "CAP_SYS_PACCT"; \
5227+table[21].capval = CAP_SYS_PACCT; \
5228+table[22].capname = "CAP_SYS_ADMIN"; \
5229+table[22].capval = CAP_SYS_ADMIN; \
5230+table[23].capname = "CAP_SYS_BOOT"; \
5231+table[23].capval = CAP_SYS_BOOT; \
5232+table[24].capname = "CAP_SYS_NICE"; \
5233+table[24].capval = CAP_SYS_NICE; \
5234+table[25].capname = "CAP_SYS_RESOURCE"; \
5235+table[25].capval = CAP_SYS_RESOURCE; \
5236+table[26].capname = "CAP_SYS_TIME"; \
5237+table[26].capval = CAP_SYS_TIME; \
5238+table[27].capname = "CAP_SYS_TTY_CONFIG"; \
5239+table[27].capval = CAP_SYS_TTY_CONFIG; \
5240+table[28].capname = "CAP_MKNOD"; \
5241+table[28].capval = CAP_MKNOD; \
5242+table[29].capname = "CAP_LEASE"; \
5243+table[29].capval = CAP_LEASE;
5244+
5245+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5246+ * Global variables
5247+ * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * */
5248+
5249+int _enable_oblivion_load = 0;
5250+int obv_disable = 0; /* handles boot time disabling of oblivion*/
5251+static struct obv_proc_db procdb;
5252+static struct obv_file_db filedb;
5253+/* Main variables for holding the rulesets*/
5254+static spinlock_t obv_lock = SPIN_LOCK_UNLOCKED;
5255+__u8 obv_status = (OBV_1ST | OBV_DISABLED);
5256+struct obv_pw obv_pwent;
5257+struct obv_cap_list *caplist;
5258+struct obv_acl obv_god_mode = { 0,0,0,~0,obv_empty_tree};
5259+/* iddqd style god mode;) Full caps/access rights*/
5260+extern kdev_t ROOT_DEV;
5261+struct obv_acl obv_auth = { 0,0,(__u8)OBV_PROC_AUTH,CAP_INIT_EFF_SET,obv_empty_tree };
5262+/* acl for authentication mode */
5263+
5264+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5265+ * Sorting Routines
5266+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5267+
5268+
5269+
5270+static __inline__ int obv_procacl_less(const struct obv_temp *a, const struct obv_proc_acl *b)
5271+{
5272+ return ( (a->file_inode < b->file_inode) || ( (a->file_inode == b->file_inode) && (a->file_dev < b->file_dev) ) ) ? 1 : 0;
5273+}
5274+
5275+#define obv_proc_acl_less(a,b) obv_procacl_less(a,b)
5276+
5277+static __inline__ int obv_procacl_eq(const struct obv_temp *a, const struct obv_proc_acl *b)
5278+{
5279+ return ( (a->file_inode == b->file_inode) && (a->file_dev == b->file_dev) ) ? 1:0;
5280+}
5281+
5282+
5283+static __inline__ int obv_acl_eq(const struct obv_acl *a, const struct obv_acl *b)
5284+{
5285+ return ( (a->file_inode == b->file_inode) && (a->file_dev == b->file_dev)) ? 1 : 0;
5286+}
5287+
5288+extern void obv_qsort(void *const pbase,size_t total_elems,size_t size,int (*cmp) (const void *, const void *));
5289+
5290+/* see obvqsort.c for above. Slightly adapted from gnu libc's qsort*/
5291+
5292+static __inline__ int obv_file_acl_cmp(const void *va, const void *vb)
5293+{
5294+ struct obv_file_acl *a = (struct obv_file_acl *) va;
5295+ struct obv_file_acl *b = (struct obv_file_acl *) vb;
5296+ if (a->file_inode < b->file_inode)
5297+ return -1;
5298+ else if(a->file_inode == b->file_inode) {
5299+ if(a->file_dev < b->file_dev)
5300+ return -1;
5301+ else if(a->file_dev == b->file_dev)
5302+ return 0;
5303+ }
5304+ return 1;
5305+}
5306+
5307+static __inline__ int obv_fileacl_less(const struct obv_file_acl *f1, const struct obv_temp *f2) {
5308+ return ( ((f1->file_inode < f2->file_inode)) || (f1->file_inode == f2->file_inode && f1->file_dev < f2->file_dev) ) ? 1 : 0;
5309+}
5310+
5311+static __inline__ int obv_fileacl_eq(const struct obv_file_acl *f1, const struct obv_temp *f2) {
5312+ return ( (f1->file_inode == f2->file_inode) && (f1->file_dev == f2->file_dev)) ? 1 : 0;
5313+}
5314+static __inline__ int obv_acl_cmp(const void *va, const void *vb)
5315+{
5316+ struct obv_acl *a = (struct obv_acl *) va;
5317+ struct obv_acl *b = (struct obv_acl *) vb;
5318+ if (a->file_inode < b->file_inode)
5319+ return -1;
5320+
5321+ else if(a->file_inode == b->file_inode) {
5322+ if(a->file_dev < b->file_dev)
5323+ return -1;
5324+ else if(a->file_dev == b->file_dev)
5325+ return 0;
5326+ }
5327+ return 1;
5328+}
5329+#define obv_acl_less(a,b) (((obv_acl_cmp((const void *)a,(const void *)b)) < 0))
5330+
5331+static struct obv_proc_acl * obv_rotl(struct obv_proc_acl *tree)
5332+{
5333+ struct obv_proc_acl *tmp = tree->right;
5334+ tree->right = tmp->left;
5335+ tmp->left = tree;
5336+ if(obv_heightof(tree->left) >= obv_heightof(tree->right))
5337+ tree->height = obv_heightof(tree->left) +1;
5338+ else
5339+ tree->height = obv_heightof(tree->right) + 1;
5340+ if(obv_heightof(tmp->left) >= obv_heightof(tmp->right))
5341+ tmp->height = obv_heightof(tmp->left) + 1;
5342+ else
5343+ tmp->height = obv_heightof(tmp->right) + 1;
5344+ return tmp;
5345+}
5346+
5347+static struct obv_proc_acl * obv_rotr(struct obv_proc_acl *tree)
5348+{
5349+ struct obv_proc_acl *tmp = tree->left;
5350+ tree->left = tmp->right;
5351+ tmp->right = tree;
5352+ if(obv_heightof(tree->left) >= obv_heightof(tree->right))
5353+ tree->height=obv_heightof(tree->left) + 1;
5354+ else
5355+ tree->height = obv_heightof(tree->right) + 1;
5356+ if(obv_heightof(tmp->left) >= obv_heightof(tmp->right))
5357+ tmp->height = obv_heightof(tmp->left) + 1;
5358+ else
5359+ tmp->height = obv_heightof(tmp->right) + 1;
5360+ return tmp;
5361+}
5362+
5363+static struct obv_proc_acl * obv_drlr(struct obv_proc_acl *tree) {
5364+ tree->right = obv_rotr(tree->right);
5365+ return obv_rotl(tree);
5366+}
5367+
5368+static struct obv_proc_acl * obv_dlrr(struct obv_proc_acl *tree) {
5369+ tree->left = obv_rotl(tree->left);
5370+ return obv_rotr(tree);
5371+}
5372+
5373+
5374+static void obv_sort(void)
5375+{
5376+ obv_qsort((void *)procdb.db,procdb.max_ref,sizeof(struct obv_acl),obv_acl_cmp);
5377+ obv_qsort((void *)filedb.db,filedb.max_ref,sizeof(struct obv_file_acl),obv_file_acl_cmp);
5378+}
5379+#ifdef CONFIG_OBV_OLD_DEBUG
5380+static void obv_list_file_acls(void)
5381+{
5382+ int i;
5383+ for(i=0;i<filedb.max_ref;i++) {
5384+ obv_seclog("File ACL pos %d has inode %ld dev %d mode %x\n",i,filedb.db[i].file_inode,filedb.db[i].file_dev,filedb.db[i].mode);
5385+ }
5386+}
5387+
5388+static void obv_traverse(struct obv_proc_acl *head)
5389+{
5390+ if(!head) {
5391+ obv_seclog("null tree\n");
5392+ return;
5393+ }
5394+ obv_seclog("Tree: %ld %d %x\n",head->file_inode,head->file_dev,head->mode);
5395+ if(head->left != obv_empty_tree) {
5396+ obv_seclog("Doing left proc acl\n");
5397+ obv_traverse(head->left);
5398+ }
5399+ if(head->right != obv_empty_tree) {
5400+ obv_seclog("Doing right proc acl\n");
5401+ obv_traverse(head->right);
5402+ }
5403+}
5404+
5405+static void obv_list_proc_acls(void)
5406+{
5407+ int i;
5408+ for(i=0;i<procdb.max_ref;i++) {
5409+ obv_seclog("ACL pos %d has inode %ld dev %d\n",i,procdb.db[i].file_inode,procdb.db[i].file_dev);
5410+ obv_seclog("ACL tree is..\n");
5411+ obv_traverse(procdb.db[i].tree);
5412+ }
5413+}
5414+#endif
5415+
5416+/* * * * * * * * * * * * * * * * * * * * * * * * * * *
5417+ * Config file management
5418+ * Yikes! If anyone has cleanup ideas I'd love to hear em
5419+ * * * * * * * * * * * * * * * * * * * * * * * * * * */
5420+
5421+
5422+
5423+
5424+static int obv_add_pw_conf(void)
5425+{
5426+ struct file *filp;
5427+ int retval;
5428+ mm_segment_t old_fs = get_fs();
5429+ filp = filp_open(CONFIG_OBV_PW_CONF, O_RDONLY, O_RDONLY);
5430+ if( ( IS_ERR(filp) ) || (filp == NULL) || (!(filp->f_op->read)) ) {
5431+ obv_seclog("Could not open config file %.1024s\n",CONFIG_OBV_PW_CONF);
5432+ return 1;
5433+ }
5434+ filp->f_pos = 0;
5435+ set_fs(KERNEL_DS);
5436+ retval = filp->f_op->read(filp,obv_pwent.sum,sizeof(obv_pwent.sum)/sizeof(obv_pwent.sum[0]),&filp->f_pos);
5437+ set_fs(old_fs);
5438+ if(retval != sizeof(obv_pwent.sum)/sizeof(obv_pwent.sum[0])) {
5439+ obv_seclog("Invalid pw entry detected, got %d wanted %d\n",retval,sizeof(obv_pwent.sum));
5440+ retval = 1;
5441+ } else retval = 0;
5442+ filp_close(filp,NULL);
5443+ return retval;
5444+}
5445+
5446+
5447+
5448+
5449+static int obv_add_file_acl(char *line)
5450+{
5451+ char *p, *q;
5452+ struct nameidata filedata;
5453+ int working = 1;
5454+ struct obv_file_acl *curr;
5455+
5456+ if( (p = memscan(line,'/',strlen(line))) == line + strlen(line) ) {
5457+ // obv_seclog("Line %.1024s seems wrong\n",line);
5458+ return 0;
5459+ }
5460+ else curr = &(filedb.db[filedb.max_ref]);
5461+
5462+ if( (q = memscan(p,' ',strlen(p))) == p + strlen(p))
5463+ return 0;
5464+ *q++ = '\0';
5465+ if(path_init(p,LOOKUP_FOLLOW|LOOKUP_POSITIVE,&filedata))
5466+ if(path_walk(p,&filedata)) {
5467+ obv_seclog("Unable to locate file %.1024s\n",p);
5468+ //goto out;
5469+ return 0;
5470+ }
5471+ if( !(filedata.dentry) || IS_ERR(filedata.dentry) ) {
5472+ obv_seclog("Error adding file acl for file %.1024s\n",p);
5473+ // goto out;
5474+ return 0;
5475+ }
5476+ curr->file_inode = filedata.dentry->d_inode->i_ino;
5477+ curr->file_dev = filedata.dentry->d_inode->i_dev;
5478+ curr->mode = 0;
5479+
5480+ while(*q == ' ') q++;
5481+ while(working) {
5482+ switch(*q) {
5483+ case 'r' :
5484+ curr->mode |= OBV_FILE_READ;
5485+ q++;
5486+ break;
5487+ case 'h' :
5488+ curr->mode |= OBV_FILE_HIDDEN;
5489+ q++;
5490+ break;
5491+ case 'a' :
5492+ curr->mode |= OBV_FILE_APPEND;
5493+ q++;
5494+ break;
5495+ case 'w' :
5496+ curr->mode |= OBV_FILE_WRITE;
5497+ q++;
5498+ break;
5499+ case 'x':
5500+ curr->mode |= OBV_FILE_EXEC;
5501+ q++;
5502+ break;
5503+ /* Note: 's' and 'a' only come into play when something is executed*/
5504+ case 's' :
5505+ filedb.db[filedb.max_ref].mode |= OBV_FILE_REQSUM;
5506+ q++;
5507+ break;
5508+ case 'u' :
5509+ filedb.db[filedb.max_ref].mode |= OBV_FILE_AUTH;
5510+ q++;
5511+ break;
5512+ default: /* if anything else, the '\0' at the end of the line will hit here and cause us to terminate, so it won't go on indefinately and start accessing memory it shouldn't*/
5513+ working = 0;
5514+ break;
5515+ }
5516+ }
5517+#ifdef CONFIG_OBV_DEBUG
5518+ obv_seclog("Added File ACL for inode %ld dev %d with mode %x and max_ref %d\n",curr->file_inode,curr->file_dev,curr->mode,filedb.max_ref);
5519+#endif
5520+ filedb.max_ref++;
5521+ path_release(&filedata);
5522+ return 0;
5523+}
5524+
5525+
5526+static __inline__ struct obv_proc_acl * obv_set(struct obv_temp *data, struct obv_proc_acl *left, struct obv_proc_acl *right,__u16 height)
5527+{
5528+ struct obv_proc_acl *dest = kmalloc(sizeof(struct obv_proc_acl),GFP_KERNEL);
5529+ if(dest == NULL) {
5530+ obv_seclog("Memory allocation failure, Oblivion panicing\n");
5531+ return procdb.db[procdb.max_ref].tree;
5532+ }
5533+ dest->file_inode = data->file_inode;
5534+ dest->file_dev = data->file_dev;
5535+ dest->mode = data->mode;
5536+ dest->left = left; dest->right = right;
5537+ dest->height = height;
5538+ return dest;
5539+}
5540+
5541+
5542+static struct obv_proc_acl * obv_tree_ins(struct obv_proc_acl *tree, struct obv_temp *entry)
5543+{
5544+ if(tree == obv_empty_tree) {
5545+ tree = obv_set(entry,obv_empty_tree,obv_empty_tree,0);
5546+ return tree;
5547+ }
5548+ else if(obv_procacl_less(entry,tree)) {
5549+ tree->left = obv_tree_ins(tree->left,entry);
5550+ if(obv_heightof(tree->left) > obv_heightof(tree->right) + 1) {
5551+ if(obv_procacl_less(entry,tree->left))
5552+ tree = obv_rotr(tree);
5553+ else
5554+ tree = obv_dlrr(tree);
5555+ }
5556+ }
5557+ else /* assuming no duplicate entries*/ {
5558+ tree->right = obv_tree_ins(tree->right,entry);
5559+ if(obv_heightof(tree->right) > obv_heightof(tree->left) + 1) {
5560+ if(obv_procacl_less(entry,tree->right))
5561+ tree = obv_drlr(tree);
5562+ else
5563+ tree = obv_rotl(tree);
5564+ }
5565+ }
5566+ if(obv_heightof(tree->left) >= obv_heightof(tree->right))
5567+ tree->height = obv_heightof(tree->left) + 1;
5568+ else
5569+ tree->height = obv_heightof(tree->right) + 1;
5570+ return tree;
5571+}
5572+
5573+static kernel_cap_t obv_cap_conv(char *p)
5574+{
5575+ kernel_cap_t cap;
5576+ int i;
5577+ char *q;
5578+ cap_t(cap) = 0;
5579+ if(!p) return cap;
5580+ if( (q = memscan(p,'\n',strlen(p))) != p + strlen(p))
5581+ *q = '\0';
5582+
5583+ while(*p == ' ') p++;
5584+ if( (strncmp(p,"CAP",3)) != 0)
5585+ goto out;
5586+ for(i=0;i<CONFIG_OBV_MAX_CAP;i++) {
5587+ if(!(strcmp(p,caplist->table[i].capname))) {
5588+ cap_t(cap) = CAP_TO_MASK(caplist->table[i].capval);
5589+ return cap;
5590+ }
5591+ }
5592+out:
5593+ return cap;
5594+}
5595+
5596+
5597+static int obv_add_proc_acl(char *line,struct obv_acl *obv)
5598+{
5599+ char *p, *q;
5600+ struct nameidata nd;
5601+ int working = 1;
5602+ struct obv_temp curr;
5603+ if( (p = memscan(line,'+',strlen(line)) ) != line + strlen(line) ) {
5604+ cap_t(obv->file_caps) |= cap_t(obv_cap_conv(++p));
5605+ return 0;
5606+ }
5607+ else if ( (p = memscan(line,'-',strlen(line)) ) != line + strlen(line) ) {
5608+ cap_t(obv->file_caps) &= ~cap_t(obv_cap_conv(++p));
5609+ return 0;
5610+ }
5611+
5612+ else {
5613+ if( (p = memscan(line,'/',strlen(line))) == line + strlen(line)) {
5614+ obv_seclog("Line %.1024s missing a /\n",line);
5615+ return 0;
5616+ }
5617+ if ( (q = memscan(p,' ',strlen(p))) == p + strlen(p)) {
5618+ obv_seclog("Missing a space in obv proc acl entry, line %.1024s\n",line);
5619+ return 0;
5620+ }
5621+ *q++ = '\0';
5622+ if(path_init(p,LOOKUP_FOLLOW|LOOKUP_POSITIVE,&nd))
5623+ if(path_walk(p,&nd)) {
5624+ obv_seclog("path walk failure for %.1024s\n",line);
5625+ return 1;
5626+ }
5627+ if( (!nd.dentry) || (IS_ERR(nd.dentry)) || (!(nd.dentry->d_inode)) ) {
5628+ if(nd.dentry)
5629+ path_release(&nd);
5630+ obv_seclog("lookup failure for %.1024s\n",line);
5631+ return 1;
5632+ }
5633+ curr.file_inode = nd.dentry->d_inode->i_ino;
5634+ curr.file_dev = nd.dentry->d_inode->i_dev;
5635+ curr.mode = 0;
5636+
5637+ while(*q == ' ') q++;
5638+ while(working) {
5639+ switch(*q) {
5640+ case 'r' :
5641+ curr.mode |= OBV_PROC_READ;
5642+ q++;
5643+ break;
5644+ case 'w' :
5645+ curr.mode |= OBV_PROC_WRITE;
5646+ q++;
5647+ break;
5648+ case 'x' :
5649+ curr.mode |= OBV_PROC_EXEC;
5650+ q++;
5651+ break;
5652+ case 'a' :
5653+ curr.mode |= OBV_PROC_APPEND;
5654+ q++;
5655+ break;
5656+ case 'f':
5657+ curr.mode |= OBV_PROC_ACCESS;
5658+ q++;
5659+ break;
5660+ case 'o':
5661+ curr.mode |= OBV_PROC_OVERRIDE;
5662+ q++;
5663+ break;
5664+ case 'u' :
5665+ curr.mode |= OBV_PROC_AUTH;
5666+ q++;
5667+ break;
5668+ case 'i' :
5669+ curr.mode |= OBV_PROC_INHERIT;
5670+ q++;
5671+ break;
5672+ case 's' :
5673+ curr.mode |= OBV_PROC_REQSUM;
5674+ q++;
5675+ break;
5676+ default:
5677+ working = 0;
5678+ break;
5679+ }
5680+ }
5681+#ifdef CONFIG_OBV_DEBUG
5682+ obv_seclog("About to insert %ld %d %.1024s\n",curr.file_inode,curr.file_dev,line);
5683+#endif
5684+ obv->tree = obv_tree_ins(obv->tree,&curr);
5685+ path_release(&nd);
5686+ return 0;
5687+ }
5688+ return 1; /* we should never make it here*/
5689+}
5690+
5691+static int obv_add_pw(char *pw)
5692+{
5693+ struct SHA1_CTX context;
5694+ SHA1Init(&context);
5695+ SHA1Update(&context,pw,strlen(pw));
5696+ SHA1Final(obv_pwent.sum,&context);
5697+ return 0;
5698+}
5699+
5700+static int obv_add_line(char *line, int type)
5701+{
5702+ static int mode = 0;
5703+ char *p,*q;
5704+ struct dentry *file;
5705+ struct nameidata filed;
5706+ static struct obv_acl *curr;
5707+ int working;
5708+ /* mode = 0 : we are ready for a new program acl
5709+ * mode = 1 : we are in the middle of reading a program acl*/
5710+ switch(type) {
5711+ case 2 : return obv_add_pw(line);
5712+ case 1 : return obv_add_file_acl(line);
5713+ case 0 : break; /* handled below*/
5714+ default: obv_seclog("Unknown type %d passed\n",type);
5715+ return 1;
5716+ break;
5717+ }
5718+
5719+ if(!mode) {
5720+ if(procdb.max_ref >= CONFIG_OBV_MAX_RULESET) return 1;
5721+ if( (p = memscan (line,'/',strlen(line))) == (line+strlen(line)) ) {
5722+ return 0;
5723+ }
5724+ else curr = &(procdb.db[procdb.max_ref]);
5725+
5726+
5727+ q = memscan(p,' ',strlen(p));
5728+ *q++= '\0';
5729+
5730+ if(path_init(p,LOOKUP_FOLLOW|LOOKUP_POSITIVE,&filed) )
5731+ if(path_walk(p,&filed)) {
5732+ obv_seclog("Add file error for file %.1024s\n",p);
5733+ return 1;
5734+ }
5735+ file = filed.dentry;
5736+ if (IS_ERR(file) || !file || !(file->d_inode)) {
5737+ if(file)
5738+ path_release(&filed);
5739+ return 1;
5740+ }
5741+ curr->file_inode = file->d_inode->i_ino;
5742+ curr->file_dev = file->d_inode->i_dev;
5743+ while(*q == ' ') q++;
5744+ curr->mode = 0;
5745+ working = 1;
5746+ while(working) {
5747+ switch(*q) {
5748+ case 'p':
5749+ curr->mode |= OBV_PROC_PROTECTED;
5750+ q++;
5751+ break;
5752+ case 'h':
5753+ curr->mode |= OBV_PROC_HIDDEN;
5754+ q++;
5755+ break;
5756+ default:
5757+ working = 0;
5758+ }
5759+ }
5760+ curr->file_caps = cap_bset;
5761+ mode = 1;
5762+#ifdef CONFIG_OBV_DEBUG
5763+ obv_seclog("Added program (full entry) with inode %ld dev %d mode %x line %.1024s\n",curr->file_inode,curr->file_dev,curr->mode,line);
5764+#endif
5765+ path_release(&filed);
5766+ curr->tree = obv_empty_tree;
5767+ return 0;
5768+ }
5769+ else if( (p=memscan(line,'}',strlen(line))) != (line + strlen(line)) ) {
5770+ procdb.max_ref++;
5771+ mode = 0;
5772+ return 0;
5773+ } else {
5774+ return obv_add_proc_acl(line,curr);
5775+ }
5776+}
5777+
5778+static int obv_init_variables(void)
5779+{
5780+ caplist = kmalloc(sizeof(struct obv_cap_list),GFP_KERNEL);
5781+ if(caplist) {
5782+ INIT_CAP_TABLE(caplist->table)
5783+ }
5784+
5785+ procdb.db = kmalloc(sizeof(struct obv_acl) * CONFIG_OBV_MAX_RULESET,GFP_KERNEL);
5786+ filedb.db = kmalloc(sizeof(struct obv_file_acl) * CONFIG_OBV_MAX_RULESET,GFP_KERNEL);
5787+ procdb.max_ref = filedb.max_ref = 0;
5788+
5789+ if( (obv_add_proc_acl(CONFIG_OBVADM_ACL,&obv_auth)) )
5790+ return 1;
5791+ else if( (obv_add_proc_acl(CONFIG_GODMODE_ACL,&obv_god_mode)) )
5792+ return 1;
5793+ else if( (obv_add_proc_acl("/etc r",&obv_auth)) )
5794+ return 1;
5795+ else if( (obv_add_proc_acl("/lib r",&obv_auth)) )
5796+ return 1;
5797+
5798+ return procdb.db && filedb.db && caplist ? 0 : 1;
5799+}
5800+
5801+
5802+static int obv_conf_parse(const char *conffile,const int type)
5803+{
5804+ /* Purpose: open and read from oblivion config file */
5805+ struct file *filp;
5806+ int bytes_read = 0, start = 0, end = 0, obv_fatal = 0;
5807+ char buffer[1024];
5808+ char *filepos = NULL,*memscanp = NULL;
5809+ mm_segment_t old_fs;
5810+ filepos = buffer;
5811+ filp = filp_open(conffile, O_RDONLY, O_RDONLY);
5812+ if( ( IS_ERR(filp) ) || (filp == NULL) ) {
5813+ obv_seclog("Could not open config file %.1024s\n",conffile);
5814+
5815+ obv_fatal = 1;
5816+ return obv_fatal;
5817+ } else if ( filp->f_op->read == NULL ) {
5818+ fput(filp);
5819+ obv_fatal = 2;
5820+ return obv_fatal;
5821+ }
5822+ /* end error checking, now for the real work */
5823+ while ( ! end ) {
5824+ filp->f_pos = start; /* offset of our read :) */
5825+ old_fs = get_fs();
5826+ filepos = buffer;
5827+ /* if current task isn't from the kernel, we'll
5828+ have a current->addr_limit.seg that isn't 0xFFFFFFFF
5829+
5830+ and we can't have that */
5831+ set_fs(KERNEL_DS);
5832+ bytes_read = filp->f_op->read (filp,buffer,1024,&filp->f_pos);
5833+ set_fs(old_fs);
5834+ if(bytes_read < 1024 ) {
5835+ end = 1;
5836+ filepos[bytes_read++] = '\n'; /* last line
5837+ must make sure we have a newline */
5838+ } while ( ( memscanp = memscan(filepos,'\n',sizeof(buffer)) ) != filepos + bytes_read && (bytes_read > 0) ) {
5839+ *memscanp++ = '\0' ;
5840+ /* necessary for later strlen()'s...*/
5841+ bytes_read -= memscanp-filepos;
5842+ filp->f_pos += memscanp-filepos;
5843+ if( (*filepos != '#') )
5844+ if(obv_add_line(filepos,type))
5845+ return 1;
5846+ filepos = memscanp; /* next area to search .. */
5847+ }
5848+ if (bytes_read == 1024 ) {
5849+ /* hmmm we got a return for no \n in the buffer
5850+ must be too long of a line */
5851+ break;
5852+ }
5853+ }
5854+ filp_close(filp,NULL);
5855+ return obv_fatal;
5856+}
5857+
5858+static void obv_free_unused_memory(void) {
5859+ int i;
5860+ if(procdb.max_ref < CONFIG_OBV_MAX_RULESET)
5861+ for(i = procdb.max_ref;i < CONFIG_OBV_MAX_RULESET;i++) {
5862+ kfree(&procdb.db[i]);
5863+ }
5864+ if(filedb.max_ref < CONFIG_OBV_MAX_RULESET)
5865+ for(i = filedb.max_ref;i < CONFIG_OBV_MAX_RULESET;i++) {
5866+ kfree(&filedb.db[i]);
5867+ }
5868+}
5869+
5870+static int oblivion_init(void)
5871+{
5872+ int error = 0;
5873+ spin_lock(&obv_lock);
5874+ obv_status &= ~OBV_DISABLED;
5875+ obv_status |= OBV_LOADING;
5876+ /* okay we're the only oblivion_init that can run due to the spinlock*/
5877+ if(obv_init_variables() )
5878+ error = -1;
5879+ else if(obv_add_pw_conf())
5880+ error = -2;
5881+ else if (obv_conf_parse(CONFIG_OBV_PROCACL_CONF,0))
5882+ error = -3;
5883+ else if(obv_conf_parse(CONFIG_OBV_FILEACL_CONF,1))
5884+ error = -4;
5885+ obv_sort();
5886+ if(!error) {
5887+ obv_free_unused_memory();
5888+ obv_status |= OBV_READY; /* locked, cocked, and ready to rock*/
5889+ }else {
5890+ obv_status |= OBV_DISABLED;
5891+ obv_seclog("Error loading , trying to run kernel with oblivion disabled. To disable oblivion at startup use <kernel image name> oblivion=off from your boot loader\n");
5892+ }
5893+ obv_status &= ~OBV_LOADING;
5894+ spin_unlock(&obv_lock);
5895+ return error;
5896+}
5897+
5898+/* * * * * * * * * * * * * * * * * * * * * * *
5899+ * Begin Misc Section
5900+ * * * * * * * * * * * * * * * * * * * * * * */
5901+
5902+/* Searching stuff, program exit cleanup, and sysctl parsing */
5903+
5904+/* Nonrecursive binary sort, idea from libc, implementation is slightly different but the inspirationw as found there=) */
5905+
5906+static __inline__ int do_obv_file_acl_search(struct obv_temp *curr)
5907+{
5908+ int high, low;
5909+ struct obv_file_acl *pos;
5910+ high = filedb.max_ref;
5911+ low = 0;
5912+ while(low < high) {
5913+ pos = &filedb.db[((low+high)/2)];
5914+ if(obv_fileacl_less(pos,curr))
5915+ low = (( (low + high) / 2) + 1 );
5916+ else if(obv_fileacl_eq(pos,curr)) {
5917+ if(pos->mode & curr->mode) {
5918+#ifdef CONFIG_OBV_DEBUG
5919+ obv_seclog("File ACL allow, req %x allowed %x\n source: %ld %d dest %ld %d\n",curr->mode,pos->mode,pos->file_inode,pos->file_dev,curr->file_inode,curr->file_dev);
5920+#endif
5921+ return OBV_ALLOW;
5922+ }
5923+ else {
5924+#ifdef CONFIG_OBV_DEBUG
5925+ if(!(curr->mode & OBV_FILE_HIDDEN))
5926+ obv_seclog("File ACL deny, req %x allowed %x\n source %ld %d dest %ld %d\n",curr->mode,pos->mode,pos->file_inode,pos->file_dev,curr->file_inode,curr->file_dev);
5927+#endif
5928+ return OBV_DENY;
5929+ }
5930+ }
5931+ else high = ( (low + high) / 2);
5932+ }
5933+ return OBV_NOTFOUND;
5934+}
5935+
5936+static __inline__ int do_obv_proc_acl_search(struct obv_acl *proc,struct obv_proc_acl *root,struct obv_temp *curr)
5937+{
5938+ /* Nonrecursively search down the Red-Black tree to see if we have an acl for this file*/
5939+ struct obv_proc_acl *pos = root;
5940+ if(proc == NULL || pos == NULL) /* no entry*/ {
5941+ return OBV_DEFAULT;
5942+ }
5943+ // obv_seclog("Got called...and there's an entry (curr is %ld %d\n",curr->file_inode,curr->file_dev);
5944+ while(pos != obv_empty_tree) {
5945+ if(obv_procacl_eq(curr,pos)) {
5946+ if(curr->mode & pos->mode) {
5947+ __u16 tmp;
5948+#ifdef CONFIG_OBV_DEBUG
5949+ obv_seclog("Process %ld %d allowed for file %ld %d tried for mode %x allowed mode %x\n",proc->file_inode,proc->file_dev,curr->file_inode,curr->file_dev,curr->mode,pos->mode);
5950+#endif
5951+ tmp = pos->mode & OBV_PROC_EXTRA;
5952+ curr->mode |= tmp; /* Store any "extra" access rights like
5953+ inherit or override*/
5954+ return OBV_ALLOW;
5955+ } else {
5956+#ifdef CONFIG_OBV_DEBUG
5957+ obv_seclog("Process %ld %d denied for file %ld %d tried for mode %x allowed mode %x\n",proc->file_inode,proc->file_dev,curr->file_inode,curr->file_dev,curr->mode,pos->mode);
5958+#endif
5959+ return OBV_DENY;
5960+ }
5961+ }
5962+ else if(obv_procacl_less(curr,pos))
5963+ pos = pos->left;
5964+ else
5965+ pos=pos->right;
5966+ }
5967+
5968+ return OBV_NOTFOUND;
5969+}
5970+
5971+static __inline__ int obv_chk_proc_acls(struct dentry * dentry, struct obv_temp *searchval, struct vfsmount *mnt)
5972+{
5973+ struct dentry *curr = dentry;
5974+ int retval = OBV_NOTFOUND;
5975+ struct nameidata tmp = {NULL, NULL};
5976+ struct vfsmount *parent;
5977+
5978+loop :
5979+ do {
5980+ if(!curr || !curr->d_inode) break;
5981+ searchval->file_inode = curr->d_inode->i_ino;
5982+ searchval->file_dev = curr->d_inode->i_dev;
5983+ retval = do_obv_proc_acl_search(current->obvacl,current->obvacl->tree,searchval);
5984+ if(curr->d_inode == curr->d_parent->d_inode) break;
5985+ curr = curr->d_parent;
5986+ } while( (curr) && (retval == OBV_NOTFOUND) );
5987+ if(retval == OBV_NOTFOUND && curr->d_inode && curr->d_inode->i_dev != ROOT_DEV ) {
5988+#ifdef CONFIG_OBV_DEBUG
5989+ obv_seclog("In mount loop(proc acl) for %ld %d\n",dentry->d_inode->i_ino,dentry->d_inode->i_dev);
5990+#endif
5991+ if(tmp.mnt) {
5992+ if(tmp.mnt == tmp.mnt->mnt_parent) goto exit;
5993+ }
5994+ else if(mnt == mnt->mnt_parent) goto exit;
5995+
5996+
5997+ if(!tmp.mnt) {
5998+ tmp.mnt = mnt->mnt_parent;
5999+ tmp.dentry = dget(mnt->mnt_mountpoint);
6000+
6001+ }
6002+
6003+ else {
6004+ parent = tmp.mnt->mnt_parent;
6005+ dput(tmp.dentry);
6006+ tmp.dentry = dget(tmp.mnt->mnt_mountpoint);
6007+ mntput(tmp.mnt);
6008+ tmp.mnt = parent;
6009+ }
6010+ mntget(tmp.mnt);
6011+ curr = tmp.dentry;
6012+ goto loop;
6013+ }
6014+exit:
6015+ if(tmp.mnt) mntput(tmp.mnt);
6016+ if(tmp.dentry) dput(tmp.dentry);
6017+
6018+
6019+ return retval == OBV_NOTFOUND ? OBV_DENY : retval;
6020+ /* if its not in a program's ACL list it should be denied */
6021+
6022+}
6023+
6024+static __inline__ int obv_chk_file_acls(struct dentry * dentry, struct obv_temp *searchval, struct vfsmount *mnt)
6025+{
6026+ struct dentry *curr = dentry;
6027+ int retval = OBV_NOTFOUND;
6028+ struct vfsmount *parent;
6029+ struct nameidata tmp = {NULL,NULL};
6030+loop:
6031+ do {
6032+ if(!curr || !curr->d_inode) break;
6033+ searchval->file_inode = curr->d_inode->i_ino;
6034+ searchval->file_dev = curr->d_inode->i_dev;
6035+ retval = do_obv_file_acl_search(searchval);
6036+ if(curr->d_inode == curr->d_parent->d_inode) break;
6037+ curr = curr->d_parent;
6038+ } while( (curr) && (retval == OBV_NOTFOUND) );
6039+
6040+ if(retval == OBV_NOTFOUND && curr->d_inode && curr->d_inode->i_dev != ROOT_DEV ) {
6041+ if(tmp.mnt) {
6042+ if(tmp.mnt == tmp.mnt->mnt_parent) goto exit;
6043+ }
6044+ else if(mnt == mnt->mnt_parent) goto exit;
6045+ if(!tmp.mnt) {
6046+ tmp.mnt = mnt->mnt_parent;
6047+ tmp.dentry = dget(mnt->mnt_mountpoint);
6048+
6049+ }
6050+
6051+ else {
6052+ parent = tmp.mnt->mnt_parent;
6053+ dput(tmp.dentry);
6054+ tmp.dentry = dget(tmp.mnt->mnt_mountpoint);
6055+ mntput(tmp.mnt);
6056+ tmp.mnt = parent;
6057+ }
6058+ mntget(tmp.mnt);
6059+ curr = tmp.dentry;
6060+ goto loop;
6061+ }
6062+exit:
6063+ if(tmp.mnt) mntput(tmp.mnt);
6064+ if(tmp.dentry) dput(tmp.dentry);
6065+
6066+
6067+
6068+ return retval;
6069+ }
6070+
6071+
6072+int obv_check_hidden(struct dentry *dentry, struct vfsmount *mnt) {
6073+ /* This has to be done a little differently than a normal search.
6074+ * If a file "allows" hidden access it is hidden, and thus requires
6075+ * a process that has hidden file access capabilities to access it.
6076+ * If the file acl denies hidden access/has no acl then no proc acl
6077+ * check is needed*/
6078+ struct obv_temp searchval;
6079+ searchval.mode = OBV_HIDDEN;
6080+ if(!dentry) return OBV_ALLOW;
6081+ if(obv_status & OBV_READY) {
6082+ if( (obv_chk_file_acls(dentry,&searchval,mnt)) == OBV_ALLOW) {
6083+ if(current->obvacl && current->obvacl->tree)
6084+ return obv_chk_proc_acls(dentry,&searchval,mnt);
6085+ else return OBV_DENY;
6086+ }
6087+ }
6088+ return OBV_ALLOW;
6089+}
6090+
6091+int obv_check_hidden_proc(struct task_struct *tsk)
6092+{
6093+ if(obv_status & OBV_READY)
6094+ if(tsk->obvacl->mode & OBV_PROC_HIDDEN)
6095+ return 1; /* next release adds processes allowed to view hidden ones*/
6096+ return 0;
6097+}
6098+
6099+int obv_check_protected(struct task_struct *tsk)
6100+{
6101+ if(obv_status & OBV_READY)
6102+ if(tsk->obvacl->mode & OBV_PROC_PROTECTED)
6103+ return 1;
6104+ return 0;
6105+}
6106+
6107+
6108+int obv_search(struct dentry *dentry, __u16 mode, struct vfsmount *mnt)
6109+{
6110+ int proc_retval = OBV_NOTFOUND, file_retval = OBV_NOTFOUND;
6111+ int retval = OBV_DEFAULT;
6112+ if(dentry && dentry->d_inode && mnt) {
6113+ if(obv_status & OBV_READY) {
6114+ struct obv_temp searchval;
6115+ searchval.mode = mode;
6116+ if(current->obvacl && current->obvacl->tree) {
6117+ if( ( proc_retval = obv_chk_proc_acls(dentry,&searchval,mnt) ) == OBV_DENY) {
6118+ if( (current->obvacl->mode & OBV_AUTH) && (S_ISCHR(dentry->d_inode->i_mode)))
6119+ retval = OBV_NOTFOUND;
6120+ /* Okay. This process is under
6121+ * authentication mode. Let it
6122+ * read/write to the tty (and pass it on
6123+ * to the file acls just in case
6124+ * Does anyone know how to gain the ino$
6125+ * from current->tty? It seems only the
6126+ * device num(major/minor) is stored*/
6127+
6128+ else {
6129+ retval = OBV_DENY;
6130+ goto out;
6131+ }
6132+ }
6133+ }
6134+
6135+
6136+ if( (proc_retval == OBV_ALLOW) && (searchval.mode & OBV_PROC_OVERRIDE)){
6137+ retval = OBV_ALLOW;
6138+ goto out;
6139+ }
6140+
6141+ if( (file_retval = obv_chk_file_acls(dentry,&searchval,mnt)) == OBV_DENY) {
6142+ retval = OBV_DENY;
6143+ goto out;
6144+ }
6145+
6146+ if( (proc_retval != file_retval) || (proc_retval == OBV_ALLOW)) {
6147+ /* The choice to check for proc_retval being OBV_ALLOW was
6148+ * random. If proc_retval and file_retval are equal and
6149+ * either one is the value OBV_ALLOW then both are OBV_ALLOW
6150+ * */
6151+ retval = OBV_ALLOW;
6152+ goto out;
6153+ }
6154+ } else retval = OBV_ALLOW; /* we aren't loaded, must be early in bootup*/
6155+ }
6156+out:
6157+ return retval; /* Else both returned OBV_NOTFOUND..must be the default*/
6158+}
6159+
6160+
6161+static __inline__ struct obv_acl * do_obv_find_proc(struct obv_acl *curr)
6162+{
6163+ int high,low;
6164+ struct obv_acl *pos;
6165+ low = 0;
6166+ high = procdb.max_ref;
6167+ while(low < high) {
6168+ pos = &procdb.db[((low+high)/2)];
6169+ if(obv_acl_less(pos,curr))
6170+ low = ( ( (low + high) / 2) +1 );
6171+ else if(obv_acl_eq(pos,curr))
6172+ return pos;
6173+ else
6174+ high = ( (high + low) / 2);
6175+ }
6176+ return NULL;
6177+}
6178+
6179+static int __inline__ obv_chk_inherit(struct dentry *dentry, struct vfsmount *mnt)
6180+{
6181+ struct obv_temp temp;
6182+ temp.mode = OBV_PROC_INHERIT;
6183+ if( (obv_chk_proc_acls(dentry,&temp,mnt)) == OBV_ALLOW)
6184+ return 1;
6185+ return 0;
6186+}
6187+
6188+static int __inline__ obv_chk_auth(struct dentry *dentry, struct vfsmount *mnt)
6189+{
6190+ struct obv_temp temp;
6191+ temp.mode = OBV_PROC_AUTH;
6192+ if( (obv_chk_proc_acls(dentry,&temp,mnt)) == OBV_ALLOW)
6193+ return 1;
6194+ return 0;
6195+}
6196+
6197+static int obv_do_auth(void)
6198+{
6199+#define OBV_AUTH_MSG "Authorize yourself to Oblivion please\n"
6200+
6201+ char *p = OBV_AUTH_MSG;
6202+ if(!(current->tty) || (!current->tty->driver.write)) return 1;
6203+ current->tty->driver.write(current->tty,0,p,strlen(p));
6204+ current->obvacl = &obv_auth;
6205+ return 0;
6206+}
6207+
6208+static int do_set_proc_acl(struct dentry *dentry, struct vfsmount *mnt, int mode)
6209+{
6210+ struct vfsmount *parent;
6211+ struct nameidata tmp = {NULL, NULL};
6212+ struct obv_acl curracl, *retval = NULL;
6213+ struct dentry *curr = dentry;
6214+
6215+
6216+ switch(mode) {
6217+ case OBV_SET_AUTH:
6218+ return obv_chk_auth(dentry,mnt);
6219+ break;
6220+ case OBV_SET_INHERIT:
6221+ return obv_chk_inherit(dentry,mnt);
6222+ break;
6223+ case OBV_SET_PROC:
6224+ break;
6225+ default :
6226+ obv_seclog("BUG! Received unknown mode %d for set_proc_acl\n",mode);
6227+ return (unsigned long)NULL;
6228+ break;
6229+ }
6230+ /* Okay now we handle OBV_SET_PROC */
6231+loop:
6232+ do {
6233+
6234+ if(!curr || !curr->d_inode) break;
6235+ curracl.file_inode = curr->d_inode->i_ino;
6236+ curracl.file_dev = curr->d_inode->i_dev;
6237+ retval = do_obv_find_proc(&curracl);
6238+ if(curr->d_inode == curr->d_parent->d_inode) break;
6239+ curr = curr->d_parent;
6240+ } while( (curr) && (!retval) );
6241+ if(!retval && curr->d_inode && curr->d_inode->i_dev != ROOT_DEV) {
6242+ if(tmp.mnt) {
6243+ if(tmp.mnt == tmp.mnt->mnt_parent)
6244+ goto exit;
6245+ }
6246+ else if(mnt == mnt->mnt_parent)
6247+ goto exit;
6248+
6249+ if(!tmp.mnt) {
6250+ tmp.mnt = mnt->mnt_parent;
6251+ tmp.dentry = dget(mnt->mnt_mountpoint);
6252+
6253+ }
6254+
6255+ else {
6256+ parent = tmp.mnt->mnt_parent;
6257+ dput(tmp.dentry);
6258+ tmp.dentry = dget(tmp.mnt->mnt_mountpoint);
6259+ mntput(tmp.mnt);
6260+ tmp.mnt = parent;
6261+ }
6262+ mntget(tmp.mnt);
6263+ curr = tmp.dentry;
6264+ goto loop;
6265+ }
6266+exit:
6267+ if(tmp.mnt) mntput(tmp.mnt);
6268+ if(tmp.dentry) dput(tmp.dentry);
6269+
6270+ return (unsigned long)retval;
6271+
6272+}
6273+
6274+static int do_obv_inherit(void)
6275+{
6276+ return 0;
6277+ /* Note: for copying due to fork() we use the code the oblivin code in
6278+ * kernel/fork.c. If we're inheriting then our current ACL
6279+ * (that of the program calling execve) is the ACL we inherit,
6280+ * so no work needs to be done. Just return success
6281+ */
6282+}
6283+
6284+
6285+int obv_set_proc_acl(struct dentry *dentry,struct task_struct *tsk,char *filename, struct vfsmount *mnt)
6286+{
6287+ struct obv_acl *temp = NULL;
6288+ if(obv_status & OBV_READY) {
6289+ if(current->obvacl) {
6290+ if(do_set_proc_acl(dentry,mnt,OBV_SET_INHERIT))
6291+ return do_obv_inherit();
6292+
6293+ else if(do_set_proc_acl(dentry,mnt,OBV_SET_AUTH))
6294+ return obv_do_auth();
6295+ }
6296+ temp = (struct obv_acl *)do_set_proc_acl(dentry,mnt,OBV_SET_PROC);
6297+ }
6298+ tsk->obvacl = temp;
6299+ if(tsk->obvacl)
6300+ tsk->cap_permitted = tsk->cap_effective = tsk->obvacl->file_caps;
6301+ return 0;
6302+}
6303+
6304+
6305+void obv_exit(struct task_struct *tsk)
6306+{
6307+ tsk->obvacl = NULL;
6308+}
6309+
6310+static int obv_chcaps(struct obv_pw *entry)
6311+{
6312+ char *p = entry->extra;
6313+ char *q;
6314+ char *mode;
6315+ p[OBV_MAX_EXTRA_LEN-1] = '\0'; /* take no chances*/
6316+ while( (q = memscan(p,'\n',strlen(p))) != p + strlen(p)) {
6317+ mode = p++;
6318+ *q++ = '\0';
6319+ switch(*mode) {
6320+ case '+' :
6321+ cap_bset |= cap_t(obv_cap_conv(p));
6322+ break;
6323+ case '-' :
6324+ cap_bset &= ~cap_t(obv_cap_conv(p));
6325+ break;
6326+ default:
6327+ break;
6328+ }
6329+ p = q;
6330+ }
6331+#ifdef CONFIG_OBV_DEBUG
6332+ obv_seclog("cap bset is now %x\n",cap_bset);
6333+#endif
6334+ return 0;
6335+}
6336+
6337+/* The following variables are needed for timer manipulation */
6338+static struct timer_list obv_badpw;
6339+static int failures = 0;
6340+static int during_wait = 0;
6341+
6342+static void obv_timer(unsigned long ignored)
6343+{
6344+ failures = 0;
6345+ during_wait = 0;
6346+ del_timer(&obv_badpw);
6347+}
6348+
6349+int obv_proc_handler(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp)
6350+{
6351+ /* This is the main todo. simply I allow disabling oblivion only
6352+ * at bootup(after its turned on). I don't have time today to
6353+ * impelement a good pw scheme. The first thing I do when I get back is to do that.
6354+ */
6355+ struct obv_pw *usermode = (struct obv_pw *) buffer;
6356+ int error = sizeof(struct obv_pw);
6357+ if(*lenp != sizeof(struct obv_pw)){
6358+ obv_seclog("Proc handler: being fed garbage %d byte send %d required\n",*lenp,sizeof(struct obv_pw));
6359+ return -EINVAL;
6360+ }
6361+ if(during_wait) return -EPERM;
6362+ switch (usermode->mode){
6363+ case OBV_SHUTDOWN_MODE:
6364+ if(!(obv_chkpw(usermode))) {
6365+ obv_seclog("shutdown auth success for "
6366+ "(%.16s:%d), UID(%d), EUID(%d), parent "
6367+ "(%.16s:%d), UID(%d), EUID(%d)\n",
6368+ current->comm,current->pid,current->uid,
6369+ current->euid,current->p_pptr->comm,
6370+ current->p_pptr->pid,current->p_pptr->uid,
6371+ current->p_pptr->euid);
6372+ spin_lock(&obv_lock);
6373+ obv_status &= ~OBV_READY;
6374+ obv_status |= OBV_DISABLED;
6375+ spin_unlock(&obv_lock);
6376+ break;
6377+ } else
6378+ error = -EPERM;
6379+ break;
6380+ case OBV_ENABLE_MODE:
6381+ if(obv_disable) {
6382+ obv_seclog("Disabled at boot time, ignoring load request\n");
6383+ break;
6384+ }
6385+ else if(obv_status & OBV_1ST) {
6386+ obv_seclog("Loading %.32s\n",OBV_VERSION);
6387+ oblivion_init();
6388+ spin_lock(&obv_lock);
6389+ obv_status &= ~OBV_1ST;
6390+ spin_unlock(&obv_lock);
6391+ break;
6392+ }
6393+ else {
6394+ obv_seclog("%.32s already loaded, re-enabling\n",OBV_VERSION);
6395+ spin_lock(&obv_lock);
6396+ obv_status &= ~OBV_DISABLED;
6397+ obv_status |= OBV_READY;
6398+ spin_unlock(&obv_lock);
6399+ break;
6400+ }
6401+
6402+ case OBV_CHCAPS_MODE :
6403+ if(obv_status & OBV_1ST) {
6404+ oblivion_init();
6405+ }
6406+ if(obv_status & OBV_1ST || !(obv_chkpw(usermode))) {
6407+ if(!(obv_chcaps(usermode))) {
6408+ obv_seclog("successful capability change by "
6409+ "(%.16s:%d), UID(%d), EUID(%d), parent "
6410+ "(%.16s:%d), UID(%d), EUID(%d)\n",
6411+ current->comm,current->pid,current->uid,
6412+ current->euid,current->p_pptr->comm,
6413+ current->p_pptr->pid,current->p_pptr->uid,
6414+ current->p_pptr->euid);
6415+
6416+ }
6417+ obv_status &= ~OBV_1ST;
6418+ }
6419+ else
6420+ error = -EPERM;
6421+ break;
6422+ case OBV_GOD_MODE:
6423+ if(!(obv_chkpw(usermode))) {
6424+ obv_seclog("successful change to admin mode by "
6425+ "(%.16s:%d), UID (%d), EUID (%d), parent "
6426+ "(%.16s:%d), UID (%d), EUID (%d)\n",
6427+ current->comm,current->pid,current->uid,
6428+ current->euid,current->p_pptr->comm,
6429+ current->p_pptr->pid,current->p_pptr->uid,
6430+ current->p_pptr->euid);
6431+ if(current->p_pptr)
6432+ current->p_pptr->obvacl = &obv_god_mode;
6433+ }
6434+ else
6435+ error = -EPERM;
6436+ break;
6437+ case OBV_AUTH_MODE:
6438+ if(!(obv_chkpw(usermode)) ) {
6439+ obv_seclog("successful authentication by "
6440+ "(%.16s:%d), UID (%d), EUID (%d), parent "
6441+ "(%.16s:%d), UID (%d), EUID (%d)\n",
6442+ current->comm,current->pid,current->uid,
6443+ current->euid,current->p_pptr->comm,
6444+ current->p_pptr->pid,current->p_pptr->uid,
6445+ current->p_pptr->euid);
6446+ if(current->p_pptr)
6447+ current->p_pptr->obvacl = NULL;
6448+ /* The parent invoked obvadm, it is the
6449+ * task that we must deal with */
6450+ }
6451+ else
6452+ error = -EPERM;
6453+ break;
6454+
6455+ default:
6456+ obv_seclog("Invalid value %d by "
6457+ "(%.16s:%d), UID(%d), EUID(%d), parent "
6458+ "(%.16s:%d), UID(%d), EUID(%d)\n",usermode->mode,
6459+ current->comm,current->pid,current->uid,
6460+ current->euid,current->p_pptr->comm,
6461+ current->p_pptr->pid,current->p_pptr->uid,
6462+ current->p_pptr->euid);
6463+ break;
6464+ }
6465+
6466+ if(error < 0) {
6467+ failures++;
6468+ if(failures > CONFIG_OBV_MAXTRIES) {
6469+ obv_seclog("Maximum pw attempts reached, locking "
6470+ "password authentication\n");
6471+ init_timer(&obv_badpw);
6472+ obv_badpw.data = 0;
6473+ obv_badpw.function = obv_timer;
6474+ obv_badpw.expires = jiffies + CONFIG_OBV_TIMEOUT*HZ;
6475+ add_timer(&obv_badpw);
6476+ during_wait = 1;
6477+ }
6478+ }
6479+
6480+ return error;
6481+}
6482diff -urN linux/kernel/obvhash.c linux.grsec/kernel/obvhash.c
6483--- linux/kernel/obvhash.c Thu Jan 1 01:00:00 1970
6484+++ linux.grsec/kernel/obvhash.c Sun Sep 30 01:54:20 2001
6485@@ -0,0 +1,160 @@
6486+#include <linux/kernel.h>
6487+#include <linux/types.h>
6488+#include <linux/fs.h>
6489+#include <linux/capability.h>
6490+#include <linux/oblivion.h>
6491+
6492+/*
6493+Modified for use in OPM by Michael Dalton <michael@linux.com>
6494+Modified for kerneli by Andrew McDonald <andrew@mcdonald.org.uk>
6495+from:
6496+
6497+SHA-1 in C
6498+By Steve Reid <steve@edmweb.com>
6499+100% Public Domain
6500+Available from:
6501+ftp://ftp.zedz.net/pub/crypto/crypto/HASH/sha/sha1.c
6502+
6503+Test Vectors (from FIPS PUB 180-1)
6504+"abc"
6505+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
6506+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
6507+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
6508+A million repetitions of "a"
6509+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
6510+*/
6511+
6512+
6513+extern struct obv_pw obv_pwent;
6514+
6515+void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
6516+{
6517+ unsigned long a, b, c, d, e;
6518+ typedef union {
6519+ unsigned char c[64];
6520+ unsigned long l[16];
6521+ } CHAR64LONG16;
6522+ CHAR64LONG16* block;
6523+#ifdef SHA1HANDSOFF
6524+ static unsigned char workspace[64];
6525+ block = (CHAR64LONG16*)workspace;
6526+ memcpy(block, buffer, 64);
6527+#else
6528+ block = (CHAR64LONG16*)buffer;
6529+#endif
6530+ /* Copy context->state[] to working vars */
6531+ a = state[0];
6532+ b = state[1];
6533+ c = state[2];
6534+ d = state[3];
6535+ e = state[4];
6536+ /* 4 rounds of 20 operations each. Loop unrolled. */
6537+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
6538+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
6539+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
6540+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
6541+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
6542+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
6543+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
6544+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
6545+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
6546+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
6547+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
6548+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
6549+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
6550+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
6551+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
6552+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
6553+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
6554+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
6555+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
6556+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
6557+ /* Add the working vars back into context.state[] */
6558+ state[0] += a;
6559+ state[1] += b;
6560+ state[2] += c;
6561+ state[3] += d;
6562+ state[4] += e;
6563+ /* Wipe variables */
6564+ a = b = c = d = e = 0;
6565+}
6566+
6567+
6568+/* SHA1Init - Initialize new context */
6569+
6570+void SHA1Init(struct SHA1_CTX* context)
6571+{
6572+ /* SHA1 initialization constants */
6573+ context->state[0] = 0x67452301;
6574+ context->state[1] = 0xEFCDAB89;
6575+ context->state[2] = 0x98BADCFE;
6576+ context->state[3] = 0x10325476;
6577+ context->state[4] = 0xC3D2E1F0;
6578+ context->count[0] = context->count[1] = 0;
6579+}
6580+
6581+
6582+/* Run your data through this. */
6583+
6584+void SHA1Update(struct SHA1_CTX* context, unsigned char* data, unsigned int len)
6585+{
6586+ unsigned int i, j;
6587+
6588+ j = (context->count[0] >> 3) & 63;
6589+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
6590+ context->count[1] += (len >> 29);
6591+ if ((j + len) > 63) {
6592+ memcpy(&context->buffer[j], data, (i = 64-j));
6593+ SHA1Transform(context->state, context->buffer);
6594+ for ( ; i + 63 < len; i += 64) {
6595+ SHA1Transform(context->state, &data[i]);
6596+ }
6597+ j = 0;
6598+ }
6599+ else i = 0;
6600+ memcpy(&context->buffer[j], &data[i], len - i);
6601+}
6602+
6603+
6604+/* Add padding and return the message digest. */
6605+
6606+void SHA1Final(unsigned char digest[20], struct SHA1_CTX* context)
6607+{
6608+ unsigned long i, j;
6609+ unsigned char finalcount[8];
6610+
6611+ for (i = 0; i < 8; i++) {
6612+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
6613+ >> ((3-(i & 3)) * 8) ) & 255);
6614+ /* Endian independent */
6615+ }
6616+ SHA1Update(context, (unsigned char *)"\200", 1);
6617+ while ((context->count[0] & 504) != 448) {
6618+ SHA1Update(context, (unsigned char *)"\0", 1);
6619+ }
6620+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
6621+ for (i = 0; i < 20; i++) {
6622+ digest[i] = (unsigned char)
6623+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
6624+ }
6625+ /* Wipe variables */
6626+ i = j = 0;
6627+ memset(context->buffer, 0, 64);
6628+ memset(context->state, 0, 20);
6629+ memset(context->count, 0, 8);
6630+ memset(&finalcount, 0, 8);
6631+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
6632+ SHA1Transform(context->state, context->buffer);
6633+#endif
6634+}
6635+
6636+int obv_chkpw(struct obv_pw *entry)
6637+{
6638+ struct SHA1_CTX context;
6639+ char *pos = memscan(entry->pw,'\n',strlen(entry->pw));
6640+ if(pos != entry->pw + strlen(entry->pw)) *pos = '\0';
6641+ SHA1Init(&context);
6642+ SHA1Update(&context,entry->pw,strlen(entry->pw));
6643+ SHA1Final(entry->sum,&context);
6644+ return memcmp(obv_pwent.sum,entry->sum,OBV_SHASUM_SIZE);
6645+}
6646diff -urN linux/kernel/obvqsort.c linux.grsec/kernel/obvqsort.c
6647--- linux/kernel/obvqsort.c Thu Jan 1 01:00:00 1970
6648+++ linux.grsec/kernel/obvqsort.c Sun Sep 30 01:54:20 2001
6649@@ -0,0 +1,229 @@
6650+/* * * * * * * * * * * * * * * * * * * * * * * * *
6651+ * The following code is a slightly modified qsort found in glibc
6652+ * The best implementation for a non-recursive qsort around
6653+ * that I could find, and probably
6654+ * better than what I would have come up with=)
6655+ * * * * * * * * * * * * * * * * * * * * * * * * */
6656+#include <linux/kernel.h>
6657+#include <linux/types.h>
6658+#include <linux/malloc.h>
6659+
6660+
6661+
6662+/* Byte-wise swap two items of size SIZE. */
6663+#define SWAP(a, b, size) \
6664+ do \
6665+ { \
6666+ register size_t __size = (size); \
6667+ register char *__a = (a), *__b = (b); \
6668+ do \
6669+ { \
6670+ char __tmp = *__a; \
6671+ *__a++ = *__b; \
6672+ *__b++ = __tmp; \
6673+ } while (--__size > 0); \
6674+ } while (0)
6675+
6676+/* Discontinue quicksort algorithm when partition gets below this size.
6677+ This particular magic number was chosen to work best on a Sun 4/260. */
6678+#define MAX_THRESH 4
6679+
6680+/* Stack node declarations used to store unfulfilled partition obligations. */
6681+typedef struct
6682+ {
6683+ char *lo;
6684+ char *hi;
6685+ } stack_node;
6686+
6687+/* The next 4 #defines implement a very fast in-line stack abstraction. */
6688+#define STACK_SIZE (8 * sizeof(unsigned long int))
6689+#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
6690+#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
6691+#define STACK_NOT_EMPTY (stack < top)
6692+
6693+
6694+/* Order size using quicksort. This implementation incorporates
6695+ four optimizations discussed in Sedgewick:
6696+
6697+ 1. Non-recursive, using an explicit stack of pointer that store the
6698+ next array partition to sort. To save time, this maximum amount
6699+ of space required to store an array of MAX_INT is allocated on the
6700+ stack. Assuming a 32-bit integer, this needs only 32 *
6701+ sizeof(stack_node) == 136 bits. Pretty cheap, actually.
6702+
6703+ 2. Chose the pivot element using a median-of-three decision tree.
6704+ This reduces the probability of selecting a bad pivot value and
6705+ eliminates certain extraneous comparisons.
6706+
6707+ 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
6708+ insertion sort to order the MAX_THRESH items within each partition.
6709+ This is a big win, since insertion sort is faster for small, mostly
6710+ sorted array segments.
6711+
6712+ 4. The larger of the two sub-partitions is always pushed onto the
6713+ stack first, with the algorithm then concentrating on the
6714+ smaller partition. This *guarantees* no more than log (n)
6715+ stack size is needed (actually O(1) in this case)! */
6716+
6717+
6718+void obv_qsort (void *pbase, size_t total_elems, size_t size, int (*cmp) (const void *, const void*))
6719+{
6720+ register char *base_ptr = (char *) pbase;
6721+
6722+ /* Allocating SIZE bytes for a pivot buffer facilitates a better
6723+ algorithm below since we can do comparisons directly on the pivot. */
6724+ char *pivot_buffer = (char *) kmalloc(size,GFP_KERNEL);
6725+ const size_t max_thresh = MAX_THRESH * size;
6726+
6727+ if (total_elems == 0)
6728+ /* Avoid lossage with unsigned arithmetic below. */
6729+ return;
6730+
6731+ if (total_elems > MAX_THRESH)
6732+ {
6733+ char *lo = base_ptr;
6734+ char *hi = &lo[size * (total_elems - 1)];
6735+ /* Largest size needed for 32-bit int!!! */
6736+ stack_node stack[STACK_SIZE];
6737+ stack_node *top = stack + 1;
6738+
6739+ while (STACK_NOT_EMPTY)
6740+ {
6741+ char *left_ptr;
6742+ char *right_ptr;
6743+
6744+ char *pivot = pivot_buffer;
6745+
6746+ /* Select median value from among LO, MID, and HI. Rearrange
6747+ LO and HI so the three values are sorted. This lowers the
6748+ probability of picking a pathological pivot value and
6749+ skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
6750+
6751+ char *mid = lo + size * ((hi - lo) / size >> 1);
6752+
6753+ if ((*cmp) ((void *) mid, (void *) lo) < 0)
6754+ SWAP (mid, lo, size);
6755+ if ((*cmp) ((void *) hi, (void *) mid) < 0)
6756+ SWAP (mid, hi, size);
6757+ else
6758+ goto jump_over;
6759+ if ((*cmp) ((void *) mid, (void *) lo) < 0)
6760+ SWAP (mid, lo, size);
6761+ jump_over:;
6762+ memcpy (pivot, mid, size);
6763+ pivot = pivot_buffer;
6764+
6765+ left_ptr = lo + size;
6766+ right_ptr = hi - size;
6767+
6768+ /* Here's the famous ``collapse the walls'' section of quicksort.
6769+ Gotta like those tight inner loops! They are the main reason
6770+ that this algorithm runs much faster than others. */
6771+ do
6772+ {
6773+ while ((*cmp) ((void *) left_ptr, (void *) pivot) < 0)
6774+ left_ptr += size;
6775+
6776+ while ((*cmp) ((void *) pivot, (void *) right_ptr) < 0)
6777+ right_ptr -= size;
6778+
6779+ if (left_ptr < right_ptr)
6780+ {
6781+ SWAP (left_ptr, right_ptr, size);
6782+ left_ptr += size;
6783+ right_ptr -= size;
6784+ }
6785+ else if (left_ptr == right_ptr)
6786+ {
6787+ left_ptr += size;
6788+ right_ptr -= size;
6789+ break;
6790+ }
6791+ }
6792+ while (left_ptr <= right_ptr);
6793+
6794+ /* Set up pointers for next iteration. First determine whether
6795+ left and right partitions are below the threshold size. If so,
6796+ ignore one or both. Otherwise, push the larger partition's
6797+ bounds on the stack and continue sorting the smaller one. */
6798+
6799+ if ((size_t) (right_ptr - lo) <= max_thresh)
6800+ {
6801+ if ((size_t) (hi - left_ptr) <= max_thresh)
6802+ /* Ignore both small partitions. */
6803+ POP (lo, hi);
6804+ else
6805+ /* Ignore small left partition. */
6806+ lo = left_ptr;
6807+ }
6808+ else if ((size_t) (hi - left_ptr) <= max_thresh)
6809+ /* Ignore small right partition. */
6810+ hi = right_ptr;
6811+ else if ((right_ptr - lo) > (hi - left_ptr))
6812+ {
6813+ /* Push larger left partition indices. */
6814+ PUSH (lo, right_ptr);
6815+ lo = left_ptr;
6816+ }
6817+ else
6818+ {
6819+ /* Push larger right partition indices. */
6820+ PUSH (left_ptr, hi);
6821+ hi = right_ptr;
6822+ }
6823+ }
6824+ }
6825+ kfree(pivot_buffer);
6826+
6827+ /* Once the BASE_PTR array is partially sorted by quicksort the rest
6828+ is completely sorted using insertion sort, since this is efficient
6829+ for partitions below MAX_THRESH size. BASE_PTR points to the beginning
6830+ of the array to sort, and END_PTR points at the very last element in
6831+ the array (*not* one beyond it!). */
6832+
6833+
6834+ {
6835+ char *const end_ptr = &base_ptr[size * (total_elems - 1)];
6836+ char *tmp_ptr = base_ptr;
6837+ char *thresh = min(end_ptr, base_ptr + max_thresh);
6838+ register char *run_ptr;
6839+
6840+ /* Find smallest element in first threshold and place it at the
6841+ array's beginning. This is the smallest array element,
6842+ and the operation speeds up insertion sort's inner loop. */
6843+
6844+ for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
6845+ if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0)
6846+ tmp_ptr = run_ptr;
6847+
6848+ if (tmp_ptr != base_ptr)
6849+ SWAP (tmp_ptr, base_ptr, size);
6850+
6851+ /* Insertion sort, running from left-hand-side up to right-hand-side. */
6852+
6853+ run_ptr = base_ptr + size;
6854+ while ((run_ptr += size) <= end_ptr)
6855+ {
6856+ tmp_ptr = run_ptr - size;
6857+ while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0)
6858+ tmp_ptr -= size;
6859+
6860+ tmp_ptr += size;
6861+ if (tmp_ptr != run_ptr)
6862+ {
6863+ char *trav;
6864+
6865+ trav = run_ptr + size;
6866+ while (--trav >= run_ptr)
6867+ {
6868+ char c = *trav;
6869+ char *hi, *lo;
6870+
6871+ for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
6872+ *hi = *lo;
6873+ *hi = c;
6874+ }
6875+ }
6876+ }
6877+ }
6878+}
6879diff -urN linux/kernel/signal.c linux.grsec/kernel/signal.c
6880--- linux/kernel/signal.c Thu Jan 4 05:45:26 2001
6881+++ linux.grsec/kernel/signal.c Sun Sep 30 01:54:20 2001
6882@@ -16,6 +16,21 @@
6883
6884 #include <asm/uaccess.h>
6885
6886+#if defined(CONFIG_GRKERNSEC_SIGNAL)||defined(CONFIG_GRKERNSEC_CHROOT)
6887+#include <linux/grsecurity.h>
6888+#endif
6889+
6890+#ifdef CONFIG_OBV_PROC
6891+#include <linux/fs.h>
6892+#include <linux/obvext.h>
6893+#endif
6894+
6895+
6896+
6897+#ifdef CONFIG_GRKERNSEC_CHROOT
6898+extern struct task_struct *child_reaper;
6899+#endif
6900+
6901 /*
6902 * SLAB caches for signal bits.
6903 */
6904@@ -518,7 +533,31 @@
6905 ret = -EPERM;
6906 if (bad_signal(sig, info, t))
6907 goto out_nolock;
6908-
6909+#ifdef CONFIG_GRKERNSEC_CHROOT
6910+ if( t->pid && current->pid && child_reaper && child_reaper->pid && current->fs && current->pid > 1
6911+ && sig && grsec_enable_chroot &&
6912+ !( sig == SIGALRM || sig == SIGIO ||
6913+ ((current->fs->root->d_inode->i_dev ==
6914+ child_reaper->fs->root->d_inode->i_dev) &&
6915+ (current->fs->root->d_inode->i_ino ==
6916+ child_reaper->fs->root->d_inode->i_ino)) ||
6917+ ((t->fs->root->d_inode->i_dev ==
6918+ current->fs->root->d_inode->i_dev) &&
6919+ (t->fs->root->d_inode->i_ino ==
6920+ current->fs->root->d_inode->i_ino)) ||
6921+ (t->pid == current->p_pptr->pid && sig == SIGCHLD) ) ) {
6922+ security_alert("denied signal %d out of chroot() jail (%.32s:%lu) of %d.%d "
6923+ "by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d) "
6924+ "to (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d)",
6925+ "denied signals in chroot()",sig,kdevname(current->fs->root->d_inode->i_dev),
6926+ current->fs->root->d_inode->i_ino,current->fs->root->d_inode->i_uid,
6927+ current->fs->root->d_inode->i_gid,current->comm,current->pid,current->uid,
6928+ current->euid,current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
6929+ current->p_pptr->euid,t->comm,t->pid,t->uid,t->euid,t->p_pptr->comm,
6930+ t->p_pptr->pid,t->p_pptr->uid,t->p_pptr->euid);
6931+ goto out_nolock;
6932+ }
6933+#endif
6934 /* The null signal is a permissions and process existance probe.
6935 No signal is actually delivered. Same goes for zombies. */
6936 ret = 0;
6937@@ -528,6 +567,25 @@
6938 spin_lock_irqsave(&t->sigmask_lock, flags);
6939 handle_stop_signal(sig, t);
6940
6941+#ifdef CONFIG_GRKERNSEC_SIGNAL
6942+ if(grsec_enable_signal && (
6943+ (sig == SIGSEGV) || (sig == SIGILL) || (sig == SIGABRT) || (sig == SIGBUS))) {
6944+ if(t->pid == current->pid) {
6945+ security_alert("signal %d sent to (%.16s:%d), UID (%d), EUID (%d), "
6946+ "parent (%.16s:%d), UID (%d), EUID (%d)","signal warnings",sig,
6947+ t->comm,t->pid,t->uid,t->euid,t->p_pptr->comm,t->p_pptr->pid,
6948+ t->p_pptr->uid,t->p_pptr->euid);
6949+ } else {
6950+ security_alert("signal %d sent to (%.16s:%d), UID (%d), EUID (%d), "
6951+ "parent (%.16s:%d), UID (%d), EUID (%d) by (%.16s:%d), UID (%d), EUID (%d), "
6952+ "parent (%.16s:%d), UID (%d), EUID (%d)","signal warnings",
6953+ sig,t->comm,t->pid,t->uid,t->euid,t->p_pptr->comm,t->p_pptr->pid,
6954+ t->p_pptr->uid,t->p_pptr->euid,current->comm,current->pid,
6955+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
6956+ current->p_pptr->uid,current->p_pptr->euid);
6957+ }
6958+ }
6959+#endif
6960 /* Optimize away the signal, if it's a signal that can be
6961 handled immediately (ie non-blocked and untraced) and
6962 that is ignored (either explicitly or by default). */
6963@@ -980,6 +1038,22 @@
6964 sys_kill(int pid, int sig)
6965 {
6966 struct siginfo info;
6967+
6968+#ifdef CONFIG_OBV_PROC
6969+ struct task_struct *tsk = find_task_by_pid(pid);
6970+ if(tsk && tsk->obvacl) {
6971+ if( (obv_check_protected(tsk)) ) {
6972+ if(current->pid > 1) {
6973+#ifdef CONFIG_OBV_DEBUG
6974+ obv_seclog("protected proc: returning EPERM, not init\n");
6975+ /* Allow init to kill for shutdown purposes*/
6976+#endif
6977+ return -EPERM;
6978+ }
6979+ }
6980+ }
6981+#endif
6982+
6983
6984 info.si_signo = sig;
6985 info.si_errno = 0;
6986diff -urN linux/kernel/sys.c linux.grsec/kernel/sys.c
6987--- linux/kernel/sys.c Fri Jul 20 05:34:31 2001
6988+++ linux.grsec/kernel/sys.c Sun Sep 30 01:54:20 2001
6989@@ -4,6 +4,7 @@
6990 * Copyright (C) 1991, 1992 Linus Torvalds
6991 */
6992
6993+#include <linux/config.h>
6994 #include <linux/module.h>
6995 #include <linux/mm.h>
6996 #include <linux/utsname.h>
6997@@ -18,6 +19,10 @@
6998 #include <asm/uaccess.h>
6999 #include <asm/io.h>
7000
7001+#ifdef CONFIG_GRKERNSEC_SUID
7002+#include <linux/grsecurity.h>
7003+#endif
7004+
7005 /*
7006 * this is where the system-wide overflow UID and GID are defined, for
7007 * architectures that now have 32-bit UID/GID but didn't in the past
7008@@ -378,6 +383,13 @@
7009 int old_egid = current->egid;
7010 int new_rgid = old_rgid;
7011 int new_egid = old_egid;
7012+#ifdef CONFIG_GRKERNSEC_SUID
7013+ if(grsec_enable_suid)
7014+ printk(KERN_INFO "grsecurity: setregid(rgid=%d/egid=%d) by (%.16s:%d),UID(%d), EUID(%d), parent (%.16s:%d), "
7015+ "UID(%d), EUID(%d)\n",rgid,egid,current->comm,current->pid,
7016+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7017+ current->p_pptr->uid,current->p_pptr->euid);
7018+#endif
7019
7020 if (rgid != (gid_t) -1) {
7021 if ((old_rgid == rgid) ||
7022@@ -419,6 +431,13 @@
7023 asmlinkage long sys_setgid(gid_t gid)
7024 {
7025 int old_egid = current->egid;
7026+#ifdef CONFIG_GRKERNSEC_SUID
7027+ if(grsec_enable_suid)
7028+ printk(KERN_INFO "grsecurity: setgid(%d) by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
7029+ "UID(%d), EUID(%d)\n",gid,current->comm,current->pid,
7030+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7031+ current->p_pptr->uid,current->p_pptr->euid);
7032+#endif
7033
7034 if (capable(CAP_SETGID))
7035 {
7036@@ -538,6 +557,13 @@
7037 new_ruid = old_ruid = current->uid;
7038 new_euid = old_euid = current->euid;
7039 old_suid = current->suid;
7040+#ifdef CONFIG_GRKERNSEC_SUID
7041+ if(grsec_enable_suid)
7042+ printk(KERN_INFO "grsecurity: setreuid(ruid=%d/euid=%d) by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
7043+ "UID(%d), EUID(%d)\n",ruid,euid,current->comm,current->pid,
7044+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7045+ current->p_pptr->uid,current->p_pptr->euid);
7046+#endif
7047
7048 if (ruid != (uid_t) -1) {
7049 new_ruid = ruid;
7050@@ -598,7 +624,13 @@
7051 old_ruid = new_ruid = current->uid;
7052 old_suid = current->suid;
7053 new_suid = old_suid;
7054-
7055+#ifdef CONFIG_GRKERNSEC_SUID
7056+ if(grsec_enable_suid)
7057+ printk(KERN_INFO "grsecurity: setuid(%d) by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
7058+ "UID(%d), EUID(%d)\n",uid,current->comm,current->pid,
7059+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7060+ current->p_pptr->uid,current->p_pptr->euid);
7061+#endif
7062 if (capable(CAP_SETUID)) {
7063 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
7064 return -EAGAIN;
7065@@ -631,6 +663,13 @@
7066 int old_ruid = current->uid;
7067 int old_euid = current->euid;
7068 int old_suid = current->suid;
7069+#ifdef CONFIG_GRKERNSEC_SUID
7070+ if(grsec_enable_suid)
7071+ printk(KERN_INFO "grsecurity: setresuid(ruid=%d/suid=%d/euid=%d) by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
7072+ "UID(%d), EUID(%d)\n",ruid,suid,euid,current->comm,current->pid,
7073+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7074+ current->p_pptr->uid,current->p_pptr->euid);
7075+#endif
7076
7077 if (!capable(CAP_SETUID)) {
7078 if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
7079@@ -682,6 +721,14 @@
7080 */
7081 asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
7082 {
7083+#ifdef CONFIG_GRKERNSEC_SUID
7084+ if(grsec_enable_suid)
7085+ printk(KERN_INFO "grsecurity: setresgid(rgid=%d/sgid=%d/egid=%d) by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
7086+ "UID(%d), EUID(%d)\n",rgid,sgid,egid,current->comm,current->pid,
7087+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7088+ current->p_pptr->uid,current->p_pptr->euid);
7089+#endif
7090+
7091 if (!capable(CAP_SETGID)) {
7092 if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
7093 (rgid != current->egid) && (rgid != current->sgid))
7094@@ -730,6 +777,13 @@
7095 asmlinkage long sys_setfsuid(uid_t uid)
7096 {
7097 int old_fsuid;
7098+#ifdef CONFIG_GRKERNSEC_SUID
7099+ if(grsec_enable_suid)
7100+ printk(KERN_INFO "grsecurity: setfsuid(%d) by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
7101+ "UID(%d), EUID(%d)\n",uid,current->comm,current->pid,
7102+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7103+ current->p_pptr->uid,current->p_pptr->euid);
7104+#endif
7105
7106 old_fsuid = current->fsuid;
7107 if (uid == current->uid || uid == current->euid ||
7108@@ -772,6 +826,13 @@
7109 asmlinkage long sys_setfsgid(gid_t gid)
7110 {
7111 int old_fsgid;
7112+#ifdef CONFIG_GRKERNSEC_SUID
7113+ if(grsec_enable_suid)
7114+ printk(KERN_INFO "grsecurity: setfsgid(%d) by (%.16s:%d), UID(%d), EUID(%d), parent (%.16s:%d), "
7115+ "UID(%d), EUID(%d)\n",gid,current->comm,current->pid,
7116+ current->uid,current->euid,current->p_pptr->comm,current->p_pptr->pid,
7117+ current->p_pptr->uid,current->p_pptr->euid);
7118+#endif
7119
7120 old_fsgid = current->fsgid;
7121 if (gid == current->gid || gid == current->egid ||
7122diff -urN linux/kernel/sysctl.c linux.grsec/kernel/sysctl.c
7123--- linux/kernel/sysctl.c Sun Sep 30 01:30:58 2001
7124+++ linux.grsec/kernel/sysctl.c Sun Sep 30 01:54:20 2001
7125@@ -34,12 +34,20 @@
7126 #include <linux/highuid.h>
7127 #include <linux/kdb.h>
7128
7129+#include <linux/grsecurity.h>
7130+
7131 #include <asm/uaccess.h>
7132
7133 #ifdef CONFIG_ROOT_NFS
7134 #include <linux/nfs_fs.h>
7135 #endif
7136
7137+#ifdef CONFIG_OBV_PROC
7138+#include <linux/obvext.h>
7139+#endif
7140+
7141+
7142+
7143 #if defined(CONFIG_SYSCTL)
7144
7145 /* External variables not in a header file. */
7146@@ -117,6 +125,9 @@
7147 static ctl_table debug_table[];
7148 static ctl_table dev_table[];
7149 extern ctl_table random_table[];
7150+#ifdef CONFIG_GRKERNSEC_SYSCTL
7151+static ctl_table grsecurity_table[];
7152+#endif
7153
7154 /* /proc declarations: */
7155
7156@@ -265,9 +276,317 @@
7157 {KERN_KDB, "kdb", &kdb_on, sizeof(int),
7158 0644, NULL, &proc_dointvec},
7159 #endif /* CONFIG_KDB */
7160+#ifdef CONFIG_GRKERNSEC_SYSCTL
7161+ {KERN_GRSECURITY, "grsecurity", NULL, 0, 0550, grsecurity_table},
7162+#endif
7163+#ifdef CONFIG_OBV_PROC
7164+ {KERN_OBV,"oblivion",NULL,sizeof(int),0600,NULL,&obv_proc_handler},
7165+#endif
7166+
7167 {0}
7168 };
7169
7170+#ifdef CONFIG_GRKERNSEC_LINK
7171+int grsec_enable_link= -1;
7172+#endif
7173+#ifdef CONFIG_GRKERNSEC_FIFO
7174+int grsec_enable_fifo= -1;
7175+#endif
7176+#ifdef CONFIG_GRKERNSEC_FD
7177+int grsec_enable_fd= -1;
7178+#endif
7179+#ifdef CONFIG_GRKERNSEC_EXECVE
7180+int grsec_enable_execve= -1;
7181+#endif
7182+#ifdef CONFIG_GRKERNSEC_FORKBOMB
7183+int grsec_enable_forkbomb= -1;
7184+#ifdef CONFIG_GRKERNSEC_SYSCTL
7185+int grsec_forkbomb_gid = -1;
7186+int grsec_forkbomb_sec = -1;
7187+int grsec_forkbomb_max = -1;
7188+#else
7189+int grsec_forkbomb_gid = CONFIG_GRKERNSEC_FORKBOMB_GID;
7190+int grsec_forkbomb_sec = CONFIG_GRKERNSEC_FORKBOMB_SEC;
7191+int grsec_forkbomb_max = CONFIG_GRKERNSEC_FORKBOMB_MAX;
7192+#endif
7193+#endif
7194+#ifdef CONFIG_GRKERNSEC_EXECLOG
7195+int grsec_enable_execlog= -1;
7196+#endif
7197+#ifdef CONFIG_GRKERNSEC_SUID
7198+int grsec_enable_suid= -1;
7199+#endif
7200+#ifdef CONFIG_GRKERNSEC_SIGNAL
7201+int grsec_enable_signal= -1;
7202+#endif
7203+#ifdef CONFIG_GRKERNSEC_COREDUMP
7204+int grsec_enable_coredump= -1;
7205+#endif
7206+#ifdef CONFIG_GRKERNSEC_FORKFAIL
7207+int grsec_enable_forkfail= -1;
7208+#endif
7209+#ifdef CONFIG_GRKERNSEC_TIME
7210+int grsec_enable_time= -1;
7211+#endif
7212+#ifdef CONFIG_GRKERNSEC_KBMAP
7213+int grsec_enable_kbmap= -1;
7214+#endif
7215+#ifdef CONFIG_GRKERNSEC_RANDNET
7216+int grsec_enable_randnet= -1;
7217+#endif
7218+#ifdef CONFIG_GRKERNSEC_CHROOT
7219+int grsec_enable_chroot= -1;
7220+#endif
7221+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
7222+int grsec_enable_chroot_execlog= -1;
7223+#endif
7224+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7225+int grsec_enable_chroot_caps= -1;
7226+#endif
7227+#ifdef CONFIG_GRKERNSEC_TPE
7228+int grsec_enable_tpe= -1;
7229+#ifdef CONFIG_GRKERNSEC_SYSCTL
7230+int grsec_tpe_gid= -1;
7231+#else
7232+int grsec_tpe_gid= CONFIG_GRKERNSEC_TPE_GID;
7233+#endif
7234+#ifdef CONFIG_GRKERNSEC_TPE_GLIBC
7235+int grsec_enable_tpe_glibc= -1;
7236+#endif
7237+#ifdef CONFIG_GRKERNSEC_TPE_ALL
7238+int grsec_enable_tpe_all= -1;
7239+#endif
7240+#endif
7241+#ifdef CONFIG_GRKERNSEC_RANDPID
7242+int grsec_enable_randpid= -1;
7243+#endif
7244+#ifdef CONFIG_GRKERNSEC_RANDID
7245+int grsec_enable_randid= -1;
7246+#endif
7247+#ifdef CONFIG_GRKERNSEC_RANDSRC
7248+int grsec_enable_randsrc= -1;
7249+#endif
7250+#ifdef CONFIG_GRKERNSEC_RANDPING
7251+int grsec_enable_randping= -1;
7252+#endif
7253+#ifdef CONFIG_GRKERNSEC_RANDTTL
7254+int grsec_enable_randttl= -1;
7255+#ifdef CONFIG_GRKERNSEC_SYSCTL
7256+int grsec_randttl_thresh= -1;
7257+#else
7258+int grsec_randttl_thresh= CONFIG_GRKERNSEC_RANDTTL_THRESH;
7259+#endif
7260+#endif
7261+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
7262+int grsec_enable_socket_all= -1;
7263+#ifdef CONFIG_GRKERNSEC_SYSCTL
7264+int grsec_socket_all_gid= -1;
7265+#else
7266+int grsec_socket_all_gid= CONFIG_GRKERNSEC_ALL_GID;
7267+#endif
7268+#endif
7269+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
7270+int grsec_enable_socket_client= -1;
7271+#ifdef CONFIG_GRKERNSEC_SYSCTL
7272+int grsec_socket_client_gid= -1;
7273+#else
7274+int grsec_socket_client_gid= CONFIG_GRKERNSEC_CLIENT_GID;
7275+#endif
7276+#endif
7277+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
7278+int grsec_enable_socket_server= -1;
7279+#ifdef CONFIG_GRKERNSEC_SYSCTL
7280+int grsec_socket_server_gid= -1;
7281+#else
7282+int grsec_socket_server_gid= CONFIG_GRKERNSEC_SERVER_GID;
7283+#endif
7284+#endif
7285+#ifdef CONFIG_GRKERNSEC_STEALTH_RST
7286+int grsec_enable_stealth_rst= -1;
7287+#endif
7288+#ifdef CONFIG_GRKERNSEC_STEALTH_UDP
7289+int grsec_enable_stealth_udp= -1;
7290+#endif
7291+#ifdef CONFIG_GRKERNSEC_STEALTH_ICMP
7292+int grsec_enable_stealth_icmp= -1;
7293+#endif
7294+#ifdef CONFIG_GRKERNSEC_STEALTH_IGMP
7295+int grsec_enable_stealth_igmp= -1;
7296+#endif
7297+#ifdef CONFIG_GRKERNSEC_STEALTH_FLAGS
7298+int grsec_enable_stealth_flags= -1;
7299+#endif
7300+
7301+#ifdef CONFIG_GRKERNSEC_SYSCTL
7302+enum {GS_LINK=1,GS_FIFO, GS_FD, GS_EXECVE, GS_FORK,
7303+GS_FORK_GID, GS_FORK_SEC, GS_FORK_MAX, GS_EXECLOG, GS_SUID,
7304+GS_SIGNAL, GS_COREDUMP, GS_FORKFAIL, GS_TIME, GS_KBMAP, GS_RANDNET,
7305+GS_CHROOT, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS, GS_TPE, GS_TPE_GID,
7306+GS_TPE_GLIBC, GS_TPE_ALL, GS_SIDCAPS, GS_RANDPID, GS_RANDID, GS_RANDSRC,
7307+GS_RANDPING, GS_RANDTTL, GS_RANDTTL_THRESH, GS_SOCKET_ALL,
7308+GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT, GS_SOCKET_CLIENT_GID,
7309+GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_STEALTH_RST,
7310+GS_STEALTH_UDP, GS_STEALTH_ICMP, GS_STEALTH_IGMP, GS_STEALTH_FLAGS};
7311+
7312+static ctl_table grsecurity_table[] = {
7313+#ifdef CONFIG_GRKERNSEC_LINK
7314+ {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int),
7315+ 0640, NULL, &proc_dointvec},
7316+#endif
7317+#ifdef CONFIG_GRKERNSEC_FIFO
7318+ {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int),
7319+ 0640, NULL, &proc_dointvec},
7320+#endif
7321+#ifdef CONFIG_GRKERNSEC_FD
7322+ {GS_FD, "secure_fds", &grsec_enable_fd, sizeof (int),
7323+ 0640, NULL, &proc_dointvec},
7324+#endif
7325+#ifdef CONFIG_GRKERNSEC_EXECVE
7326+ {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int),
7327+ 0640, NULL, &proc_dointvec},
7328+#endif
7329+#ifdef CONFIG_GRKERNSEC_FORKBOMB
7330+ {GS_FORK, "fork_bomb_prot", &grsec_enable_forkbomb, sizeof (int),
7331+ 0640, NULL, &proc_dointvec},
7332+ {GS_FORK_GID, "fork_bomb_gid", &grsec_forkbomb_gid, sizeof (int),
7333+ 0640, NULL, &proc_dointvec},
7334+ {GS_FORK_SEC, "fork_bomb_sec", &grsec_forkbomb_sec, sizeof (int),
7335+ 0640, NULL, &proc_dointvec},
7336+ {GS_FORK_MAX, "fork_bomb_max", &grsec_forkbomb_max, sizeof (int),
7337+ 0640, NULL, &proc_dointvec},
7338+#endif
7339+#ifdef CONFIG_GRKERNSEC_EXECLOG
7340+ {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int),
7341+ 0640, NULL, &proc_dointvec},
7342+#endif
7343+#ifdef CONFIG_GRKERNSEC_SUID
7344+ {GS_SUID, "suid_logging", &grsec_enable_suid, sizeof (int),
7345+ 0640, NULL, &proc_dointvec},
7346+#endif
7347+#ifdef CONFIG_GRKERNSEC_SIGNAL
7348+ {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int),
7349+ 0640, NULL, &proc_dointvec},
7350+#endif
7351+#ifdef CONFIG_GRKERNSEC_COREDUMP
7352+ {GS_COREDUMP, "coredump", &grsec_enable_coredump, sizeof (int),
7353+ 0640, NULL, &proc_dointvec},
7354+#endif
7355+#ifdef CONFIG_GRKERNSEC_FORKFAIL
7356+ {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int),
7357+ 0640, NULL, &proc_dointvec},
7358+#endif
7359+#ifdef CONFIG_GRKERNSEC_TIME
7360+ {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int),
7361+ 0640, NULL, &proc_dointvec},
7362+#endif
7363+#ifdef CONFIG_GRKERNSEC_KBMAP
7364+ {GS_KBMAP, "secure_kbmap", &grsec_enable_kbmap, sizeof (int),
7365+ 0640, NULL, &proc_dointvec},
7366+#endif
7367+#ifdef CONFIG_GRKERNSEC_RANDNET
7368+ {GS_RANDNET, "rand_net", &grsec_enable_randnet, sizeof (int),
7369+ 0640, NULL, &proc_dointvec},
7370+#endif
7371+#ifdef CONFIG_GRKERNSEC_CHROOT
7372+ {GS_CHROOT, "chroot_restrictions", &grsec_enable_chroot, sizeof (int),
7373+ 0640, NULL, &proc_dointvec},
7374+#endif
7375+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
7376+ {GS_CHROOT_EXECLOG, "chroot_execlog",
7377+ &grsec_enable_chroot_execlog, sizeof (int),
7378+ 0640, NULL, &proc_dointvec},
7379+#endif
7380+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7381+ {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int),
7382+ 0640, NULL, &proc_dointvec},
7383+#endif
7384+#ifdef CONFIG_GRKERNSEC_TPE
7385+ {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int),
7386+ 0640, NULL, &proc_dointvec},
7387+ {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int),
7388+ 0640, NULL, &proc_dointvec},
7389+#endif
7390+#ifdef CONFIG_GRKERNSEC_TPE_GLIBC
7391+ {GS_TPE_GLIBC, "tpe_glibc", &grsec_enable_tpe_glibc, sizeof (int),
7392+ 0640, NULL, &proc_dointvec},
7393+#endif
7394+#ifdef CONFIG_GRKERNSEC_TPE_ALL
7395+ {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int),
7396+ 0640, NULL, &proc_dointvec},
7397+#endif
7398+#ifdef CONFIG_GRKERNSEC_RANDPID
7399+ {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int),
7400+ 0640, NULL, &proc_dointvec},
7401+#endif
7402+#ifdef CONFIG_GRKERNSEC_RANDID
7403+ {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int),
7404+ 0640, NULL, &proc_dointvec},
7405+#endif
7406+#ifdef CONFIG_GRKERNSEC_RANDSRC
7407+ {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int),
7408+ 0640, NULL, &proc_dointvec},
7409+#endif
7410+#ifdef CONFIG_GRKERNSEC_RANDPING
7411+ {GS_RANDPING, "altered_pings", &grsec_enable_randping, sizeof (int),
7412+ 0640, NULL, &proc_dointvec},
7413+#endif
7414+#ifdef CONFIG_GRKERNSEC_RANDTTL
7415+ {GS_RANDTTL, "rand_ttl", &grsec_enable_randttl, sizeof (int),
7416+ 0640, NULL, &proc_dointvec},
7417+ {GS_RANDTTL_THRESH, "rand_ttl_thresh",
7418+ &grsec_randttl_thresh, sizeof (int),
7419+ 0640, NULL, &proc_dointvec},
7420+#endif
7421+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
7422+ {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int),
7423+ 0640, NULL, &proc_dointvec},
7424+ {GS_SOCKET_ALL_GID, "socket_all_gid",
7425+ &grsec_socket_all_gid, sizeof (int),
7426+ 0640, NULL, &proc_dointvec},
7427+#endif
7428+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
7429+ {GS_SOCKET_CLIENT, "socket_client",
7430+ &grsec_enable_socket_client, sizeof (int),
7431+ 0640, NULL, &proc_dointvec},
7432+ {GS_SOCKET_CLIENT_GID, "socket_client_gid",
7433+ &grsec_socket_client_gid, sizeof (int),
7434+ 0640, NULL, &proc_dointvec},
7435+#endif
7436+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
7437+ {GS_SOCKET_SERVER, "socket_server",
7438+ &grsec_enable_socket_server, sizeof (int),
7439+ 0640, NULL, &proc_dointvec},
7440+ {GS_SOCKET_SERVER_GID, "socket_server_gid",
7441+ &grsec_socket_server_gid, sizeof (int),
7442+ 0640, NULL, &proc_dointvec},
7443+#endif
7444+#ifdef CONFIG_GRKERNSEC_STEALTH_RST
7445+ {GS_STEALTH_RST, "stealth_rst", &grsec_enable_stealth_rst, sizeof (int),
7446+ 0640, NULL, &proc_dointvec},
7447+#endif
7448+#ifdef CONFIG_GRKERNSEC_STEALTH_UDP
7449+ {GS_STEALTH_UDP, "stealth_udp", &grsec_enable_stealth_udp, sizeof (int),
7450+ 0640, NULL, &proc_dointvec},
7451+#endif
7452+#ifdef CONFIG_GRKERNSEC_STEALTH_ICMP
7453+ {GS_STEALTH_ICMP, "stealth_icmp",
7454+ &grsec_enable_stealth_icmp, sizeof (int),
7455+ 0640, NULL, &proc_dointvec},
7456+#endif
7457+#ifdef CONFIG_GRKERNSEC_STEALTH_IGMP
7458+ {GS_STEALTH_IGMP, "stealth_igmp",
7459+ &grsec_enable_stealth_igmp, sizeof (int),
7460+ 0640, NULL, &proc_dointvec},
7461+#endif
7462+#ifdef CONFIG_GRKERNSEC_STEALTH_FLAGS
7463+ {GS_STEALTH_FLAGS, "stealth_flags",
7464+ &grsec_enable_stealth_flags, sizeof (int),
7465+ 0640, NULL, &proc_dointvec},
7466+#endif
7467+ {0}
7468+};
7469+#endif
7470+
7471 static ctl_table vm_table[] = {
7472 {VM_FREEPG, "freepages",
7473 &freepages, sizeof(freepages_t), 0444, NULL, &proc_dointvec},
7474@@ -363,6 +682,7 @@
7475 if (!oldlenp || get_user(old_len, oldlenp))
7476 return -EFAULT;
7477 }
7478+
7479 tmp = &root_table_header.ctl_entry;
7480 do {
7481 struct ctl_table_header *head =
7482@@ -373,6 +693,7 @@
7483 &context);
7484 if (context)
7485 kfree(context);
7486+
7487 if (error != -ENOTDIR)
7488 return error;
7489 tmp = tmp->next;
7490@@ -843,7 +1164,7 @@
7491
7492 #define TMPBUFLEN 20
7493 char buf[TMPBUFLEN], *p;
7494-
7495+
7496 if (!table->data || !table->maxlen || !*lenp ||
7497 (filp->f_pos && !write)) {
7498 *lenp = 0;
7499@@ -851,6 +1172,22 @@
7500 }
7501
7502 i = (int *) table->data;
7503+#ifdef CONFIG_GRKERNSEC_SYSCTL
7504+ if(table->de->parent->name &&
7505+ (strlen(table->de->parent->name) == 10)) {
7506+ if((!strcmp(table->de->parent->name,"grsecurity")) &&
7507+ (write) && (*i != -1)){
7508+ security_alert("attempt to modify grsecurity "
7509+ "sysctl values by (%.16s:%d), UID (%d), EUID (%d), "
7510+ "parent (%.16s:%d), UID (%d), EUID (%d)",
7511+ "attempted sysctl changes",current->comm,current->pid,
7512+ current->uid,current->euid,current->p_pptr->comm,
7513+ current->p_pptr->pid,current->p_pptr->uid,
7514+ current->p_pptr->euid);
7515+ return -EACCES;
7516+ }
7517+ }
7518+#endif
7519 vleft = table->maxlen / sizeof(int);
7520 left = *lenp;
7521
7522diff -urN linux/kernel/time.c linux.grsec/kernel/time.c
7523--- linux/kernel/time.c Mon Oct 16 21:58:51 2000
7524+++ linux.grsec/kernel/time.c Sun Sep 30 01:54:20 2001
7525@@ -29,6 +29,9 @@
7526 #include <linux/smp_lock.h>
7527
7528 #include <asm/uaccess.h>
7529+#ifdef CONFIG_GRKERNSEC_TIME
7530+#include <linux/grsecurity.h>
7531+#endif
7532
7533 /*
7534 * The timezone where the local system is located. Used as a default by some
7535@@ -105,6 +108,13 @@
7536 time_maxerror = NTP_PHASE_LIMIT;
7537 time_esterror = NTP_PHASE_LIMIT;
7538 write_unlock_irq(&xtime_lock);
7539+#ifdef CONFIG_GRKERNSEC_TIME
7540+ if(grsec_enable_time)
7541+ security_alert("time set by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d)",
7542+ "time sets", current->comm,current->pid,current->uid,current->euid,
7543+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
7544+ current->p_pptr->euid);
7545+#endif
7546 return 0;
7547 }
7548
7549@@ -181,6 +191,13 @@
7550 * globally block out interrupts when it runs.
7551 */
7552 do_settimeofday(tv);
7553+#ifdef CONFIG_GRKERNSEC_TIME
7554+ if(grsec_enable_time)
7555+ security_alert("time set by (%.16s:%d), UID (%d), EUID (%d), parent (%.16s:%d), UID (%d), EUID (%d)",
7556+ "time sets", current->comm,current->pid,current->uid,current->euid,
7557+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
7558+ current->p_pptr->euid);
7559+#endif
7560 }
7561 return 0;
7562 }
7563diff -urN linux/mm/mmap.c linux.grsec/mm/mmap.c
7564--- linux/mm/mmap.c Tue Jul 3 21:14:15 2001
7565+++ linux.grsec/mm/mmap.c Sun Sep 30 02:05:24 2001
7566@@ -13,10 +13,15 @@
7567 #include <linux/init.h>
7568 #include <linux/file.h>
7569 #include <linux/fs.h>
7570+#include <linux/random.h>
7571
7572 #include <asm/uaccess.h>
7573 #include <asm/pgalloc.h>
7574
7575+#ifdef CONFIG_GRKERNSEC_STACK
7576+#include <linux/grsecurity.h>
7577+#endif
7578+
7579 /* description of effects of mapping type and prot in current implementation.
7580 * this is due to the limited x86 page protection hardware. The expected
7581 * behavior is in parens:
7582@@ -243,6 +248,24 @@
7583 */
7584 vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
7585
7586+#ifdef CONFIG_GRKERNSEC_PAX
7587+ if (current->flags & PF_PAX_PAGEEXEC) {
7588+ if (flags & MAP_GROWSDOWN)
7589+ vm_flags &= ~VM_EXEC;
7590+
7591+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
7592+ if ((current->flags & PF_PAX_MPROTECT) && !(prot & PROT_EXEC))
7593+ vm_flags &= ~VM_MAYEXEC;
7594+ if ((current->flags & PF_PAX_MPROTECT) && (flags & MAP_GROWSDOWN))
7595+ vm_flags &= ~VM_MAYEXEC;
7596+#endif
7597+
7598+ } else {
7599+ if (prot & (PROT_READ | PROT_WRITE)) /* they imply PROT_EXEC on IA-32 */
7600+ vm_flags |= VM_EXEC;
7601+ }
7602+#endif
7603+
7604 /* mlock MCL_FUTURE? */
7605 if (vm_flags & VM_LOCKED) {
7606 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
7607@@ -406,9 +429,20 @@
7608 if (len > TASK_SIZE)
7609 return -ENOMEM;
7610 if (!addr)
7611+#ifdef CONFIG_GRKERNSEC_STACK
7612+ addr = TASK_UNMAPPED_BASE(len);
7613+#else
7614 addr = TASK_UNMAPPED_BASE;
7615+#endif
7616 addr = PAGE_ALIGN(addr);
7617
7618+
7619+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
7620+ /* PaX: randomize base address if requested */
7621+ if (current->flags & PF_PAX_RANDMMAP) {
7622+ addr += current->mm->delta_mmap;
7623+ }
7624+#endif
7625 for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
7626 /* At this point: (!vma || addr < vma->vm_end). */
7627 if (TASK_SIZE - len < addr)
7628@@ -859,6 +893,17 @@
7629
7630 flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
7631
7632+#ifdef CONFIG_GRKERNSEC_PAX
7633+ if (current->flags & PF_PAX_PAGEEXEC) {
7634+ flags &= ~VM_EXEC;
7635+
7636+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
7637+ if (current->flags & PF_PAX_MPROTECT)
7638+ flags &= ~VM_MAYEXEC;
7639+#endif
7640+ }
7641+#endif
7642+
7643 /* Can we just expand an old anonymous mapping? */
7644 if (addr) {
7645 struct vm_area_struct * vma = find_vma(mm, addr-1);
7646diff -urN linux/mm/mprotect.c linux.grsec/mm/mprotect.c
7647--- linux/mm/mprotect.c Mon Mar 19 21:35:08 2001
7648+++ linux.grsec/mm/mprotect.c Sun Sep 30 02:06:18 2001
7649@@ -261,6 +261,12 @@
7650 break;
7651 }
7652
7653+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
7654+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
7655+ if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYEXEC)) {
7656+ newflags &= ~VM_MAYWRITE;
7657+ }
7658+#endif
7659 if (vma->vm_end >= end) {
7660 error = mprotect_fixup(vma, nstart, end, newflags);
7661 break;
7662diff -urN linux/net/core/dev.c linux.grsec/net/core/dev.c
7663--- linux/net/core/dev.c Mon Jul 16 01:29:40 2001
7664+++ linux.grsec/net/core/dev.c Sun Sep 30 01:54:20 2001
7665@@ -2751,7 +2751,23 @@
7666 dp = &dev->next;
7667 }
7668 }
7669-
7670+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7671+#ifdef CONFIG_PROC_FS
7672+ proc_net_create("dev", S_IRUSR|S_IRGRP, dev_get_info);
7673+ create_proc_read_entry("net/softnet_stat", S_IRUSR|S_IRGRP, 0, dev_proc_stats, NULL);
7674+#ifdef WIRELESS_EXT
7675+ proc_net_create("wireless", S_IRUSR|S_IRGRP, dev_get_wireless_info);
7676+#endif /* WIRELESS_EXT */
7677+#endif /* CONFIG_PROC_FS */
7678+#elif CONFIG_GRKERNSEC_PROC_USER
7679+#ifdef CONFIG_PROC_FS
7680+ proc_net_create("dev", S_IRUSR, dev_get_info);
7681+ create_proc_read_entry("net/softnet_stat", S_IRUSR, 0, dev_proc_stats, NULL);
7682+#ifdef WIRELESS_EXT
7683+ proc_net_create("wireless", S_IRUSR, dev_get_wireless_info);
7684+#endif /* WIRELESS_EXT */
7685+#endif /* CONFIG_PROC_FS */
7686+#else
7687 #ifdef CONFIG_PROC_FS
7688 proc_net_create("dev", 0, dev_get_info);
7689 create_proc_read_entry("net/softnet_stat", 0, 0, dev_proc_stats, NULL);
7690@@ -2759,7 +2775,7 @@
7691 proc_net_create("wireless", 0, dev_get_wireless_info);
7692 #endif /* WIRELESS_EXT */
7693 #endif /* CONFIG_PROC_FS */
7694-
7695+#endif
7696 dev_boot_phase = 0;
7697
7698 open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
7699diff -urN linux/net/core/utils.c linux.grsec/net/core/utils.c
7700--- linux/net/core/utils.c Mon Aug 23 19:01:02 1999
7701+++ linux.grsec/net/core/utils.c Sun Sep 30 01:54:20 2001
7702@@ -23,16 +23,50 @@
7703
7704 static unsigned long net_rand_seed = 152L;
7705
7706+#ifdef CONFIG_GRKERNSEC_RANDNET
7707+#include <linux/random.h>
7708+#include <linux/grsecurity.h>
7709+
7710+#define RNG_N_STORED_WORDS 256
7711+unsigned long rng_storage[RNG_N_STORED_WORDS];
7712+int nleft=0;
7713+#endif
7714+
7715 unsigned long net_random(void)
7716 {
7717+#ifdef CONFIG_GRKERNSEC_RANDNET
7718+ if (grsec_enable_randnet) {
7719+ if (!nleft)
7720+ {
7721+ get_random_bytes(rng_storage,sizeof(rng_storage));
7722+ nleft=RNG_N_STORED_WORDS;
7723+ }
7724+
7725+ nleft--;
7726+ return rng_storage[nleft];
7727+ } else {
7728+ net_rand_seed=net_rand_seed*69069L+1;
7729+ return net_rand_seed^jiffies;
7730+ }
7731+#else
7732 net_rand_seed=net_rand_seed*69069L+1;
7733 return net_rand_seed^jiffies;
7734+#endif
7735 }
7736
7737 void net_srandom(unsigned long entropy)
7738 {
7739+#ifdef CONFIG_GRKERNSEC_RANDNET
7740+ if(grsec_enable_randnet)
7741+ add_mouse_randomness((__u32)entropy);
7742+ else {
7743 net_rand_seed ^= entropy;
7744 net_random();
7745+ }
7746+#else
7747+ net_rand_seed ^= entropy;
7748+ net_random();
7749+#endif
7750 }
7751
7752 int net_msg_cost = 5*HZ;
7753@@ -71,3 +105,4 @@
7754 spin_unlock_irqrestore(&ratelimit_lock, flags);
7755 return 0;
7756 }
7757+
7758diff -urN linux/net/ipv4/af_inet.c linux.grsec/net/ipv4/af_inet.c
7759--- linux/net/ipv4/af_inet.c Sun Sep 30 01:30:52 2001
7760+++ linux.grsec/net/ipv4/af_inet.c Sun Sep 30 01:54:20 2001
7761@@ -83,6 +83,10 @@
7762 #include <linux/init.h>
7763 #include <linux/poll.h>
7764 #include <linux/netfilter_ipv4.h>
7765+#if defined(CONFIG_GRKERNSEC_RANDTTL) || defined(CONFIG_GRKERNSEC_RANDID)
7766+#include <linux/random.h>
7767+#include <linux/grsecurity.h>
7768+#endif
7769
7770 #include <asm/uaccess.h>
7771 #include <asm/system.h>
7772@@ -320,6 +324,10 @@
7773 struct list_head *p;
7774 struct inet_protosw *answer;
7775
7776+#ifdef CONFIG_GRKERNSEC_RANDTTL
7777+ unsigned long randttl;
7778+#endif
7779+
7780 sock->state = SS_UNCONNECTED;
7781 sk = sk_alloc(PF_INET, GFP_KERNEL, 1);
7782 if (sk == NULL)
7783@@ -372,7 +380,14 @@
7784 else
7785 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
7786
7787+#ifdef CONFIG_GRKERNSEC_RANDID
7788+if(grsec_enable_randid)
7789+get_random_bytes(&sk->protinfo.af_inet.id,(sizeof(sk->protinfo.af_inet.id) / 2));
7790+else
7791 sk->protinfo.af_inet.id = 0;
7792+#else
7793+ sk->protinfo.af_inet.id = 0;
7794+#endif
7795
7796 sock_init_data(sock,sk);
7797
7798@@ -384,7 +399,16 @@
7799
7800 sk->backlog_rcv = sk->prot->backlog_rcv;
7801
7802- sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl;
7803+#ifdef CONFIG_GRKERNSEC_RANDTTL
7804+if(grsec_enable_randttl){
7805+ get_random_bytes(&randttl,sizeof(randttl));
7806+ sk->protinfo.af_inet.ttl = grsec_randttl_thresh +
7807+ (randttl % (256 - grsec_randttl_thresh));
7808+} else
7809+ sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl;
7810+#else
7811+ sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl;
7812+#endif
7813
7814 sk->protinfo.af_inet.mc_loop = 1;
7815 sk->protinfo.af_inet.mc_ttl = 1;
7816@@ -1185,6 +1209,25 @@
7817 /*
7818 * Create all the /proc entries.
7819 */
7820+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7821+#ifdef CONFIG_PROC_FS
7822+ proc_net_create ("raw", S_IRUSR|S_IRGRP, raw_get_info);
7823+ proc_net_create ("netstat", S_IRUSR|S_IRGRP, netstat_get_info);
7824+ proc_net_create ("snmp", S_IRUSR|S_IRGRP, snmp_get_info);
7825+ proc_net_create ("sockstat", S_IRUSR|S_IRGRP, afinet_get_info);
7826+ proc_net_create ("tcp", S_IRUSR|S_IRGRP, tcp_get_info);
7827+ proc_net_create ("udp", S_IRUSR|S_IRGRP, udp_get_info);
7828+#endif
7829+#elif CONFIG_GRKERNSEC_PROC_USER
7830+#ifdef CONFIG_PROC_FS
7831+ proc_net_create ("raw", S_IRUSR, raw_get_info);
7832+ proc_net_create ("netstat", S_IRUSR, netstat_get_info);
7833+ proc_net_create ("snmp", S_IRUSR, snmp_get_info);
7834+ proc_net_create ("sockstat", S_IRUSR, afinet_get_info);
7835+ proc_net_create ("tcp", S_IRUSR, tcp_get_info);
7836+ proc_net_create ("udp", S_IRUSR, udp_get_info);
7837+#endif
7838+#else
7839 #ifdef CONFIG_PROC_FS
7840 proc_net_create ("raw", 0, raw_get_info);
7841 proc_net_create ("netstat", 0, netstat_get_info);
7842@@ -1192,6 +1235,7 @@
7843 proc_net_create ("sockstat", 0, afinet_get_info);
7844 proc_net_create ("tcp", 0, tcp_get_info);
7845 proc_net_create ("udp", 0, udp_get_info);
7846+#endif
7847 #endif /* CONFIG_PROC_FS */
7848 return 0;
7849 }
7850diff -urN linux/net/ipv4/arp.c linux.grsec/net/ipv4/arp.c
7851--- linux/net/ipv4/arp.c Wed May 16 19:21:45 2001
7852+++ linux.grsec/net/ipv4/arp.c Sun Sep 30 01:54:20 2001
7853@@ -1196,8 +1196,13 @@
7854 neigh_table_init(&arp_tbl);
7855
7856 dev_add_pack(&arp_packet_type);
7857-
7858+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7859+ proc_net_create ("arp", S_IRUSR|S_IRGRP, arp_get_info);
7860+#elif CONFIG_GRKERNSEC_PROC_USER
7861+ proc_net_create ("arp", S_IRUSR, arp_get_info);
7862+#else
7863 proc_net_create ("arp", 0, arp_get_info);
7864+#endif
7865
7866 #ifdef CONFIG_SYSCTL
7867 neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4");
7868diff -urN linux/net/ipv4/fib_frontend.c linux.grsec/net/ipv4/fib_frontend.c
7869--- linux/net/ipv4/fib_frontend.c Tue Jun 12 04:15:27 2001
7870+++ linux.grsec/net/ipv4/fib_frontend.c Sun Sep 30 01:54:20 2001
7871@@ -642,9 +642,19 @@
7872
7873 void __init ip_fib_init(void)
7874 {
7875+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7876+#ifdef CONFIG_PROC_FS
7877+ proc_net_create("route",S_IRUSR|S_IRGRP,fib_get_procinfo);
7878+#endif /* CONFIG_PROC_FS */
7879+#elif CONFIG_GRKERNSEC_PROC_USER
7880+#ifdef CONFIG_PROC_FS
7881+ proc_net_create("route",S_IRUSR,fib_get_procinfo);
7882+#endif /* CONFIG_PROC_FS */
7883+#else
7884 #ifdef CONFIG_PROC_FS
7885 proc_net_create("route",0,fib_get_procinfo);
7886 #endif /* CONFIG_PROC_FS */
7887+#endif
7888
7889 #ifndef CONFIG_IP_MULTIPLE_TABLES
7890 local_table = fib_hash_init(RT_TABLE_LOCAL);
7891diff -urN linux/net/ipv4/icmp.c linux.grsec/net/ipv4/icmp.c
7892--- linux/net/ipv4/icmp.c Thu Jun 21 06:00:55 2001
7893+++ linux.grsec/net/ipv4/icmp.c Sun Sep 30 01:54:20 2001
7894@@ -87,6 +87,14 @@
7895 #include <asm/system.h>
7896 #include <asm/uaccess.h>
7897 #include <net/checksum.h>
7898+#ifdef CONFIG_GRKERNSEC_RANDPING
7899+#include <linux/random.h>
7900+#endif
7901+
7902+#if defined(CONFIG_GRKERNSEC_RANDPING)||\
7903+ defined(CONFIG_GRKERNSEC_STEALTH_ICMP)
7904+#include <linux/grsecurity.h>
7905+#endif
7906
7907 #define min(a,b) ((a)<(b)?(a):(b))
7908
7909@@ -364,7 +372,6 @@
7910 icmp_xmit_unlock_bh();
7911 }
7912
7913-
7914 /*
7915 * Send an ICMP message in response to a situation
7916 *
7917@@ -728,10 +735,18 @@
7918
7919 icmp_param.data.icmph=*skb->h.icmph;
7920 icmp_param.data.icmph.type=ICMP_ECHOREPLY;
7921+#ifdef CONFIG_GRKERNSEC_RANDPING
7922+ if(grsec_enable_randping)
7923+ icmp_param.data.icmph.un.echo.id =
7924+ skb->h.icmph->un.echo.id;
7925+#endif
7926 icmp_param.skb=skb;
7927 icmp_param.offset=0;
7928 icmp_param.data_len=skb->len;
7929 icmp_param.head_len=sizeof(struct icmphdr);
7930+#ifdef CONFIG_GRKERNSEC_STEALTH_ICMP
7931+ if (!grsec_enable_stealth_icmp)
7932+#endif
7933 icmp_reply(&icmp_param, skb);
7934 }
7935 }
7936@@ -773,6 +788,9 @@
7937 icmp_param.offset=0;
7938 icmp_param.data_len=0;
7939 icmp_param.head_len=sizeof(struct icmphdr)+12;
7940+#ifdef CONFIG_GRKERNSEC_STEALTH_ICMP
7941+ if(!grsec_enable_stealth_icmp)
7942+#endif
7943 icmp_reply(&icmp_param, skb);
7944 }
7945
7946diff -urN linux/net/ipv4/igmp.c linux.grsec/net/ipv4/igmp.c
7947--- linux/net/ipv4/igmp.c Thu Apr 12 21:11:39 2001
7948+++ linux.grsec/net/ipv4/igmp.c Sun Sep 30 01:54:20 2001
7949@@ -98,6 +98,10 @@
7950 #include <linux/mroute.h>
7951 #endif
7952
7953+#ifdef CONFIG_GRKERNSEC_STEALTH_IGMP
7954+#include <linux/grsecurity.h>
7955+#endif
7956+
7957
7958 #define IP_MAX_MEMBERSHIPS 20
7959
7960@@ -199,7 +203,10 @@
7961 struct igmphdr *ih;
7962 struct rtable *rt;
7963 u32 dst;
7964-
7965+#ifdef CONFIG_GRKERNSEC_STEALTH_IGMP
7966+ if(grsec_enable_stealth_igmp)
7967+ return(-1);
7968+#endif
7969 /* According to IGMPv2 specs, LEAVE messages are
7970 * sent to all-routers group.
7971 */
7972diff -urN linux/net/ipv4/ip_gre.c linux.grsec/net/ipv4/ip_gre.c
7973--- linux/net/ipv4/ip_gre.c Tue May 15 10:29:35 2001
7974+++ linux.grsec/net/ipv4/ip_gre.c Sun Sep 30 01:54:20 2001
7975@@ -28,6 +28,10 @@
7976 #include <linux/inetdevice.h>
7977 #include <linux/igmp.h>
7978 #include <linux/netfilter_ipv4.h>
7979+#ifdef CONFIG_GRKERNSEC_RANDTTL
7980+#include <linux/random.h>
7981+#include <linux/grsecurity.h>
7982+#endif
7983
7984 #include <net/sock.h>
7985 #include <net/ip.h>
7986@@ -846,6 +850,9 @@
7987 iph->saddr = rt->rt_src;
7988
7989 if ((iph->ttl = tiph->ttl) == 0) {
7990+#ifdef CONFIG_GRKERNSEC_RANDTTL
7991+ unsigned long randttl;
7992+#endif
7993 if (skb->protocol == __constant_htons(ETH_P_IP))
7994 iph->ttl = old_iph->ttl;
7995 #ifdef CONFIG_IPV6
7996@@ -853,6 +860,13 @@
7997 iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
7998 #endif
7999 else
8000+#ifdef CONFIG_GRKERNSEC_RANDTTL
8001+ if(grsec_enable_randttl){
8002+ get_random_bytes(&randttl,sizeof(randttl));
8003+ iph->ttl = grsec_randttl_thresh +
8004+ (randttl % (256 - grsec_randttl_thresh));
8005+ } else
8006+#endif
8007 iph->ttl = sysctl_ip_default_ttl;
8008 }
8009
8010diff -urN linux/net/ipv4/ip_output.c linux.grsec/net/ipv4/ip_output.c
8011--- linux/net/ipv4/ip_output.c Wed Jul 11 01:11:43 2001
8012+++ linux.grsec/net/ipv4/ip_output.c Sun Sep 30 01:54:20 2001
8013@@ -76,6 +76,10 @@
8014 #include <linux/netfilter_ipv4.h>
8015 #include <linux/mroute.h>
8016 #include <linux/netlink.h>
8017+#ifdef CONFIG_GRKERNSEC_RANDID
8018+#include <linux/random.h>
8019+#include <linux/grsecurity.h>
8020+#endif
8021
8022 /*
8023 * Shall we try to damage output packets if routing dev changes?
8024@@ -328,7 +332,9 @@
8025 kfree_skb(skb);
8026 return -EMSGSIZE;
8027 }
8028+
8029 ip_select_ident(iph, &rt->u.dst, sk);
8030+
8031 if (skb->ip_summed == CHECKSUM_HW &&
8032 (skb = skb_checksum_help(skb)) == NULL)
8033 return -ENOMEM;
8034@@ -499,7 +505,13 @@
8035 * Begin outputting the bytes.
8036 */
8037
8038- id = sk->protinfo.af_inet.id++;
8039+#ifdef CONFIG_GRKERNSEC_RANDID
8040+ if(grsec_enable_randid){
8041+ get_random_bytes(&id,(sizeof(id) / 2));
8042+ sk->protinfo.af_inet.id = id;
8043+ } else
8044+#endif
8045+ id = sk->protinfo.af_inet.id++;
8046
8047 do {
8048 char *data;
8049@@ -554,7 +566,7 @@
8050 */
8051 __ip_select_ident(iph, &rt->u.dst);
8052 id = iph->id;
8053- }
8054+ }
8055
8056 /*
8057 * Any further fragments will have MF set.
8058@@ -994,7 +1006,17 @@
8059 ip_rt_init();
8060 inet_initpeers();
8061
8062+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8063+#ifdef CONFIG_IP_MULTICAST
8064+ proc_net_create("igmp", S_IRUSR|S_IRGRP, ip_mc_procinfo);
8065+#endif
8066+#elif CONFIG_GRKERNSEC_PROC_USER
8067+#ifdef CONFIG_IP_MULTICAST
8068+ proc_net_create("igmp", S_IRUSR, ip_mc_procinfo);
8069+#endif
8070+#else
8071 #ifdef CONFIG_IP_MULTICAST
8072 proc_net_create("igmp", 0, ip_mc_procinfo);
8073+#endif
8074 #endif
8075 }
8076diff -urN linux/net/ipv4/ip_sockglue.c linux.grsec/net/ipv4/ip_sockglue.c
8077--- linux/net/ipv4/ip_sockglue.c Thu Apr 12 21:11:39 2001
8078+++ linux.grsec/net/ipv4/ip_sockglue.c Sun Sep 30 01:54:20 2001
8079@@ -42,6 +42,10 @@
8080
8081 #include <linux/errqueue.h>
8082 #include <asm/uaccess.h>
8083+#ifdef CONFIG_GRKERNSEC_RANDTTL
8084+#include <linux/random.h>
8085+#include <linux/grsecurity.h>
8086+#endif
8087
8088 #define MAX(a,b) ((a)>(b)?(a):(b))
8089
8090@@ -383,7 +387,9 @@
8091 int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen)
8092 {
8093 int val=0,err;
8094-
8095+#ifdef CONFIG_GRKERNSEC_RANDTTL
8096+ unsigned long randttl;
8097+#endif
8098 if (level != SOL_IP)
8099 return -ENOPROTOOPT;
8100
8101@@ -500,8 +506,16 @@
8102 case IP_TTL:
8103 if (optlen<1)
8104 goto e_inval;
8105- if(val==-1)
8106+ if(val==-1){
8107+#ifdef CONFIG_GRKERNSEC_RANDTTL
8108+ if(grsec_enable_randttl){
8109+ get_random_bytes(&randttl,sizeof(randttl));
8110+ val = grsec_randttl_thresh +
8111+ (randttl % (256 - grsec_randttl_thresh));
8112+ } else
8113+#endif
8114 val = sysctl_ip_default_ttl;
8115+ }
8116 if(val<1||val>255)
8117 goto e_inval;
8118 sk->protinfo.af_inet.ttl=val;
8119diff -urN linux/net/ipv4/ipmr.c linux.grsec/net/ipv4/ipmr.c
8120--- linux/net/ipv4/ipmr.c Sat Jun 30 04:38:26 2001
8121+++ linux.grsec/net/ipv4/ipmr.c Sun Sep 30 01:54:20 2001
8122@@ -1761,8 +1761,20 @@
8123 init_timer(&ipmr_expire_timer);
8124 ipmr_expire_timer.function=ipmr_expire_process;
8125 register_netdevice_notifier(&ip_mr_notifier);
8126+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8127+#ifdef CONFIG_PROC_FS
8128+ proc_net_create("ip_mr_vif",S_IRUSR|S_IRGRP,ipmr_vif_info);
8129+ proc_net_create("ip_mr_cache",S_IRUSR|S_IRGRP,ipmr_mfc_info);
8130+#endif
8131+#elif CONFIG_GRKERNSEC_PROC_USER
8132+#ifdef CONFIG_PROC_FS
8133+ proc_net_create("ip_mr_vif",S_IRUSR,ipmr_vif_info);
8134+ proc_net_create("ip_mr_cache",S_IRUSR,ipmr_mfc_info);
8135+#endif
8136+#else
8137 #ifdef CONFIG_PROC_FS
8138 proc_net_create("ip_mr_vif",0,ipmr_vif_info);
8139 proc_net_create("ip_mr_cache",0,ipmr_mfc_info);
8140 #endif
8141+#endif
8142 }
8143diff -urN linux/net/ipv4/route.c linux.grsec/net/ipv4/route.c
8144--- linux/net/ipv4/route.c Fri Jul 20 03:11:13 2001
8145+++ linux.grsec/net/ipv4/route.c Sun Sep 30 01:54:20 2001
8146@@ -2525,9 +2525,31 @@
8147 ip_rt_gc_interval;
8148 add_timer(&rt_periodic_timer);
8149
8150- proc_net_create ("rt_cache", 0, rt_cache_get_info);
8151+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8152+ proc_net_create ("rt_cache", S_IRUSR|S_IRGRP, rt_cache_get_info);
8153+#elif CONFIG_GRKERNSEC_PROC_USER
8154+ proc_net_create ("rt_cache", S_IRUSR, rt_cache_get_info);
8155+#else
8156+ proc_net_create ("rt_cache", 0, rt_cache_get_info);
8157+#endif
8158+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8159+ proc_net_create ("rt_cache_stat", S_IRUSR|S_IRGRP, rt_cache_stat_get_info);
8160+#elif CONFIG_GRKERNSEC_PROC_USER
8161+ proc_net_create ("rt_cache_stat", S_IRUSR, rt_cache_stat_get_info);
8162+#else
8163 proc_net_create ("rt_cache_stat", 0, rt_cache_stat_get_info);
8164+#endif
8165+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8166 #ifdef CONFIG_NET_CLS_ROUTE
8167- create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL);
8168+ create_proc_read_entry("net/rt_acct", S_IRUSR|S_IRGRP, 0, ip_rt_acct_read, NULL);
8169+#endif
8170+#elif CONFIG_GRKERNSEC_PROC_USER
8171+#ifdef CONFIG_NET_CLS_ROUTE
8172+ create_proc_read_entry("net/rt_acct", S_IRUSR, 0, ip_rt_acct_read, NULL);
8173+#endif
8174+#else
8175+#ifdef CONFIG_NET_CLS_ROUTE
8176+ create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL);
8177+#endif
8178 #endif
8179 }
8180diff -urN linux/net/ipv4/tcp_ipv4.c linux.grsec/net/ipv4/tcp_ipv4.c
8181--- linux/net/ipv4/tcp_ipv4.c Wed Apr 25 23:57:39 2001
8182+++ linux.grsec/net/ipv4/tcp_ipv4.c Sun Sep 30 01:54:21 2001
8183@@ -63,6 +63,13 @@
8184 #include <linux/stddef.h>
8185 #include <linux/ipsec.h>
8186
8187+#if defined(CONFIG_GRKERNSEC_RANDID)||defined(CONFIG_GRKERNSEC_RANDSRC)||\
8188+ defined(CONFIG_GRKERNSEC_STEALTH_RST)||\
8189+ defined(CONFIG_GRKERNSEC_STEALTH_FLAGS)
8190+#include <linux/grsecurity.h>
8191+#endif
8192+
8193+
8194 extern int sysctl_ip_dynaddr;
8195
8196 /* Check TCP sequence numbers in ICMP packets. */
8197@@ -177,12 +184,37 @@
8198 int high = sysctl_local_port_range[1];
8199 int remaining = (high - low) + 1;
8200 int rover;
8201+#ifdef CONFIG_GRKERNSEC_RANDSRC
8202+ unsigned long longrover;
8203+ int count = 0;
8204+#endif
8205
8206 spin_lock(&tcp_portalloc_lock);
8207 rover = tcp_port_rover;
8208+#ifdef CONFIG_GRKERNSEC_RANDSRC
8209+ do {
8210+ if(grsec_enable_randsrc){
8211+ if(count < 64){
8212+ get_random_bytes(&longrover,sizeof(longrover));
8213+ rover=low+(longrover % (high - low));
8214+ } else if(count == 64)
8215+ rover = tcp_port_rover;
8216+ else if(count > 64){
8217+ rover++;
8218+ if ((rover < low) || (rover > high))
8219+ rover = low;
8220+ }
8221+ count++;
8222+ } else {
8223+ rover++;
8224+ if ((rover < low) || (rover > high))
8225+ rover = low;
8226+ }
8227+#else
8228 do { rover++;
8229 if ((rover < low) || (rover > high))
8230 rover = low;
8231+#endif
8232 head = &tcp_bhash[tcp_bhashfn(rover)];
8233 spin_lock(&head->lock);
8234 for (tb = head->chain; tb; tb = tb->next)
8235@@ -192,7 +224,9 @@
8236 next:
8237 spin_unlock(&head->lock);
8238 } while (--remaining > 0);
8239+
8240 tcp_port_rover = rover;
8241+
8242 spin_unlock(&tcp_portalloc_lock);
8243
8244 /* Exhausted local port range during search? */
8245@@ -718,6 +752,11 @@
8246 tp->ext_header_len = 0;
8247 if (sk->protinfo.af_inet.opt)
8248 tp->ext_header_len = sk->protinfo.af_inet.opt->optlen;
8249+#ifdef CONFIG_GRKERNSEC_RANDID
8250+if(grsec_enable_randid)
8251+ get_random_bytes(&sk->protinfo.af_inet.id,(sizeof(sk->protinfo.af_inet.id) / 2));
8252+else
8253+#endif
8254 sk->protinfo.af_inet.id = tp->write_seq^jiffies;
8255
8256 tp->mss_clamp = 536;
8257@@ -1031,7 +1070,10 @@
8258 struct tcphdr *th = skb->h.th;
8259 struct tcphdr rth;
8260 struct ip_reply_arg arg;
8261-
8262+#ifdef CONFIG_GRKERNSEC_STEALTH_RST
8263+ if(grsec_enable_stealth_rst)
8264+ return;
8265+#endif
8266 /* Never send a reset in response to a reset. */
8267 if (th->rst)
8268 return;
8269@@ -1444,6 +1486,11 @@
8270 newtp->ext_header_len = 0;
8271 if (newsk->protinfo.af_inet.opt)
8272 newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen;
8273+#ifdef CONFIG_GRKERNSEC_RANDID
8274+ if(grsec_enable_randid)
8275+ get_random_bytes(&newsk->protinfo.af_inet.id,(sizeof(newsk->protinfo.af_inet.id) / 2));
8276+ else
8277+#endif
8278 newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
8279
8280 tcp_sync_mss(newsk, dst->pmtu);
8281@@ -1608,6 +1655,18 @@
8282
8283 if (th->doff < sizeof(struct tcphdr)/4)
8284 goto bad_packet;
8285+#ifdef CONFIG_GRKERNSEC_STEALTH_FLAGS
8286+if(grsec_enable_stealth_flags){
8287+ if(th->fin && th->syn)
8288+ goto discard_it;
8289+
8290+ if(!(th->ack || th->syn || th->rst) || th->res1)
8291+ goto discard_it;
8292+
8293+ if(th->fin && th->psh && th->urg)
8294+ goto discard_it;
8295+}
8296+#endif
8297 if (!pskb_may_pull(skb, th->doff*4))
8298 goto discard_it;
8299
8300diff -urN linux/net/ipv4/udp.c linux.grsec/net/ipv4/udp.c
8301--- linux/net/ipv4/udp.c Thu Apr 12 21:11:39 2001
8302+++ linux.grsec/net/ipv4/udp.c Sun Sep 30 01:54:21 2001
8303@@ -93,7 +93,12 @@
8304 #include <net/route.h>
8305 #include <net/inet_common.h>
8306 #include <net/checksum.h>
8307-
8308+#ifdef CONFIG_GRKERNSEC_RANDID
8309+#include <linux/random.h>
8310+#endif
8311+#if defined(CONFIG_GRKERNSEC_RANDID) || defined(CONFIG_GRKERNSEC_STEALTH_UDP)
8312+#include <linux/grsecurity.h>
8313+#endif
8314 /*
8315 * Snmp MIB for the UDP layer
8316 */
8317@@ -738,6 +743,12 @@
8318 sk->daddr = rt->rt_dst;
8319 sk->dport = usin->sin_port;
8320 sk->state = TCP_ESTABLISHED;
8321+
8322+#ifdef CONFIG_GRKERNSEC_RANDID
8323+if(grsec_enable_randid)
8324+ get_random_bytes(&sk->protinfo.af_inet.id,(sizeof(sk->protinfo.af_inet.id) / 2));
8325+else
8326+#endif
8327 sk->protinfo.af_inet.id = jiffies;
8328
8329 sk_dst_set(sk, &rt->u.dst);
8330@@ -909,12 +920,14 @@
8331 sock_put(sk);
8332 return 0;
8333 }
8334-
8335 /* No socket. Drop packet silently, if checksum is wrong */
8336 if (udp_checksum_complete(skb))
8337 goto csum_error;
8338
8339 UDP_INC_STATS_BH(UdpNoPorts);
8340+#ifdef CONFIG_GRKERNSEC_STEALTH_UDP
8341+ if(!grsec_enable_stealth_udp)
8342+#endif
8343 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
8344
8345 /*
8346diff -urN linux/net/socket.c linux.grsec/net/socket.c
8347--- linux/net/socket.c Fri Jul 20 03:11:13 2001
8348+++ linux.grsec/net/socket.c Sun Sep 30 01:54:21 2001
8349@@ -87,6 +87,13 @@
8350 #include <net/scm.h>
8351 #include <linux/netfilter.h>
8352
8353+#if defined(CONFIG_GRKERNSEC_SOCKET_ALL)||\
8354+ defined(CONFIG_GRKERNSEC_SOCKET_CLIENT)||\
8355+ defined(CONFIG_GRKERNSEC_SOCKET_SERVER)
8356+#include <linux/grsecurity.h>
8357+#endif
8358+
8359+
8360 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
8361 static loff_t sock_lseek(struct file *file, loff_t offset, int whence);
8362 static ssize_t sock_read(struct file *file, char *buf,
8363@@ -914,7 +921,18 @@
8364 {
8365 int retval;
8366 struct socket *sock;
8367-
8368+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
8369+ if(grsec_enable_socket_all &&
8370+ (in_group_p(grsec_socket_all_gid)) && (family != AF_UNIX) && (family != AF_LOCAL)){
8371+ security_alert("attempted socket(%d,%d,%d) by (%.16s:%d), "
8372+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), "
8373+ "EUID(%d)","attempted sockets",family,type,protocol,
8374+ current->comm,current->pid,current->uid,current->euid,
8375+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
8376+ current->p_pptr->euid);
8377+ return -EACCES;
8378+ }
8379+#endif
8380 retval = sock_create(family, type, protocol, &sock);
8381 if (retval < 0)
8382 goto out;
8383@@ -1011,7 +1029,18 @@
8384 struct socket *sock;
8385 char address[MAX_SOCK_ADDR];
8386 int err;
8387-
8388+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
8389+ if(grsec_enable_socket_server &&
8390+ (in_group_p(grsec_socket_server_gid)) && (umyaddr->sa_family != AF_UNIX) && (umyaddr->sa_family != AF_LOCAL)){
8391+ security_alert("attempted bind() by (%.16s:%d), "
8392+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), "
8393+ "EUID(%d)","attempted binds",
8394+ current->comm,current->pid,current->uid,current->euid,
8395+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
8396+ current->p_pptr->euid);
8397+ return -EACCES;
8398+ }
8399+#endif
8400 if((sock = sockfd_lookup(fd,&err))!=NULL)
8401 {
8402 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
8403@@ -1119,10 +1148,21 @@
8404 struct socket *sock;
8405 char address[MAX_SOCK_ADDR];
8406 int err;
8407-
8408 sock = sockfd_lookup(fd, &err);
8409 if (!sock)
8410 goto out;
8411+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
8412+ if(grsec_enable_socket_client &&
8413+ (in_group_p(grsec_socket_client_gid)) && (uservaddr->sa_family != AF_UNIX) && (uservaddr->sa_family != AF_LOCAL)){
8414+ security_alert("attempted connect() to fd %d by (%.16s:%d), "
8415+ "UID(%d), EUID(%d), parent (%.16s:%d), UID(%d), "
8416+ "EUID(%d)","attempted connects",fd,
8417+ current->comm,current->pid,current->uid,current->euid,
8418+ current->p_pptr->comm,current->p_pptr->pid,current->p_pptr->uid,
8419+ current->p_pptr->euid);
8420+ return -ENETUNREACH;
8421+ }
8422+#endif
8423 err = move_addr_to_kernel(uservaddr, addrlen, address);
8424 if (err < 0)
8425 goto out_put;
This page took 0.906118 seconds and 4 git commands to generate.