]> git.pld-linux.org Git - packages/kernel.git/blob - linux-grsecurity-1.8-2.4.7.patch
- added description of djurban's branch
[packages/kernel.git] / linux-grsecurity-1.8-2.4.7.patch
1 diff -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  #
366 diff -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 +
382 diff -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 +
398 diff -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 +
414 diff -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 +
430 diff -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
493 diff -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 */
508 diff -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))
528 diff -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. */ 
573 diff -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)
646 diff -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])
883 diff -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 +
1415 diff -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);
1430 diff -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 +
1446 diff -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 +
1462 diff -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 +
1478 diff -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 +
1494 diff -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 +
1509 diff -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 +
1525 diff -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 +
1540 diff -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 +
1555 diff -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 +
1571 diff -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 +
1587 diff -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 +
1603 diff -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;
1641 diff -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);
1698 diff -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];
1736 diff -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;
1751 diff -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;
1766 diff -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                 }
1781 diff -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                 }
1796 diff -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)
1811 diff -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);
1838 diff -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;
1853 diff -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;
1868 diff -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;
1883 diff -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;
1898 diff -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                 }
1913 diff -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);
1973 diff -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);
2093 diff -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);
2577 diff -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:
3055 diff -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)
3511 diff -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)
3611 diff -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;
3626 diff -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) {
3685 diff -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)
3860 diff -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,
3904 diff -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
4032 diff -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__ */
4049 diff -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:
4115 diff -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 */
4172 diff -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.  */
4201 diff -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  /*
4224 diff -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
4252 diff -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);
4267 diff -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;
4312 diff -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], \
4378 diff -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
4393 diff -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 */
4542 diff -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);
4550 diff -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 +
4632 diff -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);
4653 diff -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
4722 diff -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  
4734 diff -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  }
4758 diff -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  }
4783 diff -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  {
4832 diff -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
4843 diff -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);
4893 diff -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  
5121 diff -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 +}
6482 diff -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 +}
6646 diff -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 +}
6879 diff -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;
6986 diff -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 ||
7122 diff -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         
7522 diff -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  }
7563 diff -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);
7646 diff -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;
7662 diff -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);
7699 diff -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 +
7758 diff -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  }
7850 diff -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");
7868 diff -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);
7891 diff -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  
7946 diff -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          */
7972 diff -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  
8010 diff -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  }
8076 diff -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;
8119 diff -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  }
8143 diff -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  }
8180 diff -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  
8300 diff -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         /*
8346 diff -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 3.949471 seconds and 3 git commands to generate.