diff -urN linux/Documentation/Configure.help linux/Documentation/Configure.help
--- linux/Documentation/Configure.help	Fri Dec 21 12:41:53 2001
+++ linux/Documentation/Configure.help	Sun Jan 20 12:01:27 2002
@@ -19794,6 +19794,682 @@
 
   "Area6" will work for most boards. For ADX, select "Area5".
 
+Grsecurity
+CONFIG_GRKERNSEC
+  If you say Y here, you will be able to configure many features that
+  will enhance the security of your system.  It is highly recommended
+  that you say Y here and read through the help for each option so
+  you fully understand what its doing and can evaluate its usefulness
+  for your machine.
+
+OpenWall Non-executable Stack
+CONFIG_GRKERNSEC_STACK
+  If you say Y here, your system will not allow execution of
+  code on the stack, making buffer overflow exploitation more difficult.
+  The code for this protection is taken from the Openwall patch for
+  linux 2.2 by Solar Designer. You can view his projects at 
+  http://www.openwall.com/linux.
+  Exploits against your machine with this protection will have to dabble 
+  in more obscure methods of exploitation(bss,got,heap..)
+
+Gcc trampoline support
+CONFIG_GRKERNSEC_STACK_GCC
+  If you say Y here, the system will support trampoline code along
+  with the stack protection.  If you do not have any programs on
+  your system that require this (glibc 2.0 users must say YES to
+  this option) you may say no here.
+
+PaX protection
+CONFIG_GRKERNSEC_PAX 
+  By design the IA-32 architecture does not allow for protecting
+  memory pages against execution, i.e. if a page is readable (such
+  as the stack or heap) it is also executable.  There is a well
+  known exploit technique that makes use of this fact and a common
+  programming mistake where an attacker can introduce executable
+  code of his choice somewhere in the attacked program's memory
+  (typically the stack or the heap) and then execute it.  If the
+  attacked program was running with different (typically higher)
+  privileges than that of the attacker, then he can elevate his
+  own privilege level (e.g. get a root shell, write to files for
+  which he does not have write access to, etc).
+
+  Since the implementation is software based, it comes with a
+  performance impact, you should evaluate your system carefully
+  before deciding to use this feature on production systems.
+
+  Enabling this feature will enforce the non-executable flag on
+  memory pages thereby making it harder to execute 'foreign' code
+  in a program.  This will also break programs that rely on the
+  old behaviour and expect that dynamically allocated memory via
+  the malloc() family of functions is executable (which it is not).
+  Notable examples are the XFree86 4.x server, the java runtime
+  and wine.
+
+  NOTE: you can use the 'chpax' utility to enable/disable this
+  feature on a per file basis.  chpax is available at
+  http://pageexec.virtualave.net
+
+Emulate trampolines
+CONFIG_GRKERNSEC_PAX_EMUTRAMP
+  There are some programs and libraries that for one reason or
+  another attempt to execute special small code snippets from
+  non-executable memory pages.  Most notable examples are the
+  signal handler return code generated by the kernel itself and
+  the GCC trampolines.
+
+  If you enabled CONFIG_GRKERNSEC_PAX then such programs will no
+  longer work under your kernel.  As a remedy you can say Y here
+  and use the 'chpax' utility to enable trampoline emulation for
+  the affected programs yet still have the protection provided by
+  CONFIG_GRKERNSEC_PAX.  Alternatively you can say N here and use
+  the 'chpax' utility to disable CONFIG_GRKERNSEC_PAX for the
+  affected files.  chpax is available at 
+  http://pageexec.virtualave.net
+
+  NOTE: enabling this feature *may* open up a loophole in the
+  protection provided by CONFIG_GRKERNSEC_PAX that an attacker
+  could abuse.  Therefore the best solution is to not have any
+  files on your system that would require this option.  This can
+  be achieved by not using libc5 (which relies on the kernel
+  signal handler return code) and not using or rewriting programs
+  that make use of the nested function implementation of GCC.
+  Skilled users can just fix GCC itself so that it implements
+  nested function calls in a way that does not interfere with PaX.
+
+Restrict mprotect()
+CONFIG_GRKERNSEC_PAX_MPROTECT
+  Enabling this option will prevent programs from changing the
+  executable status of memory pages that were not originally
+  created as executable.  The kernel will also prevent programs
+  from making read-only executable pages writable again.
+
+  You should say Y here to complete the protection provided by
+  the enforcement of the PAGE_EXEC flag (CONFIG_GRKERNSEC_PAX).
+
+  NOTE: you can use the 'chpax' utility to enable/disable this
+  feature on a per file basis. chpax is available at
+  http://pageexec.virtualave.net
+
+Randomize mmap() base
+CONFIG_GRKERNSEC_PAX_RANDMMAP
+  By saying Y here the kernel will somewhat randomize the address
+  space layout of programs at each execution (the top of the stack, the
+  base address for mmap() requests that do not specify one themselves
+  and the base address of dynamic ELF executables).
+
+  As a result all dynamically loaded libraries will appear at random
+  addresses and therefore be harder to exploit by a technique where
+  an attacker attempts to execute library code for his purposes
+  (e.g. spawn a shell from an exploited program that is running at
+  an elevated privilege level).
+
+  Furthermore, if a program is relinked as a dynamic ELF file, its
+  base address layout will be randomized as well, completing the full
+  randomization of the address space.  Attacking such programs becomes
+  a guess game.
+
+  It is strongly recommended to say Y here even if CONFIG_GRKERNSEC_PAX
+  is not enabled as address space layout randomization has negligible 
+  impact on performance yet it provides a very effective protection.
+
+  NOTE: you can use the 'chpax' utility to enable/disable this
+  feature on a per file basis.  chpax is available at
+  http://pageexec.virtualave.net
+
+Read-only kernel memory
+CONFIG_GRKERNSEC_KMEM
+  If you say Y here, root will not be able to modify the contents of
+  kernel memory.  If module support is removed in addition to enabling 
+  this option, the ability of an attacker to insert foreign code into 
+  a running kernel is removed.  If the sysctl option is enabled, a 
+  sysctl option with name "read_only_kmem" is created.
+
+Fixed mmap restrictions
+CONFIG_GRKERNSEC_MMAPFIXED
+  If you say Y here, it will be impossible for an attacker to bypass the
+  PaX buffer overflow protection by mmaping an executable memory region
+  with a specific address set.  If the sysctl option is enabled, a
+  sysctl option with name "mmap_fixed_restrict" is created.
+
+Proc Restrictions
+CONFIG_GRKERNSEC_PROC
+  If you say Y here, the permissions of the /proc filesystem
+  will be altered to enhance system security and privacy.  Depending
+  upon the options you choose, you can either restrict users to see
+  only the processes they themselves run, or choose a group that can
+  view all processes and files normally restricted to root if you choose
+  the "restrict to user only" option.  NOTE: If you're running identd as 
+  a non-root user, you will have to run it as the group you specify here.
+
+Restrict /proc to user only
+CONFIG_GRKERNSEC_PROC_USER
+  If you say Y here, non-root users will only be able to view their own 
+  processes, and restricts them from viewing network-related information,  
+  running dmesg(8), and viewing kernel symbol and module information.
+
+Restrict /proc to user and group
+CONFIG_GRKERNSEC_PROC_USERGROUP
+  If you say Y here, you will be able to select a group that will be
+  able to view all processes, network-related information, and
+  kernel and symbol information.  This option is useful if you want
+  to run identd as a non-root user.
+
+Linking restrictions
+CONFIG_GRKERNSEC_LINK
+  If you say Y here, /tmp race exploits will be prevented, since users
+  will no longer be able to follow symlinks owned by other users in 
+  world-writeable +t directories (i.e. /tmp), unless the owner of the 
+  symlink is the owner of the directory. users will also not be
+  able to hardlink to files they do not own.  If the sysctl option is
+  enabled, a sysctl option with name "linking_restrictions" is created.
+
+FIFO restrictions
+CONFIG_GRKERNSEC_FIFO
+  If you say Y here, users will not be able to write to FIFOs they don't
+  own in world-writeable +t directories (i.e. /tmp), unless the owner of
+  the FIFO is the same owner of the directory it's held in.  If the sysctl
+  option is enabled, a sysctl option with name "fifo_restrictions" is 
+  created.
+
+Secure file descriptors
+CONFIG_GRKERNSEC_FD
+  If you say Y here, binaries will be protected from data spoofing
+  attacks (eg. making a program read /etc/shadow).  The patches do this
+  by opening up /dev/null to any of the stdin, stdout, stderr file descriptors
+  for binaries that are open.  If the sysctl option is enabled, a sysctl 
+  option with name "secure_fds" is created.
+
+Exec process limiting
+CONFIG_GRKERNSEC_EXECVE
+  If you say Y here, users with a resource limit on processes will
+  have the value checked during execve() calls.  The current system
+  only checks the system limit during fork() calls.  If the sysctl option
+  is enabled, a sysctl option with name "execve_limiting" is created.
+
+Fork-bombing protection
+CONFIG_GRKERNSEC_FORKBOMB
+  If you say Y here, you will be able to configure a group to add to users
+  on your system that you want to be unable to fork-bomb the system.
+  You will be able to specify a maximum process limit for the user and
+  set a rate limit for all forks under their uid. (Fork-bombing is a
+  tactic used by attackers that can be enacted in two ways, (1) loading
+  up thousands of processes until the system can't take any more (this
+  method can be stopped outside of the kernel with PAM, however we place
+  protection for it in the kernel to be more complete and reduce overhead),
+  and (2), by forking processes at a rapid rate, and then killing them
+  off, which cannot be protected against in the same way at tactic 1)
+  The rate limit is specified in forks allowed per second.  Set this
+  limit low enough to stop tactic 2, but high enough to allow for
+  normal operation.  The protection will kill the offending process.
+  If the sysctl option is enabled, a sysctl option with name 
+  "fork_bomb_prot" is created.
+
+Max processes for fork-bomb protection
+CONFIG_GRKERNSEC_FORKBOMB_MAX
+  Here you can configure the maximum number of processes users in the
+  fork-bomb protected group can run.  I would not recommend setting a
+  value lower than 8, since some programs like man(1) spawn up to 8
+  processes to run.  The default value should be fine for most purposes.
+  If the sysctl option is enabled, a sysctl option with name
+  "fork_bomb_max" is created.
+
+Forks allowed per second
+CONFIG_GRKERNSEC_FORKBOMB_SEC
+  Here you can specify the maximum number of forks allowed per second.
+  You don't want to set this value too low, or else you'll hinder
+  normal operation of your system.  The default value should be fine for
+  most users.  If the sysctl option is enabled, a sysctl option with name
+  "fork_bomb_sec" is created.
+
+Group for fork-bomb protection
+CONFIG_GRKERNSEC_FORKBOMB_GID
+  Here you can choose the GID to enable fork-bomb protection for.
+  Remember to add the users you want protection enabled for to the GID 
+  specified here.  If the sysctl option is enabled, whatever you choose
+  here won't matter. You'll have to specify the GID in your bootup 
+  script by echoing the GID to the proper /proc entry.  View the help
+  on the sysctl option for more information.  If the sysctl option is
+  enabled, a sysctl option with name "fork_bomb_gid" is created.
+
+Single group for auditing
+CONFIG_GRKERNSEC_AUDIT_GROUP
+  If you say Y here, the exec, chdir, (un)mount, and ipc logging features
+  will only operate on a group you specify.  This option is recommended
+  if you only want to watch certain users instead of having a large
+  amount of logs from the entire system.  If the sysctl option is enabled,
+  a sysctl option with name "audit_group" is created.
+
+GID for auditing
+CONFIG_GRKERNSEC_AUDIT_GID
+  Here you can choose the GID that will be the target of kernel auditing.
+  Remember to add the users you want to log to the GID specified here.
+  If the sysctl option is enabled, whatever you choose here won't matter. 
+  You'll have to specify the GID in your bootup script by echoing the GID 
+  to the proper /proc entry.  View the help on the sysctl option for more 
+  information.  If the sysctl option is enabled, a sysctl option with name 
+  "audit_gid" is created.
+
+Chdir logging
+CONFIG_GRKERNSEC_AUDIT_CHDIR
+  If you say Y here, all chdir() calls will be logged.  If the sysctl 
+  option is enabled, a sysctl option with name "audit_chdir" is created.
+
+(Un)Mount logging
+CONFIG_GRKERNSEC_AUDIT_MOUNT
+  If you say Y here, all mounts and unmounts will be logged.  If the 
+  sysctl option is enabled, a sysctl option with name "audit_mount" is 
+  created.
+
+IPC logging
+CONFIG_GRKERNSEC_AUDIT_IPC
+  If you say Y here, creation and removal of message queues, semaphores,
+  and shared memory will be logged.  If the sysctl option is enabled, a
+  sysctl option with name "audit_ipc" is created.
+
+Exec logging
+CONFIG_GRKERNSEC_EXECLOG
+  If you say Y here, all execve() calls will be logged (since the
+  other exec*() calls are frontends to execve(), all execution
+  will be logged).  Useful for shell-servers that like to keep track
+  of their users.  If the sysctl option is enabled, a sysctl option with
+  name "exec_logging" is created.
+  WARNING: This option when enabled will produce a LOT of logs, especially
+  on an active system.
+
+Set*id logging
+CONFIG_GRKERNSEC_SUID
+  If you say Y here, all set*id() calls will be logged.  Such information
+  could be useful when detecting a possible intrusion attempt.  This 
+  option can produce a lot of logs on an active system.  If the sysctl
+  option is enabled, a sysctl option with name "suid_logging" is created.
+
+Log set*ids to root
+CONFIG_GRKERNSEC_SUID
+  If you say Y here, only set*id() calls where a user is changing to the
+  gid or uid of the root user will be logged.  Such information
+  could be useful when detecting a possible intrusion attempt.  This
+  option will produce less logs than logging all calls.  If the sysctl
+  option is enabled, a sysctl option with name "suid_root_logging" is
+  created.
+
+Altered default IPC permissions
+CONFIG_GRKERNSEC_IPC
+  If you say Y here, the default permissions for IPC objects will be
+  set based on the filesystem umask of the user creating the object.
+  By default linux sets the permissions to ugo+rwx, which can be
+  a security problem if the application doesn't explicitly set the
+  permissions of the IPC object.
+
+Signal logging
+CONFIG_GRKERNSEC_SIGNAL
+  If you say Y here, certain important signals will be logged, such as
+  SIGSEGV, which will as a result inform you of when a error in a program
+  occurred, which in some cases could mean a possible exploit attempt.
+  If the sysctl option is enabled, a sysctl option with name 
+  "signal_logging" is created.
+
+BSD-style coredumps
+CONFIG_GRKERNSEC_COREDUMP
+  If you say Y here, linux will use a style similar to BSD for
+  coredumps, core.processname.  Not a security feature, just
+  a useful one.  If the sysctl option is enabled, a sysctl option with 
+  name "coredump" is created.
+
+Fork failure logging
+CONFIG_GRKERNSEC_FORKFAIL
+  If you say Y here, all failed fork() attempts will be logged.
+  This could suggest a fork bomb, or someone attempting to overstep
+  their process limit.  If the sysctl option is enabled, a sysctl option
+  with name "forkfail_logging" is created.
+
+Time change logging
+CONFIG_GRKERNSEC_TIME
+  If you say Y here, any changes of the system clock will be logged.
+  If the sysctl option is enabled, a sysctl option with name 
+  "timechange_logging" is created.
+
+Secure keymap loading
+CONFIG_GRKERNSEC_KBMAP
+  If you say Y here, KDSKBENT and KDSKBSENT ioctl calls being
+  called by unprivileged users will be denied. If you answer N,
+  everyone with access to the console will be able to modify keyboard 
+  bindings.  If the sysctl option is enabled, a sysctl option with name
+  "secure_kbmap" is created.
+
+Chroot jail restrictions
+CONFIG_GRKERNSEC_CHROOT
+  If you say Y here, you will be able to choose several options that will
+  make breaking out of a chrooted jail much more difficult.  If you
+  encounter no software incompatibilities with the following options, it
+  is recommended that you enable each one.
+
+Restricted signals in chroot
+CONFIG_GRKERNSEC_CHROOT_SIG
+  If you say Y here, processes inside a chroot will not be able to send
+  signals outside of the chroot.  The only signals allowed are null 
+  signals which perform no action, and the parent process sending 
+  a certain signal to its child.  If the sysctl option is enabled, a
+  sysctl option with name "chroot_restrict_sigs" is created.
+
+Deny mounts in chroot
+CONFIG_GRKERNSEC_CHROOT_MOUNT
+  If you say Y here, processes inside a chroot will not be able to
+  mount or remount filesystems.  If the sysctl option is enabled, a 
+  sysctl option with name "chroot_deny_mount" is created.
+
+Deny double-chroots
+CONFIG_GRKERNSEC_CHROOT_DOUBLE
+  If you say Y here, processes inside a chroot will not be able to chroot
+  again.  This is a widely used method of breaking out of a chroot jail
+  and should not be allowed.  If the sysctl option is enabled, a sysctl
+  option with name "chroot_deny_chroot" is created.
+
+Enforce chdir("/") on all chroots
+CONFIG_GRKERNSEC_CHROOT_CHDIR
+  If you say Y here, the current working directory of all newly-chrooted
+  applications will be set to the the root directory of the chroot.
+  The man page on chroot(2) states:
+  Note that this call does not change  the  current  working
+  directory,  so  that `.' can be outside the tree rooted at
+  `/'.  In particular, the  super-user  can  escape  from  a
+  `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.  
+
+  It is recommended that you say Y here, since it's not known to break
+  any software.  If the sysctl option is enabled, a sysctl option with
+  name "chroot_enforce_chdir" is created.
+
+Deny (f)chmod +s in chroot
+CONFIG_GRKERNSEC_CHROOT_CHMOD
+  If you say Y here, processes inside a chroot will not be able to chmod
+  or fchmod files to make them have suid or sgid bits.  This protects 
+  against another published method of breaking a chroot.  If the sysctl 
+  option is enabled, a sysctl option with name "chroot_deny_chmod" is
+  created.
+
+Deny mknod in chroot
+CONFIG_GRKERNSEC_CHROOT_MKNOD
+  If you say Y here, processes inside a chroot will not be allowed to
+  mknod.  The problem with using mknod inside a chroot is that it
+  would allow an attacker to create a device entry that is the same
+  as one on the physical root of your system, which could range from
+  anyhing from the console device to a device for your harddrive (which
+  they could then use to wipe the drive or steal data).  It is recommended
+  that you say Y here, unless you run into software incompatibilities.
+  If the sysctl option is enabled, a sysctl option with name
+  "chroot_deny_mknod" is created.
+
+Deny ptraces in chroot
+CONFIG_GRKERNSEC_CHROOT_PTRACE
+  If you say Y here, processes inside a chroot will not be able to ptrace
+  other processes.  Ptracing a process allows one to attach and alter the
+  flow of execution for the process.  It is strongly recommended that you
+  say Y here.  If the sysctl option is enabled, a sysctl option with name
+  "chroot_deny_ptrace" is created.
+
+Restrict priority changes in chroot
+CONFIG_GRKERNSEC_CHROOT_NICE
+  If you say Y here, processes inside a chroot will not be able to raise
+  the priority of processes in the chroot, or alter the priority of 
+  processes outside the chroot.  This provides more security than simply
+  removing CAP_SYS_NICE from the process' capability set.  If the
+  sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
+  is created.
+
+Log all execs within chroot
+CONFIG_GRKERNSEC_CHROOT_EXECLOG
+  If you say Y here, all executions inside a chroot jail will be logged 
+  to syslog.  If the sysctl option is enabled, a sysctl option with name
+  "chroot_execlog" is created.
+
+Chroot jail capability restrictions
+CONFIG_GRKERNSEC_CHROOT_CAPS
+  If you say Y here, the capabilities on all root processes within a
+  chroot jail will be lowered to stop module insertion, raw i/o,
+  system and net admin tasks, transferring capabilities, and
+  tty configuration tasks.  This is left an option because it breaks
+  some apps.  Disable this if your chrooted apps are having
+  problems performing those kinds of tasks.  If the sysctl option is 
+  enabled, a sysctl option with name "chroot_caps" is created.
+
+Trusted path execution
+CONFIG_GRKERNSEC_TPE
+  If you say Y here, you will be able to choose a gid to add to the
+  supplementary groups of users you want to mark as "untrusted."
+  These users will not be able to execute any files that are not in
+  root-owned directories writeable only by root.  If the sysctl option
+  is enabled, a sysctl option with name "tpe" is created.
+
+Group for trusted path execution
+CONFIG_GRKERNSEC_TPE_GID
+  Here you can choose the GID to enable trusted path protection for.
+  Remember to add the users you want protection enabled for to the GID 
+  specified here.  If the sysctl option is enabled, whatever you choose
+  here won't matter. You'll have to specify the GID in your bootup 
+  script by echoing the GID to the proper /proc entry.  View the help
+  on the sysctl option for more information.  If the sysctl option is
+  enabled, a sysctl option with name "tpe_gid" is created.
+
+Partially restrict non-root users
+CONFIG_GRKERNSEC_TPE_ALL
+  If you say Y here, All other non-root users will only be allowed to
+  execute files in directories they own that are not group or
+  world-writeable, or in directories owned by root and writeable only by
+  root.  If the sysctl option is enabled, a sysctl option with name 
+  "tpe_restrict_all" is created.
+
+Trusted path execution glibc protection
+CONFIG_GRKERNSEC_TPE_GLIBC
+  If you say Y here, all non-root users will not be able to execute
+  any files while glibc specific environment variables such as
+  LD_PRELOAD are set, which could be used to evade the trusted path 
+  execution protection.  It also protects against evasion through 
+  /lib/ld-2.*  It is recommended you say Y here also. If the sysctl option 
+  is enabled, a sysctl option with name "tpe_glibc" is created.
+
+Restricted ptrace
+CONFIG_GRKERNSEC_PTRACE
+  If you say Y here, no one but root will be able to ptrace processes.
+  Tracing syscalls inside the kernel will also be disabled.  All allowed
+  ptraces will be logged when this option is enabled.  If the sysctl
+  option is enabled, a sysctl option with name "restrict_ptrace" is
+  created.
+
+Allow ptrace for group
+CONFIG_GRKERNSEC_PTRACE_GROUP
+  If you say Y here, you will be able to choose a GID of whose users
+  will be able to ptrace.  If the sysctl option is enabled, a sysctl 
+  option with name "allow_ptrace_group" is created.
+
+GID for ptrace
+CONFIG_GRKERNSEC_PTRACE_GID
+  Here you can choose the GID of whose users will be able to ptrace.
+  Remember to add the users you want ptrace enabled for to the GID
+  specified here.  If the sysctl option is enabled, whatever you choose
+  here won't matter. You'll have to specify the GID in your bootup
+  script by echoing the GID to the proper /proc entry.  View the help
+  on the sysctl option for more information.  If the sysctl option is
+  enabled, a sysctl option with name "ptrace_gid" is created.
+
+Randomized PIDs
+CONFIG_GRKERNSEC_RANDPID
+  If you say Y here, all PIDs created on the system will be
+  pseudo-randomly generated.  This is extremely effective along
+  with the /proc restrictions to disallow an attacker from guessing
+  pids of daemons, etc.  PIDs are also used in some cases as part
+  of a naming system for temporary files, so this option would keep
+  those filenames from being predicted as well.  We also use code
+  to make sure that PID numbers aren't reused too soon.  If the sysctl
+  option is enabled, a sysctl option with name "rand_pids" is created.
+
+Limit uid/gid changes to root
+CONFIG_GRKERNSEC_TTYROOT
+  If you say Y here, you will be able choose from three option that
+  will allow you to restrict access to the root account by console
+  type.  These options should only be enabled if you are sure of what
+  you're doing.  Also note that they only apply to processes that have
+  ttys, which generally involves some kind of user-interaction.  The
+  options are basically in place to keep users on a system who have a
+  (stolen) password for root from using it unless their console
+  credentials match.
+
+Deny physical consoles (tty)
+CONFIG_GRKERNSEC_TTYROOT_PHYS
+  If you say Y here, access to root from physical consoles will be
+  denied. This is only recommended for rare cases where you will
+  never need to be physically at the machine.  If the sysctl option
+  is enabled, a sysctl option with name "deny_phys_root" is created.
+
+Deny serial consoles (ttyS)
+CONFIG_GRKERNSEC_TTYROOT_SERIAL
+  If you say Y here, access to root from serial consoles will be
+  denied. Most people can say Y here, since most don't use serial
+  devices for their console access.  If you are unsure, say N.  If
+  the sysctl option is enabled, a sysctl option with name 
+  "deny_serial_root" is created.
+
+Deny pseudo consoles (pty)
+CONFIG_GRKERNSEC_TTYROOT_PSEUDO
+  If you say Y here, access to root from pseudo consoles will be
+  denied. Pseudo consoles include consoles from telnet, ssh, or any other
+  kind of interactive shell initiated from the network.  Pseudo consoles
+  also include any terminals you use in XFree86.  If you will only be
+  accessing the machine for root access from the physical console, you
+  can say Y here.  Only say Y here if you're sure of what you're doing.
+  If the sysctl option is enabled, a sysctl option with name 
+  "deny_pseudo_root" is created.
+
+Randomized IP IDs
+CONFIG_GRKERNSEC_RANDID
+  If you say Y here, all the id field on all outgoing packets
+  will be randomized.  This hinders os fingerprinters and
+  keeps your machine from being used as a bounce for an untraceable
+  portscan.  Ids are used for fragmented packets, fragments belonging
+  to the same packet have the same id.  By default linux only
+  increments the id value on each packet sent to an individual host.
+  We use a port of the OpenBSD random ip id code to achieve the
+  randomness, while keeping the possibility of id duplicates to
+  near none.  If the sysctl option is enabled, a sysctl option with name
+  "rand_ip_ids" is created.
+
+Randomized TCP source ports
+CONFIG_GRKERNSEC_RANDSRC
+  If you say Y here, situations where a source port is generated on the
+  fly for the TCP protocol (ie. with connect() ) will be altered so that
+  the source port is generated at random, instead of a simple incrementing
+  algorithm.  If the sysctl option is enabled, a sysctl option with name
+  "rand_tcp_src_ports" is created.
+
+Altered Ping IDs
+CONFIG_GRKERNSEC_RANDPING
+  If you say Y here, the way Linux handles echo replies will be changed
+  so that the reply uses an ID equal to the ID of the echo request.
+  This will help in confusing OS detection.  If the sysctl option is
+  enabled, a sysctl option with name "altered_pings" is created.
+
+Randomized TTL
+CONFIG_GRKERNSEC_RANDTTL
+  If you say Y here, your TTL (time to live) for packets will be set at
+  random, with a base level you specify, to further confuse OS detection.
+  If the sysctl option is enabled, a sysctl option with name "rand_ttl"
+  is created.
+
+Randomized TTL threshold
+CONFIG_GRKERNSEC_RANDTTL_THRESH
+  Here you can choose a base TTL for the randomization.  The default value
+  for this setting is the Linux default TTL.  Most users will want to 
+  leave this setting as-is.  The higher you set the base level (note that
+  you can't set it above 255) the more hops your packets will live.  
+  If the sysctl option is enabled, whatever you choose here won't matter. 
+  You'll have to specify the threshold in your bootup script by echoing 
+  the threshold to the proper /proc entry.  View the help on the sysctl 
+  option for more information.  If the sysctl option is enabled, a sysctl 
+  option with name "rand_ttl_thresh" is created.
+
+Socket restrictions
+CONFIG_GRKERNSEC_SOCKET
+  If you say Y here, you will be able to choose from several options.
+  If you assign a GID on your system and add it to the supplementary
+  groups of users you want to restrict socket access to, this patch
+  will perform up to three things, based on the option(s) you choose.
+
+Deny all socket access
+CONFIG_GRKERNSEC_SOCKET_ALL
+  If you say Y here, you will be able to choose a GID of whose users will
+  be unable to connect to other hosts from your machine or run server
+  applications from your machine.  If the sysctl option is enabled, a
+  sysctl option with name "socket_all" is created.
+
+Group for disabled socket access
+CONFIG_GRKERNSEC_SOCKET_ALL_GID
+  Here you can choose the GID to disable socket access for. Remember to 
+  add the users you want socket access disabled for to the GID 
+  specified here.  If the sysctl option is enabled, whatever you choose
+  here won't matter. You'll have to specify the GID in your bootup 
+  script by echoing the GID to the proper /proc entry.  View the help
+  on the sysctl option for more information.  If the sysctl option is
+  enabled, a sysctl option with name "socket_all_gid" is created.
+
+Deny all client socket access
+CONFIG_GRKERNSEC_SOCKET_CLIENT
+  If you say Y here, you will be able to choose a GID of whose users will
+  be unable to connect to other hosts from your machine, but will be
+  able to run servers.  If this option is enabled, all users in the group
+  you specify will have to use passive mode when initiating ftp transfers
+  from the shell on your machine.  If the sysctl option is enabled, a
+  sysctl option with name "socket_client" is created.
+
+Group for disabled client socket access
+CONFIG_GRKERNSEC_SOCKET_CLIENT_GID
+  Here you can choose the GID to disable client socket access for. 
+  Remember to add the users you want client socket access disabled for to 
+  the GID specified here.  If the sysctl option is enabled, whatever you 
+  choose here won't matter. You'll have to specify the GID in your bootup 
+  script by echoing the GID to the proper /proc entry.  View the help
+  on the sysctl option for more information.  If the sysctl option is
+  enabled, a sysctl option with name "socket_client_gid" is created.
+
+Deny all server socket access
+CONFIG_GRKERNSEC_SOCKET_SERVER
+  If you say Y here, you will be able to choose a GID of whose users will
+  be unable to run server applications from your machine.  If the sysctl 
+  option is enabled, a sysctl option with name "socket_server" is created.
+
+Group for disabled server socket access
+CONFIG_GRKERNSEC_SOCKET_SERVER_GID
+  Here you can choose the GID to disable server socket access for. 
+  Remember to add the users you want server socket access disabled for to 
+  the GID specified here.  If the sysctl option is enabled, whatever you 
+  choose here won't matter. You'll have to specify the GID in your bootup 
+  script by echoing the GID to the proper /proc entry.  View the help
+  on the sysctl option for more information.  If the sysctl option is
+  enabled, a sysctl option with name "socket_server_gid" is created.
+
+Sysctl support
+CONFIG_GRKERNSEC_SYSCTL
+  If you say Y here, you will be able to change the options that
+  grsecurity runs with at bootup, without having to recompile your
+  kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
+  to enable (1) or disable (0) various features.  All the sysctl entries
+  are mutable until the "grsec_lock" entry is set to a non-zero value.
+  All features are disabled by default. Please note that this option could 
+  reduce the effectiveness of the added security of this patch if an ACL 
+  system is not put in place.  Your init scripts should be read-only, and 
+  root should not have access to adding modules or performing raw i/o 
+  operations.  All options should be set at startup, and the grsec_lock 
+  entry should be set to a non-zero value after all the options are set.  
+  *THIS IS EXTREMELY IMPORTANT*
+
+Oblivion ACL System
+CONFIG_GRKERNSEC_ACL
+  If you say Y here, you enable the Access Control List system for 
+  grsecurity called Oblivion. Oblivion is a very advanced ACL system
+  that is optimized for speed and correctness of ACLS.  Unlike many 
+  other popular ACL systems, it allows both process and file ACLs.
+  To use the ACL system, you must also download the userspace code
+  and documentation off the grsecurity website: http://grsecurity.net
+  You will then need to run obvadm setup to set your password and create 
+  your config files.
+  
 #
 # m68k-specific kernel options
 # Documented by Chris Lawrence <mailto:quango@themall.net> et al.
diff -urN linux/Makefile linux/Makefile
--- linux/Makefile	Fri Dec 21 12:41:53 2001
+++ linux/Makefile	Thu Jan 17 17:12:27 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 17
-EXTRAVERSION =
+EXTRAVERSION = -grsec-1.9.3a
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux/arch/alpha/config.in linux/arch/alpha/config.in
--- linux/arch/alpha/config.in	Tue Nov 20 18:49:31 2001
+++ linux/arch/alpha/config.in	Sun Jan 13 01:24:51 2002
@@ -393,3 +393,12 @@
 fi
 
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/arm/config.in linux/arch/arm/config.in
--- linux/arch/arm/config.in	Fri Nov  9 16:58:02 2001
+++ linux/arch/arm/config.in	Sun Jan 13 01:24:51 2002
@@ -606,3 +606,12 @@
 dep_bool '  Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '  kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/cris/config.in linux/arch/cris/config.in
--- linux/arch/cris/config.in	Mon Oct 15 16:42:14 2001
+++ linux/arch/cris/config.in	Sun Jan 13 01:24:51 2002
@@ -251,3 +251,12 @@
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/i386/config.in linux/arch/i386/config.in
--- linux/arch/i386/config.in	Fri Dec 21 12:41:53 2001
+++ linux/arch/i386/config.in	Sun Jan 13 01:24:51 2002
@@ -416,3 +416,12 @@
 fi
 
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux/arch/i386/kernel/entry.S	Fri Nov  2 20:18:49 2001
+++ linux/arch/i386/kernel/entry.S	Sun Jan 13 01:24:51 2002
@@ -45,6 +45,7 @@
 #include <linux/linkage.h>
 #include <asm/segment.h>
 #include <asm/smp.h>
+#include <asm/page.h>
 
 EBX		= 0x00
 ECX		= 0x04
@@ -381,8 +382,52 @@
 	jmp error_code
 
 ENTRY(page_fault)
+#ifdef CONFIG_GRKERNSEC_PAX
+	ALIGN
+	pushl $ SYMBOL_NAME(pax_do_page_fault)
+	pushl %ds
+	pushl %eax
+	xorl %eax,%eax
+	pushl %ebp
+	pushl %edi
+	pushl %esi
+	pushl %edx
+	decl %eax			# eax = -1
+	pushl %ecx
+	pushl %ebx
+	cld
+	movl %es,%ecx
+	movl ORIG_EAX(%esp), %esi	# get the error code
+	movl ES(%esp), %edi		# get the function address
+	movl %eax, ORIG_EAX(%esp)
+	movl %ecx, ES(%esp)
+	movl %esp,%edx
+	pushl %esi			# push the error code
+	pushl %edx			# push the pt_regs pointer
+	movl $(__KERNEL_DS),%edx
+	movl %edx,%ds
+	movl %edx,%es
+	GET_CURRENT(%ebx)
+	call *%edi
+	addl $8,%esp
+	decl %eax
+	jnz ret_from_exception
+
+	popl %ebx
+	popl %ecx
+	popl %edx
+	popl %esi
+	popl %edi
+	popl %ebp
+	popl %eax
+	popl %ds
+	popl %es
+	addl $4,%esp
+	jmp system_call
+#else
 	pushl $ SYMBOL_NAME(do_page_fault)
 	jmp error_code
+#endif
 
 ENTRY(machine_check)
 	pushl $0
diff -urN linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S
--- linux/arch/i386/kernel/head.S	Wed Jun 20 14:00:53 2001
+++ linux/arch/i386/kernel/head.S	Sun Jan 13 01:24:51 2002
@@ -433,7 +433,11 @@
 	.quad 0x0000000000000000	/* not used */
 	.quad 0x00cf9a000000ffff	/* 0x10 kernel 4GB code at 0x00000000 */
 	.quad 0x00cf92000000ffff	/* 0x18 kernel 4GB data at 0x00000000 */
+#ifdef CONFIG_GRKERNSEC_STACK
+        .quad 0x00cbfa000000f7ff        /* 0x23 user   3GB-8MB code at 0 */
+#else
 	.quad 0x00cffa000000ffff	/* 0x23 user   4GB code at 0x00000000 */
+#endif
 	.quad 0x00cff2000000ffff	/* 0x2b user   4GB data at 0x00000000 */
 	.quad 0x0000000000000000	/* not used */
 	.quad 0x0000000000000000	/* not used */
diff -urN linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- linux/arch/i386/kernel/ptrace.c	Wed Nov 21 13:42:41 2001
+++ linux/arch/i386/kernel/ptrace.c	Sun Jan 13 01:24:51 2002
@@ -21,6 +21,9 @@
 #include <asm/i387.h>
 #include <asm/debugreg.h>
 
+#if defined(CONFIG_GRKERNSEC_CHROOT_PTRACE) || defined(CONFIG_GRKERNSEC_PTRACE)
+#include <linux/grsecurity.h>
+#endif
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
@@ -177,6 +180,32 @@
 	if (pid == 1)		/* you may not mess with init */
 		goto out_tsk;
 
+#ifdef CONFIG_GRKERNSEC_PTRACE
+	if(grsec_enable_ptrace && current->uid
+#ifdef CONFIG_GRKERNSEC_PTRACE_GROUP
+	   && ((grsec_enable_ptrace_group && !in_group_p(grsec_ptrace_gid))
+	   || !grsec_enable_ptrace_group)
+#endif
+	) {
+		security_alert("denied ptrace of (%.16s:%d) by " DEFAULTSECMSG,
+				"denied ptraces", child->comm, child->pid, DEFAULTSECARGS);
+		goto out_tsk;
+	}
+		security_alert("ptrace of (%.16s:%d) by " DEFAULTSECMSG,
+				"ptraces", child->comm, child->pid, DEFAULTSECARGS);
+#endif		
+#ifdef CONFIG_GRKERNSEC_CHROOT_PTRACE
+	if(grsec_enable_chroot_ptrace && proc_is_chrooted(current) &&
+	   have_same_root(current,child)) {
+		security_alert("denied ptrace of process(%.16s:%d) within chroot jail "
+                               "(%.32s:%lu) by " DEFAULTSECMSG, 
+                               "ptrace from chroot",
+                               child->comm,child->pid,kdevname(current->fs->root->d_inode->i_dev),
+                               current->fs->root->d_inode->i_ino, 
+			       DEFAULTSECARGS);
+		goto out_tsk;
+	}
+#endif
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
 		goto out_tsk;
@@ -439,11 +468,23 @@
 	return ret;
 }
 
+#ifdef CONFIG_GRKERNSEC_PTRACE
+asmlinkage void syscall_trace(int unused)
+#else
 asmlinkage void syscall_trace(void)
+#endif
 {
+#ifdef CONFIG_GRKERNSEC_PTRACE
+	struct pt_regs *regs = (struct pt_regs *) &unused;
+#endif
+
 	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) !=
 			(PT_PTRACED|PT_TRACESYS))
 		return;
+#ifdef CONFIG_GRKERNSEC_PTRACE
+	if(!user_mode(regs))
+		return;
+#endif
 	/* the 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
 	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
diff -urN linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- linux/arch/i386/kernel/signal.c	Fri Sep 14 17:15:40 2001
+++ linux/arch/i386/kernel/signal.c	Sun Jan 13 01:24:51 2002
@@ -7,6 +7,7 @@
  *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -421,11 +422,15 @@
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
 	} else {
+#ifdef CONFIG_GRKERNSEC_STACK
+		err |= __put_user(MAGIC_SIGRETURN, &frame->pretcode);
+#else
 		err |= __put_user(frame->retcode, &frame->pretcode);
 		/* This is popl %eax ; movl $,%eax ; int $0x80 */
 		err |= __put_user(0xb858, (short *)(frame->retcode+0));
 		err |= __put_user(__NR_sigreturn, (int *)(frame->retcode+2));
 		err |= __put_user(0x80cd, (short *)(frame->retcode+6));
+#endif
 	}
 
 	if (err)
@@ -496,11 +501,15 @@
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
 	} else {
+#ifdef CONFIG_GRKERNSEC_STACK
+		err |= __put_user(MAGIC_RT_SIGRETURN, &frame->pretcode);
+#else
 		err |= __put_user(frame->retcode, &frame->pretcode);
 		/* This is movl $,%eax ; int $0x80 */
 		err |= __put_user(0xb8, (char *)(frame->retcode+0));
 		err |= __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1));
 		err |= __put_user(0x80cd, (short *)(frame->retcode+5));
+#endif
 	}
 
 	if (err)
@@ -557,6 +566,18 @@
 				regs->eip -= 2;
 		}
 	}
+
+#ifdef CONFIG_GRKERNSEC_PAX
+	/* PaX: clean up as our trace attempt became obsolete */
+	if ((current->flags & PF_PAX_PAGEEXEC) && (current->ptrace & PT_PAX_TRACE)) {
+		if (!(current->ptrace & PT_PAX_OLDTF)) {
+			regs->eflags &= ~TF_MASK;
+		}
+		current->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
+		current->thread.pax_faults.eip = 0;
+		current->thread.pax_faults.count = 0;
+	}
+#endif
 
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
diff -urN linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- linux/arch/i386/kernel/traps.c	Sun Sep 30 15:26:08 2001
+++ linux/arch/i386/kernel/traps.c	Sun Jan 13 01:24:51 2002
@@ -49,6 +49,9 @@
 
 #include <linux/irq.h>
 #include <linux/module.h>
+#ifdef CONFIG_GRKERNSEC_STACK
+#include <linux/grsecurity.h>
+#endif
 
 asmlinkage int system_call(void);
 asmlinkage void lcall7(void);
@@ -348,14 +351,183 @@
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
 
+#if defined(CONFIG_GRKERNSEC_STACK) && defined(CONFIG_GRKERNSEC_STACK_GCC)
+static unsigned long *get_reg(struct pt_regs *regs, unsigned char regnum)
+{
+    switch (regnum) {
+	case 0: return &regs->eax;
+	case 1: return &regs->ecx;
+	case 2: return &regs->edx;
+	case 3: return &regs->ebx;
+	case 4: return &regs->esp;
+	case 5: return &regs->ebp;
+	case 6: return &regs->esi;
+	case 7: return &regs->edi;
+    }
+    return NULL;
+}
+static unsigned long get_modrm(struct pt_regs *regs, int *err)
+{
+       unsigned char modrm, sib;
+       signed char rel8;
+       unsigned long rel32;
+       int size, regnum, scale;
+       unsigned long index, base, addr, value;
+
+       *err |= __get_user(modrm, (unsigned char *)(regs->eip + 1));
+       size = 2;
+       regnum = modrm & 7;
+       addr = *get_reg(regs, regnum);
+       if (regnum == 4 && (modrm & 0xC0) != 0xC0) {
+               *err |= __get_user(sib, (unsigned char *)(regs->eip + 2));
+               size = 3;
+               scale = sib >> 6;
+               index = *get_reg(regs, (sib >> 3) & 7);
+               base = *get_reg(regs, sib & 7);
+               addr = base + (index << scale);
+       }
+
+       switch (modrm & 0xC0) {
+       case 0x00:
+               if (regnum == 5) {
+                       *err |= __get_user(addr,
+                               (unsigned long *)(regs->eip + 2));
+                       size = 6;
+               }
+               *err |= __get_user(value, (unsigned long *)addr);
+               break;
+
+       case 0x40:
+               *err |= __get_user(rel8, (signed char *)(regs->eip + size));
+               size++;
+               addr += rel8;
+               *err |= __get_user(value, (unsigned long *)addr);
+               break;
+
+       case 0x80:
+               *err |= __get_user(rel32, (unsigned long *)(regs->eip + size));
+               size += 4;
+               addr += rel32;
+               *err |= __get_user(value, (unsigned long *)addr);
+               break;
+
+       case 0xC0:
+       default:
+               value = addr;
+       }
+
+       if (*err) return 0;
+       regs->eip += size;
+       return value;
+}
+#endif
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
+#ifdef CONFIG_GRKERNSEC_STACK
+    unsigned long addr;
+#ifdef CONFIG_GRKERNSEC_STACK_GCC
+    unsigned char insn;
+    int err, count;
+#endif
+#endif
 	if (regs->eflags & VM_MASK)
 		goto gp_in_vm86;
 
 	if (!(regs->xcs & 3))
 		goto gp_in_kernel;
 
+#ifdef CONFIG_GRKERNSEC_STACK
+/* Check if it was return from a signal handler */
+        if ((regs->xcs & 0xFFFF) == __USER_CS)
+        if (*(unsigned char *)regs->eip == 0xC3)
+        if (!__get_user(addr, (unsigned long *)regs->esp)) {
+                if ((addr & 0xFFFFFFFE) == MAGIC_SIGRETURN) {
+/* Call sys_sigreturn() or sys_rt_sigreturn() to restore the context */
+                        regs->esp += 8;
+                        __asm__("movl %3,%%esi\n\t"
+                                "subl %1,%%esp\n\t"
+                                "movl %2,%%ecx\n\t"
+                                "movl %%esp,%%edi\n\t"
+                                "rep; movsl\n\t"
+                                "testl $1,%4\n\t"
+                                "jnz 1f\n\t"
+                                "call sys_sigreturn\n\t"
+                                "leal %3,%%edi\n\t"
+                                "jmp 2f\n\t"
+                                "1:\n\t"
+                                "call sys_rt_sigreturn\n\t"
+                                "leal %3,%%edi\n\t"
+                                "2:\n\t"
+                                "addl %1,%%edi\n\t"
+                                "movl %%esp,%%esi\n\t"
+                                "movl %2,%%ecx\n\t"
+                                "movl (%%edi),%%edi\n\t"
+                                "rep; movsl\n\t"
+                                "movl %%esi,%%esp"
+                        :
+/* %eax is returned separately */
+                        "=a" (regs->eax)
+                        :
+                        "i" (sizeof(*regs)),
+                        "i" (sizeof(*regs) >> 2),
+                        "m" (regs),
+                        "r" (addr)
+                        :
+                        "cx", "dx", "si", "di", "cc", "memory");
+                        return;
+                }
+/*
+ *  * Check if we're returning to the stack area, which is only likely to happen
+ *   * when attempting to exploit a buffer overflow.
+ *    */
+                if ((addr & 0xFF800000) == 0xBF800000 ||
+                    (addr >= PAGE_OFFSET - _STK_LIM && addr < PAGE_OFFSET))
+                        security_alert("return onto stack by " DEFAULTSECMSG,
+                                "returns onto stack", DEFAULTSECARGS);
+        }
+ 
+#ifdef CONFIG_GRKERNSEC_STACK_GCC
+/* Check if it could have been a trampoline call */
+        if ((regs->xcs & 0xFFFF) == __USER_CS)
+        if (*(unsigned char *)regs->eip == 0xFF)
+        if (!__get_user(insn, (unsigned char *)(regs->eip + 1)))
+        if ((insn & 0x38) == 0x10 && insn != 0xD4) {    /* call mod r/m */
+/* First, emulate the call */
+                err = 0;
+                addr = get_modrm(regs, &err);
+                if (!err) {
+                        regs->esp -= 4;
+                        err = __put_user(regs->eip, (unsigned long *)regs->esp);
+                        regs->eip = addr;
+                }  
+/* Then, start emulating the trampoline itself */
+               count = 0;
+               while (!err && !__get_user(insn, (unsigned char *)regs->eip++))
+               if ((insn & 0xF8) == 0xB8) {            /* movl imm32,%reg */
+/* We only have 8 GP registers, no reason to initialize one twice */
+                        if (count++ >= 8) break;
+                        err |= __get_user(addr, (unsigned long *)regs->eip);
+                        regs->eip += 4;
+                        *get_reg(regs, insn & 7) = addr;
+                } else
+                if (insn == 0xFF) {
+                        err |= __get_user(insn, (unsigned char *)regs->eip);
+                        if ((insn & 0xF8) == 0xE0) {    /* jmp *%reg */
+                                regs->eip = *get_reg(regs, insn & 7);
+                                if (err) break; else return;
+                        }
+                        break;
+                } else
+               if (insn == 0xE9) {                     /* jmp rel32 */
+                       err |= __get_user(addr, (unsigned long *)regs->eip);
+                       if (err) break;
+                       regs->eip += 4 + addr;
+                       return;
+               } else
+                       break;
+       }                        
+#endif
+#endif
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
 	force_sig(SIGSEGV, current);
@@ -452,6 +624,10 @@
 	inb(0x71);		/* dummy */
 }
 
+#ifdef CONFIG_GRKERNSEC_PAX
+void pax_handle_ptes(struct task_struct *tsk);
+#endif
+
 /*
  * Our handling of the processor debug registers is non-trivial.
  * We do not clear them on entry and exit from the kernel. Therefore
@@ -482,6 +658,22 @@
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
+#ifdef CONFIG_GRKERNSEC_PAX
+	/* PaX: clean up */
+	if ((tsk->flags & PF_PAX_PAGEEXEC) && (condition & DR_STEP) && (tsk->ptrace & PT_PAX_TRACE)) {
+		tsk->ptrace &= ~PT_PAX_TRACE;
+		pax_handle_ptes(tsk);
+		if (!(tsk->ptrace & PT_PAX_KEEPTF) && !(tsk->ptrace & PT_PAX_OLDTF))
+			regs->eflags &= ~TF_MASK;
+		tsk->ptrace &= ~PT_PAX_KEEPTF;
+		if (!(tsk->ptrace & PT_PAX_OLDTF)) {
+			condition &= ~DR_STEP;
+			if (!(condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)))
+				return;
+		}
+		tsk->ptrace &= ~PT_PAX_OLDTF;
+	}
+#endif
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 		if (!tsk->thread.debugreg[7])
diff -urN linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- linux/arch/i386/mm/fault.c	Tue Oct  9 18:13:03 2001
+++ linux/arch/i386/mm/fault.c	Sun Jan 13 01:24:51 2002
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995  Linus Torvalds
  */
 
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -19,6 +20,9 @@
 #include <linux/init.h>
 #include <linux/tty.h>
 #include <linux/vt_kern.h>		/* For unblank_screen() */
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_RANDMMAP)
+#include <linux/unistd.h>
+#endif
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -146,23 +150,31 @@
  *	bit 1 == 0 means read, 1 means write
  *	bit 2 == 0 means kernel, 1 means user-mode
  */
+#ifdef CONFIG_GRKERNSEC_PAX
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
+#else
 asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+#endif
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct * vma;
+#ifndef CONFIG_GRKERNSEC_PAX
 	unsigned long address;
+#endif
 	unsigned long page;
 	unsigned long fixup;
 	int write;
 	siginfo_t info;
 
+#ifndef CONFIG_GRKERNSEC_PAX
 	/* get the address */
 	__asm__("movl %%cr2,%0":"=r" (address));
 
 	/* It's safe to allow irq's after cr2 has been saved */
 	if (regs->eflags & X86_EFLAGS_IF)
 		local_irq_enable();
+#endif
 
 	tsk = current;
 
@@ -220,21 +232,37 @@
 good_area:
 	info.si_code = SEGV_ACCERR;
 	write = 0;
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+	switch (error_code & 7) {
+#else
 	switch (error_code & 3) {
+#endif
 		default:	/* 3: write, present */
 #ifdef TEST_VERIFY_AREA
 			if (regs->cs == KERNEL_CS)
 				printk("WP fault at %08lx\n", regs->eip);
 #endif
 			/* fall through */
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		case 7:		/* PaX: write, present, some protection violation */
+#endif
 		case 2:		/* write, not present */
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		case 6:
+#endif
 			if (!(vma->vm_flags & VM_WRITE))
 				goto bad_area;
 			write++;
 			break;
 		case 1:		/* read, present */
 			goto bad_area;
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		case 5:		/* PaX: read, present, protection violation */
+#endif
 		case 0:		/* read, not present */
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		case 4:
+#endif
 			if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
 				goto bad_area;
 	}
@@ -409,3 +437,441 @@
 		return;
 	}
 }
+#ifdef CONFIG_GRKERNSEC_PAX
+/* PaX: called with the page_table_lock spinlock held */
+static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+
+	pgd = pgd_offset(mm, address);
+	if (!pgd || !pgd_present(*pgd))
+		return 0;
+	pmd = pmd_offset(pgd, address);
+	if (!pmd || !pmd_present(*pmd))
+		return 0;
+	return pte_offset(pmd, address);
+}
+
+/*
+ * PaX: decide what to do with offenders
+ *
+ * returns 0 when access should be allowed
+ *         1 when task should be killed
+ *         2 when sigreturn trampoline was detected
+ *         3 when rt_sigreturn trampoline was detected
+ *         4 when gcc trampoline was detected
+ */
+static int pax_handle_read_fault(struct pt_regs *regs, unsigned long address)
+{
+	static unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
+	int err;
+
+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
+	if (!(current->flags & PF_PAX_EMUTRAMP))
+		return 1;
+
+	{ /* PaX: sigreturn emulation */
+		unsigned char pop, mov;
+		unsigned short sys;
+		unsigned long nr;
+
+		err = __get_user(pop, (unsigned char *)(regs->eip));
+		err |= __get_user(mov, (unsigned char *)(regs->eip + 1));
+		err |= __get_user(nr, (unsigned long *)(regs->eip + 2));
+		err |= __get_user(sys, (unsigned short *)(regs->eip + 6));
+
+		if (!err) {
+			if (pop == 0x58 &&
+			    mov == 0xb8 &&
+			    nr == __NR_sigreturn &&
+			    sys == 0x80cd)
+			{
+				regs->esp += 4;
+				regs->eax = nr;
+				regs->eip += 8;
+				return 2;
+			}
+		}
+	}
+
+	{ /* PaX: rt_sigreturn emulation */
+		unsigned char mov;
+		unsigned short sys;
+		unsigned long nr;
+
+		err = __get_user(mov, (unsigned char *)(regs->eip));
+		err |= __get_user(nr, (unsigned long *)(regs->eip + 1));
+		err |= __get_user(sys, (unsigned short *)(regs->eip + 5));
+
+		if (!err) {
+			if (mov == 0xb8 &&
+			    nr == __NR_rt_sigreturn &&
+			    sys == 0x80cd)
+			{
+				regs->eax = nr;
+				regs->eip += 7;
+				return 3;
+			}
+		}
+	}
+
+	{ /* PaX: gcc trampoline emulation #1 */
+		unsigned char mov1, mov2;
+		unsigned short jmp;
+		unsigned long addr1, addr2, ret;
+
+		err = __get_user(mov1, (unsigned char *)(regs->eip));
+		err |= __get_user(addr1, (unsigned long *)(regs->eip + 1));
+		err |= __get_user(mov2, (unsigned char *)(regs->eip + 5));
+		err |= __get_user(addr2, (unsigned long *)(regs->eip + 6));
+		err |= __get_user(jmp, (unsigned short *)(regs->eip + 10));
+		err |= __get_user(ret, (unsigned long *)(regs->esp));
+
+		if (!err) {
+			unsigned short call;
+
+			err = __get_user(call, (unsigned short *)(ret-2));
+			if (!err) {
+				if ((mov1 & 0xF8) == 0xB8 &&
+				    (mov2 & 0xF8) == 0xB8 &&
+				    (mov1 & 0x07) != (mov2 & 0x07) &&
+				    (jmp & 0xF8FF) == 0xE0FF &&
+				    (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
+				    (call & 0xF8FF) == 0xD0FF &&
+				    (regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]]))
+				{
+					((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
+					((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
+					regs->eip = addr2;
+					return 4;
+				}
+			}
+		}
+	}
+
+	{ /* PaX: gcc trampoline emulation #2 */
+		unsigned char mov, jmp;
+		unsigned long addr1, addr2, ret;
+
+		err = __get_user(mov, (unsigned char *)(regs->eip));
+		err |= __get_user(addr1, (unsigned long *)(regs->eip + 1));
+		err |= __get_user(jmp, (unsigned char *)(regs->eip + 5));
+		err |= __get_user(addr2, (unsigned long *)(regs->eip + 6));
+		err |= __get_user(ret, (unsigned long *)(regs->esp));
+
+		if (!err) {
+			unsigned short call;
+
+			err = __get_user(call, (unsigned short *)(ret-2));
+			if (!err) {
+				if ((mov & 0xF8) == 0xB8 &&
+				    jmp == 0xE9 &&
+				    (call & 0xF8FF) == 0xD0FF &&
+				    (regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]]))
+				{
+					((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
+					regs->eip += addr2 + 10;
+					return 4;
+				}
+			}
+		}
+	}
+#endif
+
+	return 1; /* PaX in action */
+}
+
+static int pax_handle_opcode(struct task_struct *tsk, struct pt_regs *regs)
+{
+	unsigned long opsize = 1;
+	unsigned long opsize_override = 0;
+	unsigned long i;
+
+	if (regs->eflags & TF_MASK)
+		tsk->ptrace |= PT_PAX_OLDTF;
+	else
+		tsk->ptrace &= ~PT_PAX_OLDTF;
+	tsk->ptrace &= ~PT_PAX_KEEPTF;
+
+	for (i=0; i<15; i++) {
+		unsigned char opcode;
+		if (__get_user(opcode, (unsigned char*)(regs->eip+i)))
+			break;
+		switch (opcode) {
+		case 0x26:
+		case 0x2E:
+		case 0x36:
+		case 0x3E:
+		case 0x64:
+		case 0x65:
+		case 0x67:
+		case 0xF0:
+		case 0xF2:
+		case 0xF3:
+			break;
+
+		case 0x66:
+			opsize_override = 1;
+			break;
+
+		case 0x9C: /* PUSHF */
+			if (opsize ^ opsize_override) {
+				__put_user(regs->eflags & 0x00FCFFFFul, (unsigned long*)(regs->esp-4));
+				regs->esp -= 4;
+			} else {
+				__put_user(regs->eflags, (unsigned short*)(regs->esp-2));
+				regs->esp -= 2;
+			}
+			regs->eip += i + 1;
+			return 1;
+
+		case 0x9D: /* POPF */
+		case 0xCF: /* IRET */
+			tsk->ptrace |= PT_PAX_KEEPTF;
+			return 0;
+
+		default:
+			return 0;
+		}
+ 	}
+	return 0;
+}
+
+static inline void pax_handle_pte(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte;
+	pte = pax_get_pte(mm, address);
+	if (pte) {
+		set_pte(pte, pte_exprotect(*pte));
+		__flush_tlb_one(address);
+	}
+}
+
+#define PAX_SPIN_COUNT 256
+
+void pax_handle_ptes(struct task_struct *tsk)
+{
+	struct mm_struct *mm;
+
+	mm = tsk->mm;
+	spin_lock(&mm->page_table_lock);
+	switch (tsk->thread.pax_faults.count) {
+	default:
+		printk(KERN_ERR "PAX: wtf: %s:%d, %ld\n", tsk->comm, tsk->pid, tsk->thread.pax_faults.count);
+		break;
+
+	case PAX_SPIN_COUNT+4:
+		pax_handle_pte(mm, tsk->thread.pax_faults.addresses[3]);
+
+	case PAX_SPIN_COUNT+3:
+		pax_handle_pte(mm, tsk->thread.pax_faults.addresses[2]);
+
+	case PAX_SPIN_COUNT+2:
+		pax_handle_pte(mm, tsk->thread.pax_faults.addresses[1]);
+
+	case PAX_SPIN_COUNT+1:
+		pax_handle_pte(mm, tsk->thread.pax_faults.addresses[0]);
+	}
+	spin_unlock(&mm->page_table_lock);
+	tsk->thread.pax_faults.eip = 0;
+	tsk->thread.pax_faults.count = 0;
+}
+
+/*
+ * PaX: handle the extra page faults or pass it down to the original handler
+ *
+ * returns 0 when nothing special was detected
+ *         1 when sigreturn trampoline (syscall) has to be emulated
+ */
+asmlinkage int pax_do_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+	struct task_struct *tsk = current;
+	struct mm_struct *mm = current->mm;
+	unsigned long address;
+	pte_t *pte;
+	unsigned char pte_mask = _PAGE_ACCESSED | _PAGE_USER;
+	int ret;
+	unsigned long i;
+
+	__asm__("movl %%cr2,%0":"=r" (address));
+
+	/* It's safe to allow irq's after cr2 has been saved */
+	if (regs->eflags & X86_EFLAGS_IF)
+		local_irq_enable();
+
+	if ((error_code & 5) != 5 || address >= TASK_SIZE || regs->xcs != __USER_CS || (VM_MASK & regs->eflags))
+		goto chain;
+
+	/* PaX: it's our fault, let's handle it if we can */
+
+	if (error_code == 7) {
+		pte_mask |= _PAGE_DIRTY;
+	/* PaX: take a look at read faults before acquiring any locks */
+	} else if (regs->eip == address) { /* read/instruction fetch attempt from a protected page in user mode */
+		ret = pax_handle_read_fault(regs, address);
+		switch (ret) {
+		case 4:
+			tsk->thread.pax_faults.eip = 0;
+			tsk->thread.pax_faults.count = 0;
+			return 0;
+
+		case 3:
+		case 2:
+			tsk->thread.pax_faults.eip = 0;
+			tsk->thread.pax_faults.count = 0;
+			return 1;
+
+		default:
+		case 1: {
+			char* buffer = (char*)__get_free_page(GFP_KERNEL);
+			char* path=NULL;
+
+			if (buffer) {
+				struct vm_area_struct* vma;
+
+				down_read(&mm->mmap_sem);
+				vma = mm->mmap;
+				while (vma) {
+					if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
+						break;
+					}
+					vma = vma->vm_next;
+				}
+				if (vma)
+					path = d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt, buffer, PAGE_SIZE);
+				up_read(&mm->mmap_sem);
+			}
+			printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, EIP: %08lX, ESP: %08lX\n", path, tsk->comm, tsk->pid, tsk->uid, tsk->euid, regs->eip, regs->esp);
+			if (buffer) free_page((unsigned long)buffer);
+			printk(KERN_ERR "PAX: bytes at EIP: ");
+			for (i = 0; i < 20; i++) {
+				unsigned char c;
+				if (__get_user(c, (unsigned char*)(regs->eip+i))) {
+					printk("<invalid address>.");
+					break;
+				}
+				printk("%02x ", c);
+			}
+			printk("\n");
+
+			tsk->thread.pax_faults.eip = 0;
+			tsk->thread.pax_faults.count = 0;
+			tsk->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
+			regs->eflags &= ~TF_MASK;
+			tsk->thread.cr2 = address;
+			tsk->thread.error_code = error_code;
+			tsk->thread.trap_no = 14;
+			force_sig(SIGKILL,tsk);
+			return 0;
+		}
+
+		case 0:
+		}
+	}
+
+	spin_lock(&mm->page_table_lock);
+	pte = pax_get_pte(mm, address);
+	if (!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte)) {
+		spin_unlock(&mm->page_table_lock);
+		goto chain;
+	}
+
+	if ((error_code == 7) && !pte_write(*pte)) { /* write attempt to a protected page in user mode */
+		spin_unlock(&mm->page_table_lock);
+		goto chain;
+	}
+
+	/*
+	 * PaX: fill DTLB with user rights and retry
+	 */
+	if (regs->eip != tsk->thread.pax_faults.eip) { /* detect DTLB trashing */
+		tsk->thread.pax_faults.eip = regs->eip;
+		tsk->thread.pax_faults.count = 0;
+
+pax_emu:
+		__asm__ __volatile__ (
+			"orb %2,%1\n"
+			"invlpg %0\n"
+			"testb $0,%0\n"
+			"xorb %3,%1\n"
+			:
+			: "m" (*(char*)address), "m" (*(char*)pte) , "r" (pte_mask) , "i" (_PAGE_USER)
+			: "memory", "cc");
+		spin_unlock(&mm->page_table_lock);
+		return 0;
+	}
+
+	if (tsk->thread.pax_faults.count < PAX_SPIN_COUNT) {
+		++tsk->thread.pax_faults.count;
+		goto pax_emu;
+	}
+	spin_unlock(&mm->page_table_lock);
+
+	if (tsk->thread.pax_faults.count == PAX_SPIN_COUNT) {
+		if (pax_handle_opcode(tsk, regs)) {
+			tsk->thread.pax_faults.eip = 0;
+			tsk->thread.pax_faults.count = 0;
+			tsk->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
+			return 0;
+		} else {
+			++tsk->thread.pax_faults.count;
+		}
+	}
+
+	if (tsk->thread.pax_faults.count > PAX_SPIN_COUNT+1+3) {
+		printk(KERN_ERR "PAX: preventing DoS: %s:%d, EIP: %08lX, ESP: %08lX\n", tsk->comm, tsk->pid, regs->eip, regs->esp);
+		printk(KERN_ERR "PAX: bytes at EIP: ");
+		for (i = 0; i < 20; i++) {
+			unsigned char c;
+			if (__get_user(c, (unsigned char*)(regs->eip+i))) {
+				printk("<invalid address>.");
+				break;
+			}
+			printk("%02x ", c);
+		}
+		printk("\n");
+
+		tsk->thread.pax_faults.eip = 0;
+		tsk->thread.pax_faults.count = 0;
+		tsk->ptrace &= ~(PT_PAX_TRACE | PT_PAX_KEEPTF | PT_PAX_OLDTF);
+		regs->eflags &= ~TF_MASK;
+		tsk->thread.cr2 = address;
+		tsk->thread.error_code = error_code;
+		tsk->thread.trap_no = 14;
+		force_sig(SIGKILL,tsk);
+		return 0;
+	}
+
+	spin_lock(&mm->page_table_lock);
+	pte = pax_get_pte(mm, address);
+	if (pte) {
+		set_pte(pte, pte_mkexec(*pte));
+		__flush_tlb_one(address);
+		tsk->thread.pax_faults.addresses[tsk->thread.pax_faults.count-PAX_SPIN_COUNT-1] = address;
+		++tsk->thread.pax_faults.count;
+	}
+	spin_unlock(&mm->page_table_lock);
+	tsk->ptrace |= PT_PAX_TRACE;
+	regs->eflags |= TF_MASK;
+
+#if 0
+	if (tsk->thread.pax_faults.count > PAX_SPIN_COUNT+1+1) {
+		printk(KERN_ERR "PAX: DTLB trashing, level %ld: %s:%d,"
+				"EIP: %08lX, ESP: %08lX, cr2: %08lX\n",
+				tsk->thread.pax_faults.count - (PAX_SPIN_COUNT+1),
+				tsk->comm, tsk->pid, regs->eip, regs->esp, address);
+		printk(KERN_ERR "PAX: DTLB trashing, %08lX, %08lX, %08lX\n",
+				tsk->thread.pax_faults.addresses[0],
+				tsk->thread.pax_faults.addresses[1],
+				tsk->thread.pax_faults.addresses[2]);
+	}
+#endif
+	return 0;
+
+chain:
+	do_page_fault(regs, error_code, address);
+	return 0;
+}
+#endif
+
diff -urN linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- linux/arch/i386/mm/init.c	Fri Dec 21 12:41:53 2001
+++ linux/arch/i386/mm/init.c	Sun Jan 13 01:24:51 2002
@@ -400,7 +400,11 @@
 	pmd = pmd_offset(pgd, vaddr);
 	pte = pte_offset(pmd, vaddr);
 	old_pte = *pte;
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+	*pte = mk_pte_phys(0, PAGE_READONLY_EXEC);
+#else
 	*pte = mk_pte_phys(0, PAGE_READONLY);
+#endif
 	local_flush_tlb();
 
 	boot_cpu_data.wp_works_ok = do_test_wp_bit(vaddr);
diff -urN linux/arch/ia64/config.in linux/arch/ia64/config.in
--- linux/arch/ia64/config.in	Fri Nov  9 17:26:17 2001
+++ linux/arch/ia64/config.in	Sun Jan 13 01:24:51 2002
@@ -276,3 +276,12 @@
 fi
 
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/m68k/config.in linux/arch/m68k/config.in
--- linux/arch/m68k/config.in	Mon Jun 11 22:15:27 2001
+++ linux/arch/m68k/config.in	Sun Jan 13 01:24:51 2002
@@ -546,3 +546,12 @@
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/mips/config.in linux/arch/mips/config.in
--- linux/arch/mips/config.in	Mon Oct 15 16:41:34 2001
+++ linux/arch/mips/config.in	Sun Jan 13 01:24:51 2002
@@ -520,3 +520,12 @@
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 fi
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/mips64/config.in linux/arch/mips64/config.in
--- linux/arch/mips64/config.in	Sun Sep  9 13:43:02 2001
+++ linux/arch/mips64/config.in	Sun Jan 13 01:24:51 2002
@@ -276,3 +276,12 @@
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 fi
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/parisc/config.in linux/arch/parisc/config.in
--- linux/arch/parisc/config.in	Tue Apr 17 20:19:25 2001
+++ linux/arch/parisc/config.in	Sun Jan 13 01:24:51 2002
@@ -208,3 +208,11 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/ppc/config.in linux/arch/ppc/config.in
--- linux/arch/ppc/config.in	Fri Nov 16 13:10:08 2001
+++ linux/arch/ppc/config.in	Sun Jan 13 01:24:51 2002
@@ -393,3 +393,12 @@
 bool 'Include kgdb kernel debugger' CONFIG_KGDB
 bool 'Include xmon kernel debugger' CONFIG_XMON
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/s390/config.in linux/arch/s390/config.in
--- linux/arch/s390/config.in	Fri Nov  9 16:58:02 2001
+++ linux/arch/s390/config.in	Sun Jan 13 01:24:51 2002
@@ -73,3 +73,11 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/s390x/config.in linux/arch/s390x/config.in
--- linux/arch/s390x/config.in	Thu Oct 11 12:04:57 2001
+++ linux/arch/s390x/config.in	Sun Jan 13 01:24:51 2002
@@ -77,3 +77,11 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/sh/config.in linux/arch/sh/config.in
--- linux/arch/sh/config.in	Mon Oct 15 16:36:48 2001
+++ linux/arch/sh/config.in	Sun Jan 13 01:24:51 2002
@@ -386,3 +386,12 @@
    bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
 fi
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/sparc/config.in linux/arch/sparc/config.in
--- linux/arch/sparc/config.in	Mon Jun 11 22:15:27 2001
+++ linux/arch/sparc/config.in	Sun Jan 13 01:24:51 2002
@@ -266,3 +266,12 @@
 
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- linux/arch/sparc64/config.in	Fri Dec 21 12:41:53 2001
+++ linux/arch/sparc64/config.in	Sun Jan 13 01:24:51 2002
@@ -306,3 +306,12 @@
 fi
 
 endmenu
+
+mainmenu_option next_comment
+comment 'Grsecurity'
+bool 'Grsecurity' CONFIG_GRKERNSEC
+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
+    source grsecurity/Config.in
+fi
+endmenu
+
diff -urN linux/drivers/char/mem.c linux/drivers/char/mem.c
--- linux/drivers/char/mem.c	Fri Dec 21 12:41:54 2001
+++ linux/drivers/char/mem.c	Fri Jan 18 16:40:05 2002
@@ -25,6 +25,9 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
+#ifdef CONFIG_GRKERNSEC_KMEM
+#include <linux/grsecurity.h>
+#endif
 
 #ifdef CONFIG_I2C
 extern int i2c_init_all(void);
@@ -46,6 +49,14 @@
 			    const char * buf, size_t count, loff_t *ppos)
 {
 	ssize_t written;
+#ifdef CONFIG_GRKERNSEC_KMEM
+	if(grsec_enable_kmem) {
+		security_alert("attempted write to read-only kernel memory by "
+				 DEFAULTSECMSG, "attempted kernel writes", 
+				 DEFAULTSECARGS);
+		return -EPERM;
+	}
+#endif
 
 	written = 0;
 #if defined(__sparc__) || defined(__mc68000__)
@@ -200,9 +211,21 @@
 	/*
 	 * Don't dump addresses that are not real memory to a core file.
 	 */
+#ifdef CONFIG_GRKERNSEC_PAX
+	if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) {
+#else 
 	if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
+#endif
 		vma->vm_flags |= VM_IO;
 
+#ifdef CONFIG_GRKERNSEC_PAX
+		/* it turned out to be device memory (eg. video RAM), don't apply PaX */
+		if ((current->flags & PF_PAX_PAGEEXEC) &&!(vma->vm_flags & VM_EXEC)) {
+			vma->vm_flags |= VM_EXEC | VM_MAYEXEC;
+			vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
+		}                                                                                                          
+	}
+#endif
 	if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
 			     vma->vm_page_prot))
 		return -EAGAIN;
@@ -291,7 +314,9 @@
 			wrote = (unsigned long) high_memory - p;
 
 		wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
-
+#ifdef CONFIG_GRKERNSEC_KMEM
+	if(grsec_enable_kmem && (wrote == -EPERM)) return -EPERM;
+#endif
 		p += wrote;
 		buf += wrote;
 		count -= wrote;
@@ -401,8 +426,12 @@
 			count = size;
 
 		zap_page_range(mm, addr, count);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+	        zeromap_page_range(addr, count, vma->vm_page_prot); 
+#else
         	zeromap_page_range(addr, count, PAGE_COPY);
 
+#endif
 		size -= count;
 		buf += count;
 		addr += count;
diff -urN linux/drivers/char/random.c linux/drivers/char/random.c
--- linux/drivers/char/random.c	Fri Nov  9 17:01:21 2001
+++ linux/drivers/char/random.c	Sun Jan 13 01:24:51 2002
@@ -260,6 +260,12 @@
 /*
  * Configuration information
  */
+#ifdef CONFIG_GRKERNSEC_RANDNET
+#include <linux/grsecurity.h>
+#define DEFAULT_POOL_SIZE_RANDNET 4096
+#define SECONDARY_POOL_SIZE_RANDNET 1024
+#define BATCH_ENTROPY_SIZE_RANDNET 2048
+#endif
 #define DEFAULT_POOL_SIZE 512
 #define SECONDARY_POOL_SIZE 128
 #define BATCH_ENTROPY_SIZE 256
@@ -387,8 +393,13 @@
 /*
  * Static global variables
  */
+#ifdef CONFIG_GRKERNSEC_RANDPID
+struct entropy_store *random_state; /* The default global store */
+struct entropy_store *sec_random_state; /* secondary store */
+#else
 static struct entropy_store *random_state; /* The default global store */
 static struct entropy_store *sec_random_state; /* secondary store */
+#endif
 static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
 static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
 
@@ -1433,11 +1444,23 @@
 {
 	int i;
 
-	if (create_entropy_store(DEFAULT_POOL_SIZE, &random_state))
+	if (create_entropy_store(
+#ifdef CONFIG_GRKERNSEC_RANDNET
+	grsec_enable_randnet?DEFAULT_POOL_SIZE_RANDNET:
+#endif
+	DEFAULT_POOL_SIZE, &random_state))
 		return;		/* Error, return */
-	if (batch_entropy_init(BATCH_ENTROPY_SIZE, random_state))
+	if (batch_entropy_init(
+#ifdef CONFIG_GRKERNSEC_RANDNET
+	grsec_enable_randnet?BATCH_ENTROPY_SIZE_RANDNET:
+#endif
+	BATCH_ENTROPY_SIZE, random_state))
 		return;		/* Error, return */
-	if (create_entropy_store(SECONDARY_POOL_SIZE, &sec_random_state))
+	if (create_entropy_store(
+#ifdef CONFIG_GRKERNSEC_RANDNET
+	grsec_enable_randnet?SECONDARY_POOL_SIZE_RANDNET:
+#endif
+	SECONDARY_POOL_SIZE, &sec_random_state))
 		return;		/* Error, return */
 	clear_entropy_store(random_state);
 	clear_entropy_store(sec_random_state);
diff -urN linux/drivers/char/vt.c linux/drivers/char/vt.c
--- linux/drivers/char/vt.c	Fri Nov 16 13:08:28 2001
+++ linux/drivers/char/vt.c	Sun Jan 13 01:24:51 2002
@@ -37,6 +37,10 @@
 #include <asm/vc_ioctl.h>
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 
+#ifdef CONFIG_GRKERNSEC_KBMAP
+#include <linux/grsecurity.h>
+#endif
+
 char vt_dont_switch;
 extern struct tty_driver console_driver;
 
@@ -177,7 +181,11 @@
 		    val = (i ? K_HOLE : K_NOSUCHMAP);
 		return put_user(val, &user_kbe->kb_value);
 	case KDSKBENT:
+#ifdef CONFIG_GRKERNSEC_KBMAP
+		if (!perm || (grsec_enable_kbmap && !suser()))
+#else 
 		if (!perm)
+#endif
 			return -EPERM;
 		if (!i && v == K_NOSUCHMAP) {
 			/* disallocate map */
@@ -298,7 +306,11 @@
 			return -EFAULT;
 		return ((p && *p) ? -EOVERFLOW : 0);
 	case KDSKBSENT:
+#ifdef CONFIG_GRKERNSEC_KBMAP
+		if (!perm || (grsec_enable_kbmap && !suser()))
+#else 
 		if (!perm)
+#endif
 			return -EPERM;
 
 		q = func_table[i];
diff -urN linux/drivers/ieee1394/video1394.c linux/drivers/ieee1394/video1394.c
--- linux/drivers/ieee1394/video1394.c	Fri Dec 21 12:41:54 2001
+++ linux/drivers/ieee1394/video1394.c	Sun Jan 13 01:24:51 2002
@@ -843,7 +843,11 @@
         pos=(unsigned long) d->buf;
         while (size > 0) {
                 page = kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
+#else
                 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+#endif
                         return -EAGAIN;
                 start+=PAGE_SIZE;
                 pos+=PAGE_SIZE;
diff -urN linux/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- linux/drivers/media/video/bttv-driver.c	Fri Dec 21 12:41:54 2001
+++ linux/drivers/media/video/bttv-driver.c	Sun Jan 13 01:24:51 2002
@@ -2052,7 +2052,11 @@
         pos=(unsigned long) btv->fbuffer;
         while (size > 0) {
                 page = kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+                if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
+#else
                 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+#endif
                         return -EAGAIN;
                 start+=PAGE_SIZE;
                 pos+=PAGE_SIZE;
diff -urN linux/drivers/media/video/cpia.c linux/drivers/media/video/cpia.c
--- linux/drivers/media/video/cpia.c	Thu Oct 25 16:53:47 2001
+++ linux/drivers/media/video/cpia.c	Sun Jan 13 01:24:51 2002
@@ -3005,7 +3005,11 @@
 	pos = (unsigned long)(cam->frame_buf);
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC)) {
+#else
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
+#endif
 			up(&cam->busy_lock);
 			return -EAGAIN;
 		}
diff -urN linux/drivers/media/video/meye.c linux/drivers/media/video/meye.c
--- linux/drivers/media/video/meye.c	Fri Dec 21 12:41:54 2001
+++ linux/drivers/media/video/meye.c	Sun Jan 13 01:24:51 2002
@@ -1263,7 +1263,11 @@
 
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC)) {
+#else
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
+#endif
 			up(&meye.lock);
 			return -EAGAIN;
 		}
diff -urN linux/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- linux/drivers/media/video/planb.c	Thu Oct 25 16:53:47 2001
+++ linux/drivers/media/video/planb.c	Sun Jan 13 01:24:51 2002
@@ -2009,7 +2009,11 @@
 	}
 	for (i = 0; i < pb->rawbuf_size; i++) {
 		if (remap_page_range(start, virt_to_phys((void *)pb->rawbuf[i]),
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+						PAGE_SIZE, PAGE_SHARED_EXEC))
+#else
 						PAGE_SIZE, PAGE_SHARED))
+#endif
 			return -EAGAIN;
 		start += PAGE_SIZE;
 		if (size <= PAGE_SIZE)
diff -urN linux/drivers/media/video/zr36067.c linux/drivers/media/video/zr36067.c
--- linux/drivers/media/video/zr36067.c	Fri Nov  9 17:01:22 2001
+++ linux/drivers/media/video/zr36067.c	Sun Jan 13 01:24:51 2002
@@ -4322,7 +4322,11 @@
 				    frag_tab[2 * j];
 				page = virt_to_phys(bus_to_virt(pos));	/* should just be pos on i386 */
 				if (remap_page_range
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+				    (start, page, todo, PAGE_SHARED_EXEC)) {
+#else
 				    (start, page, todo, PAGE_SHARED)) {
+#endif
 					printk(KERN_ERR
 					       "%s: zoran_mmap(V4L): remap_page_range failed\n",
 					       zr->name);
@@ -4363,7 +4367,11 @@
 			       ("V4L remap page range %d 0x%lx %ld to 0x%lx\n",
 				i, page, todo, start));
 			if (remap_page_range
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+			    (start, page, todo, PAGE_SHARED_EXEC)) {
+#else
 			    (start, page, todo, PAGE_SHARED)) {
+#endif
 				printk(KERN_ERR
 				       "%s: zoran_mmap(V4L): remap_page_range failed\n",
 				       zr->name);
diff -urN linux/drivers/media/video/zr36120.c linux/drivers/media/video/zr36120.c
--- linux/drivers/media/video/zr36120.c	Fri Nov  9 17:01:22 2001
+++ linux/drivers/media/video/zr36120.c	Sun Jan 13 01:24:51 2002
@@ -1484,7 +1484,11 @@
 	pos = (unsigned long)ztv->fbuffer;
 	while (size>0) {
 		unsigned long page = virt_to_phys((void*)pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
+#else
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+#endif
 			return -EAGAIN;
 		start += PAGE_SIZE;
 		pos += PAGE_SIZE;
diff -urN linux/drivers/usb/ov511.c linux/drivers/usb/ov511.c
--- linux/drivers/usb/ov511.c	Fri Sep 14 17:04:07 2001
+++ linux/drivers/usb/ov511.c	Sun Jan 13 01:24:51 2002
@@ -2769,7 +2769,11 @@
 	pos = (unsigned long)ov511->fbuf;
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
+#else
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+#endif
 			return -EAGAIN;
 		start += PAGE_SIZE;
 		pos += PAGE_SIZE;
diff -urN linux/drivers/usb/pwc-if.c linux/drivers/usb/pwc-if.c
--- linux/drivers/usb/pwc-if.c	Fri Dec 21 12:41:55 2001
+++ linux/drivers/usb/pwc-if.c	Sun Jan 13 01:24:51 2002
@@ -1581,7 +1581,11 @@
 	pos = (unsigned long)pdev->image_data;
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
+#else
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+#endif
 			return -EAGAIN;
 
 		start += PAGE_SIZE;
diff -urN linux/drivers/usb/se401.c linux/drivers/usb/se401.c
--- linux/drivers/usb/se401.c	Fri Sep 14 17:27:10 2001
+++ linux/drivers/usb/se401.c	Sun Jan 13 01:24:51 2002
@@ -1374,7 +1374,11 @@
 	pos = (unsigned long)se401->fbuf;
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC)) {
+#else
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
+#endif
 			up(&se401->lock);
 			return -EAGAIN;
 		}
diff -urN linux/drivers/usb/usbvideo.c linux/drivers/usb/usbvideo.c
--- linux/drivers/usb/usbvideo.c	Thu Oct 11 02:42:46 2001
+++ linux/drivers/usb/usbvideo.c	Sun Jan 13 01:24:51 2002
@@ -1199,7 +1199,11 @@
 	pos = (unsigned long) uvd->fbuf;
 	while (size > 0) {
 		page = usbvideo_kvirt_to_pa(pos);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED_EXEC))
+#else
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+#endif
 			return -EAGAIN;
 
 		start += PAGE_SIZE;
diff -urN linux/fs/binfmt_aout.c linux/fs/binfmt_aout.c
--- linux/fs/binfmt_aout.c	Fri Nov  2 20:39:20 2001
+++ linux/fs/binfmt_aout.c	Sun Jan 13 01:24:51 2002
@@ -5,6 +5,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/config.h>
 
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -307,6 +308,25 @@
 	current->mm->mmap = NULL;
 	compute_creds(bprm);
  	current->flags &= ~PF_FORKNOEXEC;
+#ifdef CONFIG_GRKERNSEC_STACK
+       if (N_FLAGS(ex) & F_STACKEXEC) current->flags |= PF_STACKEXEC;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX
+      if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC))
+              current->flags |= PF_PAX_PAGEEXEC;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
+      if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
+              current->flags |= PF_PAX_EMUTRAMP;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
+      if (!(N_FLAGS(ex) & F_PAX_MPROTECT))        
+              current->flags |= PF_PAX_MPROTECT;
+#endif
+
 #ifdef __sparc__
 	if (N_MAGIC(ex) == NMAGIC) {
 		loff_t pos = fd_offset;
@@ -393,7 +413,11 @@
 
 		down_write(&current->mm->mmap_sem);
  		error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+				PROT_READ | PROT_WRITE,
+#else
 				PROT_READ | PROT_WRITE | PROT_EXEC,
+#endif
 				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
 				fd_offset + ex.a_text);
 		up_write(&current->mm->mmap_sem);
diff -urN linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- linux/fs/binfmt_elf.c	Fri Dec 21 12:41:55 2001
+++ linux/fs/binfmt_elf.c	Sun Jan 13 01:24:51 2002
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 
+#include <linux/config.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/sched.h>
@@ -33,6 +34,9 @@
 #include <linux/smp_lock.h>
 #include <linux/compiler.h>
 #include <linux/highmem.h>
+#if defined(CONFIG_GRKERNSEC_PAX_RANDMMAP) || defined(CONFIG_GRKERNSEC_PAX)
+#include <linux/random.h>
+#endif
 
 #include <asm/uaccess.h>
 #include <asm/param.h>
@@ -73,7 +77,10 @@
 #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
 #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))
 
-static struct linux_binfmt elf_format = {
+#ifndef CONFIG_GRKERNSEC_STACK
+static
+#endif
+struct linux_binfmt elf_format = {
 	NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
 };
 
@@ -138,6 +145,11 @@
 	} else
 		u_platform = p;
 
+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
+	if (current->flags & PF_PAX_RANDMMAP)
+		u_platform -= (current->mm->delta_stack & ~PAGE_MASK);
+#endif
+
 	/*
 	 * Force 16 byte _final_ alignment here for generality.
 	 */
@@ -599,7 +611,49 @@
 	current->mm->end_data = 0;
 	current->mm->end_code = 0;
 	current->mm->mmap = NULL;
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+	current->mm->delta_mmap = 0;
+	current->mm->delta_exec = 0;
+	current->mm->delta_stack = 0;
+#endif
 	current->flags &= ~PF_FORKNOEXEC;
+
+#ifdef CONFIG_GRKERNSEC_STACK
+       if (elf_ex.e_flags & EF_STACKEXEC)
+	current->flags |= PF_STACKEXEC;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX
+	if (!(elf_ex.e_flags & EF_PAX_PAGEEXEC))
+		current->flags |= PF_PAX_PAGEEXEC;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
+	if (elf_ex.e_flags & EF_PAX_EMUTRAMP)
+		current->flags |= PF_PAX_EMUTRAMP;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
+	if (!(elf_ex.e_flags & EF_PAX_MPROTECT))
+		current->flags |= PF_PAX_MPROTECT;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
+	if (!(elf_ex.e_flags & EF_PAX_RANDMMAP)) {
+		unsigned short delta;
+		current->flags |= PF_PAX_RANDMMAP;
+
+		get_random_bytes(&delta, sizeof(delta));
+		current->mm->delta_mmap = (unsigned long)delta << PAGE_SHIFT;
+
+		get_random_bytes(&delta, sizeof(delta));
+		current->mm->delta_exec = (unsigned long)delta << PAGE_SHIFT;
+
+		get_random_bytes(&delta, sizeof(delta));
+		current->mm->delta_stack = (unsigned long)delta << 4;
+	}
+#endif
+
 	elf_entry = (unsigned long) elf_ex.e_entry;
 
 	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
@@ -654,6 +708,13 @@
 			   base, as well as whatever program they might try to exec.  This
 		           is because the brk will follow the loader, and is not movable.  */
 			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
+			/* PaX: randomize base address at the default exe base if requested */
+			if (current->flags | PF_PAX_RANDMMAP) {
+				load_bias = ELF_PAGESTART(0x08048000 - vaddr + current->mm->delta_exec);
+			}
+#endif
+
 		}
 
 		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
diff -urN linux/fs/devices.c linux/fs/devices.c
--- linux/fs/devices.c	Sat Sep 22 23:35:43 2001
+++ linux/fs/devices.c	Sun Jan 13 01:24:51 2002
@@ -162,7 +162,11 @@
  * is contain the open that then fills in the correct operations
  * depending on the special file...
  */
-static struct file_operations def_chr_fops = {
+
+#ifndef CONFIG_GRKERNSEC_FD
+static
+#endif
+struct file_operations def_chr_fops = {
 	open:		chrdev_open,
 };
 
diff -urN linux/fs/exec.c linux/fs/exec.c
--- linux/fs/exec.c	Fri Dec 21 12:41:55 2001
+++ linux/fs/exec.c	Thu Jan 17 17:00:54 2002
@@ -48,6 +48,19 @@
 
 int core_uses_pid;
 
+#if defined(CONFIG_GRKERNSEC_FD) || defined(CONFIG_GRKERNSEC_EXECVE) ||\
+    defined(CONFIG_GRKERNSEC_COREDUMP)||defined(CONFIG_GRKERNSEC_TPE) ||\
+    defined(CONFIG_GRKERNSEC_CHROOT_EXECLOG) || \
+    defined(CONFIG_GRKERNSEC_EXECLOG) ||\
+    defined(CONFIG_GRKERNSEC_PTRACE) || defined(CONFIG_GRKERNSEC_ACL)
+#include <linux/grsecurity.h>
+#endif
+
+#ifdef CONFIG_GRKERNSEC_FD
+#include <linux/major.h>
+extern struct file_operations def_chr_fops;
+#endif
+
 static struct linux_binfmt *formats;
 static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
 
@@ -278,7 +291,12 @@
 	lru_cache_add(page);
 	flush_dcache_page(page);
 	flush_page_to_ram(page);
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page,
+		(tsk->flags & PF_PAX_PAGEEXEC)?PAGE_COPY_NOEXEC:PAGE_COPY_EXEC))));
+#else
 	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
+#endif
 	tsk->mm->rss++;
 	spin_unlock(&tsk->mm->page_table_lock);
 
@@ -299,6 +317,12 @@
 
 	stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
 
+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
+	if (current->flags & PF_PAX_RANDMMAP)
+		stack_base = PAGE_MASK & (stack_base - current->mm->delta_stack);
+
+#endif
+ 
 	bprm->p += stack_base;
 	if (bprm->loader)
 		bprm->loader += stack_base;
@@ -312,9 +336,15 @@
 	{
 		mpnt->vm_mm = current->mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
+#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
+		mpnt->vm_end = stack_base + MAX_ARG_PAGES*PAGE_SIZE;
+		mpnt->vm_page_prot = (current->flags & PF_PAX_PAGEEXEC)?PAGE_COPY_NOEXEC:PAGE_COPY_EXEC;
+		mpnt->vm_flags = (current->flags & PF_PAX_PAGEEXEC)?VM_STACK_FLAGS:(VM_STACK_FLAGS|VM_EXEC|VM_MAYEXEC);
+#else
 		mpnt->vm_end = STACK_TOP;
 		mpnt->vm_page_prot = PAGE_COPY;
 		mpnt->vm_flags = VM_STACK_FLAGS;
+#endif
 		mpnt->vm_ops = NULL;
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
@@ -473,6 +503,69 @@
 	if (atomic_dec_and_test(&oldsig->count))
 		kmem_cache_free(sigact_cachep, oldsig);
 }
+#ifdef CONFIG_GRKERNSEC_FD
+static inline int tweak_fd_open_null(struct linux_binprm *bprm)
+{
+	struct inode *i;
+	struct dentry *d;
+	struct file *f;
+
+	if(!(i = get_empty_inode()))
+		return -ENOMEM;
+	if(!(d = dget(d_alloc_root(i)))) {
+        	iput(i);
+        	return -ENOMEM;
+    	}
+	if(!(f = get_empty_filp())) {
+        	dput(d);
+        	iput(i);
+        	return -ENFILE;
+    	}
+    	i->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
+    	i->i_uid = current->fsuid;
+    	i->i_gid = current->fsgid;
+    	i->i_rdev = MKDEV(MEM_MAJOR,3);
+    	i->i_blksize = PAGE_SIZE;
+    	i->i_blocks = 0;
+    	i->i_atime = i->i_mtime = i->i_ctime = CURRENT_TIME;
+    	i->i_fop = &def_chr_fops;
+    	i->i_state = I_DIRTY;
+
+    	f->f_flags = O_RDWR;
+    	f->f_mode = FMODE_READ | FMODE_WRITE;
+    	f->f_dentry = d;
+	f->f_op = i->i_fop;
+    	f->f_pos = 0;
+    	f->f_reada = 0;
+    	f->f_op->open(i,f);
+
+    	bprm->tweak_fd_null = f;
+
+   	return 0;
+}
+
+static int tweak_fd_0_1_2(struct linux_binprm *bprm)
+{
+    	int fd,new,retval;
+
+    	for(fd=0;fd<=2;fd++) {
+        	if(current->files->fd[fd]) continue;
+        	if((new = get_unused_fd()) != fd) {
+            		if(new >= 0) put_unused_fd(new);
+            		return -EMFILE;
+        	}
+        	if(bprm->tweak_fd_null)
+            		atomic_inc(&bprm->tweak_fd_null->f_count);
+        	else
+            		if((retval = tweak_fd_open_null(bprm)))
+                		return retval;
+
+        	fd_install(fd,bprm->tweak_fd_null);
+        	bprm->tweak_fd_mask |= 1 << fd;
+    	}
+    	return 0;
+}
+#endif
 
 /*
  * These functions flushes out all traces of the currently running executable
@@ -563,6 +656,25 @@
 				current->comm[i++] = ch;
 	}
 	current->comm[i] = '\0';
+#ifdef CONFIG_GRKERNSEC_STACK
+        current->flags &= ~PF_STACKEXEC;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX
+	current->flags &= ~PF_PAX_PAGEEXEC;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
+	current->flags &= ~PF_PAX_EMUTRAMP;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
+	current->flags &= ~PF_PAX_MPROTECT;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
+	current->flags &= ~PF_PAX_RANDMMAP;
+#endif
 
 	flush_thread();
 
@@ -580,6 +692,10 @@
 	flush_signal_handlers(current);
 	flush_old_files(current->files);
 
+#ifdef CONFIG_GRKERNSEC_FD
+        if(grsec_enable_fd)
+        	return tweak_fd_0_1_2(bprm);
+#endif
 	return 0;
 
 mmap_failed:
@@ -626,8 +742,8 @@
 
 	if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
 		/* Set-uid? */
-		if (mode & S_ISUID)
-			bprm->e_uid = inode->i_uid;
+                if (mode & S_ISUID)
+                        bprm->e_uid = inode->i_uid;
 
 		/* Set-gid? */
 		/*
@@ -635,9 +751,9 @@
 		 * is a candidate for mandatory locking, not a setgid
 		 * executable.
 		 */
-		if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
-			bprm->e_gid = inode->i_gid;
-	}
+                if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
+                        bprm->e_gid = inode->i_gid;
+}
 
 	/* We don't have VFS support for capabilities yet */
 	cap_clear(bprm->cap_inheritable);
@@ -660,7 +776,26 @@
 		if (bprm->e_uid == 0) 
 			cap_set_full(bprm->cap_effective);
 	}
-
+#ifdef CONFIG_GRKERNSEC_PTRACE
+	if (current->ptrace & PT_PTRACED){
+ 		if(current->uid && grsec_enable_ptrace
+#ifdef CONFIG_GRKERNSEC_PTRACE_GROUP
+	    && ((grsec_enable_ptrace_group && !in_group_p(grsec_ptrace_gid))
+	    || !grsec_enable_ptrace_group)
+#endif
+		) {
+			security_alert("denied ptrace of [%.32s:%lu] (%s) by " DEFAULTSECMSG,
+				"denied ptraces", kdevname(bprm->file->f_dentry->d_inode->i_dev),
+                                bprm->file->f_dentry->d_inode->i_ino, bprm->filename, 
+				DEFAULTSECARGS);
+			return -EPERM;
+	   	}
+		security_alert("ptrace of [%.32s:%lu] (%s) by " DEFAULTSECMSG,
+			"ptraces", kdevname(bprm->file->f_dentry->d_inode->i_dev),
+                        bprm->file->f_dentry->d_inode->i_ino, bprm->filename, 
+			DEFAULTSECARGS);
+	}
+#endif
 	memset(bprm->buf,0,BINPRM_BUF_SIZE);
 	return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
 }
@@ -708,6 +843,9 @@
 							current->cap_permitted);
 			}
 		}
+#ifdef CONFIG_GRKERNSEC_FD
+            if (grsec_enable_fd) tweak_fd_0_1_2(bprm);
+#endif
 		do_unlock = 1;
 	}
 
@@ -859,6 +997,20 @@
 	struct file *file;
 	int retval;
 	int i;
+#if defined(CONFIG_GRKERNSEC_EXECLOG) || defined(CONFIG_GRKERNSEC_EXECLOG_GROUP)
+	int x;
+	char *grargs;
+	char grarg[68];
+#endif
+
+#ifdef CONFIG_GRKERNSEC_EXECVE
+    	if(grsec_enable_execve && current->user)
+   		if(atomic_read(&current->user->processes) > current->rlim[RLIMIT_NPROC].rlim_cur) {
+			security_alert("Attempt to overstep process limit by " DEFAULTSECMSG,
+		       			"proc limit overstep", DEFAULTSECARGS);
+			return -EAGAIN;
+    		}
+#endif
 
 	file = open_exec(filename);
 
@@ -866,6 +1018,16 @@
 	if (IS_ERR(file))
 		return retval;
 
+#ifdef CONFIG_GRKERNSEC_ACL
+if( ( (gr_search(file->f_dentry,GR_EXEC,file->f_vfsmnt)) == GR_DENY) ) {
+	security_alert("denying execution of %.1024s by " DEFAULTSECMSG,
+                       "file exec attempts", filename, DEFAULTSECARGS);
+	allow_write_access(file);
+	fput(file);
+	return -EPERM;
+}
+#endif
+
 	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
 
@@ -886,10 +1048,111 @@
 		return bprm.envc;
 	}
 
+#ifdef CONFIG_GRKERNSEC_FD
+        if (grsec_enable_fd) {
+		bprm.tweak_fd_mask = 0;
+        	bprm.tweak_fd_null = NULL;
+	}
+#endif
 	retval = prepare_binprm(&bprm);
 	if (retval < 0) 
 		goto out; 
 
+
+#ifdef CONFIG_GRKERNSEC_TPE
+if (grsec_enable_tpe) {
+#ifdef CONFIG_GRKERNSEC_TPE_GLIBC
+if (grsec_enable_tpe_glibc) {
+#ifdef CONFIG_GRKERNSEC_TPE_ALL
+if(grsec_enable_tpe_all?current->uid:in_group_p(grsec_tpe_gid)){
+#else
+if(in_group_p(grsec_tpe_gid)){
+#endif
+		char **envpp=envp,*envpt;
+                while(*envpp){
+		envpt=*envpp;
+		if((*envpt == 'L') && (*(envpt + 1) == 'D') &&
+ 		(*(envpt + 2) == '_') && strchr(envpt,'=')){
+	security_alert("denied exec of %.32s by " DEFAULTSECMSG
+	"reason: malicious environment","denied execs",
+	filename, DEFAULTSECARGS);
+	dput(file->f_dentry);
+	return -EACCES;
+		}
+		*envpp=*++envpp;
+        }
+    if(!strncmp(file->f_dentry->d_name.name,"ld-2.",5) &&
+    !strncmp(file->f_dentry->d_parent->d_name.name,"lib",3)){
+	security_alert("denied exec of %.32s by " DEFAULTSECMSG
+	"reason: tried to bypass via ld","denied execs",
+	filename, DEFAULTSECARGS);
+	dput(file->f_dentry);
+	return -EACCES;
+    }
+}
+}
+#endif
+if((current->uid) &&
+   ((file->f_dentry->d_parent->d_inode->i_uid) ||
+   (!(file->f_dentry->d_parent->d_inode->i_uid) &&
+   ((file->f_dentry->d_parent->d_inode->i_mode & S_IWGRP) ||
+    (file->f_dentry->d_parent->d_inode->i_mode & S_IWOTH)))) &&
+   (in_group_p(grsec_tpe_gid))){
+	security_alert("denied exec of %.32s by " DEFAULTSECMSG
+			"reason: untrusted","denied execs",
+			filename, DEFAULTSECARGS);
+	dput(file->f_dentry);
+	return -EACCES;
+}
+#ifdef CONFIG_GRKERNSEC_TPE_ALL
+else if(grsec_enable_tpe_all &&
+	(current->uid) && !(((!(file->f_dentry->d_parent->d_inode->i_uid) &&
+    !(file->f_dentry->d_parent->d_inode->i_mode & S_IWGRP) &&
+    !(file->f_dentry->d_parent->d_inode->i_mode & S_IWOTH)) ||
+    ((file->f_dentry->d_parent->d_inode->i_uid == current->uid) &&
+    !(file->f_dentry->d_parent->d_inode->i_mode & S_IWGRP) &&
+    !(file->f_dentry->d_parent->d_inode->i_mode & S_IWOTH))))){
+	security_alert("denied exec of %.32s by " DEFAULTSECMSG
+	"reason: untrusted","denied execs",
+	filename, DEFAULTSECARGS);
+	dput(file->f_dentry);
+	return -EACCES;
+}
+#endif
+}
+#endif
+
+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
+	if(grsec_enable_chroot_execlog && proc_is_chrooted(current)) {
+		printk(KERN_INFO "grsec: exec of %.64s within chroot "
+		       "jail (%.32s:%lu) by process " DEFAULTSECMSG "\n",
+			       filename,kdevname(current->fs->root->d_inode->i_dev),
+			       current->fs->root->d_inode->i_ino,
+			       DEFAULTSECARGS);
+		}
+#endif
+
+#if defined(CONFIG_GRKERNSEC_EXECLOG) || defined(CONFIG_GRKERNSEC_EXECLOG_GROUP)
+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
+	if (in_group_p(grsec_audit_gid) && grsec_enable_group) {
+#else
+	if (grsec_enable_execlog) {
+#endif
+	    	for(x=0;x<sizeof(grarg);x++)
+	    		grarg[x]='\0';
+	    	for(x=0;x<bprm.argc;x++) {
+			if((strlen(argv[x]) + strlen(grarg) + 2) < sizeof(grarg)) {
+		    		grargs=strcat(grarg,argv[x]);
+		    		if(x<bprm.argc-1)
+					grargs=strcat(grarg," ");
+		}
+	    }
+	    printk(KERN_INFO "grsec: exec of [%.32s:%lu] (%.68s) by " DEFAULTSECMSG
+			"\n", kdevname(file->f_dentry->d_inode->i_dev),
+			      file->f_dentry->d_inode->i_ino, grarg, DEFAULTSECARGS);
+	}
+#endif
+
 	retval = copy_strings_kernel(1, &bprm.filename, &bprm);
 	if (retval < 0) 
 		goto out; 
@@ -904,9 +1167,20 @@
 		goto out; 
 
 	retval = search_binary_handler(&bprm,regs);
-	if (retval >= 0)
+	if (retval >= 0) {
+#ifdef CONFIG_GRKERNSEC_ACL
+		if(gr_set_proc_acl(file->f_dentry,current,filename,file->f_vfsmnt)) {
+			security_alert("could not set acl for %ld %d",
+			"acl set failures",
+			file->f_dentry->d_inode->i_ino,
+			file->f_dentry->d_inode->i_dev);
+			goto out; 
+		}
+#endif
+
 		/* execve success */
 		return retval;
+	}
 
 out:
 	/* Something went wrong, return the inode and free the argument pages*/
@@ -920,6 +1194,13 @@
 			__free_page(page);
 	}
 
+#ifdef CONFIG_GRKERNSEC_FD
+	if(grsec_enable_fd && bprm.tweak_fd_mask) {                                            
+		for(i=0;i<=2;i++)
+            		if(bprm.tweak_fd_mask & (1 << i))
+                		(void)sys_close(i);
+	}
+#endif
 	return retval;
 }
 
@@ -952,7 +1233,14 @@
 		goto fail;
 
 	memcpy(corename,"core.", 5);
+#ifdef CONFIG_GRKERNSEC_COREDUMP
+       if(grsec_enable_coredump)
+	       memcpy(corename+5,current->comm,sizeof(current->comm));
+       else
+	       corename[4] = '\0';
+#else
 	corename[4] = '\0';
+#endif
  	if (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)
  		sprintf(&corename[4], ".%d", current->pid);
 	file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW, 0600);
@@ -970,7 +1258,11 @@
 		goto close_fail;
 	if (!file->f_op->write)
 		goto close_fail;
+#ifdef CONFIG_GRKERNSEC_ACL
+	if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
+#else
 	if (do_truncate(file->f_dentry, 0) != 0)
+#endif
 		goto close_fail;
 
 	retval = binfmt->core_dump(signr, regs, file);
diff -urN linux/fs/namei.c linux/fs/namei.c
--- linux/fs/namei.c	Wed Oct 17 17:46:29 2001
+++ linux/fs/namei.c	Sat Jan 19 02:50:42 2002
@@ -26,6 +26,11 @@
 #include <asm/namei.h>
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_GRKERNSEC_LINK) || defined(CONFIG_GRKERNSEC_FIFO) ||\
+    defined(CONFIG_GRKERNSEC_CHROOT_MKNOD) || defined(CONFIG_GRKERNSEC_ACL)
+#include <linux/grsecurity.h>
+#endif
+
 #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
 
 /* [Feb-1997 T. Schoebel-Theuer]
@@ -342,6 +347,27 @@
 		current->state = TASK_RUNNING;
 		schedule();
 	}
+
+#ifdef CONFIG_GRKERNSEC_LINK
+        if(grsec_enable_link && S_ISLNK(dentry->d_inode->i_mode) &&
+          (dentry->d_parent->d_inode->i_mode & S_ISVTX) &&
+          dentry->d_parent->d_inode->i_uid != dentry->d_inode->i_uid &&
+          (dentry->d_parent->d_inode->i_mode & S_IWOTH) &&
+          current->fsuid != dentry->d_inode->i_uid) {
+          security_alert("not following symlink (%.30s/%.30s) of [%.32s]:%lu owned by %d.%d "
+                         "by " DEFAULTSECMSG,"symlinks not followed",
+                         dentry->d_parent->d_name.name,
+                         dentry->d_name.name,
+                         kdevname(dentry->d_inode->i_dev),
+                         dentry->d_inode->i_ino,
+                         dentry->d_inode->i_uid,
+                         dentry->d_inode->i_gid,
+                         DEFAULTSECARGS);
+	path_release(nd);
+        return -EACCES;
+        }
+#endif
+
 	current->link_count++;
 	current->total_link_count++;
 	UPDATE_ATIME(dentry->d_inode);
@@ -625,6 +651,22 @@
 		else if (this.len == 2 && this.name[1] == '.')
 			nd->last_type = LAST_DOTDOT;
 return_base:
+#ifdef CONFIG_GRKERNSEC_ACL
+		if(nd->dentry && !(IS_ERR(nd->dentry)))
+			if( ( (gr_check_hidden(nd->dentry,nd->mnt)) == GR_DENY) ) {
+				security_alert("attempt to access hidden file "
+				"with inode %ld dev %d by " 
+				DEFAULTSECMSG, 
+				"hidden file access attempts",
+				nd->dentry->d_inode->i_ino,
+				nd->dentry->d_inode->i_dev, DEFAULTSECARGS);
+				err =  -ENOENT; /*Fake that its not there*/
+				dput(dentry);
+				path_release(nd);
+				goto return_err;
+			}
+#endif
+
 		return 0;
 out_dput:
 		dput(dentry);
@@ -976,6 +1018,52 @@
 	struct dentry *dentry;
 	struct dentry *dir;
 	int count = 0;
+#ifdef CONFIG_GRKERNSEC_ACL
+	int tmp;
+	if(flag & GR_NONEXISTANT) {
+		flag &= ~GR_NONEXISTANT;
+		if(path_init(pathname,lookup_flags(flag)|LOOKUP_PARENT,nd))
+			error = path_walk(pathname,nd);
+		if(error) return error;
+	} else {
+		if(path_init(pathname,lookup_flags(flag),nd))
+			error = path_walk(pathname,nd);
+		if(error) return error;
+	}
+	if( (tmp = (flag&O_ACCMODE)) > 0) {
+		if(tmp & FMODE_READ ) {
+			if( (gr_search(nd->dentry,GR_READ,nd->mnt)) == GR_DENY) {
+				security_alert("attempt to open %.1024s read-only "
+				"by " DEFAULTSECMSG, 	
+				"file open attempts", pathname, DEFAULTSECARGS);
+				error = -EPERM;
+				goto exit;
+			}
+		}
+		else if(flag & O_APPEND) {
+			if( (gr_search(nd->dentry,GR_APPEND,nd->mnt)) == GR_DENY) {
+				security_alert("attempt to open %.1024s "
+					"append-only by " DEFAULTSECMSG ,
+					"file open attempts",
+	               			pathname, DEFAULTSECARGS);
+				error = -EPERM;
+				goto exit;
+			}
+		}
+		if(tmp & FMODE_WRITE && (!(flag & O_APPEND))) { /* its write*/
+			if( ( (gr_search(nd->dentry,GR_WRITE,nd->mnt)) == GR_DENY) ) {
+				security_alert("attempt to open %.1024s "
+					"for writing by " DEFAULTSECMSG,
+					"file open attempts",
+	                		pathname, DEFAULTSECARGS);
+				error = -EPERM;
+				goto exit;
+			}
+		}
+	}
+	path_release(nd);
+#endif
+
 
 	acc_mode = ACC_MODE(flag);
 
@@ -1083,6 +1171,22 @@
 	 * actually live on the filesystem itself, and as such you
 	 * can write to them even if the filesystem is read-only.
 	 */
+#ifdef CONFIG_GRKERNSEC_FIFO
+               if (grsec_enable_fifo &&
+		   S_ISFIFO(inode->i_mode) && !(flag & O_EXCL) &&
+                   (dentry->d_parent->d_inode->i_mode & S_ISVTX) &&
+                   inode->i_uid != dentry->d_parent->d_inode->i_uid &&
+                   current->fsuid != inode->i_uid) {
+                       if (!permission(inode, acc_mode))
+                       security_alert("denied writing FIFO (%.32s/%.32s) of %d.%d "
+                               "by " DEFAULTSECMSG,
+                               "writes into a FIFO denied",dentry->d_parent->d_name.name,dentry->d_name.name,
+                               inode->i_uid, inode->i_gid,
+			       DEFAULTSECARGS);
+                       error = -EACCES;
+                       goto exit_dput;
+               }
+#endif
 	if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
 	    	flag &= ~O_TRUNC;
 	} else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
@@ -1126,7 +1230,11 @@
 		if (!error) {
 			DQUOT_INIT(inode);
 			
+#ifdef CONFIG_GRKERNSEC_ACL
+			error = do_truncate(dentry,0,nd->mnt);
+#else
 			error = do_truncate(dentry, 0);
+#endif
 		}
 		put_write_access(inode);
 		if (error)
@@ -1157,6 +1265,24 @@
 	 * stored in nd->last.name and we will have to putname() it when we
 	 * are done. Procfs-like symlinks just set LAST_BIND.
 	 */
+#ifdef CONFIG_GRKERNSEC_LINK
+	if(grsec_enable_link && S_ISLNK(dentry->d_inode->i_mode) &&
+	  (dentry->d_parent->d_inode->i_mode & S_ISVTX) &&
+	  dentry->d_parent->d_inode->i_uid != dentry->d_inode->i_uid &&
+	  (dentry->d_parent->d_inode->i_mode & S_IWOTH) &&
+	  current->fsuid != dentry->d_inode->i_uid) {
+	  security_alert("not following symlink (%.30s/%.30s) [%.32s]:%lu of %d.%d "
+			 "by " DEFAULTSECMSG,"symlinks not followed",
+			 dentry->d_parent->d_name.name, dentry->d_name.name, 
+			 kdevname(dentry->d_inode->i_dev), 
+			 dentry->d_inode->i_ino, dentry->d_inode->i_uid,
+			 dentry->d_inode->i_gid,
+			 DEFAULTSECARGS);
+	error = -EACCES;
+	goto exit_dput;
+	}
+#endif
+
 	UPDATE_ATIME(dentry->d_inode);
 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 	dput(dentry);
@@ -1241,6 +1367,9 @@
 	struct dentry * dentry;
 	struct nameidata nd;
 
+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
+	char grdevmode;
+#endif
 	if (S_ISDIR(mode))
 		return -EPERM;
 	tmp = getname(filename);
@@ -1256,6 +1385,37 @@
 
 	mode &= ~current->fs->umask;
 	if (!IS_ERR(dentry)) {
+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
+	if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && proc_is_chrooted(current)) {
+		switch (mode & S_IFMT) {
+		    case S_IFREG:	grdevmode = 'r';	break;
+		    case S_IFCHR:	grdevmode = 'c';	break;
+		    case S_IFBLK:	grdevmode = 'b';	break;
+		    case S_IFSOCK:	grdevmode = 's';	break;
+		    default:		grdevmode = 'u';
+		}
+		security_alert("refused attempt to mknod(%c:%.32s) (%.30s) from chroot() jail (%s:%lu) "
+			       "owned by %d %d by " DEFAULTSECMSG, 
+			       "mknods in chroot denied",grdevmode,kdevname(dev),tmp,
+			       kdevname(current->fs->root->d_inode->i_dev),current->fs->root->d_inode->i_ino,
+			       current->fs->root->d_inode->i_uid,current->fs->root->d_inode->i_gid,
+			       DEFAULTSECARGS);
+			error = -EPERM;
+			dput(dentry);
+			goto out_dput;
+	}
+#endif	
+#ifdef CONFIG_GRKERNSEC_ACL
+	if( ( (gr_search(nd.dentry,GR_WRITE,nd.mnt)) == GR_DENY) ) {
+		security_alert("attempt to mknod %.1024s (dev %d) by "
+				DEFAULTSECMSG, "mknod attempts", filename, dev,
+				DEFAULTSECARGS);
+		error = -EPERM;
+		dput(dentry);
+		goto out_dput;
+	}
+#endif
+	
 		switch (mode & S_IFMT) {
 		case 0: case S_IFREG:
 			error = vfs_create(nd.dentry->d_inode,dentry,mode);
@@ -1271,6 +1431,7 @@
 		}
 		dput(dentry);
 	}
+out_dput:
 	up(&nd.dentry->d_inode->i_sem);
 	path_release(&nd);
 out:
@@ -1323,6 +1484,18 @@
 		dentry = lookup_create(&nd, 1);
 		error = PTR_ERR(dentry);
 		if (!IS_ERR(dentry)) {
+#ifdef CONFIG_GRKERNSEC_ACL
+			error = 0;
+			if( ( ((gr_search(nd.dentry,GR_WRITE,nd.mnt)) == GR_DENY))){
+			security_alert("attempt to mkdir %.1024s by "
+					DEFAULTSECMSG, "mkdir attempts",
+					pathname,
+					DEFAULTSECARGS);
+				error = -EPERM;
+			}
+			if(!error)
+#endif
+
 			error = vfs_mkdir(nd.dentry->d_inode, dentry,
 					  mode & ~current->fs->umask);
 			dput(dentry);
@@ -1431,7 +1604,18 @@
 	dentry = lookup_hash(&nd.last, nd.dentry);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
-		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+#ifdef CONFIG_GRKERNSEC_ACL
+		error = 0;
+		if( ( (gr_search(nd.dentry,GR_WRITE,nd.mnt)) == GR_DENY)) {
+			security_alert("attempt to rmdir %.1024s by "
+					DEFAULTSECMSG, "rmdir attempts",
+					pathname,
+					DEFAULTSECARGS);
+			error = -EPERM;
+		}
+		if(!error)
+#endif
+			error = vfs_rmdir(nd.dentry->d_inode, dentry);
 		dput(dentry);
 	}
 	up(&nd.dentry->d_inode->i_sem);
@@ -1494,7 +1678,18 @@
 		/* Why not before? Because we want correct error value */
 		if (nd.last.name[nd.last.len])
 			goto slashes;
-		error = vfs_unlink(nd.dentry->d_inode, dentry);
+#ifdef CONFIG_GRKERNSEC_ACL
+		error = 0;
+		if( ( (gr_search(dentry,GR_WRITE, nd.mnt)) == GR_DENY)) {
+		security_alert("attempt to unlink %.1024s by " DEFAULTSECMSG,
+				"unlink attempts",
+                		name, DEFAULTSECARGS);
+			error = -EPERM;
+		}
+		if(!error)
+#endif
+
+			error = vfs_unlink(nd.dentry->d_inode, dentry);
 	exit2:
 		dput(dentry);
 	}
@@ -1559,7 +1754,20 @@
 		dentry = lookup_create(&nd, 0);
 		error = PTR_ERR(dentry);
 		if (!IS_ERR(dentry)) {
-			error = vfs_symlink(nd.dentry->d_inode, dentry, from);
+#ifdef CONFIG_GRKERNSEC_ACL
+			error = 0;
+			if( gr_search(nd.dentry,GR_WRITE,nd.mnt) == GR_DENY)
+			{
+				security_alert("attempt to symlink %.1024s"
+					   "to %.1024s by " DEFAULTSECMSG,
+					   "symlink attempts",
+					from, to, DEFAULTSECARGS);
+				error = -EPERM;
+			}
+
+			if(!error)	
+#endif
+				error = vfs_symlink(nd.dentry->d_inode, dentry, from);
 			dput(dentry);
 		}
 		up(&nd.dentry->d_inode->i_sem);
@@ -1650,6 +1858,36 @@
 		new_dentry = lookup_create(&nd, 0);
 		error = PTR_ERR(new_dentry);
 		if (!IS_ERR(new_dentry)) {
+#if defined(CONFIG_GRKERNSEC_LINK) || defined(CONFIG_GRKERNSEC_ACL)
+			error = 0;
+#ifdef CONFIG_GRKERNSEC_LINK
+			if(grsec_enable_link) {
+				if(current->fsuid != old_nd.dentry->d_inode->i_uid &&
+		  		  (!S_ISREG(old_nd.dentry->d_inode->i_mode) ||
+		  		  (old_nd.dentry->d_inode->i_mode & S_ISUID) ||
+	          		  ((old_nd.dentry->d_inode->i_mode & (S_ISGID | S_IXGRP)) == 
+		  		  (S_ISGID | S_IXGRP)) || (error = permission(old_nd.dentry->d_inode,
+		  		  MAY_READ | MAY_WRITE))) && !capable(CAP_FOWNER) 
+				  && current->uid) {
+					security_alert("denied hardlink of %.30s (owned by %d.%d) to %.30s for "
+							DEFAULTSECMSG, "denied hardlinks",oldname,old_nd.dentry->d_inode->i_uid,
+							old_nd.dentry->d_inode->i_gid,newname,DEFAULTSECARGS);
+					error = -EPERM;
+				}
+			}
+			if(!error)
+#endif	
+#ifdef CONFIG_GRKERNSEC_ACL
+			if( gr_search(old_nd.dentry,GR_WRITE,old_nd.mnt) == GR_DENY || gr_search(nd.dentry,GR_WRITE,nd.mnt) == GR_DENY) {
+				security_alert("attempt to link %.1024s to %.1024s by " 
+                                	DEFAULTSECMSG, "attempted links", oldname, newname,
+					DEFAULTSECARGS);
+				error = -EPERM;
+			}
+			if(!error)
+#endif
+#endif
+
 			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
 			dput(new_dentry);
 		}
@@ -1887,11 +2125,26 @@
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
 		goto exit4;
+#ifdef CONFIG_GRKERNSEC_ACL
+	error = 0;
+	if( gr_search(old_dir,GR_WRITE,oldnd.mnt) == GR_DENY || gr_search(new_dir,GR_WRITE,newnd.mnt) == GR_DENY) {
+		security_alert("attempt to rename %.1024s to %.1024s by " 
+                                DEFAULTSECMSG, "rename attempts", 
+				oldname, newname,
+				DEFAULTSECARGS);
+		error = -EPERM;
+	}
+	if(!error) {
+#endif
+
 
 	lock_kernel();
 	error = vfs_rename(old_dir->d_inode, old_dentry,
 				   new_dir->d_inode, new_dentry);
 	unlock_kernel();
+#ifdef CONFIG_GRKERNSEC_ACL
+	}
+#endif
 
 	dput(new_dentry);
 exit4:
diff -urN linux/fs/namespace.c linux/fs/namespace.c
--- linux/fs/namespace.c	Fri Dec 21 12:41:55 2001
+++ linux/fs/namespace.c	Sun Jan 20 12:04:44 2002
@@ -16,6 +16,10 @@
 #include <linux/acct.h>
 #include <linux/module.h>
 #include <linux/devfs_fs_kernel.h>
+#if defined(CONFIG_GRKERNSEC_CHROOT_MOUNT) || defined(CONFIG_GRKERNSEC_AUDIT_MOUNT)
+#include <linux/sched.h>
+#include <linux/grsecurity.h>
+#endif
 
 #include <asm/uaccess.h>
 
@@ -353,6 +357,14 @@
 	}
 	spin_unlock(&dcache_lock);
 	up(&mount_sem);
+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
+	if(
+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
+        grsec_enable_group && in_group_p(grsec_audit_gid) &&
+#endif
+	grsec_enable_mount)
+		printk(KERN_INFO "grsec: unmount of %.30s by " DEFAULTSECMSG "\n",mnt->mnt_devname, DEFAULTSECARGS);
+#endif
 	return retval;
 }
 
@@ -673,6 +685,23 @@
 		retval = path_walk(dir_name, &nd);
 	if (retval)
 		return retval;
+
+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
+      if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
+                security_alert("denied attempt to mount (%.30s) as %.64s from chroot jail (%.32s:%lu) "
+                "of %d.%d by " DEFAULTSECMSG, "denied mounts in chroot",
+		dev_name,dir_name, kdevname(current->fs->root->d_inode->i_dev),
+              current->fs->root->d_inode->i_ino,current->fs->root->d_inode->i_uid,
+              current->fs->root->d_inode->i_gid, DEFAULTSECARGS);
+                       retval = -EPERM;
+                       path_release(&nd);
+                       return retval;
+      }
+#endif
+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
+	if(grsec_enable_mount)
+		printk(KERN_INFO "grsec: mount %.30s to %.64s by " DEFAULTSECMSG "\n",dev_name,dir_name, DEFAULTSECARGS);
+#endif
 
 	if (flags & MS_REMOUNT)
 		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
diff -urN linux/fs/open.c linux/fs/open.c
--- linux/fs/open.c	Fri Oct 12 16:48:42 2001
+++ linux/fs/open.c	Sun Jan 20 12:04:15 2002
@@ -18,8 +18,32 @@
 
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE)||\
+    defined(CONFIG_GRKERNSEC_CHROOT_CAPS) ||\
+    defined(CONFIG_GRKERNSEC_CHROOT_CHMOD) ||\
+    defined(CONFIG_GRKERNSEC_CHROOT_CHDIR) ||\
+    defined(CONFIG_GRKERNSEC_AUDIT_CHDIR) ||\
+    defined(CONFIG_GRKERNSEC_ACL)
+#include <linux/grsecurity.h>
+#endif
+
+
 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
 
+#ifdef CONFIG_GRKERNSEC_ACL
+static int conv_flags(int p) {
+	int retval = LOOKUP_FOLLOW;
+	if(p & O_NOFOLLOW)
+		retval &= ~LOOKUP_FOLLOW;
+	if( (p & (O_CREAT|O_EXCL)) == (O_CREAT | O_EXCL))
+		retval &= ~LOOKUP_FOLLOW;
+	if(p & O_DIRECTORY)
+		retval |= LOOKUP_DIRECTORY;
+	return retval;
+}
+#endif
+
+
 int vfs_statfs(struct super_block *sb, struct statfs *buf)
 {
 	int retval = -ENODEV;
@@ -71,7 +95,11 @@
 	return error;
 }
 
+#ifdef CONFIG_GRKERNSEC_ACL
+int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
+#else
 int do_truncate(struct dentry *dentry, loff_t length)
+#endif
 {
 	struct inode *inode = dentry->d_inode;
 	int error;
@@ -81,6 +109,17 @@
 	if (length < 0)
 		return -EINVAL;
 
+#ifdef CONFIG_GRKERNSEC_ACL
+	if( ( (gr_search(dentry,GR_WRITE,mnt)) == GR_DENY)) {
+		security_alert("attempted to truncate file with inode %ld dev "
+			"%d by " DEFAULTSECMSG, "file truncate attempts",
+			dentry->d_inode->i_ino,
+			dentry->d_inode->i_dev, DEFAULTSECARGS);
+		return -EPERM;
+	}
+#endif
+
+
 	down(&inode->i_sem);
 	newattrs.ia_size = length;
 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
@@ -139,7 +178,11 @@
 	error = locks_verify_truncate(inode, NULL, length);
 	if (!error) {
 		DQUOT_INIT(inode);
+#ifdef CONFIG_GRKERNSEC_ACL
+		error = do_truncate(nd.dentry, length, nd.mnt);
+#else
 		error = do_truncate(nd.dentry, length);
+#endif
 	}
 	put_write_access(inode);
 
@@ -191,7 +234,11 @@
 
 	error = locks_verify_truncate(inode, file, length);
 	if (!error)
+#ifdef CONFIG_GRKERNSEC_ACL
+		error = do_truncate(dentry, length, file->f_vfsmnt);
+#else
 		error = do_truncate(dentry, length);
+#endif
 out_putf:
 	fput(file);
 out:
@@ -245,6 +292,19 @@
 	if (IS_RDONLY(inode))
 		goto dput_and_out;
 
+#ifdef CONFIG_GRKERNSEC_ACL
+       if( ( (gr_search(nd.dentry,GR_WRITE,nd.mnt)) == GR_DENY)) {
+               security_alert("attempted to change access time for file"  
+               		"with inode %ld dev %d by " DEFAULTSECMSG,
+			"file access time change attempts",
+               		nd.dentry->d_inode->i_ino,
+                        nd.dentry->d_inode->i_dev, DEFAULTSECARGS);
+	       error = -EPERM;
+	       goto dput_and_out;
+       }
+#endif
+
+
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
 	if (times) {
@@ -290,6 +350,19 @@
 	if (IS_RDONLY(inode))
 		goto dput_and_out;
 
+#ifdef CONFIG_GRKERNSEC_ACL
+       if( ( (gr_search(nd.dentry,GR_WRITE,nd.mnt)) == GR_DENY)) {
+               security_alert("attempted to change access time for file with"
+                	"inode %ld dev %d by " DEFAULTSECMSG,
+			"file access time change attempts",
+               		nd.dentry->d_inode->i_ino,
+                        nd.dentry->d_inode->i_dev, DEFAULTSECARGS);
+                error = -EPERM;
+		goto dput_and_out;
+       }
+#endif
+
+
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
 	if (utimes) {
@@ -341,6 +414,17 @@
 
 	res = user_path_walk(filename, &nd);
 	if (!res) {
+#ifdef CONFIG_GRKERNSEC_ACL
+       if( ( (gr_search(nd.dentry,GR_WRITE,nd.mnt)) == GR_DENY)) {
+               security_alert("attempted to access file with inode %ld dev "
+               		"%d by " DEFAULTSECMSG, "file access attempts",
+			nd.dentry->d_inode->i_ino,
+                        nd.dentry->d_inode->i_dev, DEFAULTSECARGS);
+               path_release(&nd);
+               return -EPERM;
+       }
+#endif
+
 		res = permission(nd.dentry->d_inode, mode);
 		/* SuS v2 requires we report a read only fs too */
 		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
@@ -378,6 +462,25 @@
 	if (error)
 		goto dput_and_out;
 
+#ifdef CONFIG_GRKERNSEC_ACL
+       if( ( (gr_search(nd.dentry,GR_READ,nd.mnt)) == GR_DENY)) {
+               security_alert("Attempted to chdir to directory with inode %ld dev "
+               		"%d by " DEFAULTSECMSG, "chdir attempts",
+			nd.dentry->d_inode->i_ino,
+                        nd.dentry->d_inode->i_dev, DEFAULTSECARGS);
+               error = -EPERM;
+               goto dput_and_out;
+       }
+#endif
+
+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
+	if(
+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
+	grsec_enable_group && in_group_p(grsec_audit_gid) &&
+#endif
+	grsec_enable_chdir)
+		printk(KERN_INFO "grsec: chdir(\"%.64s\") by " DEFAULTSECMSG "\n", filename, DEFAULTSECARGS);
+#endif
 	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
 
 dput_and_out:
@@ -408,6 +511,17 @@
 		goto out_putf;
 
 	error = permission(inode, MAY_EXEC);
+
+#ifdef CONFIG_GRKERNSEC_ACL
+       if( ( (gr_search(file->f_dentry,GR_WRITE,file->f_vfsmnt)) == GR_DENY)) {
+               security_alert("attempted to truncate file with inode %ld dev "
+               		"%d by " DEFAULTSECMSG, "file truncate attempts",
+			file->f_dentry->d_inode->i_ino,
+                        file->f_dentry->d_inode->i_dev, DEFAULTSECARGS);
+               error = -EPERM;
+       }
+#endif
+
 	if (!error)
 		set_fs_pwd(current->fs, mnt, dentry);
 out_putf:
@@ -441,9 +555,39 @@
 	error = -EPERM;
 	if (!capable(CAP_SYS_CHROOT))
 		goto dput_and_out;
+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
+	if(grsec_enable_chroot_double && proc_is_chrooted(current)) {
+		security_alert("denied attempt to chroot() from (%.32s:%lu) to (%.30s)"
+			       ", process " DEFAULTSECMSG,
+			       "double chroot() denied",
+			       kdevname(current->fs->root->d_inode->i_dev),
+			       current->fs->root->d_inode->i_ino,name,
+			       DEFAULTSECARGS);
+			goto dput_and_out;
+	}
+#endif	
 
 	set_fs_root(current->fs, nd.mnt, nd.dentry);
 	set_fs_altroot();
+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
+	if(grsec_enable_chroot_caps && current->pid && current->pid > 1) {
+	    cap_lower(current->cap_permitted,CAP_FOWNER & CAP_SETPCAP & CAP_LINUX_IMMUTABLE &
+		      CAP_NET_ADMIN & CAP_SYS_MODULE & CAP_SYS_RAWIO & CAP_SYS_PACCT &
+		      CAP_SYS_ADMIN & CAP_SYS_BOOT & CAP_SYS_RESOURCE & CAP_SYS_TIME &
+		      CAP_SYS_TTY_CONFIG);
+	    cap_lower(current->cap_inheritable,CAP_FOWNER & CAP_SETPCAP & CAP_LINUX_IMMUTABLE &
+		      CAP_NET_ADMIN & CAP_SYS_MODULE & CAP_SYS_RAWIO & CAP_SYS_PACCT &
+		      CAP_SYS_ADMIN & CAP_SYS_BOOT & CAP_SYS_RESOURCE & CAP_SYS_TIME &
+		      CAP_SYS_TTY_CONFIG);
+	    cap_lower(current->cap_effective,CAP_FOWNER & CAP_SETPCAP & CAP_LINUX_IMMUTABLE &
+		      CAP_NET_ADMIN & CAP_SYS_MODULE & CAP_SYS_RAWIO & CAP_SYS_PACCT &
+		      CAP_SYS_ADMIN & CAP_SYS_BOOT & CAP_SYS_RESOURCE & CAP_SYS_TIME &
+		      CAP_SYS_TTY_CONFIG);
+	}
+#endif
+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
+	if (grsec_enable_chroot_chdir) set_fs_pwd(current->fs, nd.mnt, nd.dentry);
+#endif
 	error = 0;
 dput_and_out:
 	path_release(&nd);
@@ -472,8 +616,36 @@
 	err = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto out_putf;
+
+#ifdef CONFIG_GRKERNSEC_ACL
+	if( ( (gr_search(dentry,GR_WRITE,file->f_vfsmnt)) == GR_DENY)) {
+		security_alert("Attempt to fchmod program with inode %ld dev %d "
+			"by " DEFAULTSECMSG, "fchmod attempts",
+			dentry->d_inode->i_ino,
+                        dentry->d_inode->i_dev, DEFAULTSECARGS);
+
+		err = -EPERM;
+		goto out_putf;
+	}
+#endif
+
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
+	if(grsec_enable_chroot_chmod && ((mode & S_ISUID) || (mode & S_ISGID))
+	   && proc_is_chrooted(current)) {
+	    security_alert("denied attempt to fchmod +s (%.32s:%lu) owned by %d.%d to mode 0%07o "
+			   "from chroot jail (%.32s:%lu) of %d.%d by "
+			   DEFAULTSECMSG,
+			   "denied fchmod +s in chroot",
+			   kdevname(inode->i_dev),inode->i_ino,inode->i_uid,inode->i_gid,mode,
+			   kdevname(current->fs->root->d_inode->i_dev),current->fs->root->d_inode->i_ino,
+			   current->fs->root->d_inode->i_uid,current->fs->root->d_inode->i_gid,
+			   DEFAULTSECARGS);
+		err = -EPERM;
+		goto out_putf;
+	}	    
+#endif
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	err = notify_change(dentry, &newattrs);
@@ -504,8 +676,34 @@
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto dput_and_out;
 
+#ifdef CONFIG_GRKERNSEC_ACL
+	if( ( (gr_search(nd.dentry,GR_WRITE,nd.mnt)) == GR_DENY)) {
+		security_alert("Attempt to chmod file %1024s by "
+				DEFAULTSECMSG, "chmod attempts",
+                	        filename, DEFAULTSECARGS); 
+		error = -EPERM;
+		goto dput_and_out;
+	}
+#endif
+
+
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
+	if (grsec_enable_chroot_chmod && ((mode & S_ISUID) || (mode & S_ISGID))
+	    && proc_is_chrooted(current)) {
+	    security_alert("denied attempt to chmod +s (%.32s:%lu) (%.30s) owned by %d.%d to mode 0%07o "
+			   "from chroot jail (%.32s:%lu) of %d.%d by "
+			   DEFAULTSECMSG,"denied chmod +s in chroot",
+			   kdevname(inode->i_dev),inode->i_ino,filename,inode->i_uid,inode->i_gid,
+			   mode,kdevname(current->fs->root->d_inode->i_dev),
+			   current->fs->root->d_inode->i_ino,current->fs->root->d_inode->i_uid,
+			   current->fs->root->d_inode->i_gid,
+			   DEFAULTSECARGS);
+		    error = -EPERM;
+		    goto dput_and_out;
+	}
+#endif
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	error = notify_change(nd.dentry, &newattrs);
@@ -516,7 +714,11 @@
 	return error;
 }
 
+#ifdef CONFIG_GRKERNSEC_ACL
+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
+#else
 static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+#endif
 {
 	struct inode * inode;
 	int error;
@@ -533,6 +735,17 @@
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto out;
+#ifdef CONFIG_GRKERNSEC_ACL
+	if( ( (gr_search(dentry,GR_WRITE,mnt)) == GR_DENY)) {
+		security_alert("Attempt to chown file with inode %ld dev %d "
+			"to %d.%d by " DEFAULTSECMSG, "chown attempts",
+			dentry->d_inode->i_ino,dentry->d_inode->i_dev,
+			user, group, DEFAULTSECARGS);
+		error = -EPERM;
+		goto out;
+	}
+#endif
+
 	if (user == (uid_t) -1)
 		user = inode->i_uid;
 	if (group == (gid_t) -1)
@@ -583,7 +796,11 @@
 
 	error = user_path_walk(filename, &nd);
 	if (!error) {
+#ifdef CONFIG_GRKERNSEC_ACL
+		error = chown_common(nd.dentry, user, group, nd.mnt);
+#else
 		error = chown_common(nd.dentry, user, group);
+#endif
 		path_release(&nd);
 	}
 	return error;
@@ -596,7 +813,11 @@
 
 	error = user_path_walk_link(filename, &nd);
 	if (!error) {
+#ifdef CONFIG_GRKERNSEC_ACL
+		error = chown_common(nd.dentry, user, group, nd.mnt);
+#else
 		error = chown_common(nd.dentry, user, group);
+#endif
 		path_release(&nd);
 	}
 	return error;
@@ -610,7 +831,11 @@
 
 	file = fget(fd);
 	if (file) {
+#ifdef CONFIG_GRKERNSEC_ACL
+		error = chown_common(file->f_dentry, user, group, file->f_vfsmnt);
+#else
 		error = chown_common(file->f_dentry, user, group);
+#endif
 		fput(file);
 	}
 	return error;
@@ -634,12 +859,41 @@
 {
 	int namei_flags, error;
 	struct nameidata nd;
+#ifdef CONFIG_GRKERNSEC_ACL
+	struct nameidata obv;
+#endif
 
 	namei_flags = flags;
 	if ((namei_flags+1) & O_ACCMODE)
 		namei_flags++;
 	if (namei_flags & O_TRUNC)
 		namei_flags |= 2;
+
+#ifdef CONFIG_GRKERNSEC_ACL
+	error = 0;
+	if(path_init(filename,conv_flags(namei_flags),&obv))
+		error = path_walk(filename,&obv);
+	if(error) goto out;
+	if(!obv.dentry->d_inode) 
+		flags |= GR_NONEXISTANT;
+	else 
+		if(S_ISBLK(obv.dentry->d_inode->i_mode) && !capable(CAP_SYS_RAWIO)) {
+			security_alert("Attempt to block device %ld %d with "
+				"insuffificent capabilities by process "
+			        DEFAULTSECMSG,
+				"attempt to access block devices",
+				obv.dentry->d_inode->i_ino,
+				obv.dentry->d_inode->i_dev, DEFAULTSECARGS);
+			path_release(&obv);
+			error = -EPERM;
+			return ERR_PTR(error);
+		}
+
+	path_release(&obv);
+out:
+
+#endif
+
 
 	error = open_namei(filename, namei_flags, mode, &nd);
 	if (!error)
diff -urN linux/fs/proc/base.c linux/fs/proc/base.c
--- linux/fs/proc/base.c	Thu Oct 11 02:42:47 2001
+++ linux/fs/proc/base.c	Sun Jan 13 01:24:51 2002
@@ -24,6 +24,10 @@
 #include <linux/file.h>
 #include <linux/string.h>
 
+#ifdef CONFIG_GRKERNSEC_ACL
+#include <linux/grsecurity.h>
+#endif
+
 /*
  * For hysterical raisins we keep the same inumbers as in the old procfs.
  * Feel free to change the macro below - just keep the range distinct from
@@ -663,7 +667,11 @@
 	inode->i_gid = 0;
 	if (ino == PROC_PID_INO || task_dumpable(task)) {
 		inode->i_uid = task->euid;
+#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
 		inode->i_gid = task->egid;
+#else
+               inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
+#endif
 	}
 
 out:
@@ -966,13 +974,27 @@
 	if (!task)
 		goto out;
 
+#ifdef CONFIG_GRKERNSEC_ACL
+		if(gr_check_hidden_proc(task->acl)) {
+			free_task_struct(task);
+			goto out;
+		}
+#endif
+
+
 	inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
 
 	free_task_struct(task);
 
 	if (!inode)
 		goto out;
+#ifdef CONFIG_GRKERNSEC_PROC_USER
+	inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
+	inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
+#else
 	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+#endif
 	inode->i_op = &proc_base_inode_operations;
 	inode->i_fop = &proc_base_operations;
 	inode->i_nlink = 3;
@@ -1012,8 +1034,13 @@
 		int pid = p->pid;
 		if (!pid)
 			continue;
+#ifdef CONFIG_GRKERNSEC_ACL
+			if(gr_check_hidden_proc(p->acl)) 
+				continue;
+#endif
 		if (--index >= 0)
 			continue;
+
 		pids[nr_pids] = pid;
 		nr_pids++;
 		if (nr_pids >= PROC_MAXPIDS)
diff -urN linux/fs/proc/generic.c linux/fs/proc/generic.c
--- linux/fs/proc/generic.c	Fri Sep  7 13:53:59 2001
+++ linux/fs/proc/generic.c	Sun Jan 13 01:24:51 2002
@@ -491,6 +491,22 @@
 	return ent;
 }
 
+#ifdef CONFIG_GRKERNSEC_PROC
+struct proc_dir_entry *proc_priv_mkdir(const char *name, mode_t mode, struct proc_dir_entry *parent)
+{
+	struct proc_dir_entry *ent;
+
+	ent = proc_create(&parent, name, mode, 2);
+	if (ent) {
+		ent->proc_fops = &proc_dir_operations;
+		ent->proc_iops = &proc_dir_inode_operations;
+
+		proc_register(parent, ent);
+	}
+	return ent;
+}
+#endif
+
 struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
 					 struct proc_dir_entry *parent)
 {
diff -urN linux/fs/proc/inode.c linux/fs/proc/inode.c
--- linux/fs/proc/inode.c	Sat Nov 17 14:24:32 2001
+++ linux/fs/proc/inode.c	Sun Jan 13 01:24:51 2002
@@ -152,7 +152,11 @@
 		if (de->mode) {
 			inode->i_mode = de->mode;
 			inode->i_uid = de->uid;
+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
+			inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
+#else
 			inode->i_gid = de->gid;
+#endif
 		}
 		if (de->size)
 			inode->i_size = de->size;
diff -urN linux/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- linux/fs/proc/proc_misc.c	Wed Nov 21 00:29:09 2001
+++ linux/fs/proc/proc_misc.c	Sun Jan 13 01:24:51 2002
@@ -507,8 +507,10 @@
 		{"meminfo",	meminfo_read_proc},
 		{"version",	version_read_proc},
 #ifdef CONFIG_MODULES
+#ifndef CONFIG_GRKERNSEC_PROC
 		{"modules",	modules_read_proc},
 #endif
+#endif
 		{"stat",	kstat_read_proc},
 		{"devices",	devices_read_proc},
 		{"partitions",	partitions_read_proc},
@@ -531,6 +533,13 @@
 	for (p = simple_ones; p->name; p++)
 		create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
 
+#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES)
+#ifdef CONFIG_GRKERNSEC_PROC_USER
+	create_proc_read_entry("modules", S_IRUSR, NULL, &modules_read_proc, NULL);
+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
+	create_proc_read_entry("modules", S_IRUSR | S_IRGRP, NULL, &modules_read_proc, NULL);
+#endif
+#endif
 	/* And now for trickier ones */
 	entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
 	if (entry)
@@ -538,7 +547,13 @@
 	create_seq_entry("mounts", 0, &proc_mounts_operations);
 	create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
 #ifdef CONFIG_MODULES
+#ifdef CONFIG_GRKERNSEC_PROC_USER
+	create_seq_entry("ksyms", S_IRUSR, &proc_ksyms_operations);
+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
+	create_seq_en