]> git.pld-linux.org Git - packages/kernel.git/commitdiff
- full grsec with some of PAX features enables
authorJan Rękorajski <baggins@pld-linux.org>
Wed, 5 Nov 2003 15:50:37 +0000 (15:50 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    grsecurity-2.0-rc3-2.4.22-O1.patch -> 1.1
    kernel-grsec.config -> 1.26

grsecurity-2.0-rc3-2.4.22-O1.patch [new file with mode: 0644]
kernel-grsec.config

diff --git a/grsecurity-2.0-rc3-2.4.22-O1.patch b/grsecurity-2.0-rc3-2.4.22-O1.patch
new file mode 100644 (file)
index 0000000..ef5cf36
--- /dev/null
@@ -0,0 +1,18496 @@
+diff -urN linux-2.4.22/Documentation/Configure.help linux-2.4.22-grsec-O1/Documentation/Configure.help
+--- linux-2.4.22/Documentation/Configure.help  2003-10-20 18:59:11.000000000 +0200
++++ linux-2.4.22-grsec-O1/Documentation/Configure.help 2003-10-21 14:24:33.000000000 +0200
+@@ -2977,6 +2977,20 @@
+   If you want to compile it as a module, say M here and read
+   Documentation/modules.txt.  If unsure, say `N'.
++stealth networking support
++CONFIG_IP_NF_MATCH_STEALTH
++  Enabling this option will drop all syn packets coming to unserved tcp
++  ports as well as all packets coming to unserved udp ports.  If you
++  are using your system to route any type of packets (ie. via NAT)
++  you should put this module at the end of your ruleset, since it will 
++  drop packets that aren't going to ports that are listening on your 
++  machine itself, it doesn't take into account that the packet might be 
++  destined for someone on your internal network if you're using NAT for 
++  instance.
++
++  If you want to compile it as a module, say M here and read
++  Documentation/modules.txt.  If unsure, say `N'.
++
+ MAC address match support
+ CONFIG_IP_NF_MATCH_MAC
+   MAC matching allows you to match packets based on the source
+@@ -23554,6 +23568,871 @@
+   "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 the features and can evaluate their usefulness
++  for your machine.
++
++Additional security levels
++CONFIG_GRKERNSEC_LOW
++
++  Low additional security
++  -----------------------------------------------------------------------
++  If you choose this option, several of the grsecurity options will
++  be enabled that will give you greater protection against a number
++  of attacks, while assuring that none of your software will have any 
++  conflicts with the additional security measures.  If you run a lot of 
++  unusual software, or you are having problems with the higher security 
++  levels, you should say Y here.  With this option, the following features
++  are enabled:
++  
++  linking restrictions
++  fifo restrictions
++  random pids
++  enforcing nproc on execve()
++  restricted dmesg
++  random ip ids
++  enforced chdir("/") on chroot
++
++  Medium additional security
++  -----------------------------------------------------------------------
++  If you say Y here, several features in addition to those included in the 
++  low additional security level will be enabled.  These features provide
++  even more security to your system, though in rare cases they may
++  be incompatible with very old or poorly written software.  If you 
++  enable this option, make sure that your auth service (identd) is 
++  running as gid 10 (usually group wheel). With this option the following 
++  features (in addition to those provided in the low additional security 
++  level) will be enabled:
++
++  random tcp source ports
++  altered ping ids
++  failed fork logging
++  time change logging
++  signal logging
++  deny mounts in chroot
++  deny double chrooting
++  deny sysctl writes in chroot
++  deny mknod in chroot
++  deny access to abstract AF_UNIX sockets out of chroot
++  deny pivot_root in chroot
++  denied writes of /dev/kmem, /dev/mem, and /dev/port
++  /proc restrictions with special gid set to 10 (usually wheel)
++  address space layout randomization
++
++  High additional security
++  ----------------------------------------------------------------------
++  If you say Y here, many of the features of grsecurity will be enabled,
++  that will protect you against many kinds of attacks against
++  your system.  The heightened security comes at a cost of an 
++  increased chance of incompatibilities with rare software on your 
++  machine.  It is highly recommended that you view 
++  <http://grsecurity.net/features.htm> and read about each option.  Since 
++  this security level enabled PaX, you should also view 
++  <http://pageexec.virtualave.net> and read about the PaX project.  While 
++  you are there, download chpax.c and run chpax -p on binaries that cause 
++  problems with PaX.  Also remember that since the /proc restrictions are 
++  enabled, you must run your identd as group wheel (gid 10).  
++  This security level enables the following features in addition to those
++  listed in the low and medium security levels:
++
++  additional /proc restrictions
++  chmod restrictions in chroot
++  no signals, ptrace, or viewing processes outside of chroot
++  capability restrictions in chroot
++  deny fchdir out of chroot
++  priority restrictions in chroot
++  segmentation-based implementation of PaX
++  mprotect restrictions
++  removal of /proc/<pid>/[maps|mem]
++  kernel stack randomization
++  mount/unmount/remount logging
++  kernel symbol hiding
++
++Customized additional security
++CONFIG_GRKERNSEC_CUSTOM
++  If you say Y here, you will be able to configure every grsecurity 
++  option, which allows you to enable many more features that aren't 
++  covered in the basic security levels.  These additional features include 
++  TPE, socket restrictions, and the sysctl system for grsecurity.  It is 
++  advised that you read through the help for each option to determine its 
++  usefulness in your situation.
++
++Enforce non-executable pages
++CONFIG_GRKERNSEC_PAX_NOEXEC
++  By design some architectures do not allow for protecting memory
++  pages against execution or even if they do, Linux does not make
++  use of this feature.  In practice this means that 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 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).
++
++  Enabling this option will let you choose from various features
++  that prevent the injection and execution of '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>
++
++Paging based non-executable pages
++CONFIG_GRKERNSEC_PAX_PAGEEXEC
++  This implementation is based on the paging feature of the CPU.
++  On i386 it has a variable performance impact on applications
++  depending on their memory usage pattern.  You should carefully
++  test your applications before using this feature in production.
++  On alpha, parisc, sparc and sparc64 there is no performance
++  impact.  On ppc there is a slight performance impact.
++
++Segmentation based non-executable pages
++CONFIG_GRKERNSEC_PAX_SEGMEXEC
++  This implementation is based on the segmentation feature of the
++  CPU and has little performance impact, however applications will
++  be limited to a 1.5 GB address space instead of the normal 3 GB.
++
++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_PAGEEXEC or 
++  CONFIG_GRKERNSEC_PAX_SEGMEXEC 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 the non-executable pages.
++
++  On parisc and ppc you MUST enable this option and EMUSIGRT as
++  well, otherwise your system will not even boot.
++
++  Alternatively you can say N here and use the 'chpax' utility
++  to disable CONFIG_GRKERNSEC_PAX_PAGEEXEC and 
++  CONFIG_GRKERNSEC_PAX_SEGMEXEC for the affected files.
++
++  NOTE: enabling this feature *may* open up a loophole in the
++  protection provided by non-executable pages 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.
++
++Automatically emulate sigreturn trampolines
++CONFIG_GRKERNSEC_PAX_EMUSIGRT
++  Enabling this option will have the kernel automatically detect
++  and emulate signal return trampolines executing on the stack
++  that would otherwise lead to task termination.
++
++  This solution is intended as a temporary one for users with
++  legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
++  Modula-3 runtime, etc) or executables linked to such, basically
++  everything that does not specify its own SA_RESTORER function in
++  normal executable memory like glibc 2.1+ does.
++
++  On parisc and ppc you MUST enable this option, otherwise your
++  system will not even boot.
++
++  NOTE: this feature cannot be disabled on a per executable basis
++  and since it *does* open up a loophole in the protection provided
++  by non-executable pages, the best solution is to not have any
++  files on your system that would require this option.
++
++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,
++   - making read-only executable pages writable again,
++   - creating executable pages from anonymous memory.
++
++  You should say Y here to complete the protection provided by
++  the enforcement of non-executable pages.
++
++  NOTE: you can use the 'chpax' utility to control this
++  feature on a per file basis. chpax is available at
++  <http://pageexec.virtualave.net>
++
++Disallow ELF text relocations
++CONFIG_GRKERNSEC_PAX_NOELFRELOCS
++  Non-executable pages and mprotect() restrictions are effective
++  in preventing the introduction of new executable code into an
++  attacked task's address space.  There remain only two venues
++  for this kind of attack: if the attacker can execute already
++  existing code in the attacked task then he can either have it
++  create and mmap() a file containing his code or have it mmap()
++  an already existing ELF library that does not have position
++  independent code in it and use mprotect() on it to make it
++  writable and copy his code there.  While protecting against
++  the former approach is beyond PaX, the latter can be prevented
++  by having only PIC ELF libraries on one's system (which do not
++  need to relocate their code).  If you are sure this is your case,
++  then enable this option otherwise be careful as you may not even
++  be able to boot or log on your system (for example, some PAM
++  modules are erroneously compiled as non-PIC by default).
++
++  NOTE: if you are using dynamic ELF executables (as suggested
++  when using ASLR) then you must have made sure that you linked
++  your files using the PIC version of crt1 (the et_dyn.zip package
++  referenced there has already been updated to support this).
++
++Enforce non-executable kernel pages
++CONFIG_GRKERNSEC_PAX_KERNEXEC
++  This is the kernel land equivalent of PAGEEXEC and MPROTECT,
++  that is, enabling this option will make it harder to inject
++  and execute 'foreign' code in kernel memory itself.
++
++Address Space Layout Randomization
++CONFIG_GRKERNSEC_PAX_ASLR
++  Many if not most exploit techniques rely on the knowledge of
++  certain addresses in the attacked program.  The following options
++  will allow the kernel to apply a certain amount of randomization
++  to specific parts of the program thereby forcing an attacker to
++  guess them in most cases.  Any failed guess will most likely crash
++  the attacked program which allows the kernel to detect such attempts
++  and react on them.  PaX itself provides no reaction mechanisms,
++  instead it is strongly encouraged that you make use of grsecurity's
++  built-in crash detection features or develop one yourself.
++
++  By saying Y here you can choose to randomize the following areas:
++   - top of the task's kernel stack
++   - top of the task's userland stack
++   - base address for mmap() requests that do not specify one
++     (this includes all libraries)
++   - base address of the main executable
++
++  It is strongly recommended to say Y here 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 control most of these features
++  on a per file basis.
++
++Randomize kernel stack base
++CONFIG_GRKERNSEC_PAX_RANDKSTACK
++  By saying Y here the kernel will randomize every task's kernel
++  stack on every system call.  This will not only force an attacker
++  to guess it but also prevent him from making use of possible
++  leaked information about it.
++
++  Since the kernel stack is a rather scarce resource, randomization
++  may cause unexpected stack overflows, therefore you should very
++  carefully test your system.  Note that once enabled in the kernel
++  configuration, this feature cannot be disabled on a per file basis.
++
++Randomize user stack base
++CONFIG_GRKERNSEC_PAX_RANDUSTACK
++  By saying Y here the kernel will randomize every task's userland
++  stack.  The randomization is done in two steps where the second
++  one may apply a big amount of shift to the top of the stack and
++  cause problems for programs that want to use lots of memory (more
++  than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
++  For this reason the second step can be controlled by 'chpax' on
++  a per file basis.
++
++Randomize ET_EXEC base
++CONFIG_GRKERNSEC_PAX_RANDEXEC     
++  By saying Y here the kernel will randomize the base address of normal
++  ET_EXEC ELF executables as well.  This is accomplished by mapping the
++  executable in memory in a special way which also allows for detecting
++  attackers who attempt to execute its code for their purposes.  Since
++  this special mapping causes performance degradation and the attack
++  detection may create false alarms as well, you should carefully test
++  your executables when this feature is enabled.
++
++  This solution is intended only as a temporary one until you relink
++  your programs as a dynamic ELF file.
++
++  NOTE: you can use the 'chpax' utility to control this feature
++  on a per file basis.
++
++Allow ELF ET_EXEC text relocations
++CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
++  On some architectures like the alpha there are incorrectly
++  created applications that require text relocations and would
++  not work without enabling this option.  If you are an alpha
++  user, you should enable this option and disable it once you
++  have made sure that none of your applications need it.
++
++Automatically emulate ELF PLT
++CONFIG_GRKERNSEC_PAX_EMUPLT
++  Enabling this option will have the kernel automatically detect
++  and emulate the Procedure Linkage Table entries in ELF files.
++  On some architectures such entries are in writable memory, and
++  become non-executable leading to task termination.  Therefore
++  it is mandatory that you enable this option on alpha, parisc, ppc,
++  sparc and sparc64, otherwise your system would not even boot.
++
++  NOTE: this feature *does* open up a loophole in the protection
++  provided by the non-executable pages, therefore the proper
++  solution is to modify the toolchain to produce a PLT that does
++  not need to be writable.
++
++
++Randomize mmap() base
++CONFIG_GRKERNSEC_PAX_RANDMMAP
++  By saying Y here the kernel will use a randomized base address for
++  mmap() requests that do not specify one themselves.  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 will be randomized as well, completing the full
++  randomization of the address space layout.  Attacking such programs
++  becomes a guess game.  You can find an example of doing this at
++  <http://pageexec.virtualave.net/et_dyn.zip> and practical samples at
++  <http://www.grsecurity.net/grsec-gcc-specs.tar.gz> .
++
++  NOTE: you can use the 'chpax' utility to control this feature
++  on a per file basis.
++
++Deny writing to /dev/kmem, /dev/mem, and /dev/port
++CONFIG_GRKERNSEC_KMEM
++  If you say Y here, /dev/kmem and /dev/mem won't be allowed to
++  be written to via mmap or otherwise to modify the running kernel.
++  /dev/port will also not be allowed to be opened. If you have module
++  support disabled, enabling this will close up four ways that are
++  currently used  to insert malicious code into the running kernel.
++  Even with all these features enabled, we still highly recommend that
++  you use the ACL system, as it is still possible for an attacker to 
++  modify the running kernel through privileged I/O granted by ioperm/iopl.
++  If you are not using XFree86, you may be able to stop this additional
++  case by enabling the 'Disable privileged I/O' option. Though nothing
++  legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
++  but only to video memory, which is the only writing we allow in this
++  case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
++  not be allowed to mprotect it with PROT_WRITE later.
++  Enabling this feature could make certain apps like VMWare stop working,
++  as they need to write to other locations in /dev/mem.
++  It is highly recommended that you say Y here if you meet all the 
++  conditions above.
++
++Disable privileged I/O
++CONFIG_GRKERNSEC_IO
++  If you say Y here, all ioperm and iopl calls will return an error.
++  Ioperm and iopl can be used to modify the running kernel.
++  Unfortunately, some programs need this access to operate properly,
++  the most notable of which are XFree86 and hwclock.  hwclock can be
++  remedied by having RTC support in the kernel, so CONFIG_RTC is
++  enabled if this option is enabled, to ensure that hwclock operates
++  correctly.  XFree86 still will not operate correctly with this option
++  enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
++  and you still want to protect your kernel against modification,
++  use the ACL system.
++
++Hide kernel symbols
++CONFIG_GRKERNSEC_HIDESYM
++  If you say Y here, getting information on loaded modules, and 
++  displaying all kernel symbols through a syscall will be restricted
++  to users with CAP_SYS_MODULE.  This option is only effective 
++  provided the following conditions are met:
++  1) The kernel using grsecurity is not precompiled by some distribution
++  2) You are using the ACL system and hiding other files such as your
++     kernel image and System.map
++  3) You have the additional /proc restrictions enabled, which removes
++     /proc/kcore
++  If the above conditions are met, this option will aid to provide a
++  useful protection against local and remote kernel exploitation of
++  overflows and arbitrary read/write vulnerabilities.
++
++/proc/<pid>/ipaddr support
++CONFIG_GRKERNSEC_PROC_IPADDR
++  If you say Y here, a new entry will be added to each /proc/<pid>
++  directory that contains the IP address of the person using the task.
++  The IP is carried across local TCP and AF_UNIX stream sockets.
++  This information can be useful for IDS/IPSes to perform remote response
++  to a local attack.  The entry is readable by only the owner of the 
++  process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
++  the RBAC system), and thus does not create privacy concerns.
++
++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,  
++  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.
++
++Remove addresses from /proc/pid/[maps|stat]
++CONFIG_GRKERNSEC_PROC_MEMMAP
++  If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
++  give no information about the addresses of its mappings if
++  PaX features that rely on random addresses are enabled on the task.
++  If you use PaX it is greatly recommended that you say Y here as it 
++  closes up a hole that makes the full ASLR useless for suid 
++  binaries.
++
++Additional proc restrictions
++CONFIG_GRKERNSEC_PROC_ADD
++  If you say Y here, additional restrictions will be placed on
++  /proc that keep normal users from viewing cpu and device information.
++
++Dmesg(8) Restriction
++CONFIG_GRKERNSEC_DMESG
++  If you say Y here, non-root users will not be able to use dmesg(8)
++  to view up to the last 4kb of messages in the kernel's log buffer.
++  If the sysctl option is enabled, a sysctl option with name "dmesg" is 
++  created.
++
++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-writable +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-writable +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.
++
++Enforce RLIMIT_NPROC on execs
++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.
++
++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.
++
++Resource logging
++CONFIG_GRKERNSEC_RESLOG
++  If you say Y here, all attempts to overstep resource limits will
++  be logged with the resource name, the requested size, and the current
++  limit.  It is highly recommended that you say Y here.
++
++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.
++
++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.
++
++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.
++
++Deny access to abstract AF_UNIX sockets out of chroot
++CONFIG_GRKERNSEC_CHROOT_UNIX
++  If you say Y here, processes inside a chroot will not be able to
++  connect to abstract (meaning not belonging to a filesystem) Unix
++  domain sockets that were bound outside of a chroot.  It is recommended
++  that you say Y here.  If the sysctl option is enabled, a sysctl option
++  with name "chroot_deny_unix" is created.
++
++Deny shmat() out of chroot
++CONFIG_GRKERNSEC_CHROOT_SHMAT
++  If you say Y here, processes inside a chroot will not be able to attach
++  to shared memory segments that were created outside of the chroot jail.
++  It is recommended that you say Y here.  If the sysctl option is enabled,
++  a sysctl option with name "chroot_deny_shmat" is created.
++
++Protect outside processes
++CONFIG_GRKERNSEC_CHROOT_FINDTASK
++  If you say Y here, processes inside a chroot will not be able to
++  kill, send signals with fcntl, ptrace, capget, setpgid, getpgid, 
++  getsid, or view any process outside of the chroot.  If the sysctl 
++  option is enabled, a sysctl option with name "chroot_findtask" 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 pivot_root in chroot
++CONFIG_GRKERNSEC_CHROOT_PIVOT
++  If you say Y here, processes inside a chroot will not be able to use
++  a function called pivot_root() that was introduced in Linux 2.3.41.  It 
++  works similar to chroot in that it changes the root filesystem.  This 
++  function could be misused in a chrooted process to attempt to break out 
++  of the chroot, and therefore should not be allowed.  If the sysctl 
++  option is enabled, a sysctl option with name "chroot_deny_pivot" 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.
++
++Deny fchdir outside of chroot
++CONFIG_GRKERNSEC_CHROOT_FCHDIR
++  If you say Y here, a well-known method of breaking chroots by fchdir'ing
++  to a file descriptor of the chrooting process that points to a directory
++  outside the filesystem will be stopped.  If the sysctl option
++  is enabled, a sysctl option with name "chroot_deny_fchdir" 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
++  anything 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.
++
++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.  This can cause a large amount of logs if certain
++  applications (eg. djb's daemontools) are installed on the system, and
++  is therefore left as an option.  If the sysctl option is enabled, a 
++  sysctl option with name "chroot_execlog" is created.
++
++Deny sysctl writes in chroot
++CONFIG_GRKERNSEC_CHROOT_SYSCTL
++  If you say Y here, an attacker in a chroot will not be able to
++  write to sysctl entries, either by sysctl(2) or through a /proc
++  interface.  It is strongly recommended that you say Y here. If the
++  sysctl option is enabled, a sysctl option with name 
++  "chroot_deny_sysctl" 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, rebooting the system, modifying immutable 
++  files, modifying IPC owned by another, and changing the system time.
++  This is left an option because it can break 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 writable 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 non-root users other than the ones in the 
++  group specified in the main TPE option will only be allowed to
++  execute files in directories they own that are not group or
++  world-writable, or in directories owned by root and writable only by
++  root.  If the sysctl option is enabled, a sysctl option with name 
++  "tpe_restrict_all" 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.
++
++Larger entropy pools
++CONFIG_GRKERNSEC_RANDNET
++  If you say Y here, the entropy pools used for many features of Linux
++  and grsecurity will be doubled in size.  Since several grsecurity 
++  features use additional randomness, it is recommended that you say Y 
++  here.  Saying Y here has a similar effect as modifying
++  /proc/sys/kernel/random/poolsize.
++
++Truly random TCP ISN selection
++CONFIG_GRKERNSEC_RANDISN
++  If you say Y here, Linux's default selection of TCP Initial Sequence
++  Numbers (ISNs) will be replaced with that of OpenBSD.  Linux uses
++  an MD4 hash based on the connection plus a time value to create the
++  ISN, while OpenBSD's selection is random.  If the sysctl option is 
++  enabled, a sysctl option with name "rand_isns" 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.
++
++Randomized RPC XIDs
++CONFIG_GRKERNSEC_RANDRPC
++  If you say Y here, the method of determining XIDs for RPC requests will
++  be randomized, instead of using linux's default behavior of simply
++  incrementing the XID.  If you want your RPC connections to be more
++  secure, say Y here.  If the sysctl option is enabled, a sysctl option 
++  with name "rand_rpc" 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*
++
++Number of burst messages
++CONFIG_GRKERNSEC_FLOODBURST
++  This option allows you to choose the maximum number of messages allowed
++  within the flood time interval you chose in a separate option.  The 
++  default should be suitable for most people, however if you find that 
++  many of your logs are being interpreted as flooding, you may want to 
++  raise this value.
++
++Seconds in between log messages
++CONFIG_GRKERNSEC_FLOODTIME
++  This option allows you to enforce the number of seconds between
++  grsecurity log messages.  The default should be suitable for most 
++  people, however, if you choose to change it, choose a value small enough
++  to allow informative logs to be produced, but large enough to
++  prevent flooding.
++
++Hide kernel processes
++CONFIG_GRKERNSEC_ACL_HIDEKERN
++  If you say Y here, when the ACL system is enabled via gradm -E,
++  an additional ACL will be passed to the kernel that hides all kernel
++  processes.  These processes will only be viewable by the authenticated
++  admin, or processes that have viewing access set.
++
++Maximum tries before password lockout
++CONFIG_GRKERNSEC_ACL_MAXTRIES
++  This option enforces the maximum number of times a user can attempt
++  to authorize themselves with the grsecurity ACL system before being
++  denied the ability to attempt authorization again for a specified time.  
++  The lower the number, the harder it will be to brute-force a password.
++
++Time to wait after max password tries, in seconds
++CONFIG_GRKERNSEC_ACL_TIMEOUT
++  This option specifies the time the user must wait after attempting to 
++  authorize to the ACL system with the maximum number of invalid 
++  passwords.  The higher the number, the harder it will be to brute-force 
++  a password.
++
+ Disable data cache
+ CONFIG_DCACHE_DISABLE
+   This option allows you to run the kernel with data cache disabled.
+diff -urN linux-2.4.22/Makefile linux-2.4.22-grsec-O1/Makefile
+--- linux-2.4.22/Makefile      2003-10-20 18:59:11.000000000 +0200
++++ linux-2.4.22-grsec-O1/Makefile     2003-10-21 14:24:33.000000000 +0200
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 4
+ SUBLEVEL = 22
+-EXTRAVERSION =
++EXTRAVERSION = -grsec
+ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+@@ -134,9 +134,10 @@
+ CORE_FILES    =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
+ NETWORKS      =net/network.o
++GRSECURITY    =grsecurity/grsec.o
+ LIBS          =$(TOPDIR)/lib/lib.a
+-SUBDIRS               =kernel drivers mm fs net ipc lib crypto
++SUBDIRS               =kernel drivers mm fs net ipc lib crypto grsecurity
+ DRIVERS-n :=
+ DRIVERS-y :=
+@@ -279,7 +280,7 @@
+ export        CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
+-export        NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
++export        NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS GRSECURITY
+ .S.s:
+       $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
+@@ -298,6 +299,7 @@
+               $(CORE_FILES) \
+               $(DRIVERS) \
+               $(NETWORKS) \
++              $(GRSECURITY) \
+               $(LIBS) \
+               --end-group \
+               -o vmlinux
+diff -urN linux-2.4.22/arch/alpha/config.in linux-2.4.22-grsec-O1/arch/alpha/config.in
+--- linux-2.4.22/arch/alpha/config.in  2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/alpha/config.in 2003-10-21 14:24:33.000000000 +0200
+@@ -457,3 +457,12 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
++
+diff -urN linux-2.4.22/arch/alpha/kernel/osf_sys.c linux-2.4.22-grsec-O1/arch/alpha/kernel/osf_sys.c
+--- linux-2.4.22/arch/alpha/kernel/osf_sys.c   2003-06-13 16:51:29.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/alpha/kernel/osf_sys.c  2003-10-21 14:24:33.000000000 +0200
+@@ -33,6 +33,7 @@
+ #include <linux/file.h>
+ #include <linux/types.h>
+ #include <linux/ipc.h>
++#include <linux/grsecurity.h>
+ #include <asm/fpu.h>
+ #include <asm/io.h>
+@@ -230,6 +231,11 @@
+       struct file *file = NULL;
+       unsigned long ret = -EBADF;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+ #if 0
+       if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
+               printk("%s: unimplemented OSF mmap flags %04lx\n", 
+@@ -240,6 +246,13 @@
+               if (!file)
+                       goto out;
+       }
++
++      if(gr_handle_mmap(file, prot)) {
++              fput(file);
++              ret = -EACCES;
++              goto out;
++      }
++
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       down_write(&current->mm->mmap_sem);
+       ret = do_mmap(file, addr, len, prot, flags, off);
+@@ -1357,6 +1370,10 @@
+          merely specific addresses, but regions of memory -- perhaps
+          this feature should be incorporated into all ports?  */
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
++#endif
++
+       if (addr) {
+               addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
+               if (addr != -ENOMEM)
+@@ -1364,8 +1381,15 @@
+       }
+       /* Next, try allocating at TASK_UNMAPPED_BASE.  */
+-      addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
+-                                       len, limit);
++
++      addr = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      if (current->flags & PF_PAX_RANDMMAP)
++              addr += current->mm->delta_mmap;
++#endif
++
++      addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
+       if (addr != -ENOMEM)
+               return addr;
+diff -urN linux-2.4.22/arch/alpha/kernel/ptrace.c linux-2.4.22-grsec-O1/arch/alpha/kernel/ptrace.c
+--- linux-2.4.22/arch/alpha/kernel/ptrace.c    2003-06-13 16:51:29.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/alpha/kernel/ptrace.c   2003-10-21 14:24:33.000000000 +0200
+@@ -13,6 +13,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/user.h>
+ #include <linux/slab.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -275,6 +276,10 @@
+       read_unlock(&tasklist_lock);
+       if (!child)
+               goto out_notsk;
++
++      if(gr_handle_ptrace(child, request))
++              goto out;
++
+       if (request == PTRACE_ATTACH) {
+               ret = ptrace_attach(child);
+               goto out;
+diff -urN linux-2.4.22/arch/alpha/mm/fault.c linux-2.4.22-grsec-O1/arch/alpha/mm/fault.c
+--- linux-2.4.22/arch/alpha/mm/fault.c 2002-11-29 00:53:08.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/alpha/mm/fault.c        2003-10-21 14:24:33.000000000 +0200
+@@ -53,6 +53,139 @@
+       __reload_thread(&current->thread);
+ }
++/*
++ * PaX: decide what to do with offenders (regs->pc = fault address)
++ *
++ * returns 1 when task should be killed
++ *         2 when patched PLT trampoline was detected
++ *         3 when unpatched PLT trampoline was detected
++ *       4 when legitimate ET_EXEC was detected
++ */
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++      int err;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (current->flags & PF_PAX_RANDEXEC) {
++              if (regs->pc >= current->mm->start_code &&
++                  regs->pc < current->mm->end_code)
++              {
++                      if (regs->r26 == regs->pc)
++                              return 1;
++                      regs->pc += current->mm->delta_exec;
++                      return 4;
++              }
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++      do { /* PaX: patched PLT emulation #1 */
++              unsigned int ldah, ldq, jmp;
++
++              err = get_user(ldah, (unsigned int *)regs->pc);
++              err |= get_user(ldq, (unsigned int *)(regs->pc+4));
++              err |= get_user(jmp, (unsigned int *)(regs->pc+8));
++
++              if (err)
++                      break;
++
++              if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
++                  (ldq & 0xFFFF0000U) == 0xA77B0000U &&
++                  jmp == 0x6BFB0000U)
++              {
++                      unsigned long r27, addr;
++                      unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++                      unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
++
++                      addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++                      err = get_user(r27, (unsigned long*)addr);
++                      if (err)
++                              break;
++
++                      regs->r27 = r27;
++                      regs->pc = r27;
++                      return 2;
++              }
++      } while (0);
++
++      do { /* PaX: patched PLT emulation #2 */
++              unsigned int ldah, lda, br;
++
++              err = get_user(ldah, (unsigned int *)regs->pc);
++              err |= get_user(lda, (unsigned int *)(regs->pc+4));
++              err |= get_user(br, (unsigned int *)(regs->pc+8));
++
++              if (err)
++                      break;
++
++              if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
++                  (lda & 0xFFFF0000U) == 0xA77B0000U &&
++                  (br & 0xFFE00000U) == 0xC3E00000U)
++              {
++                      unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
++                      unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++                      unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
++
++                      regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++                      regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++                      return 2;
++              }
++      } while (0);
++
++      do { /* PaX: unpatched PLT emulation */
++              unsigned int br;
++
++              err = get_user(br, (unsigned int *)regs->pc);
++
++              if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
++                      unsigned int br2, ldq, nop, jmp;
++                      unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
++
++                      addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++                      err = get_user(br2, (unsigned int *)addr);  
++                      err |= get_user(ldq, (unsigned int *)(addr+4));
++                      err |= get_user(nop, (unsigned int *)(addr+8));
++                      err |= get_user(jmp, (unsigned int *)(addr+12));
++                      err |= get_user(resolver, (unsigned long *)(addr+16));
++
++                      if (err)
++                              break;
++
++                      if (br2 == 0xC3600000U &&
++                          ldq == 0xA77B000CU &&
++                          nop == 0x47FF041FU &&
++                          jmp == 0x6B7B0000U)
++                      {
++                              regs->r28 = regs->pc+4;
++                              regs->r27 = addr+16;
++                              regs->pc = resolver;
++                              return 3;
++                      }
++              }
++      } while (0);
++#endif
++
++      return 1;
++}
++
++void pax_report_insns(void *pc)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 5; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int*)pc+i)) {
++                      printk("<invalid address>.");
++                      break;
++              }
++              printk("%08x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ /*
+  * This routine handles page faults.  It determines the address,
+@@ -133,8 +266,32 @@
+ good_area:
+       info.si_code = SEGV_ACCERR;
+       if (cause < 0) {
+-              if (!(vma->vm_flags & VM_EXEC))
++              if (!(vma->vm_flags & VM_EXEC)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++                      if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->pc)
++                              goto bad_area;
++
++                      up_read(&mm->mmap_sem);
++                      switch(pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++                      case 2:
++                      case 3:
++                              return;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++                      case 4:
++                              return;
++#endif
++                      }
++                      pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
++                      do_exit(SIGKILL);
++#else
+                       goto bad_area;
++#endif
++              }
+       } else if (!cause) {
+               /* Allow reads even for write-only mappings */
+               if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
+diff -urN linux-2.4.22/arch/arm/config.in linux-2.4.22-grsec-O1/arch/arm/config.in
+--- linux-2.4.22/arch/arm/config.in    2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/arm/config.in   2003-10-21 14:24:33.000000000 +0200
+@@ -734,3 +734,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/cris/config.in linux-2.4.22-grsec-O1/arch/cris/config.in
+--- linux-2.4.22/arch/cris/config.in   2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/cris/config.in  2003-10-21 14:24:33.000000000 +0200
+@@ -275,3 +275,12 @@
+ source crypto/Config.in
+ source lib/Config.in
+ 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-2.4.22/arch/i386/Makefile linux-2.4.22-grsec-O1/arch/i386/Makefile
+--- linux-2.4.22/arch/i386/Makefile    2003-06-13 16:51:29.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/Makefile   2003-10-21 14:24:33.000000000 +0200
+@@ -114,6 +114,9 @@
+ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
++arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE
++      $(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/linux/config.h -imacros $(HPATH)/asm-i386/segment.h -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds
++
+ vmlinux: arch/i386/vmlinux.lds
+ FORCE: ;
+@@ -150,6 +153,7 @@
+       @$(MAKEBOOT) clean
+ archmrproper:
++      rm -f arch/i386/vmlinux.lds
+ archdep:
+       @$(MAKEBOOT) dep
+diff -urN linux-2.4.22/arch/i386/config.in linux-2.4.22-grsec-O1/arch/i386/config.in
+--- linux-2.4.22/arch/i386/config.in   2003-10-20 18:59:07.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/config.in  2003-10-21 14:24:33.000000000 +0200
+@@ -500,3 +500,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/i386/kernel/apm.c linux-2.4.22-grsec-O1/arch/i386/kernel/apm.c
+--- linux-2.4.22/arch/i386/kernel/apm.c        2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/apm.c       2003-10-21 14:24:33.000000000 +0200
+@@ -614,7 +614,7 @@
+       __asm__ __volatile__(APM_DO_ZERO_SEGS
+               "pushl %%edi\n\t"
+               "pushl %%ebp\n\t"
+-              "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
++              "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
+               "setc %%al\n\t"
+               "popl %%ebp\n\t"
+               "popl %%edi\n\t"
+@@ -666,7 +666,7 @@
+               __asm__ __volatile__(APM_DO_ZERO_SEGS
+                       "pushl %%edi\n\t"
+                       "pushl %%ebp\n\t"
+-                      "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
++                      "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
+                       "setc %%bl\n\t"
+                       "popl %%ebp\n\t"
+                       "popl %%edi\n\t"
+@@ -1985,6 +1985,12 @@
+                __va((unsigned long)0x40 << 4));
+       _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4));
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      set_base(gdt2[APM_40 >> 3],
++              __va((unsigned long)0x40 << 4));
++      _set_limit((char *)&gdt2[APM_40 >> 3], 4095 - (0x40 << 4));
++#endif
++
+       apm_bios_entry.offset = apm_info.bios.offset;
+       apm_bios_entry.segment = APM_CS;
+       set_base(gdt[APM_CS >> 3],
+@@ -1993,6 +1999,16 @@
+                __va((unsigned long)apm_info.bios.cseg_16 << 4));
+       set_base(gdt[APM_DS >> 3],
+                __va((unsigned long)apm_info.bios.dseg << 4));
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      set_base(gdt2[APM_CS >> 3],
++              __va((unsigned long)apm_info.bios.cseg << 4));
++      set_base(gdt2[APM_CS_16 >> 3],
++              __va((unsigned long)apm_info.bios.cseg_16 << 4));
++      set_base(gdt2[APM_DS >> 3],
++              __va((unsigned long)apm_info.bios.dseg << 4));
++#endif
++
+ #ifndef APM_RELAX_SEGMENTS
+       if (apm_info.bios.version == 0x100) {
+ #endif
+@@ -2002,6 +2018,13 @@
+               _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
+               /* For the DEC Hinote Ultra CT475 (and others?) */
+               _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++              _set_limit((char *)&gdt2[APM_CS >> 3], 64 * 1024 - 1);
++              _set_limit((char *)&gdt2[APM_CS_16 >> 3], 64 * 1024 - 1);
++              _set_limit((char *)&gdt2[APM_DS >> 3], 64 * 1024 - 1);
++#endif
++
+ #ifndef APM_RELAX_SEGMENTS
+       } else {
+               _set_limit((char *)&gdt[APM_CS >> 3],
+@@ -2010,6 +2033,16 @@
+                       (apm_info.bios.cseg_16_len - 1) & 0xffff);
+               _set_limit((char *)&gdt[APM_DS >> 3],
+                       (apm_info.bios.dseg_len - 1) & 0xffff);
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++              _set_limit((char *)&gdt2[APM_CS >> 3],
++                      (apm_info.bios.cseg_len - 1) & 0xffff);
++              _set_limit((char *)&gdt2[APM_CS_16 >> 3],
++                      (apm_info.bios.cseg_16_len - 1) & 0xffff);
++              _set_limit((char *)&gdt2[APM_DS >> 3],
++                      (apm_info.bios.dseg_len - 1) & 0xffff);
++#endif
++
+       }
+ #endif
+diff -urN linux-2.4.22/arch/i386/kernel/entry.S linux-2.4.22-grsec-O1/arch/i386/kernel/entry.S
+--- linux-2.4.22/arch/i386/kernel/entry.S      2003-10-20 18:58:34.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/entry.S     2003-10-21 14:24:33.000000000 +0200
+@@ -211,6 +211,17 @@
+       jae badsys
+       call *SYMBOL_NAME(sys_call_table)(,%eax,4)
+       movl %eax,EAX(%esp)             # save the return value
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
++      cli                             # need_resched and signals atomic test
++      cmpl $0,need_resched(%ebx)
++      jne reschedule
++      cmpl $0,sigpending(%ebx)
++      jne signal_return
++      call SYMBOL_NAME(pax_randomize_kstack)
++      jmp restore_all
++#endif
++
+ ENTRY(ret_from_sys_call)
+       cli                             # need_resched and signals atomic test
+       cmpl $0,need_resched(%ebx)
+@@ -391,8 +402,56 @@
+       jmp error_code
+ ENTRY(page_fault)
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      ALIGN
++      pushl $ SYMBOL_NAME(pax_do_page_fault)
++#else
+       pushl $ SYMBOL_NAME(do_page_fault)
++#endif
++
++#ifndef CONFIG_GRKERNSEC_PAX_EMUTRAMP
+       jmp error_code
++#else
++      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
++#endif
+ ENTRY(machine_check)
+       pushl $0
+@@ -404,7 +463,7 @@
+       pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
+       jmp error_code
+-.data
++.section .rodata, "a"
+ ENTRY(sys_call_table)
+       .long SYMBOL_NAME(sys_ni_syscall)       /* 0  -  old "setup()" system call*/
+       .long SYMBOL_NAME(sys_exit)
+diff -urN linux-2.4.22/arch/i386/kernel/head.S linux-2.4.22-grsec-O1/arch/i386/kernel/head.S
+--- linux-2.4.22/arch/i386/kernel/head.S       2003-06-13 16:51:29.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/head.S      2003-10-21 14:24:33.000000000 +0200
+@@ -41,6 +41,7 @@
+  *
+  * On entry, %esi points to the real-mode code as a 32-bit pointer.
+  */
++.global startup_32
+ startup_32:
+ /*
+  * Set segments to known values
+@@ -86,7 +87,7 @@
+                                  PRESENT+RW+USER */
+ 2:    stosl
+       add $0x1000,%eax
+-      cmp $empty_zero_page-__PAGE_OFFSET,%edi
++      cmp $0x00c00007,%eax
+       jne 2b
+ /*
+@@ -100,9 +101,19 @@
+       movl %eax,%cr0          /* ..and set paging (PG) bit */
+       jmp 1f                  /* flush the prefetch-queue */
+ 1:
++
++#if !defined(CONFIG_GRKERNSEC_PAX_KERNEXEC) || defined(CONFIG_SMP)
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      orw  %bx,%bx
++      jz  1f
++#endif
++
+       movl $1f,%eax
+       jmp *%eax               /* make sure eip is relocated */
+ 1:
++#endif
++
+       /* Set up the stack pointer */
+       lss stack_start,%esp
+@@ -121,7 +132,7 @@
+  */
+       xorl %eax,%eax
+       movl $ SYMBOL_NAME(__bss_start),%edi
+-      movl $ SYMBOL_NAME(_end),%ecx
++      movl $ SYMBOL_NAME(__bss_end),%ecx
+       subl %edi,%ecx
+       rep
+       stosb
+@@ -272,8 +283,6 @@
+       jmp L6                  # main should never return here, but
+                               # just in case, we know what happens.
+-ready:        .byte 0
+-
+ /*
+  * We depend on ET to be correct. This checks for 287/387.
+  */
+@@ -319,13 +328,6 @@
+       jne rp_sidt
+       ret
+-ENTRY(stack_start)
+-      .long SYMBOL_NAME(init_task_union)+8192
+-      .long __KERNEL_DS
+-
+-/* This is the default interrupt "handler" :-) */
+-int_msg:
+-      .asciz "Unknown interrupt\n"
+       ALIGN
+ ignore_int:
+       cld
+@@ -347,6 +349,18 @@
+       popl %eax
+       iret
++.data
++ready:        .byte 0
++
++ENTRY(stack_start)
++      .long SYMBOL_NAME(init_task_union)+8192
++      .long __KERNEL_DS
++
++.section .rodata,"a"
++/* This is the default interrupt "handler" :-) */
++int_msg:
++      .asciz "Unknown interrupt\n"
++
+ /*
+  * The interrupt descriptor table has room for 256 idt's,
+  * the global descriptor table is dependent on the number
+@@ -372,41 +386,58 @@
+ SYMBOL_NAME(gdt):
+       .long SYMBOL_NAME(gdt_table)
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++.globl SYMBOL_NAME(gdt2)
++      .word 0
++gdt_descr2:
++      .word GDT_ENTRIES*8-1
++SYMBOL_NAME(gdt2):
++      .long SYMBOL_NAME(gdt_table2)
++#endif
++
+ /*
+  * This is initialized to create an identity-mapping at 0-8M (for bootup
+  * purposes) and another mapping of the 0-8M area at virtual address
+  * PAGE_OFFSET.
+  */
+-.org 0x1000
++.section .data.swapper_pg_dir,"a"
+ ENTRY(swapper_pg_dir)
+-      .long 0x00102007
+-      .long 0x00103007
+-      .fill BOOT_USER_PGD_PTRS-2,4,0
++      .long pg0-__PAGE_OFFSET+7
++      .long pg1-__PAGE_OFFSET+7
++      .long pg2-__PAGE_OFFSET+7
++      .fill BOOT_USER_PGD_PTRS-3,4,0
+       /* default: 766 entries */
+-      .long 0x00102007
+-      .long 0x00103007
++      .long pg0-__PAGE_OFFSET+7
++      .long pg1-__PAGE_OFFSET+7
++      .long pg2-__PAGE_OFFSET+7
+       /* default: 254 entries */
+-      .fill BOOT_KERNEL_PGD_PTRS-2,4,0
++      .fill BOOT_KERNEL_PGD_PTRS-3,4,0
+ /*
+  * The page tables are initialized to only 8MB here - the final page
+  * tables are set up later depending on memory size.
+  */
+-.org 0x2000
++.section .data.pg0,"a"
+ ENTRY(pg0)
++      .fill 1024,4,0
+-.org 0x3000
++.section .data.pg1,"a"
+ ENTRY(pg1)
++      .fill 1024,4,0
++
++.section .data.pg2,"a"
++ENTRY(pg2)
++      .fill 1024,4,0
+ /*
+  * empty_zero_page must immediately follow the page tables ! (The
+  * initialization loop counts until empty_zero_page)
+  */
+-
+-.org 0x4000
++.section .data.empty_zero_page,"a"
+ ENTRY(empty_zero_page)
++      .fill 1024,4,0
+-.org 0x5000
++.text
+ /*
+  * Real beginning of normal "text" segment
+@@ -419,7 +450,7 @@
+  * in the text section because it has alignment requirements
+  * that we cannot fulfill any other way.
+  */
+-.data
++.section .rodata,"a"
+ ALIGN
+ /*
+@@ -430,19 +461,55 @@
+  */
+ ENTRY(gdt_table)
+       .quad 0x0000000000000000        /* NULL descriptor */
+-      .quad 0x0000000000000000        /* not used */
+-      .quad 0x00cf9a000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
+-      .quad 0x00cf92000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
+-      .quad 0x00cffa000000ffff        /* 0x23 user   4GB code at 0x00000000 */
+-      .quad 0x00cff2000000ffff        /* 0x2b user   4GB data at 0x00000000 */
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      .quad 0x00cf9b000000ffff        /* 0x08 kernel 4GB code at 0x00000000 */
++      .quad 0xc0cf9b400000ffff        /* 0x10 kernel 4GB code at 0xc0400000 */
++#else
++      .quad 0x0000000000000000        /* not used */
++      .quad 0x00cf9b000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
++#endif
++
++      .quad 0x00cf93000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
++      .quad 0x00cffb000000ffff        /* 0x23 user   4GB code at 0x00000000 */
++      .quad 0x00cff3000000ffff        /* 0x2b user   4GB data at 0x00000000 */
++      .quad 0x0000000000000000        /* not used */
++      .quad 0x0000000000000000        /* not used */
++      /*
++       * The APM segments have byte granularity and their bases
++       * and limits are set at run time.
++       */
++      .quad 0x0040930000000000        /* 0x40 APM set up for bad BIOS's */
++      .quad 0x00409b0000000000        /* 0x48 APM CS    code */
++      .quad 0x00009b0000000000        /* 0x50 APM CS 16 code (16 bit) */
++      .quad 0x0040930000000000        /* 0x58 APM DS    data */
++      .fill NR_CPUS*4,8,0             /* space for TSS's and LDT's */
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++ENTRY(gdt_table2)
++      .quad 0x0000000000000000        /* NULL descriptor */
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      .quad 0x00cf9b000000ffff        /* 0x08 kernel 4GB code at 0x00000000 */
++      .quad 0xc0cf9b400000ffff        /* 0x10 kernel 4GB code at 0xc0400000 */
++#else
++      .quad 0x0000000000000000        /* not used */
++      .quad 0x00cf9b000000ffff        /* 0x10 kernel 4GB code at 0x00000000 */
++#endif
++
++      .quad 0x00cf93000000ffff        /* 0x18 kernel 4GB data at 0x00000000 */
++      .quad 0x60c5fb000000ffff        /* 0x23 user 1.5GB code at 0x60000000 */
++      .quad 0x00c5f3000000ffff        /* 0x2b user 1.5GB data at 0x00000000 */
++
+       .quad 0x0000000000000000        /* not used */
+       .quad 0x0000000000000000        /* not used */
+       /*
+        * The APM segments have byte granularity and their bases
+        * and limits are set at run time.
+        */
+-      .quad 0x0040920000000000        /* 0x40 APM set up for bad BIOS's */
+-      .quad 0x00409a0000000000        /* 0x48 APM CS    code */
+-      .quad 0x00009a0000000000        /* 0x50 APM CS 16 code (16 bit) */
+-      .quad 0x0040920000000000        /* 0x58 APM DS    data */
++      .quad 0x0040930000000000        /* 0x40 APM set up for bad BIOS's */
++      .quad 0x00409b0000000000        /* 0x48 APM CS    code */
++      .quad 0x00009b0000000000        /* 0x50 APM CS 16 code (16 bit) */
++      .quad 0x0040930000000000        /* 0x58 APM DS    data */
+       .fill NR_CPUS*4,8,0             /* space for TSS's and LDT's */
++#endif
+diff -urN linux-2.4.22/arch/i386/kernel/i386_ksyms.c linux-2.4.22-grsec-O1/arch/i386/kernel/i386_ksyms.c
+--- linux-2.4.22/arch/i386/kernel/i386_ksyms.c 2003-10-20 18:59:00.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/i386_ksyms.c        2003-10-21 14:24:34.000000000 +0200
+@@ -74,6 +74,9 @@
+ EXPORT_SYMBOL(get_cmos_time);
+ EXPORT_SYMBOL(apm_info);
+ EXPORT_SYMBOL(gdt);
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++EXPORT_SYMBOL(gdt2);
++#endif
+ EXPORT_SYMBOL(empty_zero_page);
+ #ifdef CONFIG_DEBUG_IOVIRT
+diff -urN linux-2.4.22/arch/i386/kernel/ioport.c linux-2.4.22-grsec-O1/arch/i386/kernel/ioport.c
+--- linux-2.4.22/arch/i386/kernel/ioport.c     2003-06-13 16:51:29.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/ioport.c    2003-10-21 14:24:34.000000000 +0200
+@@ -14,6 +14,7 @@
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
+ #include <linux/stddef.h>
++#include <linux/grsecurity.h>
+ /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
+ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
+@@ -59,8 +60,16 @@
+       if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
+               return -EINVAL;
++#ifdef CONFIG_GRKERNSEC_IO
++      if (turn_on) {
++              gr_handle_ioperm();
++#else
+       if (turn_on && !capable(CAP_SYS_RAWIO))
++#endif
+               return -EPERM;
++#ifdef CONFIG_GRKERNSEC_IO
++      }
++#endif
+       /*
+        * If it's the first ioperm() call in this thread's lifetime, set the
+        * IO bitmap up. ioperm() is much less timing critical than clone(),
+@@ -109,8 +118,13 @@
+               return -EINVAL;
+       /* Trying to gain more privileges? */
+       if (level > old) {
++#ifdef CONFIG_GRKERNSEC_IO
++              gr_handle_iopl();
++              return -EPERM;
++#else
+               if (!capable(CAP_SYS_RAWIO))
+                       return -EPERM;
++#endif
+       }
+       regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
+       return 0;
+diff -urN linux-2.4.22/arch/i386/kernel/ldt.c linux-2.4.22-grsec-O1/arch/i386/kernel/ldt.c
+--- linux-2.4.22/arch/i386/kernel/ldt.c        2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/ldt.c       2003-10-21 14:24:34.000000000 +0200
+@@ -124,6 +124,13 @@
+               }
+       }
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
++              error = -EINVAL;
++              goto out_unlock;
++      }
++#endif
++
+       entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
+                 (ldt_info.limit & 0x0ffff);
+       entry_2 = (ldt_info.base_addr & 0xff000000) |
+diff -urN linux-2.4.22/arch/i386/kernel/pci-pc.c linux-2.4.22-grsec-O1/arch/i386/kernel/pci-pc.c
+--- linux-2.4.22/arch/i386/kernel/pci-pc.c     2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/pci-pc.c    2003-10-21 14:24:34.000000000 +0200
+@@ -17,6 +17,7 @@
+ #include <asm/io.h>
+ #include <asm/smp.h>
+ #include <asm/smpboot.h>
++#include <asm/desc.h>
+ #include "pci-i386.h"
+@@ -575,10 +576,16 @@
+  * the array there.
+  */
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++#define __FLAT_KERNEL_CS 0x08
++#else
++#define __FLAT_KERNEL_CS __KERNEL_CS
++#endif
++
+ static struct {
+       unsigned long address;
+       unsigned short segment;
+-} bios32_indirect = { 0, __KERNEL_CS };
++} bios32_indirect = { 0, __FLAT_KERNEL_CS };
+ /*
+  * Returns the entry point for the given service, NULL on error
+@@ -619,7 +626,9 @@
+ static struct {
+       unsigned long address;
+       unsigned short segment;
+-} pci_indirect = { 0, __KERNEL_CS };
++} pci_indirect = { 0, __FLAT_KERNEL_CS };
++
++#undef __FLAT_KERNEL_CS
+ static int pci_bios_present;
+@@ -1456,6 +1465,7 @@
+       if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
+               pcibios_sort();
+ #endif
++
+ }
+ char * __devinit  pcibios_setup(char *str)
+diff -urN linux-2.4.22/arch/i386/kernel/process.c linux-2.4.22-grsec-O1/arch/i386/kernel/process.c
+--- linux-2.4.22/arch/i386/kernel/process.c    2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/process.c   2003-10-21 14:24:34.000000000 +0200
+@@ -590,7 +590,11 @@
+ {
+       struct pt_regs * childregs;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
++      childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p - sizeof(unsigned long))) - 1;
++#else
+       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
++#endif
+       struct_cpy(childregs, regs);
+       childregs->eax = 0;
+       childregs->esp = esp;
+@@ -651,6 +655,16 @@
+       dump->u_fpvalid = dump_fpu (regs, &dump->i387);
+ }
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++void pax_switch_segments(struct task_struct * tsk)
++{
++      if (tsk->flags & PF_PAX_SEGMEXEC)
++              __asm__ __volatile__("lgdt %0": "=m" (gdt_descr2));
++      else
++              __asm__ __volatile__("lgdt %0": "=m" (gdt_descr));
++}
++#endif
++
+ /*
+  * This special macro can be used to load a debugging register
+  */
+@@ -690,6 +704,10 @@
+       unlazy_fpu(prev_p);
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      pax_switch_segments(next_p);
++#endif
++
+       /*
+        * Reload esp0, LDT and the page table pointer:
+        */
+@@ -832,3 +850,25 @@
+ }
+ #undef last_sched
+ #undef first_sched
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK
++asmlinkage void pax_randomize_kstack(void)
++{
++      struct tss_struct *tss = init_tss + smp_processor_id();
++      unsigned long time;
++
++      rdtscl(time);
++
++      /* P4 seems to return a 0 LSB, ignore it */
++#ifdef CONFIG_MPENTIUM4
++      time &= 0x3EUL;
++      time <<= 1;
++#else
++      time &= 0x1FUL;
++      time <<= 2;
++#endif
++
++      current->thread.esp0 ^= time;
++      tss->esp0 = current->thread.esp0;
++}
++#endif
+diff -urN linux-2.4.22/arch/i386/kernel/ptrace.c linux-2.4.22-grsec-O1/arch/i386/kernel/ptrace.c
+--- linux-2.4.22/arch/i386/kernel/ptrace.c     2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/ptrace.c    2003-10-21 14:24:34.000000000 +0200
+@@ -13,6 +13,7 @@
+ #include <linux/errno.h>
+ #include <linux/ptrace.h>
+ #include <linux/user.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -182,6 +183,9 @@
+       if (pid == 1)           /* you may not mess with init */
+               goto out_tsk;
++      if(gr_handle_ptrace(child, request))
++              goto out_tsk;
++
+       if (request == PTRACE_ATTACH) {
+               ret = ptrace_attach(child);
+               goto out_tsk;
+@@ -261,6 +265,17 @@
+                         if(addr < (long) &dummy->u_debugreg[4] &&
+                            ((unsigned long) data) >= TASK_SIZE-3) break;
+                         
++#ifdef CONFIG_GRKERNSEC
++                        if(addr >= (long) &dummy->u_debugreg[0] &&
++                           addr <= (long) &dummy->u_debugreg[3]){
++                                long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
++                                long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
++                                long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
++                                if((type & 1) && (data & align))
++                                      break;
++                        }
++#endif
++
+                         if(addr == (long) &dummy->u_debugreg[7]) {
+                                 data &= ~DR_CONTROL_RESERVED;
+                                 for(i=0; i<4; i++)
+diff -urN linux-2.4.22/arch/i386/kernel/setup.c linux-2.4.22-grsec-O1/arch/i386/kernel/setup.c
+--- linux-2.4.22/arch/i386/kernel/setup.c      2003-10-20 18:59:00.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/setup.c     2003-10-21 14:24:34.000000000 +0200
+@@ -3147,7 +3147,7 @@
+       set_tss_desc(nr,t);
+       gdt_table[__TSS(nr)].b &= 0xfffffdff;
+       load_TR(nr);
+-      load_LDT(&init_mm);
++      _load_LDT(&init_mm);
+       /* Clear %fs and %gs. */
+       asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
+diff -urN linux-2.4.22/arch/i386/kernel/sys_i386.c linux-2.4.22-grsec-O1/arch/i386/kernel/sys_i386.c
+--- linux-2.4.22/arch/i386/kernel/sys_i386.c   2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/sys_i386.c  2003-10-21 14:24:34.000000000 +0200
+@@ -18,6 +18,7 @@
+ #include <linux/mman.h>
+ #include <linux/file.h>
+ #include <linux/utsname.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/ipc.h>
+@@ -48,6 +49,11 @@
+       int error = -EBADF;
+       struct file * file = NULL;
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       if (!(flags & MAP_ANONYMOUS)) {
+               file = fget(fd);
+@@ -55,8 +61,14 @@
+                       goto out;
+       }
++      if(gr_handle_mmap(file, prot)) {
++              fput(file);
++              error = -EACCES;
++              goto out;
++      }
++
+       down_write(&mm->mmap_sem);
+-      error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
++      error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
+       up_write(&mm->mmap_sem);
+       if (file)
+diff -urN linux-2.4.22/arch/i386/kernel/trampoline.S linux-2.4.22-grsec-O1/arch/i386/kernel/trampoline.S
+--- linux-2.4.22/arch/i386/kernel/trampoline.S 2002-11-29 00:53:09.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/trampoline.S        2003-10-21 14:24:34.000000000 +0200
+@@ -54,7 +54,7 @@
+       lmsw    %ax             # into protected mode
+       jmp     flush_instr
+ flush_instr:
+-      ljmpl   $__KERNEL_CS, $0x00100000
++      ljmpl   $__KERNEL_CS, $SYMBOL_NAME(startup_32)-__PAGE_OFFSET
+                       # jump to startup_32 in arch/i386/kernel/head.S
+ idt_48:
+diff -urN linux-2.4.22/arch/i386/kernel/traps.c linux-2.4.22-grsec-O1/arch/i386/kernel/traps.c
+--- linux-2.4.22/arch/i386/kernel/traps.c      2002-11-29 00:53:09.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/i386/kernel/traps.c     2003-10-21 14:24:34.000000000 +0200
+@@ -228,14 +228,23 @@
+               show_stack((unsigned long*)esp);
+               printk("\nCode: ");
++
++#ifndef CONFIG_GRKERNSEC_PAX_KERNEXEC
+               if(regs->eip < PAGE_OFFSET)
+                       goto bad;
++#endif
+               for(i=0;i<20;i++)
+               {
+                       unsigned char c;
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++                      if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) {
++#else
+                       if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
+ bad:
++#endif
++
+                               printk(" Bad EIP value.");
+                               break;
+                       }
+@@ -258,8 +267,13 @@
+       eip = regs->eip;
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      eip += __KERNEL_TEXT_OFFSET;
++#else
+       if (eip < PAGE_OFFSET)
+               goto no_bug;
++#endif
++
+       if (__get_user(ud2, (unsigned short *)eip))
+               goto no_bug;
+       if (ud2 != 0x0b0f)
+@@ -267,7 +281,13 @@
+       if (__get_user(line, (unsigned short *)(eip + 2)))
+               goto bug;
+       if (__get_user(file, (char **)(eip + 4)) ||
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++              __get_user(c, file + __KERNEL_TEXT_OFFSET))
++#else
+               (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
++#endif
++
+               file = "<bad filename>";
+       printk("kernel BUG at %s:%d!\n", file, line);
+@@ -417,6 +437,18 @@
+ gp_in_kernel:
+       {
+               unsigned long fixup;
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++              if ((regs->xcs & 0xFFFF) == __KERNEL_CS) {
++                      if (current->curr_ip)
++                              printk(KERN_ERR "PAX: From %u.%u.%u.%u: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n",
++                                              NIPQUAD(current->curr_ip), current->comm, current->pid, current->uid, current->euid, regs->eip);
++                      else
++                              printk(KERN_ERR "PAX: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n",
++                                              current->comm, current->pid, current->uid, current->euid, regs->eip);
++              }
++#endif
++
+               fixup = search_exception_table(regs->eip);
+               if (fixup) {
+                       regs->eip = fixup;
+@@ -527,13 +559,12 @@
+ {
+       unsigned int condition;
+       struct task_struct *tsk = current;
+-      unsigned long eip = regs->eip;
+       siginfo_t info;
+       __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
+       /* If the user set TF, it's simplest to clear it right away. */
+-      if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
++      if (!(regs->xcs & 3) && (regs->eflags & TF_MASK) && !(regs->eflags & VM_MASK))
+               goto clear_TF;
+       /* Mask out spurious debug traps due to lazy DR7 setting */
+@@ -855,11 +886,55 @@
+ void set_tss_desc(unsigned int n, void *addr)
+ {
+       _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      _set_tssldt_desc(gdt_table2+__TSS(n), (int)addr, 235, 0x89);
++#endif
++
++}
++
++void __set_ldt_desc(unsigned int n, void *addr, unsigned int size)
++{
++      _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
++#endif
++
+ }
+ void set_ldt_desc(unsigned int n, void *addr, unsigned int size)
+ {
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      unsigned long temp, cr3;
++      pgd_t* pgd;
++      pmd_t* pmd;
++
++      asm("movl %%cr3,%0":"=r" (cr3));
++      for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
++              pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
++              pmd = pmd_offset(pgd, temp);
++              set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_RW));
++      }
++      __flush_tlb_all();
++#endif
++
+       _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) {
++              pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp);
++              pmd = pmd_offset(pgd, temp);
++              set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
++      }
++      flush_tlb_all();
++#endif
++
+ }
+ #ifdef CONFIG_X86_VISWS_APIC
+diff -urN linux-2.4.22/arch/i386/mm/fault.c linux-2.4.22-grsec-O1/arch/i386/mm/fault.c
+--- linux-2.4.22/arch/i386/mm/fault.c  2003-10-20 18:59:09.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/mm/fault.c 2003-10-21 14:24:34.000000000 +0200
+@@ -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,8 @@
+ #include <linux/init.h>
+ #include <linux/tty.h>
+ #include <linux/vt_kern.h>            /* For unblank_screen() */
++#include <linux/unistd.h>
++#include <linux/compiler.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -123,6 +126,10 @@
+ asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
+ extern unsigned long idt;
++#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
++static int pax_handle_fetch_fault(struct pt_regs *regs);
++#endif
++
+ /*
+  * This routine handles page faults.  It determines the address,
+  * and the problem, and then passes it off to one of the appropriate
+@@ -133,23 +140,31 @@
+  *    bit 1 == 0 means read, 1 means write
+  *    bit 2 == 0 means kernel, 1 means user-mode
+  */
+-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++static int do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
++#else
++asmlinkage int 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_PAGEEXEC
+       unsigned long address;
++#endif
+       unsigned long page;
+       unsigned long fixup;
+       int write;
+       siginfo_t info;
++#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC
+       /* 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;
+@@ -256,7 +271,7 @@
+       }
+       up_read(&mm->mmap_sem);
+       tsk->in_page_fault = 0;
+-      return;
++      return 0;
+ /*
+  * Something tried to access memory that isn't in our memory map..
+@@ -268,6 +283,39 @@
+       /* User mode accesses just cause a SIGSEGV */
+       if (error_code & 4) {
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++              if (current->flags & PF_PAX_SEGMEXEC) {
++
++#if defined(CONFIG_GRKERNSEC_PAX_EMUTRAMP) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++              if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
++                      switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++                      case 5:
++                              return 0;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
++                      case 4:
++                              return 0;
++                      case 3:
++                      case 2:
++                              return 1;
++#endif
++
++                      case 1:
++                      default:
++                      }
++              }
++#endif
++
++                      if (address >= SEGMEXEC_TASK_SIZE) {
++                              pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
++                              do_exit(SIGKILL);
++                      }
++              }
++#endif
++
+               tsk->thread.cr2 = address;
+               tsk->thread.error_code = error_code;
+               tsk->thread.trap_no = 14;
+@@ -276,7 +324,7 @@
+               /* info.si_code has been set above */
+               info.si_addr = (void *)address;
+               force_sig_info(SIGSEGV, &info, tsk);
+-              return;
++              return 0;
+       }
+       /*
+@@ -289,7 +337,7 @@
+               if (nr == 6) {
+                       do_invalid_op(regs, 0);
+-                      return;
++                      return 0;
+               }
+       }
+@@ -297,7 +345,7 @@
+       /* Are we prepared to handle this kernel fault?  */
+       if ((fixup = search_exception_table(regs->eip)) != 0) {
+               regs->eip = fixup;
+-              return;
++              return 0;
+       }
+ /*
+@@ -310,6 +358,18 @@
+       if (address < PAGE_SIZE)
+               printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET) {
++              if (tsk->curr_ip)
++                      printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
++                                       NIPQUAD(tsk->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
++              else
++                      printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
++                                       tsk->comm, tsk->pid, tsk->uid, tsk->euid);
++      }
++#endif
++
+       else
+               printk(KERN_ALERT "Unable to handle kernel paging request");
+       printk(" at virtual address %08lx\n",address);
+@@ -364,7 +424,7 @@
+       /* Kernel mode? Handle exceptions or die */
+       if (!(error_code & 4))
+               goto no_context;
+-      return;
++      return 0;
+ vmalloc_fault:
+       {
+@@ -397,6 +457,337 @@
+               pte_k = pte_offset(pmd_k, address);
+               if (!pte_present(*pte_k))
+                       goto no_context;
+-              return;
++              return 0;
++      }
++}
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++/* 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);
++}
++#endif
++
++/*
++ * PaX: decide what to do with offenders (regs->eip = fault address)
++ *
++ * returns 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
++ *       5 when legitimate ET_EXEC was detected
++ */
++#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
++      static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
++#endif
++      int err;
++      
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (current->flags & PF_PAX_RANDEXEC) {
++              unsigned long esp_4;
++              if (regs->eip >= current->mm->start_code &&
++                  regs->eip < current->mm->end_code)
++              {
++                      err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
++                      if (err || esp_4 == regs->eip)
++                              return 1;
++                      regs->eip += current->mm->delta_exec;
++                      return 5;
++              }
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
++
++#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++      if (!(current->flags & PF_PAX_EMUTRAMP))
++              return 1;
++#endif
++
++      do { /* 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)
++                      break;
++
++              if (pop == 0x58 &&
++                  mov == 0xb8 &&
++                  nr == __NR_sigreturn &&
++                  sys == 0x80cd)
++              {
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++                      int sig;
++                      struct k_sigaction *ka;
++                      __sighandler_t handler;
++
++                      if (get_user(sig, (int *)regs->esp))
++                              return 1;
++                      if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
++                              return 1;
++                      ka = &current->sig->action[sig-1];
++                      handler = ka->sa.sa_handler;
++                      if (handler == SIG_DFL || handler == SIG_IGN) {
++                              if (!(current->flags & PF_PAX_EMUTRAMP))
++                                      return 1;
++                      } else if (!(ka->sa.sa_flags & SA_SIGINFO))
++                              return 1;
++#endif
++
++                      regs->esp += 4;
++                      regs->eax = nr;
++                      regs->eip += 8;
++                      return 2;
++              }
++      } while (0);
++
++      do { /* 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)
++                      break;
++
++              if (mov == 0xb8 &&
++                  nr == __NR_rt_sigreturn &&
++                  sys == 0x80cd)
++              {
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++                      int sig;
++                      struct k_sigaction *ka;
++                      __sighandler_t handler;
++
++                      if (get_user(sig, (int *)regs->esp))
++                              return 1;
++                      if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP)
++                              return 1;
++                      ka = &current->sig->action[sig-1];
++                      handler = ka->sa.sa_handler;
++                      if (handler == SIG_DFL || handler == SIG_IGN) {
++                              if (!(current->flags & PF_PAX_EMUTRAMP))
++                                      return 1;
++                      } else if (ka->sa.sa_flags & SA_SIGINFO)
++                              return 1;
++#endif
++
++                      regs->eax = nr;
++                      regs->eip += 7;
++                      return 3;
++              }
++      } while (0);
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++      if (!(current->flags & PF_PAX_EMUTRAMP))
++              return 1;
++#endif
++
++      do { /* PaX: gcc trampoline emulation #1 */
++              unsigned char mov1, mov2;
++              unsigned short jmp;
++              unsigned long addr1, addr2, ret;
++              unsigned short call;
++
++              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)
++                      break;
++
++              err = get_user(call, (unsigned short *)(ret-2));
++              if (err)
++                      break;
++
++              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;
++              }
++      } while (0);
++
++      do { /* PaX: gcc trampoline emulation #2 */
++              unsigned char mov, jmp;
++              unsigned long addr1, addr2, ret;
++              unsigned short call;
++
++              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)
++                      break;
++
++              err = get_user(call, (unsigned short *)(ret-2));
++              if (err)
++                      break;
++
++              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;
++              }
++      } while (0);
++#endif
++
++      return 1; /* PaX in action */
++}
++
++void pax_report_insns(void *pc)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 20; i++) {
++              unsigned char c;
++              if (get_user(c, (unsigned char*)pc+i)) {
++                      printk("<invalid address>.");
++                      break;
++              }
++              printk("%02x ", c);
++      }
++      printk("\n");
++}
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++/*
++ * 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 mm_struct *mm = current->mm;
++      unsigned long address;
++      pte_t *pte;
++      unsigned char pte_mask;
++      int ret;
++
++      __asm__("movl %%cr2,%0":"=r" (address));
++
++      /* It's safe to allow irq's after cr2 has been saved */
++      if (likely(regs->eflags & X86_EFLAGS_IF))
++              local_irq_enable();
++
++      if (unlikely((error_code & 5) != 5 ||
++                   address >= TASK_SIZE ||
++                   !(current->flags & PF_PAX_PAGEEXEC)))
++              return do_page_fault(regs, error_code, address);
++
++      /* PaX: it's our fault, let's handle it if we can */
++
++      /* PaX: take a look at read faults before acquiring any locks */
++      if (unlikely((error_code == 5) && (regs->eip == address))) { 
++              /* instruction fetch attempt from a protected page in user mode */
++              ret = pax_handle_fetch_fault(regs);
++              switch (ret) {
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++              case 5:
++                      return 0;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
++              case 4:
++                      return 0;
++              case 3:
++              case 2:
++                      return 1;
++#endif
++              case 1:
++              default:
++                      pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
++                      do_exit(SIGKILL);
++              }
++      }
++
++      pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
++
++      spin_lock(&mm->page_table_lock);
++      pte = pax_get_pte(mm, address);
++      if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
++              spin_unlock(&mm->page_table_lock);
++              do_page_fault(regs, error_code, address);
++              return 0;
+       }
++
++      if (unlikely((error_code == 7) && !pte_write(*pte))) {
++              /* write attempt to a protected page in user mode */
++              spin_unlock(&mm->page_table_lock);
++              do_page_fault(regs, error_code, address);
++              return 0;
++      }
++
++      /*
++       * PaX: fill DTLB with user rights and retry
++       */
++      __asm__ __volatile__ (
++              "orb %2,%1\n"
++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
++/*   
++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's   
++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
++ * page fault when examined during a TLB load attempt. this is true not only
++ * for PTEs holding a non-present entry but also present entries that will
++ * raise a page fault (such as those set up by PaX, or the copy-on-write
++ * mechanism). in effect it means that we do *not* need to flush the TLBs
++ * for our target pages since their PTEs are simply not in the TLBs at all.
++ * the best thing in omitting it is that we gain around 15-20% speed in the
++ * fast path of the page fault handler and can get rid of tracing since we
++ * can no longer flush unintended entries.
++ */
++
++              "invlpg %0\n"
++#endif
++
++              "testb $0,%0\n"
++              "xorb %3,%1\n"
++              :
++              : "m" (*(char*)address), "m" (*(char*)pte) , "q" (pte_mask) , "i" (_PAGE_USER)
++              : "memory", "cc");
++      spin_unlock(&mm->page_table_lock);
++      return 0;
+ }
++#endif
+diff -urN linux-2.4.22/arch/i386/mm/init.c linux-2.4.22-grsec-O1/arch/i386/mm/init.c
+--- linux-2.4.22/arch/i386/mm/init.c   2003-10-20 18:59:07.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/i386/mm/init.c  2003-10-21 14:24:34.000000000 +0200
+@@ -37,6 +37,8 @@
+ #include <asm/e820.h>
+ #include <asm/apic.h>
+ #include <asm/tlb.h>
++#include <asm/page_offset.h>
++#include <asm/desc.h>
+ mmu_gather_t mmu_gathers[NR_CPUS];
+ unsigned long highstart_pfn, highend_pfn;
+@@ -122,7 +124,7 @@
+ /* References to section boundaries */
+-extern char _text, _etext, _edata, __bss_start, _end;
++extern char _text, _etext, _data, _edata, __bss_start, _end;
+ extern char __init_begin, __init_end;
+ static inline void set_pte_phys (unsigned long vaddr,
+@@ -514,7 +516,7 @@
+       reservedpages = free_pages_init();
+       codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+-      datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
++      datasize =  (unsigned long) &_edata - (unsigned long) &_data;
+       initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+       printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
+@@ -582,6 +584,42 @@
+               totalram_pages++;
+       }
+       printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      /* PaX: limit KERNEL_CS to actual size */
++      {
++              unsigned long limit;
++
++              limit = (unsigned long)&_etext >> PAGE_SHIFT;
++              gdt_table[2].a = (gdt_table[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
++              gdt_table[2].b = (gdt_table[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
++
++              /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */
++              gdt_table[1].a = 0UL;
++              gdt_table[1].b = 0UL;
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++              gdt_table2[2].a = (gdt_table2[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
++              gdt_table2[2].b = (gdt_table2[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
++
++              /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */
++              gdt_table2[1].a = 0UL;
++              gdt_table2[1].b = 0UL;
++#endif
++
++      /* PaX: make KERNEL_CS read-only */
++              for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
++                      pgd_t *pgd;
++                      pmd_t *pmd;
++
++                      pgd = pgd_offset_k(addr);
++                      pmd = pmd_offset(pgd, addr);
++                      set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
++              }
++              flush_tlb_all();
++      }
++#endif
++
+ }
+ #ifdef CONFIG_BLK_DEV_INITRD
+diff -urN linux-2.4.22/arch/i386/vmlinux.lds linux-2.4.22-grsec-O1/arch/i386/vmlinux.lds
+--- linux-2.4.22/arch/i386/vmlinux.lds 2002-02-25 20:37:53.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/i386/vmlinux.lds        1970-01-01 01:00:00.000000000 +0100
+@@ -1,82 +0,0 @@
+-/* ld script to make i386 Linux kernel
+- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
+- */
+-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+-OUTPUT_ARCH(i386)
+-ENTRY(_start)
+-SECTIONS
+-{
+-  . = 0xC0000000 + 0x100000;
+-  _text = .;                  /* Text and read-only data */
+-  .text : {
+-      *(.text)
+-      *(.fixup)
+-      *(.gnu.warning)
+-      } = 0x9090
+-
+-  _etext = .;                 /* End of text section */
+-
+-  .rodata : { *(.rodata) *(.rodata.*) }
+-  .kstrtab : { *(.kstrtab) }
+-
+-  . = ALIGN(16);              /* Exception table */
+-  __start___ex_table = .;
+-  __ex_table : { *(__ex_table) }
+-  __stop___ex_table = .;
+-
+-  __start___ksymtab = .;      /* Kernel symbol table */
+-  __ksymtab : { *(__ksymtab) }
+-  __stop___ksymtab = .;
+-
+-  .data : {                   /* Data */
+-      *(.data)
+-      CONSTRUCTORS
+-      }
+-
+-  _edata = .;                 /* End of data section */
+-
+-  . = ALIGN(8192);            /* init_task */
+-  .data.init_task : { *(.data.init_task) }
+-
+-  . = ALIGN(4096);            /* Init code and data */
+-  __init_begin = .;
+-  .text.init : { *(.text.init) }
+-  .data.init : { *(.data.init) }
+-  . = ALIGN(16);
+-  __setup_start = .;
+-  .setup.init : { *(.setup.init) }
+-  __setup_end = .;
+-  __initcall_start = .;
+-  .initcall.init : { *(.initcall.init) }
+-  __initcall_end = .;
+-  . = ALIGN(4096);
+-  __init_end = .;
+-
+-  . = ALIGN(4096);
+-  .data.page_aligned : { *(.data.idt) }
+-
+-  . = ALIGN(32);
+-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+-
+-  __bss_start = .;            /* BSS */
+-  .bss : {
+-      *(.bss)
+-      }
+-  _end = . ;
+-
+-  /* Sections to be discarded */
+-  /DISCARD/ : {
+-      *(.text.exit)
+-      *(.data.exit)
+-      *(.exitcall.exit)
+-      }
+-
+-  /* Stabs debugging sections.  */
+-  .stab 0 : { *(.stab) }
+-  .stabstr 0 : { *(.stabstr) }
+-  .stab.excl 0 : { *(.stab.excl) }
+-  .stab.exclstr 0 : { *(.stab.exclstr) }
+-  .stab.index 0 : { *(.stab.index) }
+-  .stab.indexstr 0 : { *(.stab.indexstr) }
+-  .comment 0 : { *(.comment) }
+-}
+diff -urN linux-2.4.22/arch/i386/vmlinux.lds.S linux-2.4.22-grsec-O1/arch/i386/vmlinux.lds.S
+--- linux-2.4.22/arch/i386/vmlinux.lds.S       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/i386/vmlinux.lds.S      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,136 @@
++/* ld script to make i386 Linux kernel
++ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
++ */
++OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
++OUTPUT_ARCH(i386)
++ENTRY(_start)
++SECTIONS
++{
++  . = __PAGE_OFFSET + 0x100000;
++  .text.startup : {
++      BYTE(0xEA) /* jmp far */
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++      LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
++#else
++      LONG(startup_32 - __PAGE_OFFSET)
++#endif
++
++      SHORT(__KERNEL_CS)
++      }
++
++  . = ALIGN(32);
++  _data = .;
++  .data : {                   /* Data */
++      *(.data)
++      CONSTRUCTORS
++      }
++
++  . = ALIGN(32);
++  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
++
++  . = ALIGN(8192);
++  .data.init_task : { *(.data.init_task) }
++
++  . = ALIGN(4096);
++  .data.page_aligned : { *(.data.swapper_pg_dir) }
++
++  _edata = .;                 /* End of data section */
++
++  __bss_start = .;            /* BSS */
++  .bss : {
++      *(.bss)
++      LONG(0)
++      } 
++  __bss_end = . ;
++
++  . = ALIGN(4096);            /* Init code and data */
++  __init_begin = .;
++
++  .data.init : {
++      *(.data.pg0)
++      *(.data.pg1)
++      *(.data.pg2)
++      *(.data.init)
++      }
++  . = ALIGN(16);
++  __setup_start = .;
++  .setup.init : { *(.setup.init) }
++  __setup_end = .;
++  __initcall_start = .;
++  .initcall.init : { *(.initcall.init) }
++  __initcall_end = .;
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++  __text_init_start = .;
++  .text.init (. - __KERNEL_TEXT_OFFSET) : AT (__text_init_start) {
++      *(.text.init)
++      . = ALIGN(4*1024*1024) - 1;
++      BYTE(0)
++      }
++  __init_end = . + __KERNEL_TEXT_OFFSET;
++
++/*
++ * PaX: this must be kept in synch with the KERNEL_CS base
++ * in the GDTs in arch/i386/kernel/head.S
++ */
++  _text = .;                  /* Text and read-only data */
++  .text : AT (. + __KERNEL_TEXT_OFFSET) {
++#else
++  .text.init : { *(.text.init) }
++  . = ALIGN(4096);
++  __init_end = .;
++  _text = .;                  /* Text and read-only data */
++  .text : {
++#endif
++
++      *(.text)
++      *(.fixup)
++      *(.gnu.warning)
++      } = 0x9090
++
++  _etext = .;                 /* End of text section */
++  . = ALIGN(4096);
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++  . += __KERNEL_TEXT_OFFSET;
++#endif
++
++  .rodata.page_aligned : {
++      *(.data.empty_zero_page)
++      *(.data.idt)
++      }
++  .rodata : { *(.rodata) *(.rodata.*) }
++  .kstrtab : { *(.kstrtab) }
++
++  . = ALIGN(16);              /* Exception table */
++  __start___ex_table = .;
++  __ex_table : { *(__ex_table) }
++  __stop___ex_table = .;
++
++  __start___ksymtab = .;      /* Kernel symbol table */
++  __ksymtab : { *(__ksymtab) }
++  __stop___ksymtab = .;
++
++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC
++  _end = ALIGN(4*1024*1024);
++#else
++  _end = .;
++#endif
++
++  /* Sections to be discarded */
++  /DISCARD/ : {
++      *(.text.exit)
++      *(.data.exit)
++      *(.exitcall.exit)
++      }
++
++  /* Stabs debugging sections.  */
++  .stab 0 : { *(.stab) }
++  .stabstr 0 : { *(.stabstr) }
++  .stab.excl 0 : { *(.stab.excl) }
++  .stab.exclstr 0 : { *(.stab.exclstr) }
++  .stab.index 0 : { *(.stab.index) }
++  .stab.indexstr 0 : { *(.stab.indexstr) }
++  .comment 0 : { *(.comment) }
++}
+diff -urN linux-2.4.22/arch/ia64/config.in linux-2.4.22-grsec-O1/arch/ia64/config.in
+--- linux-2.4.22/arch/ia64/config.in   2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ia64/config.in  2003-10-21 14:24:34.000000000 +0200
+@@ -291,3 +291,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-2.4.22/arch/ia64/kernel/ptrace.c linux-2.4.22-grsec-O1/arch/ia64/kernel/ptrace.c
+--- linux-2.4.22/arch/ia64/kernel/ptrace.c     2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ia64/kernel/ptrace.c    2003-10-21 14:24:34.000000000 +0200
+@@ -16,6 +16,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/smp_lock.h>
+ #include <linux/user.h>
++#include <linux/grsecurity.h>
+ #include <asm/pgtable.h>
+ #include <asm/processor.h>
+@@ -1213,6 +1214,9 @@
+       if (pid == 1)           /* no messing around with init! */
+               goto out_tsk;
++      if (gr_handle_ptrace(child, request))
++              goto out_tsk;
++
+       if (request == PTRACE_ATTACH) {
+               ret = ptrace_attach(child);
+               goto out_tsk;
+diff -urN linux-2.4.22/arch/ia64/kernel/sys_ia64.c linux-2.4.22-grsec-O1/arch/ia64/kernel/sys_ia64.c
+--- linux-2.4.22/arch/ia64/kernel/sys_ia64.c   2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ia64/kernel/sys_ia64.c  2003-10-21 14:24:34.000000000 +0200
+@@ -15,6 +15,7 @@
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
+ #include <linux/highuid.h>
++#include <linux/grsecurity.h>
+ #include <asm/shmparam.h>
+ #include <asm/uaccess.h>
+@@ -206,6 +207,11 @@
+               goto out;
+       }
++      if (gr_handle_mmap(file, prot)) {
++              addr = -EACCES;
++              goto out;
++      }
++
+       down_write(&current->mm->mmap_sem);
+       addr = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
+       up_write(&current->mm->mmap_sem);
+diff -urN linux-2.4.22/arch/m68k/config.in linux-2.4.22-grsec-O1/arch/m68k/config.in
+--- linux-2.4.22/arch/m68k/config.in   2003-08-25 13:44:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/m68k/config.in  2003-10-21 14:24:34.000000000 +0200
+@@ -564,3 +564,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/mips/config.in linux-2.4.22-grsec-O1/arch/mips/config.in
+--- linux-2.4.22/arch/mips/config.in   2002-11-29 00:53:09.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/mips/config.in  2003-10-21 14:24:34.000000000 +0200
+@@ -7,3 +7,11 @@
+ define_bool CONFIG_MIPS64 n
+ source arch/mips/config-shared.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++        source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/mips64/config.in linux-2.4.22-grsec-O1/arch/mips64/config.in
+--- linux-2.4.22/arch/mips64/config.in 2002-11-29 00:53:10.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/mips64/config.in        2003-10-21 14:24:34.000000000 +0200
+@@ -7,3 +7,11 @@
+ define_bool CONFIG_MIPS64 y
+ source arch/mips/config-shared.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++        source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/parisc/config.in linux-2.4.22-grsec-O1/arch/parisc/config.in
+--- linux-2.4.22/arch/parisc/config.in 2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/parisc/config.in        2003-10-21 14:24:34.000000000 +0200
+@@ -198,3 +198,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/parisc/kernel/ioctl32.c linux-2.4.22-grsec-O1/arch/parisc/kernel/ioctl32.c
+--- linux-2.4.22/arch/parisc/kernel/ioctl32.c  2003-10-20 18:58:58.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/parisc/kernel/ioctl32.c 2003-10-21 14:24:34.000000000 +0200
+@@ -1435,7 +1435,11 @@
+        * To have permissions to do most of the vt ioctls, we either have
+        * to be the owner of the tty, or super-user.
+        */
++#ifdef CONFIG_GRKERNSEC
++      if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
++#else
+       if (current->tty == tty || suser())
++#endif
+               return 1;
+       return 0;                                                    
+ }
+diff -urN linux-2.4.22/arch/parisc/kernel/ptrace.c linux-2.4.22-grsec-O1/arch/parisc/kernel/ptrace.c
+--- linux-2.4.22/arch/parisc/kernel/ptrace.c   2002-11-29 00:53:10.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/parisc/kernel/ptrace.c  2003-10-21 14:24:34.000000000 +0200
+@@ -15,7 +15,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/user.h>
+ #include <linux/personality.h>
+-
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/system.h>
+@@ -119,6 +119,9 @@
+       if (pid == 1)           /* no messing around with init! */
+               goto out_tsk;
++      if (gr_handle_ptrace(child, request))
++              goto out_tsk;
++
+       if (request == PTRACE_ATTACH) {
+               ret = ptrace_attach(child);
+               goto out_tsk;
+diff -urN linux-2.4.22/arch/parisc/kernel/sys_parisc.c linux-2.4.22-grsec-O1/arch/parisc/kernel/sys_parisc.c
+--- linux-2.4.22/arch/parisc/kernel/sys_parisc.c       2002-11-29 00:53:10.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/parisc/kernel/sys_parisc.c      2003-10-21 14:24:34.000000000 +0200
+@@ -12,6 +12,7 @@
+ #include <linux/mman.h>
+ #include <linux/shm.h>
+ #include <linux/smp_lock.h>
++#include <linux/grsecurity.h>
+ int sys_pipe(int *fildes)
+ {
+@@ -90,6 +91,11 @@
+               inode = filp->f_dentry->d_inode;
+       }
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
++              addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
++#endif
++
+       if (inode && (flags & MAP_SHARED) && (inode->i_mapping->i_mmap_shared)) {
+               addr = get_shared_area(inode, addr, len, pgoff);
+       } else {
+@@ -104,12 +110,23 @@
+ {
+       struct file * file = NULL;
+       unsigned long error = -EBADF;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       if (!(flags & MAP_ANONYMOUS)) {
+               file = fget(fd);
+               if (!file)
+                       goto out;
+       }
++      if (gr_handle_mmap(file, prot)) {
++              fput(file);
++              return -EACCES;
++      }
++
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       down_write(&current->mm->mmap_sem);
+diff -urN linux-2.4.22/arch/parisc/kernel/sys_parisc32.c linux-2.4.22-grsec-O1/arch/parisc/kernel/sys_parisc32.c
+--- linux-2.4.22/arch/parisc/kernel/sys_parisc32.c     2003-06-13 16:51:31.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/parisc/kernel/sys_parisc32.c    2003-10-21 14:24:34.000000000 +0200
+@@ -50,6 +50,7 @@
+ #include <linux/highmem.h>
+ #include <linux/highuid.h>
+ #include <linux/mman.h>
++#include <linux/grsecurity.h>
+ #include <asm/types.h>
+ #include <asm/uaccess.h>
+@@ -177,6 +178,11 @@
+       struct file *file;
+       int retval;
+       int i;
++#ifdef CONFIG_GRKERNSEC
++      struct file *old_exec_file;
++      struct acl_subject_label *old_acl;
++      struct rlimit old_rlim[RLIM_NLIMITS];
++#endif
+       file = open_exec(filename);
+@@ -184,7 +190,26 @@
+       if (IS_ERR(file))
+               return retval;
++      gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
++
++      if (gr_handle_nproc()) {
++              allow_write_access(file);
++              fput(file);
++              return -EAGAIN;
++      }
++
++      if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
++              allow_write_access(file);
++              fput(file);
++              return -EACCES;
++      }
++
+       bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
++      bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
++#endif
++
+       memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
+       DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs));
+@@ -209,11 +234,24 @@
+       if (retval < 0)
+               goto out;
+       
++      if (!gr_tpe_allow(file)) {
++              retval = -EACCES;
++              goto out;
++      }
++
++      if (gr_check_crash_exec(file)) {
++              retval = -EACCES;
++              goto out;
++      }
++
+       retval = copy_strings_kernel(1, &bprm.filename, &bprm);
+       if (retval < 0)
+               goto out;
+       bprm.exec = bprm.p;
++
++      gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
++
+       retval = copy_strings32(bprm.envc, envp, &bprm);
+       if (retval < 0)
+               goto out;
+@@ -222,11 +260,32 @@
+       if (retval < 0)
+               goto out;
++#ifdef CONFIG_GRKERNSEC
++      old_acl = current->acl;
++      memcpy(old_rlim, current->rlim, sizeof(old_rlim));
++      old_exec_file = current->exec_file;
++      get_file(file);
++      current->exec_file = file;
++#endif
++
++      gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
++
+       retval = search_binary_handler(&bprm,regs);
+-      if (retval >= 0)
++      if (retval >= 0) {
++#ifdef CONFIG_GRKERNSEC
++              if (old_exec_file)
++                      fput(old_exec_file);
++#endif
+               /* execve success */
+               return retval;
++      }
++#ifdef CONFIG_GRKERNSEC
++      current->acl = old_acl;
++      memcpy(current->rlim, old_rlim, sizeof(old_rlim));
++      fput(current->exec_file);
++      current->exec_file = old_exec_file;
++#endif
+ out:
+       /* Something went wrong, return the inode and free the argument pages*/
+       allow_write_access(bprm.file);
+diff -urN linux-2.4.22/arch/parisc/kernel/traps.c linux-2.4.22-grsec-O1/arch/parisc/kernel/traps.c
+--- linux-2.4.22/arch/parisc/kernel/traps.c    2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/parisc/kernel/traps.c   2003-10-21 14:24:34.000000000 +0200
+@@ -637,9 +637,7 @@
+                       down_read(&current->mm->mmap_sem);
+                       vma = find_vma(current->mm,regs->iaoq[0]);
+-                      if (vma && (regs->iaoq[0] >= vma->vm_start)
+-                              && (vma->vm_flags & VM_EXEC)) {
+-
++                      if (vma && (regs->iaoq[0] >= vma->vm_start)) {
+                               fault_address = regs->iaoq[0];
+                               fault_space = regs->iasq[0];
+diff -urN linux-2.4.22/arch/parisc/mm/fault.c linux-2.4.22-grsec-O1/arch/parisc/mm/fault.c
+--- linux-2.4.22/arch/parisc/mm/fault.c        2003-06-13 16:51:31.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/parisc/mm/fault.c       2003-10-21 14:24:34.000000000 +0200
+@@ -15,6 +15,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
++#include <linux/unistd.h>
+ #include <asm/uaccess.h>
+ #include <asm/traps.h>
+@@ -53,7 +54,7 @@
+ static unsigned long
+ parisc_acctyp(unsigned long code, unsigned int inst)
+ {
+-      if (code == 6 || code == 16)
++      if (code == 6 || code == 7 || code == 16)
+           return VM_EXEC;
+       switch (inst & 0xf0000000) {
+@@ -139,6 +140,136 @@
+                       }
+ #endif
++/*
++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
++ *
++ * returns 1 when task should be killed 
++ *       2 when rt_sigreturn trampoline was detected
++ *       3 when unpatched PLT trampoline was detected
++ *       4 when legitimate ET_EXEC was detected
++ */
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC  
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++      int err;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (current->flags & PF_PAX_RANDEXEC) {
++              if (instruction_pointer(regs) >= current->mm->start_code &&
++                  instruction_pointer(regs) < current->mm->end_code)
++              {
++#if 0
++                      /* PaX: this needs fixing */
++                      if ((regs->gr[2] & ~3UL) == instruction_pointer(regs))
++                              return 1;
++#endif
++                      regs->iaoq[0] += current->mm->delta_exec;
++                      if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code &&
++                          (regs->iaoq[1] & ~3UL) < current->mm->end_code)
++                              regs->iaoq[1] += current->mm->delta_exec;
++                      return 4;
++              }
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++      do { /* PaX: unpatched PLT emulation */
++              unsigned int bl, depwi;
++
++              err = get_user(bl, (unsigned int*)instruction_pointer(regs));
++              err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
++
++              if (err)
++                      break;
++
++              if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
++                      unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
++
++                      err = get_user(ldw, (unsigned int*)addr);
++                      err |= get_user(bv, (unsigned int*)(addr+4));
++                      err |= get_user(ldw2, (unsigned int*)(addr+8));
++
++                      if (err)
++                              break;
++
++                      if (ldw == 0x0E801096U &&
++                          bv == 0xEAC0C000U &&
++                          ldw2 == 0x0E881095U)
++                      {
++                              unsigned int resolver, map;
++
++                              err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
++                              err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
++                              if (err)
++                                      break;
++
++                              regs->gr[20] = instruction_pointer(regs)+8;
++                              regs->gr[21] = map;
++                              regs->gr[22] = resolver;
++                              regs->iaoq[0] = resolver | 3UL;
++                              regs->iaoq[1] = regs->iaoq[0] + 4;
++                              return 3;
++                      }
++              }
++      } while (0);
++#endif
++ 
++#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
++
++#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++      if (!(current->flags & PF_PAX_EMUTRAMP))
++              return 1;
++#endif
++
++      do { /* PaX: rt_sigreturn emulation */
++              unsigned int ldi1, ldi2, bel, nop;
++
++              err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
++              err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
++              err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
++              err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
++
++              if (err)
++                      break;
++
++                if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
++                  ldi2 == 0x3414015AU &&
++                  bel == 0xE4008200U &&
++                  nop == 0x08000240U)
++              {
++                      regs->gr[25] = (ldi1 & 2) >> 1;
++                      regs->gr[20] = __NR_rt_sigreturn;
++                      regs->gr[31] = regs->iaoq[1] + 16;
++                      regs->sr[0] = regs->iasq[1];
++                      regs->iaoq[0] = 0x100UL;
++                      regs->iaoq[1] = regs->iaoq[0] + 4;
++                      regs->iasq[0] = regs->sr[2];
++                      regs->iasq[1] = regs->sr[2];
++                      return 2;
++              }
++      } while (0);
++#endif
++
++      return 1;
++}
++
++void pax_report_insns(void *pc)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 5; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int*)pc+i)) {
++                      printk("<invalid address>.");
++                      break;
++              }
++              printk("%08x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ void do_page_fault(struct pt_regs *regs, unsigned long code,
+                             unsigned long address)
+ {
+@@ -164,8 +295,38 @@
+       acc_type = parisc_acctyp(code,regs->iir);
+-      if ((vma->vm_flags & acc_type) != acc_type)
++      if ((vma->vm_flags & acc_type) != acc_type) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++              if ((current->flags & PF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
++                  (address & ~3UL) == instruction_pointer(regs))
++                 {
++                      up_read(&mm->mmap_sem);
++                      switch(pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++                      case 4:
++                              return;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++                      case 3:
++                              return;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
++                      case 2:
++                              return;
++#endif
++
++                      }
++                      pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
++                      do_exit(SIGKILL);
++              }
++#endif
++
+               goto bad_area;
++      }
+       /*
+        * If for any reason at all we couldn't handle the fault, make
+diff -urN linux-2.4.22/arch/ppc/config.in linux-2.4.22-grsec-O1/arch/ppc/config.in
+--- linux-2.4.22/arch/ppc/config.in    2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ppc/config.in   2003-10-21 14:24:34.000000000 +0200
+@@ -488,3 +488,12 @@
+   bool 'Support for early boot texts over serial port' CONFIG_SERIAL_TEXT_DEBUG
+ 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-2.4.22/arch/ppc/kernel/ptrace.c linux-2.4.22-grsec-O1/arch/ppc/kernel/ptrace.c
+--- linux-2.4.22/arch/ppc/kernel/ptrace.c      2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ppc/kernel/ptrace.c     2003-10-21 14:24:34.000000000 +0200
+@@ -24,6 +24,7 @@
+ #include <linux/errno.h>
+ #include <linux/ptrace.h>
+ #include <linux/user.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/page.h>
+@@ -195,6 +196,9 @@
+       if (pid == 1)           /* you may not mess with init */
+               goto out_tsk;
++      if (gr_handle_ptrace(child, request))
++              goto out_tsk;
++
+       if (request == PTRACE_ATTACH) {
+               ret = ptrace_attach(child);
+               goto out_tsk;
+diff -urN linux-2.4.22/arch/ppc/kernel/syscalls.c linux-2.4.22-grsec-O1/arch/ppc/kernel/syscalls.c
+--- linux-2.4.22/arch/ppc/kernel/syscalls.c    2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ppc/kernel/syscalls.c   2003-10-21 14:24:34.000000000 +0200
+@@ -35,6 +35,7 @@
+ #include <linux/ipc.h>
+ #include <linux/utsname.h>
+ #include <linux/file.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/ipc.h>
+@@ -175,14 +176,25 @@
+       struct file * file = NULL;
+       int ret = -EBADF;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       if (!(flags & MAP_ANONYMOUS)) {
+               if (!(file = fget(fd)))
+                       goto out;
+       }
++      if (gr_handle_mmap(file, prot)) {
++              fput(file);
++              ret = -EACCES;
++              goto out;
++      }
++
+       down_write(&current->mm->mmap_sem);
+-      ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
++      ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
+       up_write(&current->mm->mmap_sem);
+       if (file)
+               fput(file);
+diff -urN linux-2.4.22/arch/ppc/mm/fault.c linux-2.4.22-grsec-O1/arch/ppc/mm/fault.c
+--- linux-2.4.22/arch/ppc/mm/fault.c   2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ppc/mm/fault.c  2003-10-21 14:24:34.000000000 +0200
+@@ -26,6 +26,9 @@
+ #include <linux/mman.h>
+ #include <linux/mm.h>
+ #include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -52,6 +55,360 @@
+ void bad_page_fault(struct pt_regs *, unsigned long, int sig);
+ void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
++#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++void pax_syscall_close(struct vm_area_struct * vma)
++{
++      vma->vm_mm->call_syscall = 0UL;
++}
++
++static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
++{
++      struct page* page;
++      unsigned int *kaddr;
++
++      page = alloc_page(GFP_HIGHUSER);
++      if (!page)
++              return page;
++
++      kaddr = kmap(page);
++      memset(kaddr, 0, PAGE_SIZE);
++      kaddr[0] = 0x44000002U; /* sc */
++      __flush_dcache_icache(kaddr);
++      kunmap(page);
++      return page;
++}
++
++static struct vm_operations_struct pax_vm_ops = {
++      close:          pax_syscall_close,
++      nopage:         pax_syscall_nopage,
++};
++
++static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
++{
++      vma->vm_mm = current->mm;
++      vma->vm_start = addr;
++      vma->vm_end = addr + PAGE_SIZE;
++      vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
++      vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
++      vma->vm_ops = &pax_vm_ops;
++      vma->vm_pgoff = 0UL;
++      vma->vm_file = NULL;
++      vma->vm_private_data = NULL;
++      insert_vm_struct(current->mm, vma);
++      ++current->mm->total_vm;
++}
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++/*
++ * PaX: decide what to do with offenders (regs->nip = fault address)
++ *
++ * returns 1 when task should be killed
++ *         2 when patched GOT trampoline was detected
++ *         3 when patched PLT trampoline was detected
++ *         4 when unpatched PLT trampoline was detected
++ *         5 when legitimate ET_EXEC was detected
++ *         6 when sigreturn trampoline was detected
++ *         7 when rt_sigreturn trampoline was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++      int err;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (current->flags & PF_PAX_RANDEXEC) {
++              if (regs->nip >= current->mm->start_code &&
++                  regs->nip < current->mm->end_code)
++              {
++                      if (regs->link == regs->nip)
++                              return 1;
++
++                      regs->nip += current->mm->delta_exec;
++                      return 5;
++              }
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++      do { /* PaX: patched GOT emulation */
++              unsigned int blrl;
++
++              err = get_user(blrl, (unsigned int*)regs->nip);
++
++              if (!err && blrl == 0x4E800021U) {
++                      unsigned long temp = regs->nip;
++
++                      regs->nip = regs->link & 0xFFFFFFFCUL;
++                      regs->link = temp + 4UL;
++                      return 2;
++              }
++      } while (0);
++
++      do { /* PaX: patched PLT emulation #1 */
++              unsigned int b;
++
++              err = get_user(b, (unsigned int *)regs->nip);
++
++              if (!err && (b & 0xFC000003U) == 0x48000000U) {
++                      regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
++                      return 3;
++              }
++      } while (0);
++
++      do { /* PaX: unpatched PLT emulation #1 */
++              unsigned int li, b;
++
++              err = get_user(li, (unsigned int *)regs->nip);
++              err |= get_user(b, (unsigned int *)(regs->nip+4));
++
++              if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
++                      unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
++                        unsigned long addr = b | 0xFC000000UL;
++
++                        addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
++                      err = get_user(rlwinm, (unsigned int*)addr);
++                      err |= get_user(add, (unsigned int*)(addr+4));
++                      err |= get_user(li2, (unsigned int*)(addr+8));
++                      err |= get_user(addis2, (unsigned int*)(addr+12));
++                      err |= get_user(mtctr, (unsigned int*)(addr+16));
++                      err |= get_user(li3, (unsigned int*)(addr+20));
++                      err |= get_user(addis3, (unsigned int*)(addr+24));
++                      err |= get_user(bctr, (unsigned int*)(addr+28));
++
++                      if (err)
++                              break;
++
++                      if (rlwinm == 0x556C083CU &&
++                          add == 0x7D6C5A14U &&
++                          (li2 & 0xFFFF0000U) == 0x39800000U &&
++                          (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
++                          mtctr == 0x7D8903A6U &&
++                          (li3 & 0xFFFF0000U) == 0x39800000U &&
++                          (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
++                          bctr == 0x4E800420U)
++                      {
++                              regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++                              regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++                              regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
++                              regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++                              regs->ctr += (addis2 & 0xFFFFU) << 16;
++                              regs->nip = regs->ctr;
++                              return 4;
++                      }
++              }
++      } while (0);
++
++#if 0
++      do { /* PaX: unpatched PLT emulation #2 */
++              unsigned int lis, lwzu, b, bctr;
++
++              err = get_user(lis, (unsigned int *)regs->nip);
++              err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
++              err |= get_user(b, (unsigned int *)(regs->nip+8));
++              err |= get_user(bctr, (unsigned int *)(regs->nip+12));
++
++              if (err)
++                      break;
++
++              if ((lis & 0xFFFF0000U) == 0x39600000U &&
++                  (lwzu & 0xU) == 0xU &&
++                  (b & 0xFC000003U) == 0x48000000U &&
++                  bctr == 0x4E800420U)
++              {
++                      unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
++                        unsigned long addr = b | 0xFC000000UL;
++
++                        addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
++                      err = get_user(addis, (unsigned int*)addr);
++                      err |= get_user(addi, (unsigned int*)(addr+4));
++                      err |= get_user(rlwinm, (unsigned int*)(addr+8));
++                      err |= get_user(add, (unsigned int*)(addr+12));
++                      err |= get_user(li2, (unsigned int*)(addr+16));
++                      err |= get_user(addis2, (unsigned int*)(addr+20));
++                      err |= get_user(mtctr, (unsigned int*)(addr+24));
++                      err |= get_user(li3, (unsigned int*)(addr+28));
++                      err |= get_user(addis3, (unsigned int*)(addr+32));
++                      err |= get_user(bctr, (unsigned int*)(addr+36));
++
++                      if (err)
++                              break;
++
++                      if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
++                          (addi & 0xFFFF0000U) == 0x396B0000U &&
++                          rlwinm == 0x556C083CU &&
++                          add == 0x7D6C5A14U &&
++                          (li2 & 0xFFFF0000U) == 0x39800000U &&
++                          (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
++                          mtctr == 0x7D8903A6U &&
++                          (li3 & 0xFFFF0000U) == 0x39800000U &&
++                          (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
++                          bctr == 0x4E800420U)
++                      {
++                              regs->gpr[PT_R11] = 
++                              regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++                              regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++                              regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
++                              regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++                              regs->ctr += (addis2 & 0xFFFFU) << 16;
++                              regs->nip = regs->ctr;
++                              return 4;
++                      }
++              }
++      } while (0);
++#endif
++
++      do { /* PaX: unpatched PLT emulation #3 */
++              unsigned int li, b;
++
++              err = get_user(li, (unsigned int *)regs->nip);
++              err |= get_user(b, (unsigned int *)(regs->nip+4));
++
++              if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
++                      unsigned int addis, lwz, mtctr, bctr;
++                      unsigned long addr = b | 0xFC000000UL;
++
++                      addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
++                      err = get_user(addis, (unsigned int*)addr);
++                      err |= get_user(lwz, (unsigned int*)(addr+4));
++                      err |= get_user(mtctr, (unsigned int*)(addr+8));
++                      err |= get_user(bctr, (unsigned int*)(addr+12));
++
++                      if (err)
++                              break;
++
++                      if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
++                          (lwz & 0xFFFF0000U) == 0x816B0000U &&
++                          mtctr == 0x7D6903A6U &&
++                          bctr == 0x4E800420U)
++                      {
++                              unsigned int r11;
++
++                              addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++                              addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
++
++                              err = get_user(r11, (unsigned int*)addr);
++                              if (err)
++                                      break;
++
++                              regs->gpr[PT_R11] = r11;
++                              regs->ctr = r11;
++                              regs->nip = r11;
++                              return 4;
++                      }
++              }
++      } while (0);
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++      do { /* PaX: sigreturn emulation */
++              unsigned int li, sc;
++
++              err = get_user(li, (unsigned int *)regs->nip);
++              err |= get_user(sc, (unsigned int *)(regs->nip+4));
++
++              if (!err && li == 0x38007777U && sc == 0x44000002U) {
++                      struct vm_area_struct *vma;
++                      unsigned long call_syscall;
++
++                      down_read(&current->mm->mmap_sem);
++                      call_syscall = current->mm->call_syscall;
++                      up_read(&current->mm->mmap_sem);
++                      if (likely(call_syscall))
++                              goto emulate;
++
++                      vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
++
++                      down_write(&current->mm->mmap_sem);
++                      if (current->mm->call_syscall) {
++                              call_syscall = current->mm->call_syscall;
++                              up_write(&current->mm->mmap_sem);
++                              if (vma) kmem_cache_free(vm_area_cachep, vma);
++                              goto emulate;
++                      }
++
++                      call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
++                      if (!vma || (call_syscall & ~PAGE_MASK)) {
++                              up_write(&current->mm->mmap_sem);
++                              if (vma) kmem_cache_free(vm_area_cachep, vma);
++                              return 1;
++                      }
++
++                      pax_insert_vma(vma, call_syscall);
++                      current->mm->call_syscall = call_syscall;
++                      up_write(&current->mm->mmap_sem);
++
++emulate:
++                      regs->gpr[PT_R0] = 0x7777UL;
++                      regs->nip = call_syscall;
++                      return 6;
++              }
++      } while (0);
++
++      do { /* PaX: rt_sigreturn emulation */
++              unsigned int li, sc;
++
++              err = get_user(li, (unsigned int *)regs->nip);
++              err |= get_user(sc, (unsigned int *)(regs->nip+4));
++
++              if (!err && li == 0x38006666U && sc == 0x44000002U) {
++                      struct vm_area_struct *vma;
++                      unsigned int call_syscall;
++
++                      down_read(&current->mm->mmap_sem);
++                      call_syscall = current->mm->call_syscall;
++                      up_read(&current->mm->mmap_sem);
++                      if (likely(call_syscall))
++                              goto rt_emulate;
++
++                      vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
++
++                      down_write(&current->mm->mmap_sem);
++                      if (current->mm->call_syscall) {
++                              call_syscall = current->mm->call_syscall;
++                              up_write(&current->mm->mmap_sem);
++                              if (vma) kmem_cache_free(vm_area_cachep, vma);
++                              goto rt_emulate;
++                      }
++
++                      call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
++                      if (!vma || (call_syscall & ~PAGE_MASK)) {
++                              up_write(&current->mm->mmap_sem);
++                              if (vma) kmem_cache_free(vm_area_cachep, vma);
++                              return 1;
++                      }
++
++                      pax_insert_vma(vma, call_syscall);
++                      current->mm->call_syscall = call_syscall;
++                      up_write(&current->mm->mmap_sem);
++
++rt_emulate:
++                      regs->gpr[PT_R0] = 0x6666UL;
++                      regs->nip = call_syscall;
++                      return 7;
++              }
++      } while (0);
++#endif
++
++        return 1;
++}
++
++void pax_report_insns(void *pc)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 5; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int*)pc+i)) {
++                      printk("<invalid address>.");
++                      break;
++              }
++              printk("%08x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ /*
+  * Check whether the instruction at regs->nip is a store using
+  * an update addressing form which will update r1.
+@@ -112,7 +469,7 @@
+        * indicate errors in DSISR but can validly be set in SRR1.
+        */
+       if (regs->trap == 0x400)
+-              error_code &= 0x48200000;
++              error_code &= 0x58200000;
+       else
+               is_write = error_code & 0x02000000;
+ #endif /* CONFIG_4xx */
+@@ -245,6 +602,38 @@
+       /* User mode accesses cause a SIGSEGV */
+       if (user_mode(regs)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++              if (current->flags & PF_PAX_PAGEEXEC) {
++                      if ((regs->trap == 0x400) && (regs->nip == address)) {
++                              switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++                              case 2:
++                              case 3:
++                              case 4:
++                                      return;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++                              case 5:
++                                      return;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT
++                              case 6:
++                              case 7:
++                                      return;
++#endif
++
++                              }
++
++                              pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
++                              do_exit(SIGKILL);
++                      }
++              }
++#endif
++
+               info.si_signo = SIGSEGV;
+               info.si_errno = 0;
+               info.si_code = code;
+diff -urN linux-2.4.22/arch/ppc64/kernel/ioctl32.c linux-2.4.22-grsec-O1/arch/ppc64/kernel/ioctl32.c
+--- linux-2.4.22/arch/ppc64/kernel/ioctl32.c   2003-10-20 18:58:58.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/ppc64/kernel/ioctl32.c  2003-10-21 14:24:34.000000000 +0200
+@@ -1801,7 +1801,11 @@
+        * To have permissions to do most of the vt ioctls, we either have
+        * to be the owner of the tty, or super-user.
+        */
++#ifdef CONFIG_GRKERNSEC
++      if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
++#else
+       if (current->tty == tty || suser())
++#endif
+               return 1;
+       return 0;                                                    
+ }
+diff -urN linux-2.4.22/arch/s390/config.in linux-2.4.22-grsec-O1/arch/s390/config.in
+--- linux-2.4.22/arch/s390/config.in   2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/s390/config.in  2003-10-21 14:24:34.000000000 +0200
+@@ -81,3 +81,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/s390x/config.in linux-2.4.22-grsec-O1/arch/s390x/config.in
+--- linux-2.4.22/arch/s390x/config.in  2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/s390x/config.in 2003-10-21 14:24:34.000000000 +0200
+@@ -85,3 +85,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/sh/config.in linux-2.4.22-grsec-O1/arch/sh/config.in
+--- linux-2.4.22/arch/sh/config.in     2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sh/config.in    2003-10-21 14:24:34.000000000 +0200
+@@ -469,3 +469,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/sparc/boot/Makefile linux-2.4.22-grsec-O1/arch/sparc/boot/Makefile
+--- linux-2.4.22/arch/sparc/boot/Makefile      2002-08-03 02:39:43.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc/boot/Makefile     2003-10-21 14:24:34.000000000 +0200
+@@ -24,7 +24,7 @@
+ BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o
+ BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
+-      $(DRIVERS) $(NETWORKS)
++      $(DRIVERS) $(NETWORKS) $(GRSECURITY)
+ # I wanted to make this depend upon BTOBJS so that a parallel
+ # build would work, but this fails because $(HEAD) cannot work
+diff -urN linux-2.4.22/arch/sparc/config.in linux-2.4.22-grsec-O1/arch/sparc/config.in
+--- linux-2.4.22/arch/sparc/config.in  2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc/config.in 2003-10-21 14:24:34.000000000 +0200
+@@ -277,3 +277,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/sparc/kernel/ptrace.c linux-2.4.22-grsec-O1/arch/sparc/kernel/ptrace.c
+--- linux-2.4.22/arch/sparc/kernel/ptrace.c    2002-08-03 02:39:43.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc/kernel/ptrace.c   2003-10-21 14:24:34.000000000 +0200
+@@ -17,6 +17,7 @@
+ #include <linux/user.h>
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
++#include <linux/grsecurity.h>
+ #include <asm/pgtable.h>
+ #include <asm/system.h>
+@@ -310,6 +311,9 @@
+               goto out;
+       }
++      if(gr_handle_ptrace(child, request))
++              goto out_tsk;
++
+       if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
+           || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
+               if (ptrace_attach(child)) {
+diff -urN linux-2.4.22/arch/sparc/kernel/sys_sparc.c linux-2.4.22-grsec-O1/arch/sparc/kernel/sys_sparc.c
+--- linux-2.4.22/arch/sparc/kernel/sys_sparc.c 2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc/kernel/sys_sparc.c        2003-10-21 14:24:34.000000000 +0200
+@@ -20,6 +20,7 @@
+ #include <linux/utsname.h>
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/ipc.h>
+@@ -54,6 +55,13 @@
+               return -ENOMEM;
+       if (ARCH_SUN4C_SUN4 && len > 0x20000000)
+               return -ENOMEM;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
++              addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
++      else
++#endif
++
+       if (!addr)
+               addr = TASK_UNMAPPED_BASE;
+@@ -225,6 +233,11 @@
+       struct file * file = NULL;
+       unsigned long retval = -EBADF;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       if (!(flags & MAP_ANONYMOUS)) {
+               file = fget(fd);
+               if (!file)
+@@ -243,6 +256,12 @@
+       if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
+               goto out_putf;
++      if (gr_handle_mmap(file, prot)) {
++              fput(file);
++              retval = -EACCES;
++              goto out;
++      }
++
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       down_write(&current->mm->mmap_sem);
+diff -urN linux-2.4.22/arch/sparc/kernel/sys_sunos.c linux-2.4.22-grsec-O1/arch/sparc/kernel/sys_sunos.c
+--- linux-2.4.22/arch/sparc/kernel/sys_sunos.c 2002-11-29 00:53:12.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/sparc/kernel/sys_sunos.c        2003-10-21 14:24:34.000000000 +0200
+@@ -68,6 +68,11 @@
+       struct file * file = NULL;
+       unsigned long retval, ret_type;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       if(flags & MAP_NORESERVE) {
+               static int cnt;
+               if (cnt++ < 10)
+diff -urN linux-2.4.22/arch/sparc/mm/fault.c linux-2.4.22-grsec-O1/arch/sparc/mm/fault.c
+--- linux-2.4.22/arch/sparc/mm/fault.c 2003-06-13 16:51:32.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc/mm/fault.c        2003-10-21 14:24:34.000000000 +0200
+@@ -19,6 +19,9 @@
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
+ #include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
+ #include <asm/system.h>
+ #include <asm/segment.h>
+@@ -200,6 +203,261 @@
+       return 0;
+ }
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++void pax_emuplt_close(struct vm_area_struct * vma)
++{
++      vma->vm_mm->call_dl_resolve = 0UL;
++}
++
++static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
++{
++      struct page* page;
++      unsigned int *kaddr;
++
++      page = alloc_page(GFP_HIGHUSER);
++      if (!page)
++              return page;
++
++      kaddr = kmap(page);
++      memset(kaddr, 0, PAGE_SIZE);
++      kaddr[0] = 0x9DE3BFA8U; /* save */
++      flush_dcache_page(page);
++      kunmap(page);
++      return page;
++}
++
++static struct vm_operations_struct pax_vm_ops = {
++      close:          pax_emuplt_close,
++      nopage:         pax_emuplt_nopage,
++};
++
++static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
++{
++      vma->vm_mm = current->mm;
++      vma->vm_start = addr;
++      vma->vm_end = addr + PAGE_SIZE;
++      vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
++      vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
++      vma->vm_ops = &pax_vm_ops;
++      vma->vm_pgoff = 0UL;
++      vma->vm_file = NULL;
++      vma->vm_private_data = NULL;
++      insert_vm_struct(current->mm, vma);
++      ++current->mm->total_vm;
++}
++
++/*
++ * PaX: decide what to do with offenders (regs->pc = fault address)
++ *
++ * returns 1 when task should be killed
++ *         2 when patched PLT trampoline was detected
++ *         3 when unpatched PLT trampoline was detected
++ *       4 when legitimate ET_EXEC was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++      int err;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (current->flags & PF_PAX_RANDEXEC) {
++              if (regs->pc >= current->mm->start_code &&
++                  regs->pc < current->mm->end_code)
++              {
++                      if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
++                              return 1;
++
++                      regs->pc += current->mm->delta_exec;
++                      if (regs->npc >= current->mm->start_code &&
++                          regs->npc < current->mm->end_code)
++                              regs->npc += current->mm->delta_exec;
++                      return 4;
++              }
++              if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
++                  regs->pc < current->mm->end_code + current->mm->delta_exec)
++              {
++                      regs->pc -= current->mm->delta_exec;
++                      if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
++                          regs->npc < current->mm->end_code + current->mm->delta_exec)
++                              regs->npc -= current->mm->delta_exec;
++              }
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++      do { /* PaX: patched PLT emulation #1 */
++              unsigned int sethi1, sethi2, jmpl;
++
++              err = get_user(sethi1, (unsigned int *)regs->pc);
++              err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
++              err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
++
++              if (err)
++                      break;
++
++              if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
++                  (sethi2 & 0xFFC00000U) == 0x03000000U &&
++                  (jmpl & 0xFFFFE000U) == 0x81C06000U)
++              {
++                      unsigned int addr;
++
++                      regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
++                      addr = regs->u_regs[UREG_G1];
++                      addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++                      regs->pc = addr;
++                      regs->npc = addr+4;
++                      return 2;
++              }
++      } while (0);
++
++      { /* PaX: patched PLT emulation #2 */
++              unsigned int ba;
++
++              err = get_user(ba, (unsigned int *)regs->pc);
++
++              if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
++                      unsigned int addr;
++
++                      addr = regs->pc + 4 + (((ba | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++                      regs->pc = addr;
++                      regs->npc = addr+4;
++                      return 2;
++              }
++      }
++
++      do { /* PaX: patched PLT emulation #3 */
++              unsigned int sethi, jmpl, nop;
++
++              err = get_user(sethi, (unsigned int*)regs->pc);
++              err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
++              err |= get_user(nop, (unsigned int*)(regs->pc+8));
++
++              if (err)
++                      break;
++              if ((sethi & 0xFFC00000U) == 0x03000000U &&
++                  (jmpl & 0xFFFFE000U) == 0x81C06000U &&
++                  nop == 0x01000000U)
++              {
++                      unsigned int addr;
++
++                      addr = (sethi & 0x003FFFFFU) << 10;
++                      regs->u_regs[UREG_G1] = addr;
++                      addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++                      regs->pc = addr;
++                      regs->npc = addr+4;
++                      return 2;
++              }
++      } while (0);
++
++      do { /* PaX: unpatched PLT emulation step 1 */
++              unsigned int sethi, ba, nop;
++
++              err = get_user(sethi, (unsigned int *)regs->pc);
++              err |= get_user(ba, (unsigned int *)(regs->pc+4));
++              err |= get_user(nop, (unsigned int *)(regs->pc+8));
++
++              if (err)
++                      break;
++              if ((sethi & 0xFFC00000U) == 0x03000000U &&
++                  (ba & 0xFFC00000U) == 0x30800000U &&
++                  nop == 0x01000000U)
++              {
++                      unsigned int addr, save, call;
++
++                      addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
++
++                      err = get_user(save, (unsigned int *)addr);
++                      err |= get_user(call, (unsigned int *)(addr+4));
++                      err |= get_user(nop, (unsigned int *)(addr+8)); 
++                      if (err)
++                              break;
++
++                      if (save == 0x9DE3BFA8U &&
++                          (call & 0xC0000000U) == 0x40000000U &&
++                          nop == 0x01000000U)
++                      {
++                              struct vm_area_struct *vma;
++                              unsigned long call_dl_resolve;
++
++                              down_read(&current->mm->mmap_sem);
++                              call_dl_resolve = current->mm->call_dl_resolve;
++                              up_read(&current->mm->mmap_sem);
++                              if (likely(call_dl_resolve))
++                                      goto emulate;
++
++                              vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
++
++                              down_write(&current->mm->mmap_sem);
++                              if (current->mm->call_dl_resolve) {
++                                      call_dl_resolve = current->mm->call_dl_resolve;
++                                      up_write(&current->mm->mmap_sem);
++                                      if (vma) kmem_cache_free(vm_area_cachep, vma);
++                                      goto emulate;
++                              }
++
++                              call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
++                              if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
++                                      up_write(&current->mm->mmap_sem);
++                                      if (vma) kmem_cache_free(vm_area_cachep, vma);
++                                      return 1;
++                              }
++
++                              pax_insert_vma(vma, call_dl_resolve);
++                              current->mm->call_dl_resolve = call_dl_resolve;
++                              up_write(&current->mm->mmap_sem);
++
++emulate:
++                              regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
++                              regs->pc = call_dl_resolve;
++                              regs->npc = addr+4;
++                              return 3;
++                      }
++              }
++      } while (0);
++
++      do { /* PaX: unpatched PLT emulation step 2 */
++              unsigned int save, call, nop;
++
++              err = get_user(save, (unsigned int*)(regs->pc-4));
++              err |= get_user(call, (unsigned int*)regs->pc);
++              err |= get_user(nop, (unsigned int*)(regs->pc+4));
++              if (err)
++                      break;
++
++              if (save == 0x9DE3BFA8U &&
++                  (call & 0xC0000000U) == 0x40000000U &&
++                  nop == 0x01000000U)
++              {
++                      unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
++
++                      regs->u_regs[UREG_RETPC] = regs->pc;
++                      regs->pc = dl_resolve;
++                      regs->npc = dl_resolve+4;
++                      return 3;
++              }
++      } while (0);
++
++#endif
++
++      return 1;
++}
++
++void pax_report_insns(void *pc)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 5; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int*)pc+i)) {
++                      printk("<invalid address>.");
++                      break;
++              }
++              printk("%08x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
+                              unsigned long address)
+ {
+@@ -263,6 +521,29 @@
+               if(!(vma->vm_flags & VM_WRITE))
+                       goto bad_area;
+       } else {
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++              if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
++                      up_read(&mm->mmap_sem);
++                      switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++                      case 2:
++                      case 3:
++                              return;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++                      case 4:
++                              return;
++#endif
++
++                      }
++                      pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
++                      do_exit(SIGKILL);
++              }
++#endif
++
+               /* Allow reads even for write-only mappings */
+               if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                       goto bad_area;
+diff -urN linux-2.4.22/arch/sparc/mm/init.c linux-2.4.22-grsec-O1/arch/sparc/mm/init.c
+--- linux-2.4.22/arch/sparc/mm/init.c  2002-11-29 00:53:12.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/sparc/mm/init.c 2003-10-21 14:24:34.000000000 +0200
+@@ -350,17 +350,17 @@
+       /* Initialize the protection map with non-constant, MMU dependent values. */
+       protection_map[0] = PAGE_NONE;
+-      protection_map[1] = PAGE_READONLY;
+-      protection_map[2] = PAGE_COPY;
+-      protection_map[3] = PAGE_COPY;
++      protection_map[1] = PAGE_READONLY_NOEXEC;
++      protection_map[2] = PAGE_COPY_NOEXEC;
++      protection_map[3] = PAGE_COPY_NOEXEC;
+       protection_map[4] = PAGE_READONLY;
+       protection_map[5] = PAGE_READONLY;
+       protection_map[6] = PAGE_COPY;
+       protection_map[7] = PAGE_COPY;
+       protection_map[8] = PAGE_NONE;
+-      protection_map[9] = PAGE_READONLY;
+-      protection_map[10] = PAGE_SHARED;
+-      protection_map[11] = PAGE_SHARED;
++      protection_map[9] = PAGE_READONLY_NOEXEC;
++      protection_map[10] = PAGE_SHARED_NOEXEC;
++      protection_map[11] = PAGE_SHARED_NOEXEC;
+       protection_map[12] = PAGE_READONLY;
+       protection_map[13] = PAGE_READONLY;
+       protection_map[14] = PAGE_SHARED;
+diff -urN linux-2.4.22/arch/sparc/mm/srmmu.c linux-2.4.22-grsec-O1/arch/sparc/mm/srmmu.c
+--- linux-2.4.22/arch/sparc/mm/srmmu.c 2003-06-13 16:51:32.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc/mm/srmmu.c        2003-10-21 14:24:34.000000000 +0200
+@@ -2042,6 +2042,13 @@
+       BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
+       BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
+       BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
++      BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
++      BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
++#endif
++
+       BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
+       page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
+       pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
+diff -urN linux-2.4.22/arch/sparc64/config.in linux-2.4.22-grsec-O1/arch/sparc64/config.in
+--- linux-2.4.22/arch/sparc64/config.in        2003-10-20 18:59:00.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc64/config.in       2003-10-21 14:24:34.000000000 +0200
+@@ -312,3 +312,11 @@
+ source crypto/Config.in
+ source lib/Config.in
++
++mainmenu_option next_comment
++comment 'Grsecurity'
++bool 'Grsecurity' CONFIG_GRKERNSEC
++if [ "$CONFIG_GRKERNSEC" = "y" ]; then
++      source grsecurity/Config.in
++fi
++endmenu
+diff -urN linux-2.4.22/arch/sparc64/kernel/ioctl32.c linux-2.4.22-grsec-O1/arch/sparc64/kernel/ioctl32.c
+--- linux-2.4.22/arch/sparc64/kernel/ioctl32.c 2003-10-20 18:58:58.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc64/kernel/ioctl32.c        2003-10-21 14:24:34.000000000 +0200
+@@ -2047,7 +2047,11 @@
+        * To have permissions to do most of the vt ioctls, we either have
+        * to be the owner of the tty, or super-user.
+        */
++#ifdef CONFIG_GRKERNSEC
++      if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
++#else
+       if (current->tty == tty || suser())
++#endif
+               return 1;
+       return 0;                                                    
+ }
+diff -urN linux-2.4.22/arch/sparc64/kernel/itlb_base.S linux-2.4.22-grsec-O1/arch/sparc64/kernel/itlb_base.S
+--- linux-2.4.22/arch/sparc64/kernel/itlb_base.S       2003-06-13 16:51:32.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc64/kernel/itlb_base.S      2003-10-21 14:24:34.000000000 +0200
+@@ -41,7 +41,9 @@
+       CREATE_VPTE_OFFSET2(%g4, %g6)                   ! Create VPTE offset
+       ldxa            [%g3 + %g6] ASI_P, %g5          ! Load VPTE
+ 1:    brgez,pn        %g5, 3f                         ! Not valid, branch out
+-       nop                                            ! Delay-slot
++      and             %g5, _PAGE_EXEC, %g4
++      brz,pn          %g4, 3f                         ! Not executable, branch out
++      nop                                             ! Delay-slot
+ 2:    stxa            %g5, [%g0] ASI_ITLB_DATA_IN     ! Load PTE into TLB
+       retry                                           ! Trap return
+ 3:    rdpr            %pstate, %g4                    ! Move into alternate globals
+@@ -74,8 +76,6 @@
+       nop
+       nop
+       nop
+-      nop
+-      nop
+       CREATE_VPTE_NOP
+ #undef CREATE_VPTE_OFFSET1
+diff -urN linux-2.4.22/arch/sparc64/kernel/ptrace.c linux-2.4.22-grsec-O1/arch/sparc64/kernel/ptrace.c
+--- linux-2.4.22/arch/sparc64/kernel/ptrace.c  2002-11-29 00:53:12.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/sparc64/kernel/ptrace.c 2003-10-21 14:24:34.000000000 +0200
+@@ -18,6 +18,7 @@
+ #include <linux/user.h>
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
++#include <linux/grsecurity.h>
+ #include <asm/asi.h>
+ #include <asm/pgtable.h>
+@@ -161,6 +162,11 @@
+               goto out;
+       }
++      if (gr_handle_ptrace(child, (long)request)) {
++              pt_error_return(regs, EPERM);
++              goto out;
++      }
++
+       if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
+           || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
+               if (ptrace_attach(child)) {
+diff -urN linux-2.4.22/arch/sparc64/kernel/sys_sparc.c linux-2.4.22-grsec-O1/arch/sparc64/kernel/sys_sparc.c
+--- linux-2.4.22/arch/sparc64/kernel/sys_sparc.c       2003-08-25 13:44:40.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc64/kernel/sys_sparc.c      2003-10-21 14:24:34.000000000 +0200
+@@ -24,6 +24,7 @@
+ #include <linux/slab.h>
+ #include <linux/ipc.h>
+ #include <linux/personality.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/ipc.h>
+@@ -63,6 +64,13 @@
+               task_size = 0xf0000000UL;
+       if (len > task_size || len > -PAGE_OFFSET)
+               return -ENOMEM;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
++              addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
++      else
++#endif
++
+       if (!addr)
+               addr = TASK_UNMAPPED_BASE;
+@@ -289,11 +297,22 @@
+       struct file * file = NULL;
+       unsigned long retval = -EBADF;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       if (!(flags & MAP_ANONYMOUS)) {
+               file = fget(fd);
+               if (!file)
+                       goto out;
+       }
++
++      if (gr_handle_mmap(file, prot)) {
++              retval = -EACCES;
++              goto out_putf;
++      }
++
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       len = PAGE_ALIGN(len);
+       retval = -EINVAL;
+diff -urN linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c linux-2.4.22-grsec-O1/arch/sparc64/kernel/sys_sparc32.c
+--- linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c     2003-10-20 18:59:09.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc64/kernel/sys_sparc32.c    2003-10-21 14:24:34.000000000 +0200
+@@ -52,6 +52,8 @@
+ #include <linux/sysctl.h>
+ #include <linux/dnotify.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
++#include <linux/random.h>
++#include <linux/grsecurity.h>
+ #include <asm/types.h>
+ #include <asm/ipc.h>
+@@ -3235,8 +3237,18 @@
+       struct file * file;
+       int retval;
+       int i;
++#ifdef CONFIG_GRKERNSEC
++      struct file *old_exec_file;
++      struct acl_subject_label *old_acl;
++      struct rlimit old_rlim[RLIM_NLIMITS];
++#endif
+       bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
++      bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
++#endif
++
+       memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
+       file = open_exec(filename);
+@@ -3245,6 +3257,20 @@
+       if (IS_ERR(file))
+               return retval;
++      gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
++
++      if (gr_handle_nproc()) {
++              allow_write_access(file);
++              fput(file);
++              return -EAGAIN;
++      }
++
++      if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
++              allow_write_access(file);
++              fput(file);
++              return -EACCES;
++      }
++
+       bprm.file = file;
+       bprm.filename = filename;
+       bprm.sh_bang = 0;
+@@ -3265,11 +3291,24 @@
+       if (retval < 0)
+               goto out;
+       
++      if(!gr_tpe_allow(file)) {
++              retval = -EACCES;
++              goto out;
++      }
++
++      if (gr_check_crash_exec(file)) {
++              retval = -EACCES;
++              goto out;
++      }
++
+       retval = copy_strings_kernel(1, &bprm.filename, &bprm);
+       if (retval < 0)
+               goto out;
+       bprm.exec = bprm.p;
++
++      gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
++
+       retval = copy_strings32(bprm.envc, envp, &bprm);
+       if (retval < 0)
+               goto out;
+@@ -3278,11 +3317,32 @@
+       if (retval < 0)
+               goto out;
++#ifdef CONFIG_GRKERNSEC
++      old_acl = current->acl;
++      memcpy(old_rlim, current->rlim, sizeof(old_rlim));
++      old_exec_file = current->exec_file;
++      get_file(file);
++      current->exec_file = file;
++#endif
++
++        gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
++
+       retval = search_binary_handler(&bprm, regs);
+-      if (retval >= 0)
++      if (retval >= 0) {
++#ifdef CONFIG_GRKERNSEC
++              if (old_exec_file)
++                      fput(old_exec_file);
++#endif
+               /* execve success */
+               return retval;
++      }
++#ifdef CONFIG_GRKERNSEC
++      current->acl = old_acl;
++      memcpy(current->rlim, old_rlim, sizeof(old_rlim));
++      fput(current->exec_file);
++      current->exec_file = old_exec_file;
++#endif
+ out:
+       /* Something went wrong, return the inode and free the argument pages*/
+       allow_write_access(bprm.file);
+diff -urN linux-2.4.22/arch/sparc64/kernel/sys_sunos32.c linux-2.4.22-grsec-O1/arch/sparc64/kernel/sys_sunos32.c
+--- linux-2.4.22/arch/sparc64/kernel/sys_sunos32.c     2002-11-29 00:53:12.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/sparc64/kernel/sys_sunos32.c    2003-10-21 14:24:34.000000000 +0200
+@@ -68,6 +68,11 @@
+       struct file *file = NULL;
+       unsigned long retval, ret_type;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       if(flags & MAP_NORESERVE) {
+               static int cnt;
+               if (cnt++ < 10)
+diff -urN linux-2.4.22/arch/sparc64/mm/fault.c linux-2.4.22-grsec-O1/arch/sparc64/mm/fault.c
+--- linux-2.4.22/arch/sparc64/mm/fault.c       2002-11-29 00:53:12.000000000 +0100
++++ linux-2.4.22-grsec-O1/arch/sparc64/mm/fault.c      2003-10-21 14:24:34.000000000 +0200
+@@ -16,6 +16,9 @@
+ #include <linux/smp_lock.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -299,6 +302,267 @@
+       unhandled_fault (address, current, regs);
+ }
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++static void pax_emuplt_close(struct vm_area_struct * vma)
++{
++      vma->vm_mm->call_dl_resolve = 0UL;
++}
++
++static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access)
++{
++      struct page* page;
++      unsigned int *kaddr;
++
++      page = alloc_page(GFP_HIGHUSER);
++      if (!page)
++              return page;
++
++      kaddr = kmap(page);
++      memset(kaddr, 0, PAGE_SIZE);
++      kaddr[0] = 0x9DE3BFA8U; /* save */
++      flush_dcache_page(page);
++      kunmap(page);
++      return page;
++}
++
++static struct vm_operations_struct pax_vm_ops = {
++      close:          pax_emuplt_close,
++      nopage:         pax_emuplt_nopage,
++};
++
++static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
++{
++      vma->vm_mm = current->mm;
++      vma->vm_start = addr;
++      vma->vm_end = addr + PAGE_SIZE;
++      vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
++      vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
++      vma->vm_ops = &pax_vm_ops;
++      vma->vm_pgoff = 0UL; 
++      vma->vm_file = NULL;
++      vma->vm_private_data = NULL;
++      insert_vm_struct(current->mm, vma);
++      ++current->mm->total_vm;
++}
++#endif
++
++/*
++ * PaX: decide what to do with offenders (regs->tpc = fault address)
++ *
++ * returns 1 when task should be killed
++ *         2 when patched PLT trampoline was detected
++ *         3 when unpatched PLT trampoline was detected
++ *       4 when legitimate ET_EXEC was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++      int err;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (current->flags & PF_PAX_RANDEXEC) {
++              if (regs->tpc >= current->mm->start_code &&
++                  regs->tpc < current->mm->end_code)
++              {
++                      if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
++                              return 1;
++
++                      regs->tpc += current->mm->delta_exec;
++                      if (regs->tnpc >= current->mm->start_code &&
++                          regs->tnpc < current->mm->end_code)
++                              regs->tnpc += current->mm->delta_exec;
++                      return 4;
++              }
++              if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
++                  regs->tpc < current->mm->end_code + current->mm->delta_exec)
++              {
++                      regs->tpc -= current->mm->delta_exec;
++                      if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
++                          regs->tnpc < current->mm->end_code + current->mm->delta_exec)
++                              regs->tnpc -= current->mm->delta_exec;
++              }
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++      do { /* PaX: patched PLT emulation #1 */
++              unsigned int sethi1, sethi2, jmpl;
++
++              err = get_user(sethi1, (unsigned int*)regs->tpc);
++              err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
++              err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
++
++              if (err)
++                      break;
++
++              if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
++                  (sethi2 & 0xFFC00000U) == 0x03000000U &&
++                  (jmpl & 0xFFFFE000U) == 0x81C06000U)
++              {
++                      unsigned long addr;
++
++                      regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
++                      addr = regs->u_regs[UREG_G1];
++                      addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++                      regs->tpc = addr;
++                      regs->tnpc = addr+4;
++                      return 2;
++              }
++      } while (0);
++
++      { /* PaX: patched PLT emulation #2 */
++              unsigned int ba;
++
++              err = get_user(ba, (unsigned int*)regs->tpc);
++
++              if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
++                      unsigned long addr;
++
++                      addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++                      regs->tpc = addr;
++                      regs->tnpc = addr+4;
++                      return 2;
++              }
++      }
++
++      do { /* PaX: patched PLT emulation #3 */
++              unsigned int sethi, jmpl, nop;
++
++              err = get_user(sethi, (unsigned int*)regs->tpc);
++              err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
++              err |= get_user(nop, (unsigned int*)(regs->tpc+8));
++
++              if (err)
++                      break;
++
++              if ((sethi & 0xFFC00000U) == 0x03000000U &&
++                  (jmpl & 0xFFFFE000U) == 0x81C06000U &&
++                  nop == 0x01000000U)
++              {
++                      unsigned long addr;
++
++                      addr = (sethi & 0x003FFFFFU) << 10;
++                      regs->u_regs[UREG_G1] = addr;
++                      addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++                      regs->tpc = addr;
++                      regs->tnpc = addr+4;
++                      return 2;
++              }
++      } while (0);
++
++      do { /* PaX: unpatched PLT emulation step 1 */
++              unsigned int sethi, ba, nop;
++
++              err = get_user(sethi, (unsigned int*)regs->tpc);
++              err |= get_user(ba, (unsigned int*)(regs->tpc+4));
++              err |= get_user(nop, (unsigned int*)(regs->tpc+8));
++
++              if (err)
++                      break;
++
++              if ((sethi & 0xFFC00000U) == 0x03000000U &&
++                  (ba & 0xFFC00000U) == 0x30800000U &&
++                  nop == 0x01000000U)
++              {
++                      unsigned long addr;
++                      unsigned int save, call;
++
++                      addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
++
++                      err = get_user(save, (unsigned int*)addr);
++                      err |= get_user(call, (unsigned int*)(addr+4));
++                      err |= get_user(nop, (unsigned int*)(addr+8));
++
++                      if (err)
++                              break;
++
++                      if (save == 0x9DE3BFA8U &&
++                          (call & 0xC0000000U) == 0x40000000U &&
++                          nop == 0x01000000U)
++                      {
++                              struct vm_area_struct *vma;
++                              unsigned long call_dl_resolve;
++
++                              down_read(&current->mm->mmap_sem);
++                              call_dl_resolve = current->mm->call_dl_resolve;
++                              up_read(&current->mm->mmap_sem);
++                              if (likely(call_dl_resolve))
++                                      goto emulate;
++
++                              vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
++
++                              down_write(&current->mm->mmap_sem);
++                              if (current->mm->call_dl_resolve) {
++                                      call_dl_resolve = current->mm->call_dl_resolve;
++                                      up_write(&current->mm->mmap_sem);
++                                      if (vma) kmem_cache_free(vm_area_cachep, vma);
++                                      goto emulate;
++                              }
++
++                              call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
++                              if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
++                                      up_write(&current->mm->mmap_sem);
++                                      if (vma) kmem_cache_free(vm_area_cachep, vma);
++                                      return 1;
++                              }
++
++                              pax_insert_vma(vma, call_dl_resolve);
++                              current->mm->call_dl_resolve = call_dl_resolve;
++                              up_write(&current->mm->mmap_sem);
++
++emulate:
++                              regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
++                              regs->tpc = call_dl_resolve;
++                              regs->tnpc = addr+4;
++                              return 3;
++                      }
++              }
++      } while (0);
++
++      do { /* PaX: unpatched PLT emulation step 2 */
++              unsigned int save, call, nop;
++
++              err = get_user(save, (unsigned int*)(regs->tpc-4));
++              err |= get_user(call, (unsigned int*)regs->tpc);
++              err |= get_user(nop, (unsigned int*)(regs->tpc+4));
++              if (err)
++                      break;
++
++              if (save == 0x9DE3BFA8U &&
++                  (call & 0xC0000000U) == 0x40000000U &&
++                  nop == 0x01000000U)
++              {
++                      unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
++
++                      regs->u_regs[UREG_RETPC] = regs->tpc;
++                      regs->tpc = dl_resolve;
++                      regs->tnpc = dl_resolve+4;
++                      return 3;
++              }
++      } while (0);
++#endif
++
++      return 1;
++}
++
++void pax_report_insns(void *pc)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 5; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int*)pc+i)) {
++                      printk("<invalid address>.");
++                      break;
++              }
++              printk("%08x ", c);
++      }
++      printk("\n");
++}
++#endif  
++
++
+ asmlinkage void do_sparc64_fault(struct pt_regs *regs)
+ {
+       struct mm_struct *mm = current->mm;
+@@ -338,6 +602,7 @@
+       if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+               regs->tpc &= 0xffffffff;
++              regs->tnpc &= 0xffffffff;
+               address &= 0xffffffff;
+       }
+@@ -346,6 +611,34 @@
+       if (!vma)
+               goto bad_area;
++      /* PaX: detect ITLB misses on non-exec pages */
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address && 
++          !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
++      {
++              if (address != regs->tpc)
++                      goto good_area;
++
++              up_read(&mm->mmap_sem);
++              switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT
++              case 2:
++              case 3:
++                      goto fault_done;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++              case 4:
++                      goto fault_done;
++#endif
++
++              }
++              pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
++              do_exit(SIGKILL);
++      }
++#endif
++
+       /* Pure DTLB misses do not tell us whether the fault causing
+        * load/store/atomic was a write or not, it only says that there
+        * was no match.  So in such a case we (carefully) read the
+diff -urN linux-2.4.22/arch/sparc64/solaris/misc.c linux-2.4.22-grsec-O1/arch/sparc64/solaris/misc.c
+--- linux-2.4.22/arch/sparc64/solaris/misc.c   2003-10-20 18:59:10.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/sparc64/solaris/misc.c  2003-10-21 14:24:34.000000000 +0200
+@@ -54,6 +54,11 @@
+       struct file *file = NULL;
+       unsigned long retval, ret_type;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (flags & MAP_MIRROR)
++              return -EINVAL;
++#endif
++
+       /* Do we need it here? */
+       set_personality(PER_SVR4);
+       if (flags & MAP_NORESERVE) {
+diff -urN linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22-grsec-O1/arch/x86_64/ia32/ia32_ioctl.c
+--- linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c 2003-10-20 18:58:58.000000000 +0200
++++ linux-2.4.22-grsec-O1/arch/x86_64/ia32/ia32_ioctl.c        2003-10-21 14:24:34.000000000 +0200
+@@ -1933,7 +1933,11 @@
+        * To have permissions to do most of the vt ioctls, we either have
+        * to be the owner of the tty, or super-user.
+        */
++#ifdef CONFIG_GRKERNSEC
++      if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
++#else
+       if (current->tty == tty || suser())
++#endif
+               return 1;
+       return 0;                                                    
+ }
+diff -urN linux-2.4.22/drivers/char/keyboard.c linux-2.4.22-grsec-O1/drivers/char/keyboard.c
+--- linux-2.4.22/drivers/char/keyboard.c       2003-08-25 13:44:41.000000000 +0200
++++ linux-2.4.22-grsec-O1/drivers/char/keyboard.c      2003-10-21 14:24:34.000000000 +0200
+@@ -533,6 +533,16 @@
+       if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
+           !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
+               return;
++
++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
++      {
++              void *func = spec_fn_table[value];
++              if (func == show_state || func == show_ptregs ||
++                  func == show_mem)
++                      return;
++      }
++#endif
++
+       spec_fn_table[value]();
+ }
+diff -urN linux-2.4.22/drivers/char/mem.c linux-2.4.22-grsec-O1/drivers/char/mem.c
+--- linux-2.4.22/drivers/char/mem.c    2003-06-13 16:51:33.000000000 +0200
++++ linux-2.4.22-grsec-O1/drivers/char/mem.c   2003-10-21 14:24:34.000000000 +0200
+@@ -21,6 +21,7 @@
+ #include <linux/raw.h>
+ #include <linux/tty.h>
+ #include <linux/capability.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -41,6 +42,10 @@
+ #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
+ extern void tapechar_init(void);
+ #endif
++
++#ifdef CONFIG_GRKERNSEC
++extern struct file_operations grsec_fops;
++#endif
+      
+ static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
+                           const char * buf, size_t count, loff_t *ppos)
+@@ -114,6 +119,11 @@
+       unsigned long p = *ppos;
+       unsigned long end_mem;
++#ifdef CONFIG_GRKERNSEC_KMEM
++      gr_handle_mem_write();
++      return -EPERM;
++#endif
++
+       end_mem = __pa(high_memory);
+       if (p >= end_mem)
+               return 0;
+@@ -186,6 +196,12 @@
+ {
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
++#ifdef CONFIG_GRKERNSEC_KMEM
++      if (gr_handle_mem_mmap(offset, vma))
++              return -EPERM;
++#endif
++
++
+       /*
+        * Accessing memory above the top the kernel knows about or
+        * through a file pointer that was marked O_SYNC will be
+@@ -285,6 +301,11 @@
+       ssize_t virtr = 0;
+       char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
++#ifdef CONFIG_GRKERNSEC_KMEM
++      gr_handle_kmem_write();
++      return -EPERM;
++#endif
++
+       if (p < (unsigned long) high_memory) {
+               wrote = count;
+               if (count > (unsigned long) high_memory - p)
+@@ -401,7 +422,7 @@
+                       count = size;
+               zap_page_range(mm, addr, count);
+-              zeromap_page_range(addr, count, PAGE_COPY);
++              zeromap_page_range(addr, count, vma->vm_page_prot); 
+               size -= count;
+               buf += count;
+@@ -517,6 +538,15 @@
+ static int open_port(struct inode * inode, struct file * filp)
+ {
++#ifdef CONFIG_GRKERNSEC_KMEM
++      gr_handle_open_port();
++      return -EPERM;
++#endif
++      return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
++}
++
++static int open_mem(struct inode * inode, struct file * filp)
++{
+       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+ }
+@@ -574,6 +604,11 @@
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+       unsigned long size = vma->vm_end - vma->vm_start;
++#ifdef CONFIG_GRKERNSEC_KMEM
++      if (gr_handle_mem_mmap(offset, vma))
++              return -EPERM;
++#endif
++
+       /*
+        * If the user is not attempting to mmap a high memory address then
+        * the standard mmap_mem mechanism will work.  High memory addresses
+@@ -609,7 +644,6 @@
+ #define full_lseek      null_lseek
+ #define write_zero    write_null
+ #define read_full       read_zero
+-#define open_mem      open_port
+ #define open_kmem     open_mem
+ static struct file_operations mem_fops = {
+@@ -685,6 +719,11 @@
+               case 9:
+                       filp->f_op = &urandom_fops;
+                       break;
++#ifdef CONFIG_GRKERNSEC
++              case 10:
++                      filp->f_op = &grsec_fops;
++                      break;
++#endif
+               default:
+                       return -ENXIO;
+       }
+@@ -711,7 +750,10 @@
+       {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
+       {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
+       {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
+-      {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
++      {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
++#ifdef CONFIG_GRKERNSEC
++      {10,"grsec",   S_IRUSR | S_IWUGO,           &grsec_fops}
++#endif
+     };
+     int i;
+diff -urN linux-2.4.22/drivers/char/random.c linux-2.4.22-grsec-O1/drivers/char/random.c
+--- linux-2.4.22/drivers/char/random.c 2003-08-25 13:44:41.000000000 +0200
++++ linux-2.4.22-grsec-O1/drivers/char/random.c        2003-10-21 14:24:34.000000000 +0200
+@@ -262,9 +262,15 @@
+ /*
+  * Configuration information
+  */
++#ifdef CONFIG_GRKERNSEC_RANDNET
++#define DEFAULT_POOL_SIZE 1024
++#define SECONDARY_POOL_SIZE 256
++#define BATCH_ENTROPY_SIZE 512
++#else
+ #define DEFAULT_POOL_SIZE 512
+ #define SECONDARY_POOL_SIZE 128
+ #define BATCH_ENTROPY_SIZE 256
++#endif
+ #define USE_SHA
+ /*
+@@ -389,6 +395,7 @@
+ /*
+  * Static global variables
+  */
++
+ static struct entropy_store *random_state; /* The default global store */
+ static struct entropy_store *sec_random_state; /* secondary store */
+ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
+@@ -2202,6 +2209,29 @@
+       return halfMD4Transform(hash, keyptr->secret);
+ }
++#ifdef CONFIG_GRKERNSEC
++/* the following function is provided by PaX under the GPL */
++unsigned long get_random_long(void)
++{       
++      static time_t rekey_time;
++      static __u32 secret[12];
++      time_t t;
++
++      /*
++       * Pick a random secret every REKEY_INTERVAL seconds
++       */
++      t = CURRENT_TIME;
++      if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
++              rekey_time = t;
++              get_random_bytes(secret, sizeof(secret));
++      }
++
++      secret[1] = halfMD4Transform(secret+8, secret);
++      secret[0] = halfMD4Transform(secret+8, secret);
++      return *(unsigned long *)secret;
++}
++#endif
++
+ #ifdef CONFIG_SYN_COOKIES
+ /*
+  * Secure SYN cookie computation. This is the algorithm worked out by
+diff -urN linux-2.4.22/drivers/char/tty_io.c linux-2.4.22-grsec-O1/drivers/char/tty_io.c
+--- linux-2.4.22/drivers/char/tty_io.c 2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/drivers/char/tty_io.c        2003-10-21 14:24:34.000000000 +0200
+@@ -99,7 +99,7 @@
+ #include <linux/vt_kern.h>
+ #include <linux/selection.h>
+ #include <linux/devfs_fs_kernel.h>
+-
++#include <linux/grsecurity.h>
+ #include <linux/kmod.h>
+ #ifdef CONFIG_VT
+@@ -1425,7 +1425,11 @@
+               retval = -ENODEV;
+       filp->f_flags = saved_flags;
++#ifdef CONFIG_GRKERNSEC
++      if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG))
++#else
+       if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
++#endif
+               retval = -EBUSY;
+       if (retval) {
+@@ -1532,7 +1536,11 @@
+ {
+       char ch, mbz = 0;
++#ifdef CONFIG_GRKERNSEC
++      if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG))
++#else
+       if ((current->tty != tty) && !suser())
++#endif
+               return -EPERM;
+       if (get_user(ch, arg))
+               return -EFAULT;
+@@ -1570,7 +1578,11 @@
+       if (inode->i_rdev == SYSCONS_DEV ||
+           inode->i_rdev == CONSOLE_DEV) {
+               struct file *f;
++#ifdef CONFIG_GRKERNSEC
++              if (!capable(CAP_SYS_TTY_CONFIG))
++#else
+               if (!suser())
++#endif
+                       return -EPERM;
+               spin_lock(&redirect_lock);
+               f = redirect;
+@@ -1622,7 +1634,11 @@
+                * This tty is already the controlling
+                * tty for another session group!
+                */
++#ifdef CONFIG_GRKERNSEC
++              if ((arg == 1) && capable(CAP_SYS_ADMIN)) {
++#else
+               if ((arg == 1) && suser()) {
++#endif
+                       /*
+                        * Steal it away
+                        */
+diff -urN linux-2.4.22/drivers/char/vt.c linux-2.4.22-grsec-O1/drivers/char/vt.c
+--- linux-2.4.22/drivers/char/vt.c     2002-11-29 00:53:12.000000000 +0100
++++ linux-2.4.22-grsec-O1/drivers/char/vt.c    2003-10-21 14:24:34.000000000 +0200
+@@ -32,6 +32,7 @@
+ #include <linux/vt_kern.h>
+ #include <linux/kbd_diacr.h>
+ #include <linux/selection.h>
++#include <linux/grsecurity.h>
+ #ifdef CONFIG_FB_COMPAT_XPMAC
+ #include <asm/vc_ioctl.h>
+@@ -443,7 +444,11 @@
+        * to be the owner of the tty, or super-user.
+        */
+       perm = 0;
++#ifdef CONFIG_GRKERNSEC
++      if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
++#else
+       if (current->tty == tty || suser())
++#endif
+               perm = 1;
+  
+       kbd = kbd_table + console;
+@@ -1038,12 +1043,20 @@
+               return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
+       case VT_LOCKSWITCH:
++#ifdef CONFIG_GRKERNSEC
++              if (!capable(CAP_SYS_TTY_CONFIG))
++#else
+               if (!suser())
++#endif
+                  return -EPERM;
+               vt_dont_switch = 1;
+               return 0;
+       case VT_UNLOCKSWITCH:
++#ifdef CONFIG_GRKERNSEC
++              if (!capable(CAP_SYS_TTY_CONFIG))
++#else
+               if (!suser())
++#endif
+                  return -EPERM;
+               vt_dont_switch = 0;
+               return 0;
+diff -urN linux-2.4.22/drivers/pci/proc.c linux-2.4.22-grsec-O1/drivers/pci/proc.c
+--- linux-2.4.22/drivers/pci/proc.c    2002-11-29 00:53:14.000000000 +0100
++++ linux-2.4.22-grsec-O1/drivers/pci/proc.c   2003-10-21 14:24:34.000000000 +0200
+@@ -562,7 +562,15 @@
+               pci_for_each_dev(dev) {
+                       pci_proc_attach_device(dev);
+               }
++#ifdef CONFIG_GRKERNSEC_PROC_ADD
++#ifdef CONFIG_GRKERNSEC_PROC_USER
++              entry = create_proc_entry("pci", S_IRUSR, NULL);
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
++              entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
++#endif
++#else
+               entry = create_proc_entry("pci", 0, NULL);
++#endif
+               if (entry)
+                       entry->proc_fops = &proc_pci_operations;
+       }
+diff -urN linux-2.4.22/fs/binfmt_aout.c linux-2.4.22-grsec-O1/fs/binfmt_aout.c
+--- linux-2.4.22/fs/binfmt_aout.c      2001-11-03 02:39:20.000000000 +0100
++++ linux-2.4.22-grsec-O1/fs/binfmt_aout.c     2003-10-21 14:24:34.000000000 +0200
+@@ -5,6 +5,7 @@
+  */
+ #include <linux/module.h>
++#include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+@@ -113,10 +114,12 @@
+ /* If the size of the dump file exceeds the rlimit, then see what would happen
+    if we wrote the stack, but not the data area.  */
+ #ifdef __sparc__
++      gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize);
+       if ((dump.u_dsize+dump.u_ssize) >
+           current->rlim[RLIMIT_CORE].rlim_cur)
+               dump.u_dsize = 0;
+ #else
++      gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE);
+       if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
+           current->rlim[RLIMIT_CORE].rlim_cur)
+               dump.u_dsize = 0;
+@@ -124,10 +127,12 @@
+ /* Make sure we have enough room to write the stack and data areas. */
+ #ifdef __sparc__
++      gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize);
+       if ((dump.u_ssize) >
+           current->rlim[RLIMIT_CORE].rlim_cur)
+               dump.u_ssize = 0;
+ #else
++      gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE);
+       if ((dump.u_ssize+1) * PAGE_SIZE >
+           current->rlim[RLIMIT_CORE].rlim_cur)
+               dump.u_ssize = 0;
+@@ -276,6 +281,8 @@
+       rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+       if (rlim >= RLIM_INFINITY)
+               rlim = ~0;
++
++      gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss);
+       if (ex.a_data + ex.a_bss > rlim)
+               return -ENOMEM;
+@@ -307,6 +314,24 @@
+       current->mm->mmap = NULL;
+       compute_creds(bprm);
+       current->flags &= ~PF_FORKNOEXEC;
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
++              current->flags |= PF_PAX_PAGEEXEC;
++
++#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
++
++      }
++#endif
++
+ #ifdef __sparc__
+       if (N_MAGIC(ex) == NMAGIC) {
+               loff_t pos = fd_offset;
+@@ -393,7 +418,7 @@
+               down_write(&current->mm->mmap_sem);
+               error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+-                              PROT_READ | PROT_WRITE | PROT_EXEC,
++                              PROT_READ | PROT_WRITE,
+                               MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
+                               fd_offset + ex.a_text);
+               up_write(&current->mm->mmap_sem);
+diff -urN linux-2.4.22/fs/binfmt_elf.c linux-2.4.22-grsec-O1/fs/binfmt_elf.c
+--- linux-2.4.22/fs/binfmt_elf.c       2003-10-20 18:58:34.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/binfmt_elf.c      2003-10-21 14:24:34.000000000 +0200
+@@ -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,10 +34,13 @@
+ #include <linux/smp_lock.h>
+ #include <linux/compiler.h>
+ #include <linux/highmem.h>
++#include <linux/random.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/param.h>
+ #include <asm/pgalloc.h>
++#include <asm/system.h>
+ #define DLINFO_ITEMS 13
+@@ -86,6 +90,12 @@
+       if (end <= start)
+               return;
+       do_brk(start, end - start);
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if (current->flags & PF_PAX_RANDEXEC)
++              do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
++#endif
++
+ }
+@@ -445,6 +455,11 @@
+       struct exec interp_ex;
+       char passed_fileno[6];
+       struct files_struct *files;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      unsigned long load_addr_random = 0UL;
++      unsigned long load_bias_random = 0UL;
++#endif
+       
+       /* Get the exec-header */
+       elf_ex = *((struct elfhdr *) bprm->buf);
+@@ -617,7 +632,63 @@
+       current->mm->end_data = 0;
+       current->mm->end_code = 0;
+       current->mm->mmap = NULL;
++
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++      current->mm->delta_mmap = 0UL;
++      current->mm->delta_exec = 0UL;
++      current->mm->delta_stack = 0UL;
++#endif
++
+       current->flags &= ~PF_FORKNOEXEC;
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) {
++              current->flags |= PF_PAX_PAGEEXEC;
++
++#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
++              current->mm->call_dl_resolve = 0UL;
++#endif
++
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
++              current->flags &= ~PF_PAX_PAGEEXEC;
++              current->flags |= PF_PAX_SEGMEXEC;
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP
++      if (elf_ex.e_ident[EI_PAX] & EF_PAX_EMUTRAMP)
++              current->flags |= PF_PAX_EMUTRAMP;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++      if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex.e_ident[EI_PAX] & EF_PAX_MPROTECT))
++              current->flags |= PF_PAX_MPROTECT;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++      if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_RANDMMAP)) {
++              current->flags |= PF_PAX_RANDMMAP;
++
++#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
++
++              current->mm->delta_mmap = pax_delta_mask(get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
++              current->mm->delta_exec = pax_delta_mask(get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
++              current->mm->delta_stack = pax_delta_mask(get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
++      }
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      if ((elf_ex.e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC) &&
++          (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)))
++              current->flags |= PF_PAX_RANDEXEC;
++#endif
++
++      gr_set_pax_flags(current);      
++
+       elf_entry = (unsigned long) elf_ex.e_entry;
+       /* Do this so that we can load the interpreter, if need be.  We will
+@@ -673,11 +744,84 @@
+                          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(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
++                              elf_flags |= MAP_FIXED;
++                      }
++#endif
++
+               }
+-              error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
+-              if (BAD_ADDR(error))
+-                      continue;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++              if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
++                      unsigned long addr, len;
++
++                      error = -ENOMEM;
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++                      if (current->flags & PF_PAX_PAGEEXEC)
++                              error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++                      if (current->flags & PF_PAX_SEGMEXEC) {
++                              addr = ELF_PAGESTART(load_bias + vaddr);
++                              len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
++                              if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
++                                      continue;
++                              down_write(&current->mm->mmap_sem);
++                              error = do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
++                              up_write(&current->mm->mmap_sem);
++                      }
++#endif
++
++                      if (BAD_ADDR(error))
++                              continue;
++
++                      /* PaX: mirror at a randomized base */
++                      down_write(&current->mm->mmap_sem);
++
++                      if (!load_addr_set) {
++                              load_addr_random = get_unmapped_area(bprm->file, 0UL, elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT, MAP_PRIVATE);
++                              if (BAD_ADDR(load_addr_random)) {
++                                      up_write(&current->mm->mmap_sem);
++                                      continue;
++                              }
++                              load_bias_random = load_addr_random - vaddr;
++                      }
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++                      if (current->flags & PF_PAX_PAGEEXEC)
++                              load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++                      if (current->flags & PF_PAX_SEGMEXEC) {
++                              if (elf_prot & PROT_EXEC) {
++                                      load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), elf_ppnt->p_memsz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), PROT_NONE, MAP_PRIVATE | MAP_FIXED, 0UL);
++                                      if (!BAD_ADDR(load_addr_random)) {
++                                              load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
++                                              if (!BAD_ADDR(load_addr_random))
++                                                      load_addr_random -= SEGMEXEC_TASK_SIZE;
++                                      }
++                              } else
++                                      load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
++                      }
++#endif
++
++                      up_write(&current->mm->mmap_sem);
++                      if (BAD_ADDR(load_addr_random))
++                              continue;
++              } else
++#endif
++              {
++                      error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
++                      if (BAD_ADDR(error))
++                              continue;
++              }
+               if (!load_addr_set) {
+                       load_addr_set = 1;
+@@ -687,6 +831,11 @@
+                                            ELF_PAGESTART(load_bias + vaddr);
+                               load_addr += load_bias;
+                       }
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++                      current->mm->delta_exec = load_addr_random - load_addr;
++#endif
++
+               }
+               k = elf_ppnt->p_vaddr;
+               if (k < start_code) start_code = k;
+@@ -713,6 +862,18 @@
+       start_data += load_bias;
+       end_data += load_bias;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT);
++#undef pax_delta_mask
++#endif
++
++      /* Calling set_brk effectively mmaps the pages that we need
++       * for the bss and break sections
++       */
++      set_brk(elf_bss, elf_brk);
++
++      padzero(elf_bss);
++
+       if (elf_interpreter) {
+               if (interpreter_type == INTERPRETER_AOUT)
+                       elf_entry = load_aout_interp(&interp_ex,
+@@ -760,13 +921,6 @@
+       current->mm->end_data = end_data;
+       current->mm->start_stack = bprm->p;
+-      /* Calling set_brk effectively mmaps the pages that we need
+-       * for the bss and break sections
+-       */
+-      set_brk(elf_bss, elf_brk);
+-
+-      padzero(elf_bss);
+-
+ #if 0
+       printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
+       printk("(end_code) %lx\n" , (long) current->mm->end_code);
+@@ -799,6 +953,10 @@
+       ELF_PLAT_INIT(regs);
+ #endif
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      pax_switch_segments(current);
++#endif
++
+       start_thread(regs, elf_entry, bprm->p);
+       if (current->ptrace & PT_PTRACED)
+               send_sig(SIGTRAP, current, 0);
+@@ -1026,8 +1184,11 @@
+ #undef DUMP_SEEK
+ #define DUMP_WRITE(addr, nr)  \
++      do { \
++      gr_learn_resource(current, RLIMIT_CORE, size + (nr)); \
+       if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
+-              goto end_coredump;
++              goto end_coredump; \
++      } while (0);
+ #define DUMP_SEEK(off)        \
+       if (!dump_seek(file, (off))) \
+               goto end_coredump;
+diff -urN linux-2.4.22/fs/buffer.c linux-2.4.22-grsec-O1/fs/buffer.c
+--- linux-2.4.22/fs/buffer.c   2003-10-20 18:59:08.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/buffer.c  2003-10-21 14:24:34.000000000 +0200
+@@ -1890,6 +1890,9 @@
+       int err;
+       err = -EFBIG;
++
++      gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size);
++
+         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+       if (limit != RLIM_INFINITY && size > (loff_t)limit) {
+               send_sig(SIGXFSZ, current, 0);
+diff -urN linux-2.4.22/fs/exec.c linux-2.4.22-grsec-O1/fs/exec.c
+--- linux-2.4.22/fs/exec.c     2003-08-25 13:44:43.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/exec.c    2003-10-21 14:24:34.000000000 +0200
+@@ -43,6 +43,9 @@
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+ #include <asm/mmu_context.h>
++#include <linux/major.h>
++#include <linux/random.h>
++#include <linux/grsecurity.h>
+ #ifdef CONFIG_KMOD
+ #include <linux/kmod.h>
+@@ -345,6 +348,11 @@
+               mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
+               mpnt->vm_end = STACK_TOP;
+               mpnt->vm_flags = VM_STACK_FLAGS;
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++              if (!(current->flags & PF_PAX_PAGEEXEC))
++                      mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7];
++              else
++#endif
+               mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
+               mpnt->vm_ops = NULL;
+               mpnt->vm_pgoff = 0;
+@@ -610,6 +618,30 @@
+       }
+       current->comm[i] = '\0';
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      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_ASLR
++      current->flags &= ~PF_PAX_RANDMMAP;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++      current->flags &= ~PF_PAX_RANDEXEC;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      current->flags &= ~PF_PAX_SEGMEXEC;
++#endif
++
+       flush_thread();
+       de_thread(current);
+@@ -709,6 +741,9 @@
+                       cap_set_full(bprm->cap_effective);
+       }
++      if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
++              return -EACCES;
++
+       memset(bprm->buf,0,BINPRM_BUF_SIZE);
+       return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
+ }
+@@ -774,6 +809,8 @@
+         current->suid = current->euid = current->fsuid = bprm->e_uid;
+         current->sgid = current->egid = current->fsgid = bprm->e_gid;
++      gr_handle_chroot_caps(current);
++
+       if(do_unlock)
+               unlock_kernel();
+       current->keep_capabilities = 0;
+@@ -907,6 +944,11 @@
+       struct file *file;
+       int retval;
+       int i;
++#ifdef CONFIG_GRKERNSEC
++      struct file *old_exec_file;
++      struct acl_subject_label *old_acl;
++      struct rlimit old_rlim[RLIM_NLIMITS];
++#endif
+       file = open_exec(filename);
+@@ -914,7 +956,26 @@
+       if (IS_ERR(file))
+               return retval;
++      gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
++
++      if (gr_handle_nproc()) {
++              allow_write_access(file);
++              fput(file);
++              return -EAGAIN;
++      }
++
++      if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
++              allow_write_access(file);
++              fput(file);
++              return -EACCES;
++      }
++
+       bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
++      bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
++#endif
++
+       memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
+       bprm.file = file;
+@@ -938,11 +999,26 @@
+       if (retval < 0) 
+               goto out; 
++      if (!gr_tpe_allow(file)) {
++              retval = -EACCES;
++              goto out;
++      }
++
++      if(gr_check_crash_exec(file)) {
++              retval = -EACCES;
++              goto out;
++      }
++
+       retval = copy_strings_kernel(1, &bprm.filename, &bprm);
+       if (retval < 0) 
+               goto out; 
+       bprm.exec = bprm.p;
++
++      gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
++
++      gr_handle_exec_args(&bprm, argv);
++
+       retval = copy_strings(bprm.envc, envp, &bprm);
+       if (retval < 0) 
+               goto out; 
+@@ -951,11 +1027,32 @@
+       if (retval < 0) 
+               goto out; 
++#ifdef CONFIG_GRKERNSEC
++      old_acl = current->acl;
++      memcpy(old_rlim, current->rlim, sizeof(old_rlim));
++      old_exec_file = current->exec_file;
++      get_file(file);
++      current->exec_file = file;
++#endif
++
++      gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
++
+       retval = search_binary_handler(&bprm,regs);
+-      if (retval >= 0)
++      if (retval >= 0) {
++#ifdef CONFIG_GRKERNSEC
++              if (old_exec_file)
++                      fput(old_exec_file);
++#endif
+               /* execve success */
+               return retval;
++      }
++#ifdef CONFIG_GRKERNSEC
++      current->acl = old_acl;
++      memcpy(current->rlim, old_rlim, sizeof(old_rlim));
++      fput(current->exec_file);
++      current->exec_file = old_exec_file;
++#endif
+ out:
+       /* Something went wrong, return the inode and free the argument pages*/
+       allow_write_access(bprm.file);
+@@ -1097,6 +1194,43 @@
+       *out_ptr = 0;
+ }
++#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
++{
++      struct task_struct *tsk = current;
++      struct mm_struct *mm = current->mm;
++      char* buffer = (char*)__get_free_page(GFP_ATOMIC);
++      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);
++      }
++      if (tsk->curr_ip)
++              printk(KERN_ERR "PAX: From %u.%u.%u.%u: terminating task: %s(%s):%d, uid/euid: %u/%u, "
++                              "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), path, tsk->comm, tsk->pid,
++                              tsk->uid, tsk->euid, pc, sp);
++      else
++              printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
++                              "PC: %p, SP: %p\n", path, tsk->comm, tsk->pid,
++                              tsk->uid, tsk->euid, pc, sp);
++      if (buffer) free_page((unsigned long)buffer);
++      pax_report_insns(pc);
++      do_coredump(SIGKILL, regs);
++}
++#endif
++
+ int do_coredump(long signr, struct pt_regs * regs)
+ {
+       struct linux_binfmt * binfmt;
+@@ -1112,6 +1246,7 @@
+       if (!is_dumpable(current))
+               goto fail;
+       current->mm->dumpable = 0;
++      gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump);
+       if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
+               goto fail;
+@@ -1131,7 +1266,7 @@
+               goto close_fail;
+       if (!file->f_op->write)
+               goto close_fail;
+-      if (do_truncate(file->f_dentry, 0) != 0)
++      if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
+               goto close_fail;
+       retval = binfmt->core_dump(signr, regs, file);
+diff -urN linux-2.4.22/fs/fcntl.c linux-2.4.22-grsec-O1/fs/fcntl.c
+--- linux-2.4.22/fs/fcntl.c    2002-11-29 00:53:15.000000000 +0100
++++ linux-2.4.22-grsec-O1/fs/fcntl.c   2003-10-21 14:24:34.000000000 +0200
+@@ -11,6 +11,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/slab.h>
+ #include <linux/iobuf.h>
++#include <linux/grsecurity.h>
+ #include <asm/poll.h>
+ #include <asm/siginfo.h>
+@@ -64,6 +65,8 @@
+       int error;
+       int start;
++      gr_learn_resource(current, RLIMIT_NOFILE, orig_start);
++
+       write_lock(&files->file_lock);
+       
+       error = -EINVAL;
+@@ -86,6 +89,7 @@
+       }
+       
+       error = -EMFILE;
++      gr_learn_resource(current, RLIMIT_NOFILE, newfd);
+       if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+               goto out;
+@@ -141,6 +145,8 @@
+       struct file * file, *tofree;
+       struct files_struct * files = current->files;
++      gr_learn_resource(current, RLIMIT_NOFILE, newfd);
++
+       write_lock(&files->file_lock);
+       if (!(file = fcheck(oldfd)))
+               goto out_unlock;
+@@ -448,6 +454,10 @@
+                       match = -p->pgrp;
+               if (pid != match)
+                       continue;
++              if (gr_check_protected_task(p))
++                      continue;
++              if (gr_pid_is_chrooted(p))
++                      continue;
+               send_sigio_to_task(p, fown, fd, band);
+       }
+ out:
+diff -urN linux-2.4.22/fs/locks.c linux-2.4.22-grsec-O1/fs/locks.c
+--- linux-2.4.22/fs/locks.c    2003-10-20 18:59:10.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/locks.c   2003-10-21 14:24:34.000000000 +0200
+@@ -138,6 +138,7 @@
+ static struct file_lock *locks_alloc_lock(int account)
+ {
+       struct file_lock *fl;
++      if(account) gr_learn_resource(current, RLIMIT_LOCKS, current->locks);
+       if (account && current->locks >= current->rlim[RLIMIT_LOCKS].rlim_cur)
+               return NULL;
+       fl = kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
+diff -urN linux-2.4.22/fs/namei.c linux-2.4.22-grsec-O1/fs/namei.c
+--- linux-2.4.22/fs/namei.c    2003-10-20 18:59:08.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/namei.c   2003-10-21 14:24:34.000000000 +0200
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/grsecurity.h>
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -343,6 +344,13 @@
+               current->state = TASK_RUNNING;
+               schedule();
+       }
++
++      if (gr_handle_follow_link(dentry->d_parent->d_inode,
++                                dentry->d_inode, dentry, nd->mnt)) {
++              path_release(nd);
++              return -EACCES;
++      }
++
+       current->link_count++;
+       current->total_link_count++;
+       UPDATE_ATIME(dentry->d_inode);
+@@ -643,6 +651,10 @@
+                       }
+               }
+ return_base:
++              if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
++                      path_release(nd);
++                      return -ENOENT;
++              }
+               return 0;
+ out_dput:
+               dput(dentry);
+@@ -1005,7 +1017,7 @@
+       struct dentry *dentry;
+       struct dentry *dir;
+       int count = 0;
+-
++      
+       acc_mode = ACC_MODE(flag);
+       /*
+@@ -1015,7 +1027,19 @@
+               error = path_lookup(pathname, lookup_flags(flag), nd);
+               if (error)
+                       return error;
++
++              if (gr_handle_rawio(nd->dentry->d_inode)) {
++                      error = -EPERM;
++                      goto exit;
++              }
++      
++              if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
++                      error = -EACCES;
++                      goto exit;
++              }
++
+               dentry = nd->dentry;
++
+               goto ok;
+       }
+@@ -1050,7 +1074,16 @@
+       if (!dentry->d_inode) {
+               if (!IS_POSIXACL(dir->d_inode))
+                       mode &= ~current->fs->umask;
++              if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
++                      error = -EACCES;
++                      up(&dir->d_inode->i_sem);
++                      goto exit_dput;
++              }
++
+               error = vfs_create(dir->d_inode, dentry, mode);
++              if (!error)
++                      gr_handle_create(dentry, nd->mnt);
++
+               up(&dir->d_inode->i_sem);
+               dput(nd->dentry);
+               nd->dentry = dentry;
+@@ -1059,12 +1092,35 @@
+               /* Don't check for write permission, don't truncate */
+               acc_mode = 0;
+               flag &= ~O_TRUNC;
++
+               goto ok;
+       }
+       /*
+        * It already exists.
+        */
++
++      if (gr_acl_is_enabled() && S_ISBLK(dentry->d_inode->i_mode) &&
++          !capable(CAP_SYS_RAWIO)) {
++              error = -EPERM;
++              up(&dir->d_inode->i_sem);
++              goto exit_dput;
++      }
++
++      if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
++              error = -EACCES;
++              up(&dir->d_inode->i_sem);
++              goto exit_dput;
++      }
++
++      inode = dentry->d_inode;
++
++      if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
++              up(&dir->d_inode->i_sem);
++              error = -EACCES;
++              goto exit_dput;
++      }
++
+       up(&dir->d_inode->i_sem);
+       error = -EEXIST;
+@@ -1154,7 +1210,7 @@
+               if (!error) {
+                       DQUOT_INIT(inode);
+                       
+-                      error = do_truncate(dentry, 0);
++                      error = do_truncate(dentry,0,nd->mnt);
+               }
+               put_write_access(inode);
+               if (error)
+@@ -1185,6 +1241,13 @@
+        * stored in nd->last.name and we will have to putname() it when we
+        * are done. Procfs-like symlinks just set LAST_BIND.
+        */
++
++      if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
++                                dentry, nd->mnt)) {
++              error = -EACCES;
++              goto exit_dput;
++      }
++
+       UPDATE_ATIME(dentry->d_inode);
+       error = dentry->d_inode->i_op->follow_link(dentry, nd);
+       dput(dentry);
+@@ -1284,6 +1347,18 @@
+       if (!IS_POSIXACL(nd.dentry->d_inode))
+               mode &= ~current->fs->umask;
+       if (!IS_ERR(dentry)) {
++              if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
++                      error = -EPERM;
++                      dput(dentry);
++                      goto out_dput;
++              }
++
++              if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
++                      error = -EACCES;
++                      dput(dentry);
++                      goto out_dput;
++              }
++      
+               switch (mode & S_IFMT) {
+               case 0: case S_IFREG:
+                       error = vfs_create(nd.dentry->d_inode,dentry,mode);
+@@ -1297,8 +1372,13 @@
+               default:
+                       error = -EINVAL;
+               }
++
++              if(!error)
++                      gr_handle_create(dentry, nd.mnt);
++
+               dput(dentry);
+       }
++out_dput:
+       up(&nd.dentry->d_inode->i_sem);
+       path_release(&nd);
+ out:
+@@ -1352,7 +1432,16 @@
+               if (!IS_ERR(dentry)) {
+                       if (!IS_POSIXACL(nd.dentry->d_inode))
+                               mode &= ~current->fs->umask;
+-                      error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
++                      error = 0;
++
++                      if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
++                              error = -EACCES;
++
++                      if(!error)
++                              error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
++                      if(!error)
++                              gr_handle_create(dentry, nd.mnt);
++                      
+                       dput(dentry);
+               }
+               up(&nd.dentry->d_inode->i_sem);
+@@ -1436,6 +1525,8 @@
+       char * name;
+       struct dentry *dentry;
+       struct nameidata nd;
++      ino_t saved_ino = 0;
++      kdev_t saved_dev = 0;
+       name = getname(pathname);
+       if(IS_ERR(name))
+@@ -1460,7 +1551,22 @@
+       dentry = lookup_hash(&nd.last, nd.dentry);
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
+-              error = vfs_rmdir(nd.dentry->d_inode, dentry);
++              error = 0;
++              if (dentry->d_inode) {
++                      if (dentry->d_inode->i_nlink <= 1) {
++                              saved_ino = dentry->d_inode->i_ino;
++                              saved_dev = dentry->d_inode->i_dev;
++                      }
++
++                      if (!gr_acl_handle_rmdir(dentry, nd.mnt))
++                              error = -EACCES;
++              }
++
++              if (!error)
++                      error = vfs_rmdir(nd.dentry->d_inode, dentry);
++              if (!error && (saved_dev || saved_ino))
++                      gr_handle_delete(saved_ino,saved_dev);
++
+               dput(dentry);
+       }
+       up(&nd.dentry->d_inode->i_sem);
+@@ -1505,6 +1611,8 @@
+       char * name;
+       struct dentry *dentry;
+       struct nameidata nd;
++      ino_t saved_ino = 0;
++      kdev_t saved_dev = 0;
+       name = getname(pathname);
+       if(IS_ERR(name))
+@@ -1523,7 +1631,21 @@
+               /* 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);
++              error = 0;
++              if (dentry->d_inode) {
++                      if (dentry->d_inode->i_nlink <= 1) {
++                              saved_ino = dentry->d_inode->i_ino;
++                              saved_dev = dentry->d_inode->i_dev;
++                      }
++
++                      if (!gr_acl_handle_unlink(dentry, nd.mnt))
++                              error = -EACCES;
++              }
++
++              if (!error)
++                      error = vfs_unlink(nd.dentry->d_inode, dentry);
++              if (!error && (saved_ino || saved_dev))
++                      gr_handle_delete(saved_ino,saved_dev);
+       exit2:
+               dput(dentry);
+       }
+@@ -1587,7 +1709,15 @@
+               dentry = lookup_create(&nd, 0);
+               error = PTR_ERR(dentry);
+               if (!IS_ERR(dentry)) {
+-                      error = vfs_symlink(nd.dentry->d_inode, dentry, from);
++                      error = 0;
++
++                      if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
++                              error = -EACCES;
++
++                      if(!error)      
++                              error = vfs_symlink(nd.dentry->d_inode, dentry, from);
++                      if (!error)
++                              gr_handle_create(dentry, nd.mnt);
+                       dput(dentry);
+               }
+               up(&nd.dentry->d_inode->i_sem);
+@@ -1671,7 +1801,27 @@
+               new_dentry = lookup_create(&nd, 0);
+               error = PTR_ERR(new_dentry);
+               if (!IS_ERR(new_dentry)) {
+-                      error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
++                      error = 0;
++
++                      if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
++                                             old_nd.dentry->d_inode,
++                                             old_nd.dentry->d_inode->i_mode, to)) {
++                              error = -EPERM;
++                              goto out_error;
++                      }
++
++                      if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
++                                               old_nd.dentry, old_nd.mnt, to)) {
++                              error = -EACCES;
++                              goto out_error;
++                      }
++
++                      error = vfs_link(old_nd.dentry, 
++                                      nd.dentry->d_inode, new_dentry);
++
++                      if (!error)
++                              gr_handle_create(new_dentry, nd.mnt);
++out_error:
+                       dput(new_dentry);
+               }
+               up(&nd.dentry->d_inode->i_sem);
+@@ -1907,10 +2057,15 @@
+       if (IS_ERR(new_dentry))
+               goto exit4;
+-      lock_kernel();
+-      error = vfs_rename(old_dir->d_inode, old_dentry,
++      error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
++                                   old_dentry, old_dir->d_inode, oldnd.mnt, newname);
++
++      if (error == 1) {
++              lock_kernel();
++              error = vfs_rename(old_dir->d_inode, old_dentry,
+                                  new_dir->d_inode, new_dentry);
+-      unlock_kernel();
++              unlock_kernel();
++      }
+       dput(new_dentry);
+ exit4:
+diff -urN linux-2.4.22/fs/namespace.c linux-2.4.22-grsec-O1/fs/namespace.c
+--- linux-2.4.22/fs/namespace.c        2003-06-13 16:51:37.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/namespace.c       2003-10-21 14:24:34.000000000 +0200
+@@ -15,6 +15,8 @@
+ #include <linux/quotaops.h>
+ #include <linux/acct.h>
+ #include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+@@ -325,6 +327,8 @@
+                       lock_kernel();
+                       retval = do_remount_sb(sb, MS_RDONLY, 0);
+                       unlock_kernel();
++
++                      gr_log_remount(mnt->mnt_devname, retval);
+               }
+               up_write(&sb->s_umount);
+               return retval;
+@@ -350,6 +354,9 @@
+       }
+       spin_unlock(&dcache_lock);
+       up_write(&current->namespace->sem);
++
++      gr_log_unmount(mnt->mnt_devname, retval);
++
+       return retval;
+ }
+@@ -729,6 +736,12 @@
+       if (retval)
+               return retval;
++      if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
++              retval = -EPERM;
++              path_release(&nd);
++              return retval;
++      }
++
+       if (flags & MS_REMOUNT)
+               retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+                                   data_page);
+@@ -740,6 +753,9 @@
+               retval = do_add_mount(&nd, type_page, flags, mnt_flags,
+                                     dev_name, data_page);
+       path_release(&nd);
++
++      gr_log_mount(dev_name, dir_name, retval);
++
+       return retval;
+ }
+@@ -909,6 +925,9 @@
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
++      if (gr_handle_chroot_pivot())
++              return -EPERM;
++
+       lock_kernel();
+       error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
+diff -urN linux-2.4.22/fs/open.c linux-2.4.22-grsec-O1/fs/open.c
+--- linux-2.4.22/fs/open.c     2003-08-25 13:44:43.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/open.c    2003-10-21 14:24:34.000000000 +0200
+@@ -15,6 +15,7 @@
+ #include <linux/slab.h>
+ #include <linux/tty.h>
+ #include <linux/iobuf.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+@@ -95,7 +96,7 @@
+       write_unlock(&files->file_lock);
+ }
+-int do_truncate(struct dentry *dentry, loff_t length)
++int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
+ {
+       struct inode *inode = dentry->d_inode;
+       int error;
+@@ -105,6 +106,9 @@
+       if (length < 0)
+               return -EINVAL;
++      if (!gr_acl_handle_truncate(dentry, mnt))
++              return -EACCES;
++
+       down_write(&inode->i_alloc_sem);
+       down(&inode->i_sem);
+       newattrs.ia_size = length;
+@@ -165,7 +169,7 @@
+       error = locks_verify_truncate(inode, NULL, length);
+       if (!error) {
+               DQUOT_INIT(inode);
+-              error = do_truncate(nd.dentry, length);
++              error = do_truncate(nd.dentry, length, nd.mnt);
+       }
+       put_write_access(inode);
+@@ -217,7 +221,7 @@
+       error = locks_verify_truncate(inode, file, length);
+       if (!error)
+-              error = do_truncate(dentry, length);
++              error = do_truncate(dentry, length, file->f_vfsmnt);
+ out_putf:
+       fput(file);
+ out:
+@@ -286,6 +290,12 @@
+                   (error = permission(inode,MAY_WRITE)) != 0)
+                       goto dput_and_out;
+       }
++
++      if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
++              error = -EACCES;
++              goto dput_and_out;
++      }
++
+       error = notify_change(nd.dentry, &newattrs);
+ dput_and_out:
+       path_release(&nd);
+@@ -331,6 +341,12 @@
+                   (error = permission(inode,MAY_WRITE)) != 0)
+                       goto dput_and_out;
+       }
++
++      if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
++              error = -EACCES;
++              goto dput_and_out;
++      }
++
+       error = notify_change(nd.dentry, &newattrs);
+ dput_and_out:
+       path_release(&nd);
+@@ -373,6 +389,10 @@
+               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+                  && !special_file(nd.dentry->d_inode->i_mode))
+                       res = -EROFS;
++              
++              if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
++                      res =  -EACCES;
++
+               path_release(&nd);
+       }
+@@ -396,6 +416,8 @@
+       if (error)
+               goto dput_and_out;
++      gr_log_chdir(nd.dentry, nd.mnt);
++
+       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
+ dput_and_out:
+@@ -426,6 +448,13 @@
+               goto out_putf;
+       error = permission(inode, MAY_EXEC);
++
++      if (!error && !gr_chroot_fchdir(dentry, mnt))
++              error = -EPERM;
++
++      if (!error)
++              gr_log_chdir(dentry, mnt);
++
+       if (!error)
+               set_fs_pwd(current->fs, mnt, dentry);
+ out_putf:
+@@ -452,8 +481,16 @@
+       if (!capable(CAP_SYS_CHROOT))
+               goto dput_and_out;
++      if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
++              goto dput_and_out;
++
+       set_fs_root(current->fs, nd.mnt, nd.dentry);
+       set_fs_altroot();
++
++      gr_handle_chroot_caps(current);
++
++      gr_handle_chroot_chdir(nd.dentry, nd.mnt);
++
+       error = 0;
+ dput_and_out:
+       path_release(&nd);
+@@ -482,8 +519,20 @@
+       err = -EPERM;
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+               goto out_putf;
++
++      if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
++              err = -EACCES;
++              goto out_putf;
++      }
++
+       if (mode == (mode_t) -1)
+               mode = inode->i_mode;
++
++      if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
++              err = -EPERM;
++              goto out_putf;
++      }           
++
+       newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+       newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+       err = notify_change(dentry, &newattrs);
+@@ -514,8 +563,19 @@
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+               goto dput_and_out;
++      if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
++              error = -EACCES;
++              goto dput_and_out;
++      }
++
+       if (mode == (mode_t) -1)
+               mode = inode->i_mode;
++
++      if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
++              error = -EACCES;
++              goto dput_and_out;
++      }
++
+       newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+       newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+       error = notify_change(nd.dentry, &newattrs);
+@@ -526,7 +586,7 @@
+       return error;
+ }
+-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
+ {
+       struct inode * inode;
+       int error;
+@@ -543,6 +603,12 @@
+       error = -EPERM;
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+               goto out;
++
++      if (!gr_acl_handle_chown(dentry, mnt)) {
++              error = -EACCES;
++              goto out;
++      }
++
+       if (user == (uid_t) -1)
+               user = inode->i_uid;
+       if (group == (gid_t) -1)
+@@ -593,7 +659,7 @@
+       error = user_path_walk(filename, &nd);
+       if (!error) {
+-              error = chown_common(nd.dentry, user, group);
++              error = chown_common(nd.dentry, user, group, nd.mnt);
+               path_release(&nd);
+       }
+       return error;
+@@ -606,7 +672,7 @@
+       error = user_path_walk_link(filename, &nd);
+       if (!error) {
+-              error = chown_common(nd.dentry, user, group);
++              error = chown_common(nd.dentry, user, group, nd.mnt);
+               path_release(&nd);
+       }
+       return error;
+@@ -620,7 +686,8 @@
+       file = fget(fd);
+       if (file) {
+-              error = chown_common(file->f_dentry, user, group);
++              error = chown_common(file->f_dentry, user,
++                              group, file->f_vfsmnt);
+               fput(file);
+       }
+       return error;
+@@ -740,6 +807,7 @@
+        * N.B. For clone tasks sharing a files structure, this test
+        * will limit the total number of files that can be opened.
+        */
++      gr_learn_resource(current, RLIMIT_NOFILE, fd);
+       if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+               goto out;
+diff -urN linux-2.4.22/fs/proc/array.c linux-2.4.22-grsec-O1/fs/proc/array.c
+--- linux-2.4.22/fs/proc/array.c       2003-10-20 18:58:34.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/proc/array.c      2003-10-21 14:24:34.000000000 +0200
+@@ -297,6 +297,12 @@
+       return buffer - orig;
+ }
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
++                      task->flags & PF_PAX_SEGMEXEC || \
++                      task->flags & PF_PAX_RANDEXEC)
++#endif
++
+ int proc_pid_stat(struct task_struct *task, char * buffer)
+ {
+       unsigned long vsize, eip, esp, wchan;
+@@ -334,6 +340,19 @@
+       wchan = get_wchan(task);
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++      if (PAX_RAND_FLAGS) {
++              eip = 0;
++              esp = 0;
++              wchan = 0;
++      }
++#endif
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++      wchan = 0;
++      eip = 0;
++      esp = 0;
++#endif
++
+       collect_sigign_sigcatch(task, &sigign, &sigcatch);
+       /* scale priority and nice values from timeslices to -20..20 */
+@@ -372,9 +391,15 @@
+               vsize,
+               mm ? mm->rss : 0, /* you might want to shift this left 3 */
+               task->rlim[RLIMIT_RSS].rlim_cur,
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++              PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
++              PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
++              PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
++#else
+               mm ? mm->start_code : 0,
+               mm ? mm->end_code : 0,
+               mm ? mm->start_stack : 0,
++#endif
+               esp,
+               eip,
+               /* The signal information here is obsolete.
+@@ -540,7 +565,12 @@
+ #define MAPS_LINE_FORMAT      (sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8)
+ #define MAPS_LINE_MAX (sizeof(void*) == 4 ?  MAPS_LINE_MAX4 :  MAPS_LINE_MAX8)
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map,
++                                 struct task_struct *task)
++#else
+ static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map)
++#endif
+ {
+       /* produce the next line */
+       char *line;
+@@ -575,6 +605,16 @@
+       } else
+               line = buf;
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++      if (task->flags & PF_PAX_RANDMMAP ||
++          task->flags & PF_PAX_SEGMEXEC ||
++          task->flags & PF_PAX_RANDEXEC)
++              len = sprintf(line,
++                            MAPS_LINE_FORMAT,
++                            0UL, 0UL, str, 0UL,
++                            kdevname(dev), ino);
++      else
++#endif
+       len = sprintf(line,
+                     MAPS_LINE_FORMAT,
+                     map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
+@@ -640,7 +680,11 @@
+                       off -= PAGE_SIZE;
+                       goto next;
+               }
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++              len = proc_pid_maps_get_line(tmp, map, task);
++#else
+               len = proc_pid_maps_get_line(tmp, map);
++#endif
+               if (len < 0)
+                       goto out_unlock;
+               len -= off;
+@@ -683,6 +727,16 @@
+       return retval;
+ }
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR    
++int proc_pid_ipaddr(struct task_struct *task, char * buffer)   
++{      
++      int len;         
++
++      len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));  
++      return len;      
++}      
++#endif
++
+ #ifdef CONFIG_SMP
+ int proc_pid_cpu(struct task_struct *task, char * buffer)
+ {
+diff -urN linux-2.4.22/fs/proc/base.c linux-2.4.22-grsec-O1/fs/proc/base.c
+--- linux-2.4.22/fs/proc/base.c        2003-08-25 13:44:43.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/proc/base.c       2003-10-21 14:24:34.000000000 +0200
+@@ -25,6 +25,7 @@
+ #include <linux/string.h>
+ #include <linux/seq_file.h>
+ #include <linux/namespace.h>
++#include <linux/grsecurity.h>
+ /*
+  * For hysterical raisins we keep the same inumbers as in the old procfs.
+@@ -41,6 +42,9 @@
+ int proc_pid_status(struct task_struct*,char*);
+ int proc_pid_statm(struct task_struct*,char*);
+ int proc_pid_cpu(struct task_struct*,char*);
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
++int proc_pid_ipaddr(struct task_struct*,char*);
++#endif
+ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+ {
+@@ -264,9 +268,22 @@
+ static int proc_permission(struct inode *inode, int mask)
+ {
++      int ret;
++      struct task_struct *task;
++
+       if (vfs_permission(inode, mask) != 0)
+               return -EACCES;
+-      return proc_check_root(inode);
++      ret = proc_check_root(inode);
++
++      if (ret)
++              return ret;
++
++      task = inode->u.proc_i.task;
++
++      if (!task)
++              return 0;
++
++      return gr_acl_handle_procpidmem(task);
+ }
+ static ssize_t pid_maps_read(struct file * file, char * buf,
+@@ -576,6 +593,9 @@
+       PROC_PID_STATM,
+       PROC_PID_MAPS,
+       PROC_PID_CPU,
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
++      PROC_PID_IPADDR,
++#endif
+       PROC_PID_MOUNTS,
+       PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
+ };
+@@ -591,6 +611,9 @@
+ #ifdef CONFIG_SMP
+   E(PROC_PID_CPU,     "cpu",          S_IFREG|S_IRUGO),
+ #endif
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
++  E(PROC_PID_IPADDR,  "ipaddr",       S_IFREG|S_IRUSR),
++#endif
+   E(PROC_PID_MAPS,    "maps",         S_IFREG|S_IRUGO),
+   E(PROC_PID_MEM,     "mem",          S_IFREG|S_IRUSR|S_IWUSR),
+   E(PROC_PID_CWD,     "cwd",          S_IFLNK|S_IRWXUGO),
+@@ -747,10 +770,17 @@
+       get_task_struct(task);
+       inode->u.proc_i.task = task;
+       inode->i_uid = 0;
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
++      inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
++#else
+       inode->i_gid = 0;
++#endif
++
+       if (ino == PROC_PID_INO || task_dumpable(task)) {
+               inode->i_uid = task->euid;
++#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
+               inode->i_gid = task->egid;
++#endif
+       }
+ out:
+@@ -958,6 +988,12 @@
+                       inode->u.proc_i.op.proc_read = proc_pid_cpu;
+                       break;
+ #endif
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
++              case PROC_PID_IPADDR:
++                      inode->i_fop = &proc_info_file_operations;
++                      inode->u.proc_i.op.proc_read = proc_pid_ipaddr;
++                      break;
++#endif
+               case PROC_PID_MEM:
+                       inode->i_op = &proc_mem_inode_operations;
+                       inode->i_fop = &proc_mem_operations;
+@@ -1056,13 +1092,34 @@
+       if (!task)
+               goto out;
++      if(gr_check_hidden_task(task)) {
++              free_task_struct(task);
++              goto out;
++      }
++      
++#ifdef CONFIG_GRKERNSEC_PROC
++      if (current->uid && (task->uid != current->uid)
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
++          && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
++#endif
++      ) {
++              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;
+@@ -1102,6 +1159,18 @@
+               int pid = p->pid;
+               if (!pid)
+                       continue;
++              if(gr_pid_is_chrooted(p))
++                      continue;
++              if(gr_check_hidden_task(p)) 
++                      continue;
++#ifdef CONFIG_GRKERNSEC_PROC
++              if (current->uid && (p->uid != current->uid)
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
++                      && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
++#endif
++              )
++                      continue;       
++#endif
+               if (--index >= 0)
+                       continue;
+               pids[nr_pids] = pid;
+diff -urN linux-2.4.22/fs/proc/generic.c linux-2.4.22-grsec-O1/fs/proc/generic.c
+--- linux-2.4.22/fs/proc/generic.c     2003-06-13 16:51:37.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/proc/generic.c    2003-10-21 14:24:34.000000000 +0200
+@@ -503,6 +503,32 @@
+       return ent;
+ }
++#ifdef CONFIG_GRKERNSEC_PROC
++struct proc_dir_entry *proc_priv_mkdir(const char *name, struct proc_dir_entry *parent)
++{
++      struct proc_dir_entry *ent;
++      mode_t mode = 0;
++
++#ifdef CONFIG_GRKERNSEC_PROC_USER
++      mode = S_IFDIR | S_IRUSR | S_IXUSR;
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
++      mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP;
++#endif
++
++      ent = proc_create(&parent, name, mode, 2);
++      if (ent) {
++              ent->proc_fops = &proc_dir_operations;
++              ent->proc_iops = &proc_dir_inode_operations;
++
++              if (proc_register(parent, ent) < 0) {
++                      kfree(ent);
++                      ent = NULL;
++              }
++      }
++      return ent;
++}
++#endif
++
+ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
+                                        struct proc_dir_entry *parent)
+ {
+diff -urN linux-2.4.22/fs/proc/inode.c linux-2.4.22-grsec-O1/fs/proc/inode.c
+--- linux-2.4.22/fs/proc/inode.c       2003-06-13 16:51:37.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/proc/inode.c      2003-10-21 14:24:34.000000000 +0200
+@@ -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-2.4.22/fs/proc/proc_misc.c linux-2.4.22-grsec-O1/fs/proc/proc_misc.c
+--- linux-2.4.22/fs/proc/proc_misc.c   2003-10-20 18:58:34.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/proc/proc_misc.c  2003-10-21 14:24:34.000000000 +0200
+@@ -569,6 +569,7 @@
+ void __init proc_misc_init(void)
+ {
+       struct proc_dir_entry *entry;
++      int gr_mode = 0;
+       static struct {
+               char *name;
+               int (*read_proc)(char*,char**,off_t,int,int*,void*);
+@@ -583,48 +584,81 @@
+ #ifdef CONFIG_STRAM_PROC
+               {"stram",       stram_read_proc},
+ #endif
+-#ifdef CONFIG_MODULES
++#if defined(CONFIG_MODULES) && !defined(CONFIG_GRKERNSEC_PROC)
+               {"modules",     modules_read_proc},
+ #endif
+               {"stat",        kstat_read_proc},
++#ifndef CONFIG_GRKERNSEC_PROC_ADD
+               {"devices",     devices_read_proc},
+-#if !defined(CONFIG_ARCH_S390)
++#endif
++#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
+               {"interrupts",  interrupts_read_proc},
+ #endif
+               {"filesystems", filesystems_read_proc},
++#ifndef CONFIG_GRKERNSEC_PROC_ADD
+               {"dma",         dma_read_proc},
+               {"ioports",     ioports_read_proc},
+               {"cmdline",     cmdline_read_proc},
++#endif
+ #ifdef CONFIG_SGI_DS1286
+               {"rtc",         ds1286_read_proc},
+ #endif
+               {"locks",       locks_read_proc},
+               {"swaps",       swaps_read_proc},
++#ifndef CONFIG_GRKERNSEC_PROC_ADD
+               {"iomem",       memory_read_proc},
++#endif
+               {"execdomains", execdomains_read_proc},
+               {NULL,}
+       };
+       for (p = simple_ones; p->name; p++)
+               create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
++#ifdef CONFIG_GRKERNSEC_PROC_USER
++      gr_mode = S_IRUSR;
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
++      gr_mode = S_IRUSR | S_IRGRP;
++#endif
++
++#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES)
++      create_proc_read_entry("modules", gr_mode, NULL, &modules_read_proc, NULL);
++#endif
++#ifdef CONFIG_GRKERNSEC_PROC_ADD
++      create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
++      create_proc_read_entry("dma", gr_mode, NULL, &dma_read_proc, NULL);
++      create_proc_read_entry("ioports", gr_mode, NULL, &ioports_read_proc, NULL);
++      create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
++      create_proc_read_entry("iomem", gr_mode, NULL, &memory_read_proc, NULL);
++#if !defined(CONFIG_ARCH_S390)
++      create_proc_read_entry("interrupts", gr_mode, NULL, &interrupts_read_proc, NULL);
++#endif
++#endif
++
+       proc_symlink("mounts", NULL, "self/mounts");
+       /* And now for trickier ones */
+       entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
+       if (entry)
+               entry->proc_fops = &proc_kmsg_operations;
++#ifdef CONFIG_GRKERNSEC_PROC_ADD
++      create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
++      create_seq_entry("slabinfo", gr_mode,&proc_slabinfo_operations);
++#else
+       create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
+-      create_seq_entry("partitions", 0, &proc_partitions_operations);
+       create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
++#endif
++      create_seq_entry("partitions", 0, &proc_partitions_operations);
+ #ifdef CONFIG_MODULES
+-      create_seq_entry("ksyms", 0, &proc_ksyms_operations);
++      create_seq_entry("ksyms", gr_mode, &proc_ksyms_operations);
+ #endif
++#ifndef CONFIG_GRKERNSEC_PROC_ADD
+       proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
+       if (proc_root_kcore) {
+               proc_root_kcore->proc_fops = &proc_kcore_operations;
+               proc_root_kcore->size =
+                               (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
+       }
++#endif
+       if (prof_shift) {
+               entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
+               if (entry) {
+diff -urN linux-2.4.22/fs/proc/proc_tty.c linux-2.4.22-grsec-O1/fs/proc/proc_tty.c
+--- linux-2.4.22/fs/proc/proc_tty.c    2003-10-20 18:59:10.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/proc/proc_tty.c   2003-10-21 14:24:34.000000000 +0200
+@@ -174,7 +174,11 @@
+       if (!proc_mkdir("tty", 0))
+               return;
+       proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
++#ifdef CONFIG_GRKERNSEC_PROC
++      proc_tty_driver = proc_priv_mkdir("tty/driver", 0);
++#else
+       proc_tty_driver = proc_mkdir("tty/driver", 0);
++#endif
+       create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
+       create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
+diff -urN linux-2.4.22/fs/proc/root.c linux-2.4.22-grsec-O1/fs/proc/root.c
+--- linux-2.4.22/fs/proc/root.c        2002-08-03 02:39:45.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/proc/root.c       2003-10-21 14:24:34.000000000 +0200
+@@ -37,13 +37,21 @@
+               return;
+       }
+       proc_misc_init();
++#ifdef CONFIG_GRKERNSEC_PROC
++      proc_net = proc_priv_mkdir("net", 0);
++#else
+       proc_net = proc_mkdir("net", 0);
++#endif
+ #ifdef CONFIG_SYSVIPC
+       proc_mkdir("sysvipc", 0);
+ #endif
+ #ifdef CONFIG_SYSCTL
++#ifdef CONFIG_GRKERNSEC_PROC
++      proc_sys_root = proc_priv_mkdir("sys", 0);
++#else
+       proc_sys_root = proc_mkdir("sys", 0);
+ #endif
++#endif
+ #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
+       proc_mkdir("sys/fs", 0);
+       proc_mkdir("sys/fs/binfmt_misc", 0);
+@@ -67,7 +75,12 @@
+ #ifdef CONFIG_PPC_RTAS
+       proc_rtas_init();
+ #endif
++
++#ifdef CONFIG_GRKERNSEC_PROC_ADD
++      proc_bus = proc_priv_mkdir("bus", 0);
++#else
+       proc_bus = proc_mkdir("bus", 0);
++#endif
+ }
+ static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
+diff -urN linux-2.4.22/fs/readdir.c linux-2.4.22-grsec-O1/fs/readdir.c
+--- linux-2.4.22/fs/readdir.c  2002-08-03 02:39:45.000000000 +0200
++++ linux-2.4.22-grsec-O1/fs/readdir.c 2003-10-21 14:24:34.000000000 +0200
+@@ -10,6 +10,7 @@
+ #include <linux/stat.h>
+ #include <linux/file.h>
+ #include <linux/smp_lock.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+@@ -181,6 +182,7 @@
+ struct readdir_callback {
+       struct old_linux_dirent * dirent;
+       int count;
++      struct nameidata nd;
+ };
+ static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
+@@ -191,6 +193,10 @@
+       if (buf->count)
+               return -EINVAL;
++
++      if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
++              return 0;
++          
+       buf->count++;
+       dirent = buf->dirent;
+       put_user(ino, &dirent->d_ino);
+@@ -215,6 +221,9 @@
+       buf.count = 0;
+       buf.dirent = dirent;
++      buf.nd.dentry = file->f_dentry;
++      buf.nd.mnt = file->f_vfsmnt;
++
+       error = vfs_readdir(file, fillonedir, &buf);
+       if (error >= 0)
+               error = buf.count;
+@@ -242,6 +251,7 @@
+       struct linux_dirent * previous;
+       int count;
+       int error;
++      struct nameidata nd;
+ };
+ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
+@@ -254,6 +264,10 @@
+       buf->error = -EINVAL;   /* only used if we fail.. */
+       if (reclen > buf->count)
+               return -EINVAL;
++
++      if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
++              return 0;
++
+       dirent = buf->previous;
+       if (dirent)
+               put_user(offset, &dirent->d_off);
+@@ -286,6 +300,9 @@
+       buf.count = count;
+       buf.error = 0;
++      buf.nd.dentry = file->f_dentry;
++      buf.nd.mnt = file->f_vfsmnt;
++
+       error = vfs_readdir(file, filldir, &buf);
+       if (error < 0)
+               goto out_putf;
+@@ -320,6 +337,7 @@
+       struct linux_dirent64 * previous;
+       int count;
+       int error;
++      struct nameidata nd;
+ };
+ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
+@@ -332,6 +350,10 @@
+       buf->error = -EINVAL;   /* only used if we fail.. */
+       if (reclen > buf->count)
+               return -EINVAL;
++
++      if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
++              return 0;
++      
+       dirent = buf->previous;
+       if (dirent) {
+               d.d_off = offset;
+@@ -369,6 +391,9 @@
+       buf.count = count;
+       buf.error = 0;
++      buf.nd.mnt = file->f_vfsmnt;
++      buf.nd.dentry = file->f_dentry;
++
+       error = vfs_readdir(file, filldir64, &buf);
+       if (error < 0)
+               goto out_putf;
+diff -urN linux-2.4.22/grsecurity/Config.in linux-2.4.22-grsec-O1/grsecurity/Config.in
+--- linux-2.4.22/grsecurity/Config.in  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/Config.in 2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,366 @@
++define_bool CONFIG_CRYPTO y
++define_bool CONFIG_CRYPTO_SHA256 y
++choice 'Security level' \
++        "Low          CONFIG_GRKERNSEC_LOW \
++         Medium               CONFIG_GRKERNSEC_MID \
++         High         CONFIG_GRKERNSEC_HI \
++        Customized    CONFIG_GRKERNSEC_CUSTOM" Customized
++if [ "$CONFIG_GRKERNSEC_LOW" = "y" ]; then
++define_bool CONFIG_GRKERNSEC_RANDSRC n
++define_bool CONFIG_GRKERNSEC_RANDRPC n
++define_bool CONFIG_GRKERNSEC_FORKFAIL n
++define_bool CONFIG_GRKERNSEC_TIME n
++define_bool CONFIG_GRKERNSEC_SIGNAL n
++define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
++define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT n
++define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
++define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE n
++define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT n
++define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD n
++define_bool CONFIG_GRKERNSEC_PROC n
++define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
++define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
++define_bool CONFIG_GRKERNSEC_HIDESYM n
++define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
++define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n
++define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n
++define_bool CONFIG_GRKERNSEC_KMEM n
++define_bool CONFIG_GRKERNSEC_PROC_ADD n
++define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
++define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
++define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
++define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK n
++define_bool CONFIG_GRKERNSEC_PAX_ASLR n
++define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP n
++define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
++define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
++define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
++if [ "$CONFIG_X86" = "y" ]; then
++define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
++define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
++define_bool CONFIG_GRKERNSEC_IO n
++define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
++define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
++fi
++define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
++define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
++define_bool CONFIG_GRKERNSEC_RESLOG n
++define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
++define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
++
++define_int  CONFIG_GRKERNSEC_FLOODTIME 10
++define_int  CONFIG_GRKERNSEC_FLOODBURST 4
++define_bool CONFIG_GRKERNSEC_LINK y
++define_bool CONFIG_GRKERNSEC_FIFO y
++define_bool CONFIG_GRKERNSEC_RANDPID y
++define_bool CONFIG_GRKERNSEC_EXECVE y
++define_bool CONFIG_GRKERNSEC_RANDNET y
++define_bool CONFIG_GRKERNSEC_RANDISN n
++define_bool CONFIG_GRKERNSEC_DMESG y
++define_bool CONFIG_GRKERNSEC_RANDID y
++define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
++fi
++if [ "$CONFIG_GRKERNSEC_MID" = "y" ]; then
++define_bool CONFIG_GRKERNSEC_KMEM n
++define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
++define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n
++define_bool CONFIG_GRKERNSEC_HIDESYM n
++define_bool CONFIG_GRKERNSEC_PROC_ADD n
++define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
++define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
++define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
++define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
++define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
++define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n
++if [ "$CONFIG_X86" = "y" ]; then
++define_bool CONFIG_GRKERNSEC_IO n
++define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
++define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
++fi
++define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
++define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
++define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
++define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
++define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
++define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
++define_bool CONFIG_GRKERNSEC_RESLOG n
++define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
++define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
++
++define_int  CONFIG_GRKERNSEC_FLOODTIME 10
++define_int  CONFIG_GRKERNSEC_FLOODBURST 4
++define_bool CONFIG_GRKERNSEC_LINK y
++define_bool CONFIG_GRKERNSEC_FIFO y
++define_bool CONFIG_GRKERNSEC_RANDPID y
++define_bool CONFIG_GRKERNSEC_EXECVE y
++define_bool CONFIG_GRKERNSEC_DMESG y
++define_bool CONFIG_GRKERNSEC_RANDID y
++define_bool CONFIG_GRKERNSEC_RANDNET y
++define_bool CONFIG_GRKERNSEC_RANDISN y
++define_bool CONFIG_GRKERNSEC_RANDSRC y
++define_bool CONFIG_GRKERNSEC_RANDRPC y
++define_bool CONFIG_GRKERNSEC_FORKFAIL y
++define_bool CONFIG_GRKERNSEC_TIME y
++define_bool CONFIG_GRKERNSEC_SIGNAL y
++define_bool CONFIG_GRKERNSEC_CHROOT y
++define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
++define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
++define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
++define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
++define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
++define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
++define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
++define_bool CONFIG_GRKERNSEC_PROC y
++define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
++define_int  CONFIG_GRKERNSEC_PROC_GID 10
++define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
++define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n
++define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_ASLR y
++define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
++fi
++if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then
++define_int CONFIG_GRKERNSEC_FLOODTIME 10
++define_int  CONFIG_GRKERNSEC_FLOODBURST 4
++define_bool CONFIG_GRKERNSEC_LINK y
++define_bool CONFIG_GRKERNSEC_FIFO y
++define_bool CONFIG_GRKERNSEC_RANDPID y
++define_bool CONFIG_GRKERNSEC_EXECVE y
++define_bool CONFIG_GRKERNSEC_DMESG y
++define_bool CONFIG_GRKERNSEC_RANDID y
++define_bool CONFIG_GRKERNSEC_RANDSRC y
++define_bool CONFIG_GRKERNSEC_RANDRPC y
++define_bool CONFIG_GRKERNSEC_FORKFAIL y
++define_bool CONFIG_GRKERNSEC_TIME y
++define_bool CONFIG_GRKERNSEC_SIGNAL y
++define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT y
++define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
++define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
++define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR y
++define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
++define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
++define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
++define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
++define_bool CONFIG_GRKERNSEC_CHROOT_CAPS y
++define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
++define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK y
++define_bool CONFIG_GRKERNSEC_PROC y
++define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
++define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y
++define_bool CONFIG_GRKERNSEC_HIDESYM y
++define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
++define_int  CONFIG_GRKERNSEC_PROC_GID 10
++define_bool CONFIG_GRKERNSEC_KMEM y
++define_bool CONFIG_GRKERNSEC_RESLOG y
++define_bool CONFIG_GRKERNSEC_RANDNET y
++define_bool CONFIG_GRKERNSEC_RANDISN y
++
++define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
++define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
++define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
++define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
++
++define_bool CONFIG_GRKERNSEC_PROC_ADD y
++define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD y
++define_bool CONFIG_GRKERNSEC_CHROOT_NICE y
++define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y
++define_bool CONFIG_GRKERNSEC_PAX_ASLR y
++define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y
++define_bool CONFIG_GRKERNSEC_PAX_NOEXEC y
++define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n
++define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n
++define_bool CONFIG_GRKERNSEC_PAX_MPROTECT y
++define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n
++if [ "$CONFIG_X86" = "y" ]; then
++define_bool CONFIG_GRKERNSEC_IO n
++if [ "$CONFIG_MODULES" = "n" ]; then
++define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC y
++fi
++define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK y
++define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC y
++define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC y
++define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n
++define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n
++fi
++if [ "$CONFIG_PARISC" = "y" ]; then
++define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP y
++define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT y
++fi
++define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT y
++fi
++if [ "$CONFIG_GRKERNSEC_CUSTOM" = "y" ]; then
++mainmenu_option next_comment
++comment 'Address Space Protection'
++bool 'Enforce non-executable pages' CONFIG_GRKERNSEC_PAX_NOEXEC
++if [ "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
++  bool 'Paging based non-executable pages' CONFIG_GRKERNSEC_PAX_PAGEEXEC
++  if [ "$CONFIG_X86" = "y" ]; then
++    bool 'Segmentation based non-executable pages' CONFIG_GRKERNSEC_PAX_SEGMEXEC
++  fi
++  if [ "$CONFIG_X86" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_PPC32" = "y" ]; then
++    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
++      bool '   Emulate trampolines' CONFIG_GRKERNSEC_PAX_EMUTRAMP
++      if [ "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then
++        bool '    Automatically emulate sigreturn trampolines' CONFIG_GRKERNSEC_PAX_EMUSIGRT
++      fi
++    fi
++  fi
++  bool '   Restrict mprotect()' CONFIG_GRKERNSEC_PAX_MPROTECT
++  if [ "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then
++    if [ "$CONFIG_X86" = "y" ]; then
++      bool '    Disallow ELF text relocations (DANGEROUS)' CONFIG_GRKERNSEC_PAX_NOELFRELOCS
++    else
++    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" ]; then
++      bool '    Allow ELF ET_EXEC text relocations' CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
++    fi
++    if [ "$CONFIG_PPC32" = "y" ]; then
++      define_bool CONFIG_GRKERNSEC_PAX_SYSCALL y
++    fi
++    if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" -o "$CONFIG_PPC32" = "y" ]; then
++      bool '    Automatically emulate ELF PLT' CONFIG_GRKERNSEC_PAX_EMUPLT
++      if [ "$CONFIG_GRKERNSEC_PAX_EMUPLT" = "y" ]; then
++        if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
++        define_bool CONFIG_GRKERNSEC_PAX_DLRESOLVE y
++        fi
++      fi
++    fi
++    fi
++  fi
++fi
++if [ "$CONFIG_X86" = "y" -a "$CONFIG_MODULES" = "n" ]; then
++  bool 'Enforce non-executable kernel pages' CONFIG_GRKERNSEC_PAX_KERNEXEC
++fi
++bool 'Address Space Layout Randomization' CONFIG_GRKERNSEC_PAX_ASLR
++if [ "$CONFIG_GRKERNSEC_PAX_ASLR" = "y" ]; then
++  if [ "$CONFIG_X86_TSC" = "y" ]; then
++    bool '  Randomize kernel stack base' CONFIG_GRKERNSEC_PAX_RANDKSTACK
++  fi
++  bool '  Randomize user stack base' CONFIG_GRKERNSEC_PAX_RANDUSTACK
++  bool '  Randomize mmap() base' CONFIG_GRKERNSEC_PAX_RANDMMAP
++  if [ "$CONFIG_GRKERNSEC_PAX_RANDMMAP" = "y" -a "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then
++    if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then
++      bool '  Randomize ET_EXEC base' CONFIG_GRKERNSEC_PAX_RANDEXEC
++    fi
++  fi
++fi
++bool 'Deny writing to /dev/kmem, /dev/mem, and /dev/port' CONFIG_GRKERNSEC_KMEM
++if [ "$CONFIG_X86" = "y" ]; then
++  bool 'Disable privileged I/O' CONFIG_GRKERNSEC_IO
++  if [ "$CONFIG_GRKERNSEC_IO" = "y" ]; then
++    define_bool CONFIG_RTC y
++  fi
++fi
++bool 'Remove addresses from /proc/pid/[maps|stat]' CONFIG_GRKERNSEC_PROC_MEMMAP
++bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM
++endmenu
++mainmenu_option next_comment
++comment 'Role Based Access Control Options'
++bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN
++int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3
++int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30
++endmenu
++mainmenu_option next_comment
++comment 'Filesystem Protections'
++bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC
++if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then
++ bool '   Restrict to user only' CONFIG_GRKERNSEC_PROC_USER
++ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then
++  bool '   Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP
++  if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
++   int  '   GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001
++  fi
++ fi
++ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "n" -o "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
++  bool '   Additional restrictions' CONFIG_GRKERNSEC_PROC_ADD
++ fi
++fi
++bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK
++bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO
++bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT
++if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then
++bool '   Deny mounts' CONFIG_GRKERNSEC_CHROOT_MOUNT
++bool '   Deny double-chroots' CONFIG_GRKERNSEC_CHROOT_DOUBLE
++bool '   Deny pivot_root in chroot' CONFIG_GRKERNSEC_CHROOT_PIVOT
++bool '   Enforce chdir("/") on all chroots' CONFIG_GRKERNSEC_CHROOT_CHDIR
++bool '   Deny (f)chmod +s' CONFIG_GRKERNSEC_CHROOT_CHMOD
++bool '   Deny fchdir out of chroot' CONFIG_GRKERNSEC_CHROOT_FCHDIR
++bool '   Deny mknod' CONFIG_GRKERNSEC_CHROOT_MKNOD
++bool '   Deny shmat() out of chroot' CONFIG_GRKERNSEC_CHROOT_SHMAT
++bool '   Deny access to abstract AF_UNIX sockets out of chroot' CONFIG_GRKERNSEC_CHROOT_UNIX
++bool '   Protect outside processes' CONFIG_GRKERNSEC_CHROOT_FINDTASK
++bool '   Restrict priority changes' CONFIG_GRKERNSEC_CHROOT_NICE
++bool '   Deny sysctl writes in chroot' CONFIG_GRKERNSEC_CHROOT_SYSCTL
++bool '   Capability restrictions within chroot' CONFIG_GRKERNSEC_CHROOT_CAPS
++fi
++endmenu
++mainmenu_option next_comment
++comment 'Kernel Auditing'
++bool 'Single group for auditing' CONFIG_GRKERNSEC_AUDIT_GROUP
++if [ "$CONFIG_GRKERNSEC_AUDIT_GROUP" != "n" ]; then
++int  '   GID for auditing' CONFIG_GRKERNSEC_AUDIT_GID 1007
++fi
++bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG
++bool 'Resource logging' CONFIG_GRKERNSEC_RESLOG
++bool 'Log execs within chroot' CONFIG_GRKERNSEC_CHROOT_EXECLOG
++bool 'Chdir logging' CONFIG_GRKERNSEC_AUDIT_CHDIR
++bool '(Un)Mount logging' CONFIG_GRKERNSEC_AUDIT_MOUNT
++bool 'IPC logging' CONFIG_GRKERNSEC_AUDIT_IPC
++bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL
++bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL
++bool 'Time change logging' CONFIG_GRKERNSEC_TIME
++bool '/proc/<pid>/ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR
++endmenu
++mainmenu_option next_comment
++comment 'Executable Protections'
++bool 'Enforce RLIMIT_NPROC on execs' CONFIG_GRKERNSEC_EXECVE
++bool 'Dmesg(8) restriction' CONFIG_GRKERNSEC_DMESG
++bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID
++bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE
++if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then
++bool '   Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
++int  '   GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
++fi
++endmenu
++mainmenu_option next_comment
++comment 'Network Protections'
++bool 'Larger entropy pools' CONFIG_GRKERNSEC_RANDNET
++bool 'Truly random TCP ISN selection' CONFIG_GRKERNSEC_RANDISN
++bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID
++bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC
++bool 'Randomized RPC XIDs' CONFIG_GRKERNSEC_RANDRPC
++bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET
++if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then
++bool '  Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL
++if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then
++int  '   GID to deny all sockets for:' CONFIG_GRKERNSEC_SOCKET_ALL_GID 1004
++fi
++bool '  Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT
++if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then
++int  '   GID to deny client sockets for:' CONFIG_GRKERNSEC_SOCKET_CLIENT_GID 1003
++fi
++bool '  Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER
++if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then
++int  '   GID to deny server sockets for:' CONFIG_GRKERNSEC_SOCKET_SERVER_GID 1002
++fi
++fi
++endmenu
++if [ "$CONFIG_SYSCTL" != "n" ]; then
++mainmenu_option next_comment
++comment 'Sysctl support'
++bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL
++endmenu
++fi
++mainmenu_option next_comment
++comment 'Logging options'
++int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10
++int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4
++endmenu
++fi
+diff -urN linux-2.4.22/grsecurity/Makefile linux-2.4.22-grsec-O1/grsecurity/Makefile
+--- linux-2.4.22/grsecurity/Makefile   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/Makefile  2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,24 @@
++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
++# during 2001, 2002, and 2003 it has been completely redesigned by
++# Brad Spengler
++#
++# All code in this directory and various hooks inserted throughout the kernel
++# are copyright Brad Spengler, and released under the GPL, unless otherwise
++# noted (as in obsd_rand.c)
++
++O_TARGET := grsec.o
++
++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
++      grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
++      grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o
++
++ifeq ($(CONFIG_GRKERNSEC),y)
++obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
++      gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
++      gracl_learn.o
++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
++else
++obj-y += grsec_disabled.o
++endif
++
++include $(TOPDIR)/Rules.make
+diff -urN linux-2.4.22/grsecurity/gracl.c linux-2.4.22-grsec-O1/grsecurity/gracl.c
+--- linux-2.4.22/grsecurity/gracl.c    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl.c   2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,2766 @@
++/* 
++ * grsecurity/gracl.c
++ * Copyright Brad Spengler 2001, 2002, 2003
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/proc_fs.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/types.h>
++#include <linux/capability.h>
++#include <linux/sysctl.h>
++#include <linux/gracl.h>
++#include <linux/gralloc.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/mman.h>
++
++static struct acl_role_db acl_role_set;
++static struct acl_role_label *role_list_head;
++static struct name_db name_set;
++static struct name_db inodev_set;
++
++static struct acl_role_label *default_role;
++
++static u16 acl_sp_role_value;
++
++static DECLARE_MUTEX(gr_dev_sem);
++rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
++
++extern char *gr_shared_page[4][NR_CPUS];
++struct gr_arg *gr_usermode;
++
++static unsigned long gr_status = GR_STATUS_INIT;
++
++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
++extern void gr_clear_learn_entries(void);
++
++#ifdef CONFIG_GRKERNSEC_RESLOG
++extern __inline__ void gr_log_resource(const struct task_struct *task,
++                                     const int res,
++                                     const unsigned long wanted);
++#endif
++
++unsigned char *gr_system_salt;
++unsigned char *gr_system_sum;
++
++static struct sprole_pw **acl_special_roles = NULL;
++static __u16 num_sprole_pws = 0;
++
++static struct acl_role_label *kernel_role = NULL;
++
++/* The following are used to keep a place held in the hash table when we move
++   entries around.  They can be replaced during insert. */
++
++static struct acl_subject_label *deleted_subject;
++static struct acl_object_label *deleted_object;
++static struct name_entry *deleted_inodev;
++
++/* for keeping track of the last and final allocated subjects, since
++   nested subject parsing is tricky
++*/
++static struct acl_subject_label *s_last = NULL;
++static struct acl_subject_label *s_final = NULL;
++
++static unsigned int gr_auth_attempts = 0;
++static unsigned long gr_auth_expires = 0UL;
++
++extern int gr_init_uidset(void);
++extern void gr_free_uidset(void);
++extern void gr_remove_uid(uid_t uid);
++extern int gr_find_uid(uid_t uid);
++
++__inline__ int
++gr_acl_is_enabled(void)
++{
++      return (gr_status & GR_READY);
++}
++
++__inline__ int
++gr_acl_tpe_check(void)
++{
++      if (unlikely(!(gr_status & GR_READY)))
++              return 0;
++      if (current->role->roletype & GR_ROLE_TPE)
++              return 1;
++      else
++              return 0;
++}
++
++int
++gr_handle_rawio(const struct inode *inode)
++{
++      if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
++          ((gr_status & GR_READY)
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
++           || (grsec_enable_chroot_caps && proc_is_chrooted(current))
++#endif
++          ))
++              return 1;
++      return 0;
++}
++
++
++static __inline__ int
++gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
++{
++      int i;
++      unsigned long *l1;
++      unsigned long *l2;
++      unsigned char *c1;
++      unsigned char *c2;
++      int num_longs;
++
++      if (likely(lena != lenb))
++              return 0;
++
++      l1 = (unsigned long *)a;
++      l2 = (unsigned long *)b;
++
++      num_longs = lena / sizeof(unsigned long);
++
++      for (i = num_longs; i--; l1++, l2++) {
++              if (unlikely(*l1 != *l2))
++                      return 0;
++      }
++
++      c1 = (unsigned char *) l1;
++      c2 = (unsigned char *) l2;
++
++      i = lena - (num_longs * sizeof(unsigned long)); 
++
++      for (; i--; c1++, c2++) {
++              if (unlikely(*c1 != *c2))
++                      return 0;
++      }
++
++      return 1;
++}
++              
++static __inline__ char *
++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
++          char *buf, int buflen)
++{
++      char *res;
++      struct dentry *our_dentry;
++      struct vfsmount *our_mount;
++      struct vfsmount *rootmnt;
++      struct dentry *root;
++
++      our_dentry = (struct dentry *) dentry;
++      our_mount = (struct vfsmount *) vfsmnt;
++
++      read_lock(&child_reaper->fs->lock);
++      rootmnt = mntget(child_reaper->fs->rootmnt);
++      root = dget(child_reaper->fs->root);
++      read_unlock(&child_reaper->fs->lock);
++
++      spin_lock(&dcache_lock);
++      res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
++      spin_unlock(&dcache_lock);
++      dput(root);
++      mntput(rootmnt);
++      return res;
++}
++
++char *
++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      return d_real_path(dentry, mnt, gr_shared_page[0][smp_processor_id()],
++                         PAGE_SIZE);
++}
++
++char *
++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      return d_real_path(dentry, mnt, gr_shared_page[1][smp_processor_id()],
++                         PAGE_SIZE);
++}
++
++char *
++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      return d_real_path(dentry, mnt, gr_shared_page[2][smp_processor_id()],
++                         PAGE_SIZE);
++}
++
++char *
++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      return d_real_path(dentry, mnt, gr_shared_page[3][smp_processor_id()],
++                         PAGE_SIZE);
++}
++
++__inline__ __u32
++to_gr_audit(const __u32 reqmode)
++{
++      __u32 retmode = 0;
++
++      retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
++      retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
++      retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
++      retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
++      retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
++      retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
++      retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
++      retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
++      retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
++
++      return retmode;
++}
++
++__inline__ struct acl_role_label *
++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
++                    const gid_t gid)
++{
++      unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
++      struct acl_role_label *match;
++      struct role_allowed_ip *ipp;
++      __u8 i = 0;
++
++      match = acl_role_set.r_hash[index];
++
++      while (match
++             && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
++              index = (index + (1 << i)) % acl_role_set.r_size;
++              match = acl_role_set.r_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (!match || match->uidgid != uid || !(match->roletype & GR_ROLE_USER)) {
++            try_group:
++              index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
++              match = acl_role_set.r_hash[index];
++              i = 0;
++
++              while (match
++                     && (match->uidgid != gid
++                         || !(match->roletype & GR_ROLE_GROUP))) {
++                      index = (index + (1 << i)) % acl_role_set.r_size;
++                      match = acl_role_set.r_hash[index];
++                      i = (i + 1) % 32;
++              }
++
++              if (!match || match->uidgid != gid
++                  || !(match->roletype & GR_ROLE_GROUP))
++                      match = default_role;
++              else if (likely(!match->allowed_ips)) {
++                      return match;
++              } else {
++                      for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
++                              if (likely
++                                  ((task->curr_ip & ipp->netmask) ==
++                                   (ipp->addr & ipp->netmask)))
++                                      return match;
++                      }
++                      match = default_role;
++              }
++      } else if (likely(!match->allowed_ips)) {
++              return match;
++      } else {
++              for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
++                      if (likely
++                          ((task->curr_ip & ipp->netmask) ==
++                           (ipp->addr & ipp->netmask)))
++                              return match;
++              }
++              goto try_group;
++      }
++
++      return match;
++}
++
++__inline__ struct acl_subject_label *
++lookup_acl_subj_label(const ino_t ino, const kdev_t dev,
++                    const struct acl_role_label *role)
++{
++      unsigned long subj_size = role->subj_hash_size;
++      struct acl_subject_label **s_hash = role->subj_hash;
++      unsigned long index = fhash(ino, dev, subj_size);
++      struct acl_subject_label *match;
++      __u8 i = 0;
++
++      match = s_hash[index];
++
++      while (match && (match->inode != ino || match->device != dev ||
++             (match->mode & GR_DELETED))) {
++              index = (index + (1 << i)) % subj_size;
++              match = s_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (unlikely(match && (match != deleted_subject) &&
++                   (match->inode == ino) && (match->device == dev) &&
++                   !(match->mode & GR_DELETED)))
++              return match;
++      else
++              return NULL;
++}
++
++static __inline__ struct acl_object_label *
++lookup_acl_obj_label(const ino_t ino, const kdev_t dev,
++                   const struct acl_subject_label *subj)
++{
++      unsigned long obj_size = subj->obj_hash_size;
++      struct acl_object_label **o_hash = subj->obj_hash;
++      unsigned long index = fhash(ino, dev, obj_size);
++      struct acl_object_label *match;
++      __u8 i = 0;
++
++      match = o_hash[index];
++
++      while (match && (match->inode != ino || match->device != dev ||
++             (match->mode & GR_DELETED))) {
++              index = (index + (1 << i)) % obj_size;
++              match = o_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (unlikely(match && (match != deleted_object) &&
++                   (match->inode == ino) && (match->device == dev) &&
++                   !(match->mode & GR_DELETED)))
++              return match;
++      else
++              return NULL;
++}
++
++static __inline__ struct acl_object_label *
++lookup_acl_obj_label_create(const ino_t ino, const kdev_t dev,
++                   const struct acl_subject_label *subj)
++{
++      unsigned long obj_size = subj->obj_hash_size;
++      struct acl_object_label **o_hash = subj->obj_hash;
++      unsigned long index = fhash(ino, dev, obj_size);
++      struct acl_object_label *match;
++      __u8 i = 0;
++
++      match = o_hash[index];
++
++      while (match && (match->inode != ino || match->device != dev ||
++             !(match->mode & GR_DELETED))) {
++              index = (index + (1 << i)) % obj_size;
++              match = o_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (unlikely(match && (match != deleted_object) &&
++                   (match->inode == ino) && (match->device == dev) &&
++                   (match->mode & GR_DELETED)))
++              return match;
++
++      i = 0;
++      index = fhash(ino, dev, obj_size);
++      match = o_hash[index];
++
++      while (match && (match->inode != ino || match->device != dev ||
++             (match->mode & GR_DELETED))) {
++              index = (index + (1 << i)) % obj_size;
++              match = o_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (unlikely(match && (match != deleted_object) &&
++                   (match->inode == ino) && (match->device == dev) &&
++                   !(match->mode & GR_DELETED)))
++              return match;
++      else
++              return NULL;
++}
++
++static __inline__ struct name_entry *
++lookup_name_entry(const char *name)
++{
++      __u16 len = strlen(name);
++      unsigned long index = nhash(name, len, name_set.n_size);
++      struct name_entry *match;
++      __u8 i = 0;
++
++      match = name_set.n_hash[index];
++
++      while (match && !gr_streq(match->name, name, match->len, len)) {
++              index = (index + (1 << i)) % name_set.n_size;
++              match = name_set.n_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (unlikely(!match || !gr_streq(match->name, name, match->len, len)))
++              return NULL;
++      else
++              return match;
++}
++
++static __inline__ struct name_entry *
++lookup_inodev_entry(const ino_t ino, const kdev_t dev)
++{
++      unsigned long index = fhash(ino, dev, inodev_set.n_size);
++      struct name_entry *match;
++      __u8 i = 0;
++
++      match = inodev_set.n_hash[index];
++
++      while (match && (match->inode != ino || match->device != dev)) {
++              index = (index + (1 << i)) % inodev_set.n_size;
++              match = inodev_set.n_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (unlikely(match && (match != deleted_inodev) &&
++                   (match->inode == ino) && (match->device == dev)))
++              return match;
++      else
++              return NULL;
++}
++
++static void
++insert_inodev_entry(struct name_entry *nentry)
++{
++      unsigned long index = fhash(nentry->inode, nentry->device,
++                                  inodev_set.n_size);
++      struct name_entry **curr;
++      __u8 i = 0;
++
++      curr = &inodev_set.n_hash[index];
++
++      while (*curr && *curr != deleted_inodev) {
++              index = (index + (1 << i)) % inodev_set.n_size;
++              curr = &inodev_set.n_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      *curr = nentry;
++
++      return;
++}
++
++static void
++insert_acl_role_label(struct acl_role_label *role)
++{
++      unsigned long index =
++          rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
++      struct acl_role_label **curr;
++      __u8 i = 0;
++
++      curr = &acl_role_set.r_hash[index];
++
++      while (*curr) {
++              index = (index + (1 << i)) % acl_role_set.r_size;
++              curr = &acl_role_set.r_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      *curr = role;
++
++      return;
++}
++
++static int
++insert_name_entry(char *name, const ino_t inode, const kdev_t device)
++{
++      struct name_entry **curr;
++      __u8 i = 0;
++      __u16 len = strlen(name);
++      unsigned long index = nhash(name, len, name_set.n_size);
++
++      curr = &name_set.n_hash[index];
++
++      while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
++              index = (index + (1 << i)) % name_set.n_size;
++              curr = &name_set.n_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (!(*curr)) {
++              struct name_entry *nentry =
++                  acl_alloc(sizeof (struct name_entry));
++              if (!nentry)
++                      return 0;
++              nentry->name = name;
++              nentry->inode = inode;
++              nentry->device = device;
++              nentry->len = len;
++              *curr = nentry;
++              /* insert us into the table searchable by inode/dev */
++              insert_inodev_entry(nentry);
++      }
++
++      return 1;
++}
++
++static void
++insert_acl_obj_label(struct acl_object_label *obj,
++                   struct acl_subject_label *subj)
++{
++      unsigned long index =
++          fhash(obj->inode, obj->device, subj->obj_hash_size);
++      struct acl_object_label **curr;
++      __u8 i = 0;
++
++      curr = &subj->obj_hash[index];
++
++      while (*curr && *curr != deleted_object) {
++              index = (index + (1 << i)) % subj->obj_hash_size;
++              curr = &subj->obj_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      *curr = obj;
++
++      return;
++}
++
++static void
++insert_acl_subj_label(struct acl_subject_label *obj,
++                    struct acl_role_label *role)
++{
++      unsigned long subj_size = role->subj_hash_size;
++      struct acl_subject_label **s_hash = role->subj_hash;
++      unsigned long index = fhash(obj->inode, obj->device, subj_size);
++      struct acl_subject_label **curr;
++      __u8 i = 0;
++
++      curr = &s_hash[index];
++
++      while (*curr && *curr != deleted_subject) {
++              index = (index + (1 << i)) % subj_size;
++              curr = &s_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      *curr = obj;
++
++      return;
++}
++
++static void **
++create_table(__u32 * len)
++{
++      unsigned long table_sizes[] = {
++              7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
++              32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
++              4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
++              268435399, 536870909, 1073741789, 2147483647
++      };
++      void *newtable = NULL;
++      unsigned int pwr = 0;
++
++      while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
++             table_sizes[pwr] <= (2 * (*len)))
++              pwr++;
++
++      if (table_sizes[pwr] <= (2 * (*len)))
++              return newtable;
++
++      if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
++              newtable =
++                  kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
++      else
++              newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
++
++      *len = table_sizes[pwr];
++
++      return newtable;
++}
++
++static int
++init_variables(const unsigned long acl_obj_size,
++             const unsigned long acl_subj_size,
++             const unsigned long acl_ip_size,
++             const unsigned long acl_role_size,
++             const unsigned long allowed_ip_size,
++             const unsigned long acl_trans_size,
++             const __u16 num_sprole_pws)
++{
++      unsigned long stacksize;
++
++      acl_role_set.r_size = acl_role_size;
++      name_set.n_size = (acl_obj_size + acl_subj_size);
++      inodev_set.n_size = (acl_obj_size + acl_subj_size);
++
++      if (!gr_init_uidset())
++              return 1;
++
++      /* set up the stack that holds allocation info */
++
++      stacksize = (3 * acl_obj_size) + (2 * acl_role_size) +
++          (4 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
++          allowed_ip_size + (2 * num_sprole_pws) + 5;
++
++      if (!acl_alloc_stack_init(stacksize))
++              return 1;
++
++      /* create our empty, fake deleted acls */
++      deleted_subject =
++          (struct acl_subject_label *)
++          acl_alloc(sizeof (struct acl_subject_label));
++      deleted_object =
++          (struct acl_object_label *)
++          acl_alloc(sizeof (struct acl_object_label));
++      deleted_inodev =
++          (struct name_entry *) acl_alloc(sizeof (struct name_entry));
++
++      if (!deleted_subject || !deleted_object || !deleted_inodev)
++              return 1;
++
++      memset(deleted_subject, 0, sizeof (struct acl_subject_label));
++      memset(deleted_object, 0, sizeof (struct acl_object_label));
++      memset(deleted_inodev, 0, sizeof (struct name_entry));
++
++      /* We only want 50% full tables for now */
++
++      acl_role_set.r_hash =
++          (struct acl_role_label **) create_table(&acl_role_set.r_size);
++      name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
++      inodev_set.n_hash =
++          (struct name_entry **) create_table(&inodev_set.n_size);
++
++      if (!acl_role_set.r_hash || !name_set.n_hash || !inodev_set.n_hash)
++              return 1;
++      memset(acl_role_set.r_hash, 0,
++             sizeof (struct acl_role_label *) * acl_role_set.r_size);
++      memset(name_set.n_hash, 0,
++             sizeof (struct name_entry *) * name_set.n_size);
++      memset(inodev_set.n_hash, 0,
++             sizeof (struct name_entry *) * inodev_set.n_size);
++
++      return 0;
++}
++
++static void
++free_variables(void)
++{
++      struct acl_subject_label *s;
++      struct acl_role_label *r;
++      struct task_struct *task;
++
++      gr_clear_learn_entries();
++
++      read_lock(&tasklist_lock);
++      for_each_task(task) {
++              task->acl_sp_role = 0;
++              task->acl_role_id = 0;
++              task->acl = NULL;
++              task->role = NULL;
++      }
++      read_unlock(&tasklist_lock);
++
++      /* free all object hash tables */
++
++      if (role_list_head) {
++              for (r = role_list_head; r; r = r->next) {
++                      if (!r->subj_hash)
++                              break;
++                      for (s = r->proc_subject; s; s = s->next) {
++                              if (!s->obj_hash)
++                                      break;
++                              if ((s->obj_hash_size *
++                                   sizeof (struct acl_object_label *)) <=
++                                  PAGE_SIZE)
++                                      kfree(s->obj_hash);
++                              else
++                                      vfree(s->obj_hash);
++                      }
++                      if ((r->subj_hash_size *
++                           sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
++                              kfree(r->subj_hash);
++                      else
++                              vfree(r->subj_hash);
++              }
++      }
++
++      acl_free_all();
++
++      if (acl_role_set.r_hash) {
++              if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
++                  PAGE_SIZE)
++                      kfree(acl_role_set.r_hash);
++              else
++                      vfree(acl_role_set.r_hash);
++      }
++      if (name_set.n_hash) {
++              if ((name_set.n_size * sizeof (struct name_entry *)) <=
++                  PAGE_SIZE)
++                      kfree(name_set.n_hash);
++              else
++                      vfree(name_set.n_hash);
++      }
++
++      if (inodev_set.n_hash) {
++              if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
++                  PAGE_SIZE)
++                      kfree(inodev_set.n_hash);
++              else
++                      vfree(inodev_set.n_hash);
++      }
++
++      gr_free_uidset();
++
++      memset(&name_set, 0, sizeof (struct name_db));
++      memset(&inodev_set, 0, sizeof (struct name_db));
++      memset(&acl_role_set, 0, sizeof (struct acl_role_db));
++
++      role_list_head = NULL;
++      default_role = NULL;
++
++      return;
++}
++
++static __u32
++count_user_objs(struct acl_object_label *userp)
++{
++      struct acl_object_label o_tmp;
++      __u32 num = 0;
++
++      while (userp) {
++              if (copy_from_user(&o_tmp, userp,
++                                 sizeof (struct acl_object_label)))
++                      break;
++
++              userp = o_tmp.prev;
++              num++;
++      }
++
++      return num;
++}
++
++static struct acl_subject_label *
++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
++
++static int
++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
++             struct acl_role_label *role)
++{
++      struct acl_object_label *o_tmp;
++      unsigned int len;
++      char *tmp;
++
++      while (userp) {
++              if ((o_tmp = (struct acl_object_label *)
++                   acl_alloc(sizeof (struct acl_object_label))) == NULL)
++                      return -ENOMEM;
++
++              if (copy_from_user(o_tmp, userp,
++                                 sizeof (struct acl_object_label)))
++                      return -EFAULT;
++
++              userp = o_tmp->prev;
++
++              len = strnlen_user(o_tmp->filename, PATH_MAX);
++
++              if (!len || len >= PATH_MAX)
++                      return -EINVAL;
++
++              if ((tmp = (char *) acl_alloc(len)) == NULL)
++                      return -ENOMEM;
++
++              if (copy_from_user(tmp, o_tmp->filename, len))
++                      return -EFAULT;
++
++              o_tmp->filename = tmp;
++
++              insert_acl_obj_label(o_tmp, subj);
++              if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
++                                     o_tmp->device))
++                      return -ENOMEM;
++
++              if (o_tmp->nested) {
++                      o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
++                      if (IS_ERR(o_tmp->nested))
++                              return PTR_ERR(o_tmp->nested);
++
++                      s_final = o_tmp->nested;
++              }
++      }
++
++      return 0;
++}
++
++static __u32
++count_user_subjs(struct acl_subject_label *userp)
++{
++      struct acl_subject_label s_tmp;
++      __u32 num = 0;
++
++      while (userp) {
++              if (copy_from_user(&s_tmp, userp,
++                                 sizeof (struct acl_subject_label)))
++                      break;
++
++              userp = s_tmp.prev;
++              /* do not count nested subjects against this count, since
++                 they are not included in the hash table, but are
++                 attached to objects.  We have already counted
++                 the subjects in userspace for the allocation 
++                 stack
++              */
++              if (!s_tmp.parent_subject)
++                      num++;
++      }
++
++      return num;
++}
++
++static int
++copy_user_allowedips(struct acl_role_label *rolep)
++{
++      struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
++
++      ruserip = rolep->allowed_ips;
++
++      while (ruserip) {
++              rlast = rtmp;
++
++              if ((rtmp = (struct role_allowed_ip *)
++                   acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
++                      return -ENOMEM;
++
++              if (copy_from_user(rtmp, ruserip,
++                                 sizeof (struct role_allowed_ip)))
++                      return -EFAULT;
++
++              ruserip = rtmp->prev;
++
++              if (!rlast) {
++                      rtmp->prev = NULL;
++                      rolep->allowed_ips = rtmp;
++              } else {
++                      rlast->next = rtmp;
++                      rtmp->prev = rlast;
++              }
++
++              if (!ruserip)
++                      rtmp->next = NULL;
++      }
++
++      return 0;
++}
++
++static int
++copy_user_transitions(struct acl_role_label *rolep)
++{
++      struct role_transition *rusertp, *rtmp = NULL, *rlast;
++      unsigned int len;
++      char *tmp;
++
++      rusertp = rolep->transitions;
++
++      while (rusertp) {
++              rlast = rtmp;
++
++              if ((rtmp = (struct role_transition *)
++                   acl_alloc(sizeof (struct role_transition))) == NULL)
++                      return -ENOMEM;
++
++              if (copy_from_user(rtmp, rusertp,
++                                 sizeof (struct role_transition)))
++                      return -EFAULT;
++
++              rusertp = rtmp->prev;
++
++              len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
++
++              if (!len || len >= GR_SPROLE_LEN)
++                      return -EINVAL;
++
++              if ((tmp = (char *) acl_alloc(len)) == NULL)
++                      return -ENOMEM;
++
++              if (copy_from_user(tmp, rtmp->rolename, len))
++                      return -EFAULT;
++
++              rtmp->rolename = tmp;
++
++              if (!rlast) {
++                      rtmp->prev = NULL;
++                      rolep->transitions = rtmp;
++              } else {
++                      rlast->next = rtmp;
++                      rtmp->prev = rlast;
++              }
++
++              if (!rusertp)
++                      rtmp->next = NULL;
++      }
++
++      return 0;
++}
++
++static struct acl_subject_label *
++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
++{
++      struct acl_subject_label *s_tmp = NULL;
++      unsigned int len;
++      char *tmp;
++      __u32 num_objs;
++      struct acl_ip_label **i_tmp, *i_utmp2;
++      unsigned long i_num;
++      int err;
++
++
++      if ((s_tmp = (struct acl_subject_label *)
++          acl_alloc(sizeof (struct acl_subject_label))) == NULL)
++              return ERR_PTR(-ENOMEM);
++
++      if (copy_from_user(s_tmp, userp,
++                         sizeof (struct acl_subject_label)))
++              return ERR_PTR(-EFAULT);
++
++      if (!s_last) {
++              s_tmp->prev = NULL;
++              role->proc_subject = s_tmp;
++      } else {
++              s_last->next = s_tmp;
++              s_tmp->prev = s_last;
++      }
++
++      s_last = s_tmp;
++
++      len = strnlen_user(s_tmp->filename, PATH_MAX);
++
++      if (!len || len >= PATH_MAX)
++              return ERR_PTR(-EINVAL);
++
++      if ((tmp = (char *) acl_alloc(len)) == NULL)
++              return ERR_PTR(-ENOMEM);
++
++      if (copy_from_user(tmp, s_tmp->filename, len))
++              return ERR_PTR(-EFAULT);
++
++      s_tmp->filename = tmp;
++
++      if (!strcmp(s_tmp->filename, "/"))
++              role->root_label = s_tmp;
++
++      /* set up object hash table */
++      num_objs = count_user_objs(s_tmp->proc_object);
++
++      s_tmp->obj_hash_size = num_objs;
++      s_tmp->obj_hash =
++          (struct acl_object_label **)
++          create_table(&(s_tmp->obj_hash_size));
++
++      if (!s_tmp->obj_hash)
++              return ERR_PTR(-ENOMEM);
++
++      memset(s_tmp->obj_hash, 0,
++             s_tmp->obj_hash_size *
++             sizeof (struct acl_object_label *));
++
++      /* copy before adding in objects, since a nested
++         acl could be found and be the final subject
++         copied
++      */
++
++      s_final = s_tmp;
++
++      /* add in objects */
++      err = copy_user_objs(s_tmp->proc_object, s_tmp, role);
++
++      if (err)
++              return ERR_PTR(err);
++
++      /* add in ip acls */
++
++      if (!s_tmp->ip_num) {
++              s_tmp->ips = NULL;
++              goto insert;
++      }
++
++      i_tmp =
++          (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
++                                             sizeof (struct
++                                                     acl_ip_label *));
++
++      if (!i_tmp)
++              return ERR_PTR(-ENOMEM);
++
++      for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
++              *(i_tmp + i_num) =
++                  (struct acl_ip_label *)
++                  acl_alloc(sizeof (struct acl_ip_label));
++              if (!*(i_tmp + i_num))
++                      return ERR_PTR(-ENOMEM);
++
++              if (copy_from_user
++                  (&i_utmp2, s_tmp->ips + i_num,
++                   sizeof (struct acl_ip_label *)))
++                      return ERR_PTR(-EFAULT);
++
++              if (copy_from_user
++                  (*(i_tmp + i_num), i_utmp2,
++                   sizeof (struct acl_ip_label)))
++                      return ERR_PTR(-EFAULT);
++      }
++
++      s_tmp->ips = i_tmp;
++
++insert:
++      if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
++                             s_tmp->device))
++              return ERR_PTR(-ENOMEM);
++
++      return s_tmp;
++}
++
++static int
++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
++{
++      struct acl_subject_label s_pre;
++      struct acl_subject_label * ret;
++      int err;
++
++      while (userp) {
++              if (copy_from_user(&s_pre, userp,
++                                 sizeof (struct acl_subject_label)))
++                      return -EFAULT;
++              
++              /* do not add nested subjects here, add
++                 while parsing objects
++              */
++
++              if (s_pre.parent_subject) {
++                      userp = s_pre.prev;
++                      continue;
++              }
++
++              ret = do_copy_user_subj(userp, role);
++
++              err = PTR_ERR(ret);
++              if (IS_ERR(ret))
++                      return err;
++
++              insert_acl_subj_label(ret, role);
++
++              userp = s_pre.prev;
++      }
++
++      s_final->next = NULL;
++
++      return 0;
++}
++
++static int
++copy_user_acl(struct gr_arg *arg)
++{
++      struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
++      struct sprole_pw *sptmp;
++      unsigned long r_num;
++      unsigned int len;
++      char *tmp;
++      int err = 0;
++      __u16 i;
++      __u32 num_subjs;
++
++      /* we need a default and kernel role */
++      if (arg->role_db.r_entries < 2)
++              return -EINVAL;
++
++      /* copy special role authentication info from userspace */
++
++      num_sprole_pws = arg->num_sprole_pws;
++      acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
++
++      if (!acl_special_roles) {
++              err = -ENOMEM;
++              goto cleanup;
++      }
++
++      for (i = 0; i < num_sprole_pws; i++) {
++              sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
++              if (!sptmp) {
++                      err = -ENOMEM;
++                      goto cleanup;
++              }
++              if (copy_from_user(sptmp, arg->sprole_pws + i,
++                                 sizeof (struct sprole_pw))) {
++                      err = -EFAULT;
++                      goto cleanup;
++              }
++
++              len =
++                  strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
++
++              if (!len || len >= GR_SPROLE_LEN) {
++                      err = -EINVAL;
++                      goto cleanup;
++              }
++
++              if ((tmp = (char *) acl_alloc(len)) == NULL) {
++                      err = -ENOMEM;
++                      goto cleanup;
++              }
++
++              if (copy_from_user(tmp, sptmp->rolename, len)) {
++                      err = -EFAULT;
++                      goto cleanup;
++              }
++
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
++              printk(KERN_ALERT "Copying special role %s\n", tmp);
++#endif
++              sptmp->rolename = tmp;
++              acl_special_roles[i] = sptmp;
++      }
++
++      r_utmp = (struct acl_role_label **) arg->role_db.r_table;
++
++      for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
++              r_last = r_tmp;
++
++              r_tmp = acl_alloc(sizeof (struct acl_role_label));
++
++              if (!r_tmp) {
++                      err = -ENOMEM;
++                      goto cleanup;
++              }
++
++              if (copy_from_user(&r_utmp2, r_utmp + r_num,
++                                 sizeof (struct acl_role_label *))) {
++                      err = -EFAULT;
++                      goto cleanup;
++              }
++
++              if (copy_from_user(r_tmp, r_utmp2,
++                                 sizeof (struct acl_role_label))) {
++                      err = -EFAULT;
++                      goto cleanup;
++              }
++
++              if (!r_last) {
++                      r_tmp->prev = NULL;
++                      role_list_head = r_tmp;
++              } else {
++                      r_last->next = r_tmp;
++                      r_tmp->prev = r_last;
++              }
++
++              if (r_num == (arg->role_db.r_entries - 1))
++                      r_tmp->next = NULL;
++
++              len = strnlen_user(r_tmp->rolename, PATH_MAX);
++
++              if (!len || len >= PATH_MAX) {
++                      err = -EINVAL;
++                      goto cleanup;
++              }
++
++              if ((tmp = (char *) acl_alloc(len)) == NULL) {
++                      err = -ENOMEM;
++                      goto cleanup;
++              }
++              if (copy_from_user(tmp, r_tmp->rolename, len)) {
++                      err = -EFAULT;
++                      goto cleanup;
++              }
++              r_tmp->rolename = tmp;
++
++              if (!strcmp(r_tmp->rolename, "default")
++                  && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
++                      default_role = r_tmp;
++              } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
++                      kernel_role = r_tmp;
++              }
++
++              num_subjs = count_user_subjs(r_tmp->proc_subject);
++
++              r_tmp->subj_hash_size = num_subjs;
++              r_tmp->subj_hash =
++                  (struct acl_subject_label **)
++                  create_table(&(r_tmp->subj_hash_size));
++
++              if (!r_tmp->subj_hash) {
++                      err = -ENOMEM;
++                      goto cleanup;
++              }
++
++              err = copy_user_allowedips(r_tmp);
++              if (err)
++                      goto cleanup;
++
++              err = copy_user_transitions(r_tmp);
++              if (err)
++                      goto cleanup;
++
++              memset(r_tmp->subj_hash, 0,
++                     r_tmp->subj_hash_size *
++                     sizeof (struct acl_subject_label *));
++
++              s_last = NULL;
++
++              err = copy_user_subjs(r_tmp->proc_subject, r_tmp);
++
++              if (err)
++                      goto cleanup;
++
++              insert_acl_role_label(r_tmp);
++      }
++
++      goto return_err;
++      cleanup:
++      free_variables();
++      return_err:
++      return err;
++
++}
++
++static int
++gracl_init(struct gr_arg *args)
++{
++      int error = 0;
++
++      memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
++      memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
++
++      if (init_variables(args->role_db.o_entries, args->role_db.s_entries,
++                         args->role_db.i_entries, args->role_db.r_entries,
++                         args->role_db.a_entries, args->role_db.t_entries,
++                         args->num_sprole_pws)) {
++              security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
++              error = -ENOMEM;
++              free_variables();
++              goto out;
++      }
++
++      error = copy_user_acl(args);
++      if (error)
++              goto out;
++
++      if ((error = gr_set_acls(0))) {
++              free_variables();
++              goto out;
++      }
++
++      gr_status |= GR_READY;
++      out:
++      return error;
++}
++
++static struct acl_object_label *
++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
++            const struct acl_subject_label *subj)
++{
++      struct dentry *dentry = (struct dentry *) l_dentry;
++      struct vfsmount *mnt = (struct vfsmount *) l_mnt;
++      struct dentry *root;
++      struct vfsmount *rootmnt;
++      struct acl_object_label *retval;
++
++      read_lock(&child_reaper->fs->lock);
++      rootmnt = mntget(child_reaper->fs->rootmnt);
++      root = dget(child_reaper->fs->root);
++      read_unlock(&child_reaper->fs->lock);
++      spin_lock(&dcache_lock);
++
++      for (;;) {
++              if (unlikely(dentry == root && mnt == rootmnt))
++                      break;
++              if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
++                      if (mnt->mnt_parent == mnt)
++                              break;
++
++                      read_lock(&gr_inode_lock);
++                      retval =
++                          lookup_acl_obj_label(dentry->d_inode->i_ino,
++                                               dentry->d_inode->i_dev, subj);
++                      read_unlock(&gr_inode_lock);
++                      if (unlikely(retval != NULL))
++                              goto out;
++
++                      dentry = mnt->mnt_mountpoint;
++                      mnt = mnt->mnt_parent;
++                      continue;
++              }
++
++              read_lock(&gr_inode_lock);
++              retval =
++                  lookup_acl_obj_label(dentry->d_inode->i_ino,
++                                       dentry->d_inode->i_dev, subj);
++              read_unlock(&gr_inode_lock);
++              if (unlikely(retval != NULL))
++                      goto out;
++
++              dentry = dentry->d_parent;
++      }
++
++      read_lock(&gr_inode_lock);
++      retval =
++          lookup_acl_obj_label(dentry->d_inode->i_ino, dentry->d_inode->i_dev,
++                               subj);
++      read_unlock(&gr_inode_lock);
++
++      if (unlikely(retval == NULL)) {
++              read_lock(&gr_inode_lock);
++              retval =
++                  lookup_acl_obj_label(root->d_inode->i_ino,
++                                       root->d_inode->i_dev, subj);
++              read_unlock(&gr_inode_lock);
++      }
++      out:
++      spin_unlock(&dcache_lock);
++      dput(root);
++      mntput(rootmnt);
++
++      return retval;
++}
++
++static struct acl_subject_label *
++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
++             const struct acl_role_label *role)
++{
++      struct dentry *dentry = (struct dentry *) l_dentry;
++      struct vfsmount *mnt = (struct vfsmount *) l_mnt;
++      struct dentry *root;
++      struct vfsmount *rootmnt;
++      struct acl_subject_label *retval;
++
++      read_lock(&child_reaper->fs->lock);
++      rootmnt = mntget(child_reaper->fs->rootmnt);
++      root = dget(child_reaper->fs->root);
++      read_unlock(&child_reaper->fs->lock);
++      spin_lock(&dcache_lock);
++
++      for (;;) {
++              if (unlikely(dentry == root && mnt == rootmnt))
++                      break;
++              if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
++                      if (mnt->mnt_parent == mnt)
++                              break;
++
++                      read_lock(&gr_inode_lock);
++                      retval =
++                          lookup_acl_subj_label(dentry->d_inode->i_ino,
++                                                dentry->d_inode->i_dev, role);
++                      read_unlock(&gr_inode_lock);
++                      if (unlikely(retval != NULL))
++                              goto out;
++
++                      dentry = mnt->mnt_mountpoint;
++                      mnt = mnt->mnt_parent;
++                      continue;
++              }
++
++              read_lock(&gr_inode_lock);
++              retval =
++                  lookup_acl_subj_label(dentry->d_inode->i_ino,
++                                        dentry->d_inode->i_dev, role);
++              read_unlock(&gr_inode_lock);
++              if (unlikely(retval != NULL))
++                      goto out;
++
++              dentry = dentry->d_parent;
++      }
++
++      read_lock(&gr_inode_lock);
++      retval =
++          lookup_acl_subj_label(dentry->d_inode->i_ino,
++                                dentry->d_inode->i_dev, role);
++      read_unlock(&gr_inode_lock);
++
++      if (unlikely(retval == NULL)) {
++              read_lock(&gr_inode_lock);
++              retval =
++                  lookup_acl_subj_label(root->d_inode->i_ino,
++                                        root->d_inode->i_dev, role);
++              read_unlock(&gr_inode_lock);
++      }
++      out:
++      spin_unlock(&dcache_lock);
++      dput(root);
++      mntput(rootmnt);
++
++      return retval;
++}
++
++static __inline__ void
++gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
++           const struct task_struct *task, const char *pathname,
++           const __u32 mode)
++{
++      security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
++                     uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
++                     task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
++                     1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
++
++      return;
++}
++
++__u32
++gr_check_link(const struct dentry * new_dentry,
++            const struct dentry * parent_dentry,
++            const struct vfsmount * parent_mnt,
++            const struct dentry * old_dentry, const struct vfsmount * old_mnt)
++{
++      struct acl_object_label *obj;
++      __u32 oldmode, newmode;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return (GR_WRITE | GR_CREATE);
++
++      obj = chk_obj_label(old_dentry, old_mnt, current->acl);
++      oldmode = obj->mode;
++
++      if (current->acl->mode & GR_LEARN)
++              oldmode |= (GR_WRITE | GR_CREATE);
++      newmode =
++          gr_check_create(new_dentry, parent_dentry, parent_mnt,
++                          oldmode | GR_CREATE | GR_AUDIT_CREATE |
++                          GR_AUDIT_WRITE | GR_SUPPRESS);
++
++      if ((newmode & oldmode) == oldmode)
++              return newmode;
++      else if (current->acl->mode & GR_LEARN) {
++              gr_log_learn(current->role, current->uid, current->gid,
++                      current, gr_to_filename(old_dentry, old_mnt), oldmode);
++              return (GR_WRITE | GR_CREATE);
++      } else if (newmode & GR_SUPPRESS)
++              return GR_SUPPRESS;
++      else
++              return 0;
++}
++
++__u32
++gr_search_file(const struct dentry * dentry, const __u32 mode,
++             const struct vfsmount * mnt)
++{
++      __u32 retval = mode;
++      struct acl_subject_label *curracl;
++      struct acl_object_label *currobj;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return (mode & ~GR_AUDITS);
++
++      curracl = current->acl;
++
++      currobj = chk_obj_label(dentry, mnt, curracl);
++      retval = currobj->mode & mode;
++
++      if (unlikely
++          ((curracl->mode & GR_LEARN) && (mode != GR_PTRACERD)
++           && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
++              __u32 new_mode = mode;
++
++              new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
++
++              retval = new_mode;
++
++              if (!(mode & GR_NOLEARN))
++                      gr_log_learn(current->role, current->uid, current->gid,
++                                   current, gr_to_filename(dentry, mnt), new_mode);
++      }
++
++      return retval;
++}
++
++__u32
++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
++              const struct vfsmount * mnt, const __u32 mode)
++{
++      struct name_entry *match;
++      struct acl_object_label *matchpo;
++      struct acl_subject_label *curracl;
++      __u32 retval;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return (mode & ~GR_AUDITS);
++
++      match = lookup_name_entry(gr_to_filename(new_dentry, mnt));
++
++      if (!match)
++              goto check_parent;
++
++      curracl = current->acl;
++
++      read_lock(&gr_inode_lock);
++      matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
++      read_unlock(&gr_inode_lock);
++
++      if (matchpo) {
++              if ((matchpo->mode & mode) !=
++                  (mode & ~(GR_AUDITS | GR_SUPPRESS))
++                  && curracl->mode & GR_LEARN) {
++                      __u32 new_mode = mode;
++
++                      new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
++
++                      gr_log_learn(current->role, current->uid, current->gid,
++                                   current, gr_to_filename(new_dentry, mnt), new_mode);
++
++                      return new_mode;
++              }
++              return (matchpo->mode & mode);
++      }
++
++      check_parent:
++      curracl = current->acl;
++
++      matchpo = chk_obj_label(parent, mnt, curracl);
++      retval = matchpo->mode & mode;
++
++      if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
++          && (curracl->mode & GR_LEARN)) {
++              __u32 new_mode = mode;
++
++              new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
++
++              gr_log_learn(current->role, current->uid, current->gid, 
++                           current, gr_to_filename(new_dentry, mnt), new_mode);
++              return new_mode;
++      }
++
++      return retval;
++}
++
++int
++gr_check_hidden_task(const struct task_struct *task)
++{
++      if (unlikely(!(gr_status & GR_READY)))
++              return 0;
++
++      if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
++              return 1;
++
++      return 0;
++}
++
++int
++gr_check_protected_task(const struct task_struct *task)
++{
++      if (unlikely(!(gr_status & GR_READY) || !task))
++              return 0;
++
++      if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
++              return 1;
++
++      return 0;
++}
++
++__inline__ void
++gr_copy_label(struct task_struct *tsk)
++{
++      tsk->used_accept = 0;
++      tsk->used_connect = 0;
++      tsk->acl_sp_role = 0;
++      tsk->acl_role_id = current->acl_role_id;
++      tsk->acl = current->acl;
++      tsk->role = current->role;
++      tsk->curr_ip = current->curr_ip;
++      if (current->exec_file)
++              get_file(current->exec_file);
++      tsk->exec_file = current->exec_file;
++      tsk->is_writable = current->is_writable;
++      if (unlikely(current->used_accept))
++              current->curr_ip = 0;
++
++      return;
++}
++
++static __inline__ void
++gr_set_proc_res(void)
++{
++      struct acl_subject_label *proc;
++      unsigned short i;
++
++      proc = current->acl;
++
++      if (proc->mode & GR_LEARN)
++              return;
++
++      for (i = 0; i < RLIM_NLIMITS; i++) {
++              if (!(proc->resmask & (1 << i)))
++                      continue;
++
++              current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
++              current->rlim[i].rlim_max = proc->res[i].rlim_max;
++      }
++
++      return;
++}
++
++void
++gr_set_pax_flags(struct task_struct *task)
++{
++      struct acl_subject_label *proc;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return;
++
++      proc = task->acl;
++
++      if (proc->mode & GR_PAXPAGE)
++              task->flags &= ~PF_PAX_PAGEEXEC;
++      if (proc->mode & GR_PAXSEGM)
++              task->flags &= ~PF_PAX_SEGMEXEC;
++      if (proc->mode & GR_PAXGCC)
++              task->flags |= PF_PAX_EMUTRAMP;
++      if (proc->mode & GR_PAXMPROTECT)
++              task->flags &= ~PF_PAX_MPROTECT;
++      if (proc->mode & GR_PAXRANDMMAP)
++              task->flags &= ~PF_PAX_RANDMMAP;
++      if (proc->mode & GR_PAXRANDEXEC)
++              task->flags |= PF_PAX_RANDEXEC;
++
++      return;
++}
++
++static __inline__ void
++do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
++{
++      task->role = lookup_acl_role_label(task, uid, gid);
++
++      return;
++}
++
++void
++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
++{
++      struct acl_object_label *obj;
++      struct file *filp;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return;
++
++      filp = task->exec_file;
++
++      /* kernel process, we'll give them the kernel role */
++      if (unlikely(!filp)) {
++              task->role = kernel_role;
++              task->acl = kernel_role->root_label;
++              return;
++      } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
++              do_set_role_label(task, uid, gid);
++
++      task->acl =
++          chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
++
++      task->is_writable = 0;
++
++      /* ignore additional mmap checks for processes that are writable 
++         by the default ACL */
++      obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
++      if (unlikely(obj->mode & GR_WRITE))
++              task->is_writable = 1;
++      obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
++      if (unlikely(obj->mode & GR_WRITE))
++              task->is_writable = 1;
++
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
++      printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
++#endif
++
++      gr_set_proc_res();
++
++      return;
++}
++
++void
++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      struct acl_subject_label *newacl;
++      struct acl_object_label *obj;
++      __u32 retmode;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return;
++
++      newacl = chk_subj_label(dentry, mnt, current->role);
++
++      obj = chk_obj_label(dentry, mnt, current->acl);
++      retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
++
++      if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
++              if (obj->nested)
++                      current->acl = obj->nested;
++              else
++                      current->acl = newacl;
++      } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
++              security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
++                             gr_to_filename(dentry, mnt), DEFAULTSECARGS);
++
++      current->is_writable = 0;
++
++      /* ignore additional mmap checks for processes that are writable 
++         by the default ACL */
++      obj = chk_obj_label(dentry, mnt, default_role->root_label);
++      if (unlikely(obj->mode & GR_WRITE))
++              current->is_writable = 1;
++      obj = chk_obj_label(dentry, mnt, current->role->root_label);
++      if (unlikely(obj->mode & GR_WRITE))
++              current->is_writable = 1;
++
++      gr_set_proc_res();
++
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
++      printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
++#endif
++      return;
++}
++
++static __inline__ void
++do_handle_delete(const ino_t ino, const kdev_t dev)
++{
++      struct acl_object_label *matchpo;
++      struct acl_subject_label *matchps;
++      struct acl_subject_label *i;
++      struct acl_role_label *role;
++
++      for (role = role_list_head; role; role = role->next) {
++              for (i = role->proc_subject; i; i = i->next) {
++                      if (unlikely(i->parent_subject &&
++                                   (i->inode == ino) &&
++                                   (i->device == dev)))
++                              i->mode |= GR_DELETED;
++                      if (unlikely((matchpo =
++                           lookup_acl_obj_label(ino, dev, i)) != NULL))
++                              matchpo->mode |= GR_DELETED;
++              }
++
++              if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
++                      matchps->mode |= GR_DELETED;
++      }
++
++      return;
++}
++
++void
++gr_handle_delete(const ino_t ino, const kdev_t dev)
++{
++      if (unlikely(!(gr_status & GR_READY)))
++              return;
++
++      write_lock(&gr_inode_lock);
++      if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
++              do_handle_delete(ino, dev);
++      write_unlock(&gr_inode_lock);
++
++      return;
++}
++
++static __inline__ void
++update_acl_obj_label(const ino_t oldinode, const kdev_t olddevice,
++                   const ino_t newinode, const kdev_t newdevice,
++                   struct acl_subject_label *subj)
++{
++      unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
++      struct acl_object_label **match;
++      struct acl_object_label *tmp;
++      __u8 i = 0;
++
++      match = &subj->obj_hash[index];
++
++      while (*match && ((*match)->inode != oldinode ||
++             (*match)->device != olddevice ||
++             !((*match)->mode & GR_DELETED))) {
++              index = (index + (1 << i)) % subj->obj_hash_size;
++              match = &subj->obj_hash[index];
++              i = (i + 1) % 32;
++      }
++
++      if (*match && ((*match) != deleted_object)
++          && ((*match)->inode == oldinode)
++          && ((*match)->device == olddevice)
++          && ((*match)->mode & GR_DELETED)) {
++              tmp = *match;
++              tmp->inode = newinode;
++              tmp->device = newdevice;
++              tmp->mode &= ~GR_DELETED;
++
++              *match = deleted_object;
++
++              insert_acl_obj_label(tmp, subj);
++      }
++
++      return;
++}
++
++static __inline__ void
++update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice,
++                    const ino_t newinode, const kdev_t newdevice,
++                    struct acl_role_label *role)
++{
++      struct acl_subject_label **s_hash = role->subj_hash;
++      unsigned long subj_size = role->subj_hash_size;
++      unsigned long index = fhash(oldinode, olddevice, subj_size);
++      struct acl_subject_label **match;
++      struct acl_subject_label *tmp;
++      __u8 i = 0;
++
++      match = &s_hash[index];
++
++      while (*match && ((*match)->inode != oldinode ||
++             (*match)->device != olddevice ||
++             !((*match)->mode & GR_DELETED))) {
++              index = (index + (1 << i)) % subj_size;
++              i = (i + 1) % 32;
++              match = &s_hash[index];
++      }
++
++      if (*match && (*match != deleted_subject)
++          && ((*match)->inode == oldinode)
++          && ((*match)->device == olddevice)
++          && ((*match)->mode & GR_DELETED)) {
++              tmp = *match;
++
++              tmp->inode = newinode;
++              tmp->device = newdevice;
++              tmp->mode &= ~GR_DELETED;
++
++              *match = deleted_subject;
++
++              insert_acl_subj_label(tmp, role);
++      }
++
++      return;
++}
++
++static __inline__ void
++update_inodev_entry(const ino_t oldinode, const kdev_t olddevice,
++                  const ino_t newinode, const kdev_t newdevice)
++{
++      unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
++      struct name_entry **match;
++      struct name_entry *tmp;
++      __u8 i = 0;
++
++      match = &inodev_set.n_hash[index];
++
++      while (*match
++             && ((*match)->inode != oldinode
++                 || (*match)->device != olddevice)) {
++              index = (index + (1 << i)) % inodev_set.n_size;
++              i = (i + 1) % 32;
++              match = &inodev_set.n_hash[index];
++      }
++
++      if (*match && (*match != deleted_inodev)
++          && ((*match)->inode == oldinode)
++          && ((*match)->device == olddevice)) {
++              tmp = *match;
++
++              tmp->inode = newinode;
++              tmp->device = newdevice;
++
++              *match = deleted_inodev;
++
++              insert_inodev_entry(tmp);
++      }
++
++      return;
++}
++
++static __inline__ void
++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
++               const struct vfsmount *mnt)
++{
++      struct acl_subject_label *i;
++      struct acl_role_label *role;
++
++      for (role = role_list_head; role; role = role->next) {
++              update_acl_subj_label(matchn->inode, matchn->device,
++                                    dentry->d_inode->i_ino,
++                                    dentry->d_inode->i_dev, role);
++
++              for (i = role->proc_subject; i; i = i->next) {
++                      if (unlikely(i->parent_subject &&
++                                   (i->inode == dentry->d_inode->i_ino) &&
++                                   (i->device == dentry->d_inode->i_dev))) {
++                              i->inode = dentry->d_inode->i_ino;
++                              i->device = dentry->d_inode->i_dev;
++                      }
++                      update_acl_obj_label(matchn->inode, matchn->device,
++                                           dentry->d_inode->i_ino,
++                                           dentry->d_inode->i_dev, i);
++              }
++      }
++
++      update_inodev_entry(matchn->inode, matchn->device,
++                          dentry->d_inode->i_ino, dentry->d_inode->i_dev);
++
++      return;
++}
++
++void
++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      struct name_entry *matchn;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return;
++
++      matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
++
++      if (unlikely((unsigned long)matchn)) {
++              write_lock(&gr_inode_lock);
++              do_handle_create(matchn, dentry, mnt);
++              write_unlock(&gr_inode_lock);
++      }
++
++      return;
++}
++
++int
++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
++               struct dentry *old_dentry,
++               struct dentry *new_dentry,
++               struct vfsmount *mnt, const __u8 replace)
++{
++      struct name_entry *matchn;
++      int error = 0;
++
++      matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
++
++      lock_kernel();
++      error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
++      unlock_kernel();
++
++      if (unlikely(error))
++              return error;
++
++      /* we wouldn't have to check d_inode if it weren't for
++         NFS silly-renaming
++       */
++
++      write_lock(&gr_inode_lock);
++      if (unlikely(replace && new_dentry->d_inode)) {
++              if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
++                                      new_dentry->d_inode->i_dev) &&
++                  (old_dentry->d_inode->i_nlink <= 1)))
++                      do_handle_delete(new_dentry->d_inode->i_ino,
++                                       new_dentry->d_inode->i_dev);
++      }
++
++      if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
++                              old_dentry->d_inode->i_dev) &&
++          (old_dentry->d_inode->i_nlink <= 1)))
++              do_handle_delete(old_dentry->d_inode->i_ino,
++                               old_dentry->d_inode->i_dev);
++
++      if (unlikely((unsigned long)matchn))
++              do_handle_create(matchn, old_dentry, mnt);
++      write_unlock(&gr_inode_lock);
++
++      return error;
++}
++
++static int
++lookup_special_role_auth(const char *rolename, unsigned char **salt,
++                       unsigned char **sum)
++{
++      struct acl_role_label *r;
++      struct role_transition *trans;
++      __u16 i;
++      int found = 0;
++
++      /* check transition table */
++
++      for (trans = current->role->transitions; trans; trans = trans->next) {
++              if (!strcmp(rolename, trans->rolename)) {
++                      found = 1;
++                      break;
++              }
++      }
++
++      if (!found)
++              return 0;
++
++      /* handle special roles that do not require authentication */
++
++      for (r = role_list_head; r; r = r->next) {
++              if (!strcmp(rolename, r->rolename)
++                  && (r->roletype & GR_ROLE_NOPW)) {
++                      *salt = NULL;
++                      *sum = NULL;
++                      return 1;
++              }
++      }
++
++      for (i = 0; i < num_sprole_pws; i++) {
++              if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
++                      *salt = acl_special_roles[i]->salt;
++                      *sum = acl_special_roles[i]->sum;
++                      return 1;
++              }
++      }
++
++      return 0;
++}
++
++static void
++assign_special_role(char *rolename)
++{
++      struct acl_object_label *obj;
++      struct acl_role_label *r;
++      struct acl_role_label *assigned = NULL;
++      struct task_struct *tsk;
++      struct file *filp;
++
++      for (r = role_list_head; r; r = r->next)
++              if (!strcmp(rolename, r->rolename) &&
++                  (r->roletype & GR_ROLE_SPECIAL))
++                      assigned = r;
++
++      if (!assigned)
++              return;
++
++      tsk = current->p_pptr;
++      filp = tsk->exec_file;
++
++      if (tsk && filp) {
++              tsk->is_writable = 0;
++
++              acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
++              tsk->acl_sp_role = 1;
++              tsk->acl_role_id = acl_sp_role_value;
++              tsk->role = assigned;
++              tsk->acl =
++                  chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
++
++              /* ignore additional mmap checks for processes that are writable 
++                 by the default ACL */
++              obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
++              if (unlikely(obj->mode & GR_WRITE))
++                      tsk->is_writable = 1;
++              obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
++              if (unlikely(obj->mode & GR_WRITE))
++                      tsk->is_writable = 1;
++
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
++              printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
++#endif
++      }
++
++      return;
++}
++
++ssize_t
++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
++{
++      struct gr_arg *arg;
++      unsigned char *sprole_salt;
++      unsigned char *sprole_sum;
++      int error = sizeof (struct gr_arg);
++      int error2 = 0;
++
++      down(&gr_dev_sem);
++
++      arg = (struct gr_arg *) buf;
++
++      if (count != sizeof (struct gr_arg)) {
++              security_alert_good(GR_DEV_ACL_MSG, count,
++                                  (int) sizeof (struct gr_arg));
++              error = -EINVAL;
++              goto out;
++      }
++
++      if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
++          && time_before_eq(gr_auth_expires, jiffies)) {
++              gr_auth_expires = 0;
++              gr_auth_attempts = 0;
++      }
++
++      if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
++              error = -EFAULT;
++              goto out;
++      }
++
++      if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) {
++              error = -EBUSY;
++              goto out;
++      }
++
++      /* if non-root trying to do anything other than use a special role,
++         do not attempt authentication, do not count towards authentication
++         locking
++       */
++
++      if (gr_usermode->mode != SPROLE && current->uid) {
++              error = -EPERM;
++              goto out;
++      }
++
++      /* ensure pw and special role name are null terminated */
++
++      gr_usermode->pw[GR_PW_LEN - 1] = '\0';
++      gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
++
++      /* Okay. 
++       * We have our enough of the argument structure..(we have yet
++       * to copy_from_user the tables themselves) . Copy the tables
++       * only if we need them, i.e. for loading operations. */
++
++      switch (gr_usermode->mode) {
++      case STATUS:
++                      if (gr_status & GR_READY)
++                              error = 1;
++                      else
++                              error = 2;
++                      goto out;
++      case SHUTDOWN:
++              if ((gr_status & GR_READY)
++                  && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
++                      gr_status &= ~GR_READY;
++                      security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
++                      free_variables();
++                      memset(gr_usermode, 0, sizeof (struct gr_arg));
++                      memset(gr_system_salt, 0, GR_SALT_LEN);
++                      memset(gr_system_sum, 0, GR_SHA_LEN);
++              } else if (gr_status & GR_READY) {
++                      security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
++                      error = -EPERM;
++              } else {
++                      security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
++                      error = -EAGAIN;
++              }
++              break;
++      case ENABLE:
++              if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
++                      security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
++              else {
++                      if (gr_status & GR_READY)
++                              error = -EAGAIN;
++                      else
++                              error = error2;
++                      security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
++                                     DEFAULTSECARGS);
++              }
++              break;
++      case RELOAD:
++              if (!(gr_status & GR_READY)) {
++                      security_alert_good(GR_RELOADI_ACL_MSG);
++                      error = -EAGAIN;
++              } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
++                      lock_kernel();
++                      gr_status &= ~GR_READY;
++                      free_variables();
++                      if (!(error2 = gracl_init(gr_usermode))) {
++                              unlock_kernel();
++                              security_alert_good(GR_RELOAD_ACL_MSG,
++                                                  GR_VERSION);
++                      } else {
++                              unlock_kernel();
++                              error = error2;
++                              security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
++                                             DEFAULTSECARGS);
++                      }
++              } else {
++                      security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
++                                     DEFAULTSECARGS);
++                      error = -EPERM;
++              }
++              break;
++      case SEGVMOD:
++              if (unlikely(!(gr_status & GR_READY))) {
++                      security_alert_good(GR_SEGVMODI_ACL_MSG,
++                                          DEFAULTSECARGS);
++                      error = -EAGAIN;
++                      break;
++              }
++
++              if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
++                      security_alert_good(GR_SEGVMODS_ACL_MSG,
++                                          DEFAULTSECARGS);
++                      if (gr_usermode->segv_device && gr_usermode->segv_inode) {
++                              struct acl_subject_label *segvacl;
++                              segvacl =
++                                  lookup_acl_subj_label(gr_usermode->segv_inode,
++                                                        gr_usermode->segv_device,
++                                                        current->role);
++                              if (segvacl) {
++                                      segvacl->crashes = 0;
++                                      segvacl->expires = 0;
++                              }
++                      } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
++                              gr_remove_uid(gr_usermode->segv_uid);
++                      }
++              } else {
++                      security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
++                      error = -EPERM;
++              }
++              break;
++      case SPROLE:
++              if (unlikely(!(gr_status & GR_READY))) {
++                      security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
++                      error = -EAGAIN;
++                      break;
++              }
++
++              if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
++                  && time_before_eq(current->role->expires, jiffies)) {
++                      current->role->expires = 0;
++                      current->role->auth_attempts = 0;
++              }
++
++              if (time_after(current->role->expires, jiffies)) {
++                      error = -EBUSY;
++                      goto out;
++              }
++
++              if (lookup_special_role_auth
++                  (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
++                  && ((!sprole_salt && !sprole_sum)
++                      || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
++                      assign_special_role(gr_usermode->sp_role);
++                      security_alert_good(GR_SPROLES_ACL_MSG,
++                                          (current->p_pptr) ? current->
++                                          p_pptr->role->rolename : "",
++                                          acl_sp_role_value, DEFAULTSECARGS);
++              } else {
++                      security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
++                                     DEFAULTSECARGS);
++                      error = -EPERM;
++                      current->role->auth_attempts++;
++                      if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
++                              current->role->expires =
++                                  jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
++                              security_alert(GR_MAXROLEPW_ACL_MSG,
++                                     CONFIG_GRKERNSEC_ACL_MAXTRIES,
++                                     gr_usermode->sp_role, DEFAULTSECARGS);
++                      }
++
++                      goto out;
++              }
++              break;
++      case UNSPROLE:
++              if (unlikely(!(gr_status & GR_READY))) {
++                      security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
++                      error = -EAGAIN;
++                      break;
++              }
++
++              if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
++                  && time_before_eq(current->role->expires, jiffies)) {
++                      current->role->expires = 0;
++                      current->role->auth_attempts = 0;
++              }
++
++              if (time_after(current->role->expires, jiffies)) {
++                      error = -EBUSY;
++                      goto out;
++              }
++
++              if ((current->role->roletype & GR_ROLE_SPECIAL) && 
++                  lookup_special_role_auth
++                  (current->role->rolename, &sprole_salt, &sprole_sum)
++                  && ((!sprole_salt && !sprole_sum)
++                      || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
++                      security_alert_good(GR_UNSPROLES_ACL_MSG,
++                                          (current->p_pptr) ? current->
++                                          p_pptr->role->rolename : "",
++                                          (current->p_pptr) ? current->
++                                          p_pptr->acl_role_id : 0, DEFAULTSECARGS);
++                      gr_set_acls(1);
++                      if (current->p_pptr)
++                              current->p_pptr->acl_sp_role = 0;
++              } else {
++                      security_alert(GR_UNSPROLEF_ACL_MSG, gr_usermode->sp_role,
++                                     DEFAULTSECARGS);
++                      error = -EPERM;
++                      current->role->auth_attempts++;
++                      if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
++                              current->role->expires =
++                                  jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
++                              security_alert(GR_MAXROLEPW_ACL_MSG,
++                                     CONFIG_GRKERNSEC_ACL_MAXTRIES,
++                                     current->role->rolename, DEFAULTSECARGS);
++                      }
++
++                      goto out;
++              }
++              break;
++      default:
++              security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
++                             DEFAULTSECARGS);
++              error = -EINVAL;
++              break;
++      }
++
++      if (error != -EPERM)
++              goto out;
++
++      gr_auth_attempts++;
++
++      if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
++              security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
++              gr_auth_expires = jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
++      }
++
++      out:
++      up(&gr_dev_sem);
++      return error;
++}
++
++int
++gr_set_acls(const int type)
++{
++      struct acl_object_label *obj;
++      struct task_struct *task;
++      struct file *filp;
++      unsigned short i;
++
++      read_lock(&tasklist_lock);
++      for_each_task(task) {
++              /* check to see if we're called from the exit handler,
++                 if so, only replace ACLs that have inherited the admin
++                 ACL */
++
++              if (type && (task->role != current->role ||
++                           task->acl_role_id != current->acl_role_id))
++                      continue;
++
++              task->acl_role_id = 0;
++
++              if ((filp = task->exec_file)) {
++                      do_set_role_label(task, task->uid, task->gid);
++
++                      task->acl =
++                          chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
++                                         task->role);
++                      if (task->acl) {
++                              struct acl_subject_label *curr;
++                              curr = task->acl;
++
++                              task->is_writable = 0;
++                              /* ignore additional mmap checks for processes that are writable 
++                                 by the default ACL */
++                              obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
++                              if (unlikely(obj->mode & GR_WRITE))
++                                      task->is_writable = 1;
++                              obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
++                              if (unlikely(obj->mode & GR_WRITE))
++                                      task->is_writable = 1;
++
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
++                              printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
++#endif
++                              if (!(curr->mode & GR_LEARN))
++                                      for (i = 0; i < RLIM_NLIMITS; i++) {
++                                              if (!(curr->resmask & (1 << i)))
++                                                      continue;
++
++                                              task->rlim[i].rlim_cur =
++                                                  curr->res[i].rlim_cur;
++                                              task->rlim[i].rlim_max =
++                                                  curr->res[i].rlim_max;
++                                      }
++                      } else {
++                              read_unlock(&tasklist_lock);
++                              security_alert_good(GR_DEFACL_MSG, task->comm,
++                                                  task->pid);
++                              return 1;
++                      }
++              } else {
++                      // it's a kernel process
++                      task->role = kernel_role;
++                      task->acl = kernel_role->root_label;
++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
++                      task->acl->mode &= ~GR_FIND;
++#endif
++              }
++      }
++      read_unlock(&tasklist_lock);
++      return 0;
++}
++
++void
++gr_learn_resource(const struct task_struct *task,
++                const int res, const unsigned long wanted)
++{
++      struct acl_subject_label *acl;
++
++      if (unlikely((gr_status & GR_READY) &&
++                   task->acl && (task->acl->mode & GR_LEARN)))
++              goto skip_reslog;
++
++#ifdef CONFIG_GRKERNSEC_RESLOG
++      gr_log_resource(task, res, wanted);
++#endif
++      skip_reslog:
++
++      if (unlikely(!(gr_status & GR_READY) || !wanted))
++              return;
++
++      acl = task->acl;
++
++      if (likely(!acl || !(acl->mode & GR_LEARN) ||
++                 !(acl->resmask & (1 << (unsigned short) res))))
++              return;
++
++      if (wanted >= acl->res[res].rlim_cur) {
++              unsigned long res_add;
++
++              res_add = wanted;
++              switch (res) {
++              case RLIMIT_CPU:
++                      res_add += GR_RLIM_CPU_BUMP;
++                      break;
++              case RLIMIT_FSIZE:
++                      res_add += GR_RLIM_FSIZE_BUMP;
++                      break;
++              case RLIMIT_DATA:
++                      res_add += GR_RLIM_DATA_BUMP;
++                      break;
++              case RLIMIT_STACK:
++                      res_add += GR_RLIM_STACK_BUMP;
++                      break;
++              case RLIMIT_CORE:
++                      res_add += GR_RLIM_CORE_BUMP;
++                      break;
++              case RLIMIT_RSS:
++                      res_add += GR_RLIM_RSS_BUMP;
++                      break;
++              case RLIMIT_NPROC:
++                      res_add += GR_RLIM_NPROC_BUMP;
++                      break;
++              case RLIMIT_NOFILE:
++                      res_add += GR_RLIM_NOFILE_BUMP;
++                      break;
++              case RLIMIT_MEMLOCK:
++                      res_add += GR_RLIM_MEMLOCK_BUMP;
++                      break;
++              case RLIMIT_AS:
++                      res_add += GR_RLIM_AS_BUMP;
++                      break;
++              case RLIMIT_LOCKS:
++                      res_add += GR_RLIM_LOCKS_BUMP;
++                      break;
++              }
++
++              acl->res[res].rlim_cur = res_add;
++
++              if (wanted > acl->res[res].rlim_max)
++                      acl->res[res].rlim_max = res_add;
++
++              security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
++                             current->role->roletype, acl->filename,
++                             acl->res[res].rlim_cur, acl->res[res].rlim_max,
++                             "", (unsigned long) res);
++      }
++
++      return;
++}
++
++#ifdef CONFIG_SYSCTL
++extern struct proc_dir_entry *proc_sys_root;
++
++__u32
++gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
++               const void *newval)
++{
++      struct proc_dir_entry *tmp;
++      struct nameidata nd;
++      const char *proc_sys = "/proc/sys";
++      char *path = gr_shared_page[0][smp_processor_id()];
++      struct acl_object_label *obj;
++      unsigned short len = 0, pos = 0, depth = 0, i;
++      __u32 err = 0;
++      __u32 mode = 0;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return 1;
++
++      if (oldval)
++              mode |= GR_READ;
++      if (newval)
++              mode |= GR_WRITE;
++
++      /* convert the requested sysctl entry into a pathname */
++
++      for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
++              len += strlen(tmp->name);
++              len++;
++              depth++;
++      }
++
++      if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
++              return 0;       // deny
++
++      memset(path, 0, PAGE_SIZE);
++
++      memcpy(path, proc_sys, strlen(proc_sys));
++
++      pos += strlen(proc_sys);
++
++      for (; depth > 0; depth--) {
++              path[pos] = '/';
++              pos++;
++              for (i = 1, tmp = table->de; tmp != proc_sys_root;
++                   tmp = tmp->parent) {
++                      if (depth == i) {
++                              memcpy(path + pos, tmp->name,
++                                     strlen(tmp->name));
++                              pos += strlen(tmp->name);
++                      }
++                      i++;
++              }
++      }
++
++      if (path_init(path, LOOKUP_FOLLOW, &nd))
++              err = path_walk(path, &nd);
++
++      if (err)
++              goto out;
++
++      obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
++      err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
++
++      if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
++              __u32 new_mode = mode;
++
++              new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
++
++              err = new_mode;
++              gr_log_learn(current->role, current->uid, current->gid,
++                           current, path, new_mode);
++      } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
++              security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
++                             (mode & GR_READ) ? " reading" : "",
++                             (mode & GR_WRITE) ? " writing" : "",
++                             DEFAULTSECARGS);
++              err = 0;
++      } else if ((err & mode) != mode) {
++              err = 0;
++      } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
++              security_audit(GR_SYSCTL_ACL_MSG, "successful",
++                             path, (mode & GR_READ) ? " reading" : "",
++                             (mode & GR_WRITE) ? " writing" : "",
++                             DEFAULTSECARGS);
++      }
++
++      path_release(&nd);
++
++      out:
++      return err;
++}
++#endif
++
++int
++gr_handle_ptrace(struct task_struct *task, const long request)
++{
++      struct file *filp;
++      __u32 retmode;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return 0;
++
++      filp = task->exec_file;
++
++      if (unlikely(!filp))
++              return 0;
++
++      retmode = gr_search_file(filp->f_dentry, GR_PTRACERD, filp->f_vfsmnt);
++
++      if (retmode & GR_PTRACERD) {
++              switch (request) {
++              case PTRACE_POKETEXT:
++              case PTRACE_POKEDATA:
++              case PTRACE_POKEUSR:
++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
++              case PTRACE_SETREGS:
++              case PTRACE_SETFPREGS:
++#endif
++#ifdef CONFIG_X86
++              case PTRACE_SETFPXREGS:
++#endif
++#ifdef CONFIG_ALTIVEC
++              case PTRACE_SETVRREGS:
++#endif
++                      return 1;
++              default:
++                      return 0;
++              }
++      } else if (!(current->acl->mode & GR_OVERRIDE) &&
++                 !(current->role->roletype & GR_ROLE_GOD)
++                 && (current->acl != task->acl
++                     || (current->acl != current->role->root_label
++                         && current->pid != task->pid))) {
++              security_alert(GR_PTRACE_ACL_MSG,
++                             gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
++                             task->comm, task->pid, DEFAULTSECARGS);
++              return 1;
++      }
++
++      return 0;
++}
++
++int
++gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      __u32 retmode;
++      struct acl_subject_label *subj;
++
++      if (unlikely(!(gr_status & GR_READY)))
++              return 0;
++
++      if (unlikely
++          ((current->ptrace & PT_PTRACED)
++           && !(current->acl->mode & GR_OVERRIDE)))
++              retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
++      else
++              return 0;
++
++      subj = chk_subj_label(dentry, mnt, current->role);
++
++      if (!(retmode & GR_PTRACERD) &&
++          !(current->role->roletype & GR_ROLE_GOD) &&
++          (current->acl != subj)) {
++              security_alert(GR_PTRACE_EXEC_ACL_MSG,
++                             gr_to_filename(dentry, mnt), DEFAULTSECARGS);
++              return 1;
++      }
++
++      return 0;
++}
++
++int
++gr_handle_mmap(const struct file *filp, const unsigned long prot)
++{
++      struct acl_object_label *obj, *obj2;
++
++      if (unlikely(!(gr_status & GR_READY) ||
++                   (current->acl->mode & GR_OVERRIDE) || !filp ||
++                   !(prot & PROT_EXEC)))
++              return 0;
++
++      if (unlikely(current->is_writable))
++              return 0;
++
++      obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
++      obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
++                           current->role->root_label);
++      if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
++              security_alert(GR_WRITLIB_ACL_MSG,
++                             gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
++                             DEFAULTSECARGS);
++              return 1;
++      }
++
++      return 0;
++}
++
++int
++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
++{
++      __u32 mode;
++
++      if (unlikely(!file || !(prot & PROT_EXEC)))
++              return 1;
++
++      mode =
++          gr_search_file(file->f_dentry,
++                         GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
++                         file->f_vfsmnt);
++
++      if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
++              security_alert(GR_MMAP_ACL_MSG, "denied",
++                             gr_to_filename(file->f_dentry, file->f_vfsmnt),
++                             DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
++              return 0;
++      } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
++              security_audit(GR_MMAP_ACL_MSG, "successful",
++                             gr_to_filename(file->f_dentry, file->f_vfsmnt),
++                             DEFAULTSECARGS);
++              return 1;
++      }
++
++      return 1;
++}
++
++int
++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
++{
++      __u32 mode;
++
++      if (unlikely(!file || !(prot & PROT_EXEC)))
++              return 1;
++
++      mode =
++          gr_search_file(file->f_dentry,
++                         GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
++                         file->f_vfsmnt);
++
++      if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
++              security_alert(GR_MPROTECT_ACL_MSG, "denied",
++                             gr_to_filename(file->f_dentry, file->f_vfsmnt),
++                             DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
++              return 0;
++      } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
++              security_audit(GR_MPROTECT_ACL_MSG, "successful",
++                             gr_to_filename(file->f_dentry, file->f_vfsmnt),
++                             DEFAULTSECARGS);
++              return 1;
++      }
++
++      return 1;
++}
++
++void
++gr_acl_handle_psacct(struct task_struct *task, const long code)
++{
++      unsigned long runtime;
++      unsigned long cputime;
++      unsigned int wday, cday;
++      __u8 whr, chr;
++      __u8 wmin, cmin;
++      __u8 wsec, csec;
++      char cur_tty[64] = { 0 };
++      char parent_tty[64] = { 0 };
++
++      if (unlikely(!(gr_status & GR_READY) || !task->acl ||
++                   !(task->acl->mode & GR_PROCACCT)))
++              return;
++
++      runtime = (jiffies - task->start_time) / HZ;
++      wday = runtime / (3600 * 24);
++      runtime -= wday * (3600 * 24);
++      whr = runtime / 3600;
++      runtime -= whr * 3600;
++      wmin = runtime / 60;
++      runtime -= wmin * 60;
++      wsec = runtime;
++
++      cputime = (task->times.tms_utime + task->times.tms_stime) / HZ;
++      cday = cputime / (3600 * 24);
++      cputime -= cday * (3600 * 24);
++      chr = cputime / 3600;
++      cputime -= chr * 3600;
++      cmin = cputime / 60;
++      cputime -= cmin * 60;
++      csec = cputime;
++
++      security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
++                     task->pid, NIPQUAD(task->curr_ip), tty_name(task->tty,
++                                                                 cur_tty),
++                     task->uid, task->euid, task->gid, task->egid, wday, whr,
++                     wmin, wsec, cday, chr, cmin, csec,
++                     (task->
++                      flags & PF_SIGNALED) ? "killed by signal" : "exited",
++                     code, gr_parent_task_fullpath(task), 
++                     task->p_pptr->comm, task->p_pptr->pid,
++                     NIPQUAD(task->p_pptr->curr_ip),
++                     tty_name(task->p_pptr->tty, parent_tty),
++                     task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid,
++                     task->p_pptr->egid);
++
++      return;
++}
++
++void gr_set_kernel_label(struct task_struct *task)
++{
++      if (gr_status & GR_READY) {
++              task->role = kernel_role;
++              task->acl = kernel_role->root_label;
++      }
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/gracl_alloc.c linux-2.4.22-grsec-O1/grsecurity/gracl_alloc.c
+--- linux-2.4.22/grsecurity/gracl_alloc.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_alloc.c     2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,94 @@
++/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
++
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/gracl.h>
++#include <linux/grsecurity.h>
++
++static unsigned long alloc_stack_next = 1;
++static unsigned long alloc_stack_size = 1;
++static void **alloc_stack;
++
++static __inline__ int
++alloc_pop(void)
++{
++      if ((alloc_stack_next - 1) == 0)
++              return 0;
++
++      if (*(alloc_stack + alloc_stack_next - 2))
++              kfree(*(alloc_stack + alloc_stack_next - 2));
++
++      alloc_stack_next--;
++
++      return 1;
++}
++
++static __inline__ void
++alloc_push(void *buf)
++{
++      if (alloc_stack_next >= alloc_stack_size)
++              BUG();
++
++      *(alloc_stack + alloc_stack_next - 1) = buf;
++
++      alloc_stack_next++;
++
++      return;
++}
++
++void *
++acl_alloc(unsigned long len)
++{
++      void *ret;
++
++      if (len > PAGE_SIZE)
++              BUG();
++
++      ret = kmalloc(len, GFP_KERNEL);
++
++      if (ret)
++              alloc_push(ret);
++
++      return ret;
++}
++
++void
++acl_free_all(void)
++{
++      if (gr_acl_is_enabled() || !alloc_stack)
++              return;
++
++      while (alloc_pop()) ;
++
++      if (alloc_stack) {
++              if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
++                      kfree(alloc_stack);
++              else
++                      vfree(alloc_stack);
++      }
++
++      alloc_stack = NULL;
++      alloc_stack_size = 1;
++      alloc_stack_next = 1;
++
++      return;
++}
++
++int
++acl_alloc_stack_init(unsigned long size)
++{
++      if ((size * sizeof (void *)) <= PAGE_SIZE)
++              alloc_stack =
++                  (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
++      else
++              alloc_stack = (void **) vmalloc(size * sizeof (void *));
++
++      alloc_stack_size = size;
++
++      if (!alloc_stack)
++              return 0;
++      else
++              return 1;
++}
+diff -urN linux-2.4.22/grsecurity/gracl_cap.c linux-2.4.22-grsec-O1/grsecurity/gracl_cap.c
+--- linux-2.4.22/grsecurity/gracl_cap.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_cap.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,71 @@
++/* capability handling routines, (c) Brad Spengler 2002,2003 */
++
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/capability.h>
++#include <linux/gracl.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++static const char *captab_log[29] = {
++      "CAP_CHOWN",
++      "CAP_DAC_OVERRIDE",
++      "CAP_DAC_READ_SEARCH",
++      "CAP_FOWNER",
++      "CAP_FSETID",
++      "CAP_KILL",
++      "CAP_SETGID",
++      "CAP_SETUID",
++      "CAP_SETPCAP",
++      "CAP_LINUX_IMMUTABLE",
++      "CAP_NET_BIND_SERVICE",
++      "CAP_NET_BROADCAST",
++      "CAP_NET_ADMIN",
++      "CAP_NET_RAW",
++      "CAP_IPC_LOCK",
++      "CAP_IPC_OWNER",
++      "CAP_SYS_MODULE",
++      "CAP_SYS_RAWIO",
++      "CAP_SYS_CHROOT",
++      "CAP_SYS_PTRACE",
++      "CAP_SYS_PACCT",
++      "CAP_SYS_ADMIN",
++      "CAP_SYS_BOOT",
++      "CAP_SYS_NICE",
++      "CAP_SYS_RESOURCE",
++      "CAP_SYS_TIME",
++      "CAP_SYS_TTY_CONFIG",
++      "CAP_MKNOD",
++      "CAP_LEASE"
++};
++
++int
++gr_is_capable(const int cap)
++{
++      struct acl_subject_label *curracl;
++
++      if (!gr_acl_is_enabled())
++              return 1;
++
++      curracl = current->acl;
++
++      if (!cap_raised(curracl->cap_lower, cap))
++              return 1;
++
++      if ((curracl->mode & GR_LEARN)
++          && cap_raised(current->cap_effective, cap)) {
++              security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
++                             current->role->roletype, current->uid,
++                             current->gid, current->exec_file ?
++                             gr_to_filename(current->exec_file->f_dentry,
++                             current->exec_file->f_vfsmnt) : curracl->filename,
++                             curracl->filename, 0UL,
++                             0UL, "", (unsigned long) cap, NIPQUAD(current->curr_ip));
++              return 1;
++      }
++
++      if ((cap >= 0) && (cap < 29) && cap_raised(current->cap_effective, cap))
++              security_alert(GR_CAP_ACL_MSG, captab_log[cap], DEFAULTSECARGS);
++
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/gracl_fs.c linux-2.4.22-grsec-O1/grsecurity/gracl_fs.c
+--- linux-2.4.22/grsecurity/gracl_fs.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_fs.c        2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,469 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++#include <linux/gracl.h>
++
++__u32
++gr_acl_handle_hidden_file(const struct dentry * dentry,
++                        const struct vfsmount * mnt)
++{
++      __u32 mode;
++
++      if (unlikely(!dentry->d_inode))
++              return GR_FIND;
++
++      mode =
++          gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
++
++      if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
++              security_audit(GR_HIDDEN_ACL_MSG, "successful",
++                             gr_to_filename(dentry, mnt), DEFAULTSECARGS);
++              return mode;
++      } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
++              security_alert(GR_HIDDEN_ACL_MSG, "denied",
++                             gr_to_filename(dentry, mnt),
++                             DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely(!(mode & GR_FIND)))
++              return 0;
++
++      return GR_FIND;
++}
++
++__u32
++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
++                 const int fmode)
++{
++      __u32 reqmode = GR_FIND;
++      __u32 mode;
++
++      if (unlikely(!dentry->d_inode))
++              return reqmode;
++
++      if (unlikely(fmode & O_APPEND))
++              reqmode |= GR_APPEND;
++      else if (unlikely(fmode & FMODE_WRITE))
++              reqmode |= GR_WRITE;
++      if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
++              reqmode |= GR_READ;
++
++      mode =
++          gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
++                         mnt);
++
++      if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
++              security_audit(GR_OPEN_ACL_MSG, "successful",
++                             gr_to_filename(dentry, mnt),
++                             reqmode & GR_READ ? " reading" : "",
++                             reqmode & GR_WRITE ? " writing" :
++                             reqmode & GR_APPEND ? " appending" : "",
++                             DEFAULTSECARGS);
++              return reqmode;
++      } else
++          if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
++      {
++              security_alert(GR_OPEN_ACL_MSG, "denied",
++                             gr_to_filename(dentry, mnt),
++                             reqmode & GR_READ ? " reading" : "",
++                             reqmode & GR_WRITE ? " writing" : reqmode &
++                             GR_APPEND ? " appending" : "", DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely((mode & reqmode) != reqmode))
++              return 0;
++
++      return reqmode;
++}
++
++__u32
++gr_acl_handle_creat(const struct dentry * dentry,
++                  const struct dentry * p_dentry,
++                  const struct vfsmount * p_mnt, const int fmode,
++                  const int imode)
++{
++      __u32 reqmode = GR_WRITE | GR_CREATE;
++      __u32 mode;
++
++      if (unlikely(fmode & O_APPEND))
++              reqmode |= GR_APPEND;
++      if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
++              reqmode |= GR_READ;
++      if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
++              reqmode |= GR_SETID;
++
++      mode =
++          gr_check_create(dentry, p_dentry, p_mnt,
++                          reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
++
++      if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
++              security_audit(GR_CREATE_ACL_MSG, "successful",
++                             gr_to_filename(dentry, p_mnt),
++                             reqmode & GR_READ ? " reading" : "",
++                             reqmode & GR_WRITE ? " writing" :
++                             reqmode & GR_APPEND ? " appending" : "",
++                             DEFAULTSECARGS);
++              return reqmode;
++      } else
++          if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
++      {
++              security_alert(GR_CREATE_ACL_MSG, "denied",
++                             gr_to_filename(dentry, p_mnt),
++                             reqmode & GR_READ ? " reading" : "",
++                             reqmode & GR_WRITE ? " writing" : reqmode &
++                             GR_APPEND ? " appending" : "", DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely((mode & reqmode) != reqmode))
++              return 0;
++
++      return reqmode;
++}
++
++__u32
++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
++                   const int fmode)
++{
++      __u32 mode, reqmode = GR_FIND;
++
++      if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
++              reqmode |= GR_EXEC;
++      if (fmode & S_IWOTH)
++              reqmode |= GR_WRITE;
++      if (fmode & S_IROTH)
++              reqmode |= GR_READ;
++
++      mode =
++          gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
++                         mnt);
++
++      if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
++              security_audit(GR_ACCESS_ACL_MSG, "successful",
++                             gr_to_filename(dentry, mnt),
++                             reqmode & GR_READ ? " reading" : "",
++                             reqmode & GR_WRITE ? " writing" : "",
++                             reqmode & GR_EXEC ? " executing" : "",
++                             DEFAULTSECARGS);
++              return reqmode;
++      } else
++          if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
++      {
++              security_alert(GR_ACCESS_ACL_MSG, "denied",
++                             gr_to_filename(dentry, mnt),
++                             reqmode & GR_READ ? " reading" : "",
++                             reqmode & GR_WRITE ? " writing" : "",
++                             reqmode & GR_EXEC ? " executing" : "",
++                             DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely((mode & reqmode) != reqmode))
++              return 0;
++
++      return reqmode;
++}
++
++#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
++{ \
++      __u32 mode; \
++      \
++      mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
++      \
++      if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
++              security_audit(fmt, "successful", \
++                              gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
++              return mode; \
++      } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
++              security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
++                              DEFAULTSECARGS); \
++              return 0; \
++      } else if (unlikely((mode & (reqmode)) != (reqmode))) \
++              return 0; \
++      \
++      return (reqmode); \
++}
++
++__u32
++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
++{
++      generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
++                   mode_t mode)
++{
++      if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
++              generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
++                                 GR_FCHMOD_ACL_MSG);
++      } else {
++              generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
++      }
++}
++
++__u32
++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
++                  mode_t mode)
++{
++      if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
++              generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
++                                 GR_CHMOD_ACL_MSG);
++      } else {
++              generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
++      }
++}
++
++__u32
++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
++                         GR_UNIXCONNECT_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
++                    const ino_t ino)
++{
++      if (likely((unsigned long)(dentry->d_inode))) {
++              struct dentry d = *dentry;
++              struct inode inode = *(dentry->d_inode);
++
++              inode.i_ino = ino;
++              d.d_inode = &inode;
++
++              if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
++                      return 0;
++      }
++
++      return 1;
++}
++
++__u32
++gr_acl_handle_link(const struct dentry * new_dentry,
++                 const struct dentry * parent_dentry,
++                 const struct vfsmount * parent_mnt,
++                 const struct dentry * old_dentry,
++                 const struct vfsmount * old_mnt, const char *to)
++{
++      __u32 needmode = GR_WRITE | GR_CREATE;
++      __u32 mode;
++
++      mode =
++          gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
++                        old_mnt);
++
++      if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
++              security_audit(GR_LINK_ACL_MSG, "successful",
++                             gr_to_filename(old_dentry, old_mnt), to,
++                             DEFAULTSECARGS);
++              return mode;
++      } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
++              security_alert(GR_LINK_ACL_MSG, "denied",
++                             gr_to_filename(old_dentry, old_mnt), to,
++                             DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely((mode & needmode) != needmode))
++              return 0;
++
++      return (GR_WRITE | GR_CREATE);
++}
++
++__u32
++gr_acl_handle_symlink(const struct dentry * new_dentry,
++                    const struct dentry * parent_dentry,
++                    const struct vfsmount * parent_mnt, const char *from)
++{
++      __u32 needmode = GR_WRITE | GR_CREATE;
++      __u32 mode;
++
++      mode =
++          gr_check_create(new_dentry, parent_dentry, parent_mnt,
++                          GR_CREATE | GR_AUDIT_CREATE |
++                          GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
++
++      if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
++              security_audit(GR_SYMLINK_ACL_MSG, "successful",
++                             from, gr_to_filename(new_dentry, parent_mnt),
++                             DEFAULTSECARGS);
++              return mode;
++      } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
++              security_alert(GR_SYMLINK_ACL_MSG, "denied",
++                             from, gr_to_filename(new_dentry, parent_mnt),
++                             DEFAULTSECARGS);
++              return 0;
++      } else if (unlikely((mode & needmode) != needmode))
++              return 0;
++
++      return (GR_WRITE | GR_CREATE);
++}
++
++#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
++{ \
++      __u32 mode; \
++      \
++      mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
++      \
++      if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
++              security_audit(fmt, "successful", \
++                              gr_to_filename(new_dentry, parent_mnt), \
++                              DEFAULTSECARGS); \
++              return mode; \
++      } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
++              security_alert(fmt, "denied", \
++                              gr_to_filename(new_dentry, parent_mnt), \
++                              DEFAULTSECARGS); \
++              return 0; \
++      } else if (unlikely((mode & (reqmode)) != (reqmode))) \
++              return 0; \
++      \
++      return (reqmode); \
++}
++
++__u32
++gr_acl_handle_mknod(const struct dentry * new_dentry,
++                  const struct dentry * parent_dentry,
++                  const struct vfsmount * parent_mnt,
++                  const int mode)
++{
++      __u32 reqmode = GR_WRITE | GR_CREATE;
++      if (unlikely(mode & (S_ISUID | S_ISGID)))
++              reqmode |= GR_SETID;
++
++      generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
++                                reqmode, GR_MKNOD_ACL_MSG);
++}
++
++__u32
++gr_acl_handle_mkdir(const struct dentry *new_dentry,
++                  const struct dentry *parent_dentry,
++                  const struct vfsmount *parent_mnt)
++{
++      generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
++                                GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
++}
++
++#define RENAME_CHECK_SUCCESS(old, new) \
++      (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
++       ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
++
++int
++gr_acl_handle_rename(struct dentry *new_dentry,
++                   struct dentry *parent_dentry,
++                   const struct vfsmount *parent_mnt,
++                   struct dentry *old_dentry,
++                   struct inode *old_parent_inode,
++                   struct vfsmount *old_mnt, const char *newname)
++{
++      __u8 gr_replace = 1;
++      __u32 comp1, comp2;
++      int error = 0;
++
++      if (unlikely(!gr_acl_is_enabled()))
++              return 1;
++
++      if (!new_dentry->d_inode) {
++              gr_replace = 0;
++
++              comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
++                                      GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
++                                      GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
++              comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
++                                     GR_DELETE | GR_AUDIT_DELETE |
++                                     GR_AUDIT_READ | GR_AUDIT_WRITE |
++                                     GR_SUPPRESS, old_mnt);
++      } else {
++              comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
++                                     GR_CREATE | GR_DELETE |
++                                     GR_AUDIT_CREATE | GR_AUDIT_DELETE |
++                                     GR_AUDIT_READ | GR_AUDIT_WRITE |
++                                     GR_SUPPRESS, parent_mnt);
++              comp2 =
++                  gr_search_file(old_dentry,
++                                 GR_READ | GR_WRITE | GR_AUDIT_READ |
++                                 GR_DELETE | GR_AUDIT_DELETE |
++                                 GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
++      }
++
++      if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
++          ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
++              security_audit(GR_RENAME_ACL_MSG, "successful",
++                             gr_to_filename(old_dentry, old_mnt),
++                             newname, DEFAULTSECARGS);
++      else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
++               && !(comp2 & GR_SUPPRESS)) {
++              security_alert(GR_RENAME_ACL_MSG, "denied",
++                             gr_to_filename(old_dentry, old_mnt), newname,
++                             DEFAULTSECARGS);
++              error = -EACCES;
++      } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
++              error = -EACCES;
++
++      if (error)
++              return error;
++
++      error = gr_handle_rename(old_parent_inode, parent_dentry->d_inode,
++                               old_dentry, new_dentry, old_mnt, gr_replace);
++
++      return error;
++}
++
++void
++gr_acl_handle_exit(void)
++{
++      u16 id;
++      char *rolename;
++
++      if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
++              id = current->acl_role_id;
++              rolename = current->role->rolename;
++              gr_set_acls(1);
++              security_alert_good(GR_SPROLEL_ACL_MSG,
++                                  rolename, id, DEFAULTSECARGS);
++      }
++
++      if (current->exec_file) {
++              fput(current->exec_file);
++              current->exec_file = NULL;
++      }
++}
++
++int
++gr_acl_handle_procpidmem(const struct task_struct *task)
++{
++      if (unlikely(!gr_acl_is_enabled()))
++              return 0;
++
++      if (task->acl->mode & GR_PROTPROCFD)
++              return -EACCES;
++
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/gracl_ip.c linux-2.4.22-grsec-O1/grsecurity/gracl_ip.c
+--- linux-2.4.22/grsecurity/gracl_ip.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_ip.c        2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,235 @@
++/* 
++ * grsecurity/gracl_ip.c
++ * Copyright Brad Spengler 2002, 2003
++ *
++ */
++
++#include <linux/kernel.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <net/sock.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/net.h>
++#include <linux/in.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <linux/udp.h>
++#include <linux/smp_lock.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/gracl.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++#define GR_BIND       0x01
++#define GR_CONNECT    0x02
++
++static const char * gr_protocols[256] = {
++      "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
++      "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
++      "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
++      "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
++      "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
++      "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
++      "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
++      "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
++      "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
++      "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
++      "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
++      "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
++      "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
++      "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
++      "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
++      "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
++      "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
++      "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
++      "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
++      "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
++      "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
++      "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
++      "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
++      "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
++      "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
++      "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
++      "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
++      "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
++      "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
++      "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
++      "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
++      "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
++      };
++
++static const char * gr_socktypes[11] = {
++      "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
++      "unknown:7", "unknown:8", "unknown:9", "packet"
++      };
++
++static __inline__ const char *
++gr_proto_to_name(unsigned char proto)
++{
++      return gr_protocols[proto];
++}
++
++static __inline__ const char *
++gr_socktype_to_name(unsigned char type)
++{
++      return gr_socktypes[type];
++}
++
++int
++gr_search_socket(const int domain, const int type, const int protocol)
++{
++      struct acl_subject_label *curr;
++
++      if (unlikely(!gr_acl_is_enabled()))
++              goto exit;
++
++      if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
++          || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
++              goto exit;      // let the kernel handle it
++
++      curr = current->acl;
++
++      if (!curr->ips)
++              goto exit;
++
++      if ((curr->ip_type & (1 << type)) &&
++          (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
++              goto exit;
++
++      if (curr->mode & GR_LEARN) {
++              /* we don't place acls on raw sockets , and sometimes
++                 dgram/ip sockets are opened for ioctl and not
++                 bind/connect, so we'll fake a bind learn log */
++              if (type == SOCK_RAW || type == SOCK_PACKET) {
++                      __u32 fakeip = 0;
++                      security_learn(GR_IP_LEARN_MSG, current->role->rolename,
++                                     current->role->roletype, current->uid,
++                                     current->gid, current->exec_file ?
++                                     gr_to_filename(current->exec_file->f_dentry,
++                                     current->exec_file->f_vfsmnt) :
++                                     curr->filename, curr->filename,
++                                     NIPQUAD(fakeip), 0, type,
++                                     protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
++              } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
++                      __u32 fakeip = 0;
++                      security_learn(GR_IP_LEARN_MSG, current->role->rolename,
++                                     current->role->roletype, current->uid,
++                                     current->gid, current->exec_file ?
++                                     gr_to_filename(current->exec_file->f_dentry,
++                                     current->exec_file->f_vfsmnt) :
++                                     curr->filename, curr->filename,
++                                     NIPQUAD(fakeip), 0, type,
++                                     protocol, GR_BIND, NIPQUAD(current->curr_ip));
++              }
++              /* we'll log when they use connect or bind */
++              goto exit;
++      }
++
++      security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
++                     gr_proto_to_name(protocol), DEFAULTSECARGS);
++
++      return 0;
++      exit:
++      return 1;
++}
++
++static __inline__ int
++gr_search_connectbind(const int mode, const struct sock *sk,
++                    const struct sockaddr_in *addr, const int type)
++{
++      struct acl_subject_label *curr;
++      struct acl_ip_label *ip;
++      unsigned long i;
++      __u32 ip_addr = 0;
++      __u16 ip_port = 0;
++
++      if (unlikely(!gr_acl_is_enabled() || sk->family != PF_INET))
++              return 1;
++
++      curr = current->acl;
++
++      if (!curr->ips)
++              return 1;
++
++      ip_addr = addr->sin_addr.s_addr;
++      ip_port = ntohs(addr->sin_port);
++
++      for (i = 0; i < curr->ip_num; i++) {
++              ip = *(curr->ips + i);
++              if ((ip->mode & mode) &&
++                  (ip_port >= ip->low) &&
++                  (ip_port <= ip->high) &&
++                  ((ntohl(ip_addr) & ip->netmask) ==
++                   (ntohl(ip->addr) & ip->netmask))
++                  && (ip->
++                      proto[sk->protocol / 32] & (1 << (sk->protocol % 32)))
++                  && (ip->type & (1 << type)))
++                      return 1;
++      }
++
++      if (curr->mode & GR_LEARN) {
++              security_learn(GR_IP_LEARN_MSG, current->role->rolename,
++                             current->role->roletype, current->uid,
++                             current->gid, current->exec_file ?
++                             gr_to_filename(current->exec_file->f_dentry,
++                             current->exec_file->f_vfsmnt) :
++                             curr->filename, curr->filename,
++                             NIPQUAD(ip_addr), ip_port, type,
++                             sk->protocol, mode, NIPQUAD(current->curr_ip));
++              return 1;
++      }
++
++      if (mode == GR_BIND)
++              security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
++                             gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
++                             DEFAULTSECARGS);
++      else if (mode == GR_CONNECT)
++              security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
++                             gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
++                             DEFAULTSECARGS);
++
++      return 0;
++}
++
++int
++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
++{
++      return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
++}
++
++int
++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
++{
++      return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
++}
++
++int
++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
++{
++      if (addr)
++              return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
++      else {
++              struct sockaddr_in sin;
++
++              sin.sin_addr.s_addr = sk->daddr;
++              sin.sin_port = sk->dport;
++
++              return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
++      }
++}
++
++int
++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
++{
++      struct sockaddr_in sin;
++
++      if (unlikely(skb->len < sizeof (struct udphdr)))
++              return 1;       // skip this packet
++
++      sin.sin_addr.s_addr = skb->nh.iph->saddr;
++      sin.sin_port = skb->h.uh->source;
++
++      return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
++}
+diff -urN linux-2.4.22/grsecurity/gracl_learn.c linux-2.4.22-grsec-O1/grsecurity/gracl_learn.c
+--- linux-2.4.22/grsecurity/gracl_learn.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_learn.c     2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,228 @@
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/poll.h>
++#include <linux/smp_lock.h>
++#include <linux/string.h>
++#include <linux/file.h>
++#include <linux/types.h>
++#include <linux/vmalloc.h>
++#include <linux/grinternal.h>
++
++extern ssize_t write_grsec_handler(struct file * file, const char * buf,
++                                 size_t count, loff_t *ppos);
++extern int gr_acl_is_enabled(void);
++
++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
++static DECLARE_WAIT_QUEUE_HEAD(input_wait);
++static atomic_t learn_buffer_count = ATOMIC_INIT(0);
++static int gr_learn_attached;
++
++#define LEARN_BUFFER_SLOTS 256
++#define LEARN_BUFFER_SIZE 16384
++
++static spinlock_t learn_buffer_lock[LEARN_BUFFER_SLOTS] = { [0 ... (LEARN_BUFFER_SLOTS - 1)] = SPIN_LOCK_UNLOCKED };
++static char *learn_buffer[LEARN_BUFFER_SLOTS];
++static int learn_buffer_len[LEARN_BUFFER_SLOTS];
++
++static ssize_t
++read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
++{
++      DECLARE_WAITQUEUE(wait, current);
++      ssize_t retval = 0;
++      char *tmp;
++      unsigned int len;
++      int i;
++
++      add_wait_queue(&learn_wait, &wait);
++      set_current_state(TASK_INTERRUPTIBLE);
++      do {
++              if (atomic_read(&learn_buffer_count) > 1)
++                      break;
++
++              if (file->f_flags & O_NONBLOCK) {
++                      retval = -EAGAIN;
++                      goto out;
++              }
++              if (signal_pending(current)) {
++                      retval = -ERESTARTSYS;
++                      goto out;
++              }
++
++              schedule();
++      } while (1);
++
++
++      for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
++              spin_lock(&learn_buffer_lock[i]);
++              len = learn_buffer_len[i];
++              tmp = learn_buffer[i];
++              if (!len || !tmp) {
++                      spin_unlock(&learn_buffer_lock[i]);
++                      continue;
++              }
++              learn_buffer[i] = NULL;
++              learn_buffer_len[i] = 0;
++              spin_unlock(&learn_buffer_lock[i]);
++
++              if (count < ((i * LEARN_BUFFER_SIZE) + len)) {
++                      retval = -EINVAL;
++                      vfree(tmp);
++                      goto out;
++              }
++              if (copy_to_user(buf + (i * LEARN_BUFFER_SIZE), tmp, len)) {
++                      retval = -EFAULT;
++                      vfree(tmp);
++                      goto out;
++              }
++
++              retval += len;
++              vfree(tmp);
++              atomic_dec(&learn_buffer_count);
++              atomic_dec(&learn_buffer_count);
++      }
++
++      wake_up(&input_wait);
++out:
++      set_current_state(TASK_RUNNING);
++      remove_wait_queue(&learn_wait, &wait);
++      return retval;
++}
++
++static unsigned int
++poll_learn(struct file * file, poll_table * wait)
++{
++      poll_wait(file, &learn_wait, wait);
++
++      if (atomic_read(&learn_buffer_count) > 1)
++              return (POLLIN | POLLRDNORM);
++
++      return 0;
++}
++
++void
++gr_clear_learn_entries(void)
++{
++      int i;
++
++      atomic_set(&learn_buffer_count, 0);
++      wake_up(&input_wait);
++      
++      for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
++              if (learn_buffer_len[i]) {
++                      vfree(learn_buffer[i]);
++                      learn_buffer[i] = NULL;
++                      learn_buffer_len[i] = 0;
++              }
++      }
++
++      return;
++}
++
++void
++gr_add_learn_entry(const char *fmt, ...)
++{
++      DECLARE_WAITQUEUE(wait, current);
++      va_list args;
++      char *tmpbuf;
++      char *buf;
++      int i;
++      unsigned int len;
++
++      if (!gr_learn_attached)
++              return;
++
++      tmpbuf = vmalloc(LEARN_BUFFER_SIZE);
++
++      if (tmpbuf == NULL)
++              return;
++
++      va_start(args, fmt);
++      len = vsnprintf(tmpbuf, LEARN_BUFFER_SIZE, fmt, args);
++      va_end(args);
++
++      if (len < 0)
++              len = LEARN_BUFFER_SIZE - 1;
++
++      buf = vmalloc(len + 1);
++
++      if (buf == NULL) {
++              vfree(tmpbuf);
++              return;
++      }
++
++      memcpy(buf, tmpbuf, len);
++      buf[len] = '\0';
++      vfree(tmpbuf);
++
++      add_wait_queue(&input_wait, &wait);
++
++      atomic_inc(&learn_buffer_count);
++      if (atomic_read(&learn_buffer_count) > ((2 * (LEARN_BUFFER_SLOTS - 1)) + 1)) {
++              /* don't sleep under the BKL */
++//            if (unlikely(current->lock_depth >= 0)) {
++              remove_wait_queue(&input_wait, &wait);
++              atomic_dec(&learn_buffer_count);
++              vfree(buf);
++              return;
++//            }
++//            sleep_on(&input_wait);
++      }
++
++      if (!gr_acl_is_enabled()) {
++              remove_wait_queue(&input_wait, &wait);
++              atomic_dec(&learn_buffer_count);
++              vfree(buf);
++              return;
++      }
++
++      for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
++              spin_lock(&learn_buffer_lock[i]);
++
++              if (learn_buffer_len[i]) {
++                      spin_unlock(&learn_buffer_lock[i]);
++                      continue;
++              }
++
++              learn_buffer[i] = buf;
++
++              learn_buffer_len[i] = len + 1;
++
++              atomic_inc(&learn_buffer_count);
++              spin_unlock(&learn_buffer_lock[i]);
++              break;
++      }
++
++      remove_wait_queue(&input_wait, &wait);
++      wake_up_interruptible(&learn_wait);
++
++      return;
++}
++
++static int
++open_learn(struct inode *inode, struct file *file)
++{
++      if (file->f_mode & FMODE_READ && gr_learn_attached)
++              return -EBUSY;
++      else if (file->f_mode & FMODE_READ)
++              gr_learn_attached = 1;
++
++      return 0;
++}
++
++static int
++close_learn(struct inode *inode, struct file *file)
++{
++      if (file->f_mode & FMODE_READ)
++              gr_learn_attached = 0;
++
++      return 0;
++}
++              
++struct file_operations grsec_fops = {
++      read:           read_learn,
++      write:          write_grsec_handler,
++      open:           open_learn,
++      release:        close_learn,
++      poll:           poll_learn,
++};
+diff -urN linux-2.4.22/grsecurity/gracl_res.c linux-2.4.22-grsec-O1/grsecurity/gracl_res.c
+--- linux-2.4.22/grsecurity/gracl_res.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_res.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,45 @@
++/* resource handling routines (c) Brad Spengler 2002, 2003 */
++
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/gracl.h>
++#include <linux/grinternal.h>
++
++static const char *restab_log[11] = {
++      "RLIMIT_CPU",
++      "RLIMIT_FSIZE",
++      "RLIMIT_DATA",
++      "RLIMIT_STACK",
++      "RLIMIT_CORE",
++      "RLIMIT_RSS",
++      "RLIMIT_NPROC",
++      "RLIMIT_NOFILE",
++      "RLIMIT_MEMLOCK",
++      "RLIMIT_AS",
++      "RLIMIT_LOCKS"
++};
++
++__inline__ void
++gr_log_resource(const struct task_struct *task,
++              const int res, const unsigned long wanted)
++{
++      if (unlikely(res == RLIMIT_NPROC && 
++          (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
++           cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
++              return;
++
++      if (unlikely(wanted >= task->rlim[res].rlim_cur &&
++                   task->rlim[res].rlim_cur != RLIM_INFINITY))
++              security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
++                             task->rlim[res].rlim_cur,
++                             gr_task_fullpath(task), task->comm,
++                             task->pid, task->uid, task->euid,
++                             task->gid, task->egid,
++                             gr_parent_task_fullpath(task),
++                             task->p_pptr->comm,
++                             task->p_pptr->pid, task->p_pptr->uid, 
++                             task->p_pptr->euid, task->p_pptr->gid,
++                             task->p_pptr->egid);
++
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/gracl_segv.c linux-2.4.22-grsec-O1/grsecurity/gracl_segv.c
+--- linux-2.4.22/grsecurity/gracl_segv.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_segv.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,327 @@
++/* 
++ * grsecurity/gracl_segv.c
++ * Copyright Brad Spengler 2002, 2003
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/mman.h>
++#include <net/sock.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/net.h>
++#include <linux/in.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/gracl.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++static struct crash_uid *uid_set;
++static unsigned short uid_used;
++static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
++extern rwlock_t gr_inode_lock;
++extern __inline__ struct acl_subject_label *lookup_acl_subj_label(const ino_t
++                                                                inode,
++                                                                const kdev_t
++                                                                dev,
++                                                                struct
++                                                                acl_role_label
++                                                                *role);
++
++int
++gr_init_uidset(void)
++{
++      uid_set =
++          kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
++      uid_used = 0;
++
++      return uid_set ? 1 : 0;
++}
++
++void
++gr_free_uidset(void)
++{
++      if (uid_set)
++              kfree(uid_set);
++
++      return;
++}
++
++int
++gr_find_uid(const uid_t uid)
++{
++      struct crash_uid *tmp = uid_set;
++      uid_t buid;
++      int low = 0, high = uid_used - 1, mid;
++
++      while (high >= low) {
++              mid = (low + high) >> 1;
++              buid = tmp[mid].uid;
++              if (buid == uid)
++                      return mid;
++              if (buid > uid)
++                      high = mid - 1;
++              if (buid < uid)
++                      low = mid + 1;
++      }
++
++      return -1;
++}
++
++static __inline__ void
++gr_insertsort(void)
++{
++      unsigned short i, j;
++      struct crash_uid index;
++
++      for (i = 1; i < uid_used; i++) {
++              index = uid_set[i];
++              j = i;
++              while ((j > 0) && uid_set[j - 1].uid > index.uid) {
++                      uid_set[j] = uid_set[j - 1];
++                      j--;
++              }
++              uid_set[j] = index;
++      }
++
++      return;
++}
++
++static __inline__ void
++gr_insert_uid(const uid_t uid, const unsigned long expires)
++{
++      int loc;
++
++      if (uid_used == GR_UIDTABLE_MAX)
++              return;
++
++      loc = gr_find_uid(uid);
++
++      if (loc >= 0) {
++              uid_set[loc].expires = expires;
++              return;
++      }
++
++      uid_set[uid_used].uid = uid;
++      uid_set[uid_used].expires = expires;
++      uid_used++;
++
++      gr_insertsort();
++
++      return;
++}
++
++void
++gr_remove_uid(const unsigned short loc)
++{
++      unsigned short i;
++
++      for (i = loc + 1; i < uid_used; i++)
++              uid_set[i - i] = uid_set[i];
++
++      uid_used--;
++
++      return;
++}
++
++int
++gr_check_crash_uid(const uid_t uid)
++{
++      int loc;
++
++      if (unlikely(!gr_acl_is_enabled()))
++              return 0;
++
++      read_lock(&gr_uid_lock);
++      loc = gr_find_uid(uid);
++      read_unlock(&gr_uid_lock);
++
++      if (loc < 0)
++              return 0;
++
++      write_lock(&gr_uid_lock);
++      if (time_before_eq(uid_set[loc].expires, jiffies))
++              gr_remove_uid(loc);
++      else {
++              write_unlock(&gr_uid_lock);
++              return 1;
++      }
++
++      write_unlock(&gr_uid_lock);
++      return 0;
++}
++
++static __inline__ int
++proc_is_setxid(const struct task_struct *task)
++{
++      if (task->uid != task->euid || task->uid != task->suid ||
++          task->uid != task->fsuid)
++              return 1;
++      if (task->gid != task->egid || task->gid != task->sgid ||
++          task->gid != task->fsgid)
++              return 1;
++
++      return 0;
++}
++static __inline__ int
++gr_fake_force_sig(int sig, struct task_struct *t)
++{
++      unsigned long int flags;
++
++      spin_lock_irqsave(&t->sigmask_lock, flags);
++      if (t->sig == NULL) {
++              spin_unlock_irqrestore(&t->sigmask_lock, flags);
++              return -ESRCH;
++      }
++
++      if (t->sig->action[sig - 1].sa.sa_handler == SIG_IGN)
++              t->sig->action[sig - 1].sa.sa_handler = SIG_DFL;
++      sigdelset(&t->blocked, sig);
++      recalc_sigpending(t);
++      spin_unlock_irqrestore(&t->sigmask_lock, flags);
++
++      return send_sig_info(sig, (void *) 1L, t);
++}
++
++void
++gr_handle_crash(struct task_struct *task, const int sig)
++{
++      struct acl_subject_label *curr;
++      struct acl_subject_label *curr2;
++      struct task_struct *tsk;
++
++      if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
++              return;
++
++      if (unlikely(!gr_acl_is_enabled()))
++              return;
++
++      curr = task->acl;
++
++      if (!(curr->resmask & (1 << GR_CRASH_RES)))
++              return;
++
++      if (time_before_eq(curr->expires, jiffies)) {
++              curr->expires = 0;
++              curr->crashes = 0;
++      }
++
++      curr->crashes++;
++
++      if (!curr->expires)
++              curr->expires = jiffies + curr->res[GR_CRASH_RES].rlim_max;
++
++      if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
++          time_after(curr->expires, jiffies)) {
++              if (task->uid && proc_is_setxid(task)) {
++                      security_alert(GR_SEGVSTART_ACL_MSG,
++                                     gr_task_fullpath(task), task->comm,
++                                     task->pid, task->uid, task->euid,
++                                     task->gid, task->egid,
++                                     gr_parent_task_fullpath(task),
++                                     task->p_pptr->comm, task->p_pptr->pid,
++                                     task->p_pptr->uid, task->p_pptr->euid,
++                                     task->p_pptr->gid, task->p_pptr->egid,
++                                     task->uid,
++                                     curr->res[GR_CRASH_RES].rlim_max / HZ);
++                      write_lock(&gr_uid_lock);
++                      gr_insert_uid(task->uid, curr->expires);
++                      write_unlock(&gr_uid_lock);
++                      curr->expires = 0;
++                      curr->crashes = 0;
++                      read_lock(&tasklist_lock);
++                      for_each_task(tsk) {
++                              if (tsk != task && tsk->uid == task->uid)
++                                      gr_fake_force_sig(SIGKILL, tsk);
++                      }
++                      read_unlock(&tasklist_lock);
++              } else {
++                      security_alert(GR_SEGVNOSUID_ACL_MSG,
++                                     gr_task_fullpath(task), task->comm,
++                                     task->pid, task->uid, task->euid,
++                                     task->gid, task->egid,
++                                     gr_parent_task_fullpath(task),
++                                     task->p_pptr->comm, task->p_pptr->pid,
++                                     task->p_pptr->uid, task->p_pptr->euid,
++                                     task->p_pptr->gid, task->p_pptr->egid,
++                                     kdevname(curr->device), curr->inode,
++                                     curr->res[GR_CRASH_RES].rlim_max / HZ);
++                      read_lock(&tasklist_lock);
++                      for_each_task(tsk) {
++                              if (likely(tsk != task)) {
++                                      curr2 = tsk->acl;
++
++                                      if (curr2->device == curr->device &&
++                                          curr2->inode == curr->inode)
++                                              gr_fake_force_sig(SIGKILL, tsk);
++                              }
++                      }
++                      read_unlock(&tasklist_lock);
++              }
++      }
++
++      return;
++}
++
++int
++gr_check_crash_exec(const struct file *filp)
++{
++      struct acl_subject_label *curr;
++
++      if (unlikely(!gr_acl_is_enabled()))
++              return 0;
++
++      read_lock(&gr_inode_lock);
++      curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
++                                   filp->f_dentry->d_inode->i_dev,
++                                   current->role);
++      read_unlock(&gr_inode_lock);
++
++      if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
++          (!curr->crashes && !curr->expires))
++              return 0;
++
++      if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
++          time_after(curr->expires, jiffies))
++              return 1;
++      else if (time_before_eq(curr->expires, jiffies)) {
++              curr->crashes = 0;
++              curr->expires = 0;
++      }
++
++      return 0;
++}
++
++void
++gr_handle_alertkill(void)
++{
++      struct acl_subject_label *curracl;
++      __u32 curr_ip;
++      struct task_struct *task;
++
++      if (unlikely(!gr_acl_is_enabled()))
++              return;
++
++      curracl = current->acl;
++      curr_ip = current->curr_ip;
++
++      if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
++          (curr_ip != 0xffffffff)) {
++              read_lock(&tasklist_lock);
++              for_each_task(task) {
++                      if (task->curr_ip == curr_ip)
++                              gr_fake_force_sig(SIGKILL, task);
++              }
++              read_unlock(&tasklist_lock);
++      } else if (curracl->mode & GR_KILLPROC)
++              gr_fake_force_sig(SIGKILL, current);
++
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/gracl_shm.c linux-2.4.22-grsec-O1/grsecurity/gracl_shm.c
+--- linux-2.4.22/grsecurity/gracl_shm.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/gracl_shm.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,36 @@
++/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
++
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/file.h>
++#include <linux/ipc.h>
++#include <linux/gracl.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++int
++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
++              const time_t shm_createtime, const uid_t cuid, const int shmid)
++{
++      struct task_struct *task;
++
++      if (!gr_acl_is_enabled())
++              return 1;
++
++      task = find_task_by_pid(shm_cprid);
++
++      if (unlikely(!task))
++              task = find_task_by_pid(shm_lapid);
++
++      if (unlikely(task && ((task->start_time < shm_createtime) ||
++                            (task->pid == shm_lapid)) &&
++                   (task->acl->mode & GR_PROTSHM) &&
++                   (task->acl != current->acl))) {
++              security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
++                             DEFAULTSECARGS);
++              return 0;
++      }
++
++      return 1;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_chdir.c linux-2.4.22-grsec-O1/grsecurity/grsec_chdir.c
+--- linux-2.4.22/grsecurity/grsec_chdir.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_chdir.c     2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,20 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++void
++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
++      if ((grsec_enable_chdir && grsec_enable_group &&
++           in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
++                                            !grsec_enable_group)) {
++              security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
++                             DEFAULTSECARGS);
++      }
++#endif
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_chroot.c linux-2.4.22-grsec-O1/grsecurity/grsec_chroot.c
+--- linux-2.4.22/grsecurity/grsec_chroot.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_chroot.c    2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,333 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/types.h>
++#include <linux/grinternal.h>
++
++int
++gr_handle_chroot_unix(const pid_t pid)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
++      struct task_struct *p, **htable;
++
++      if (unlikely(!grsec_enable_chroot_unix))
++              return 1;
++
++      if (likely(!proc_is_chrooted(current)))
++              return 1;
++
++      read_lock(&tasklist_lock);
++
++      htable = &pidhash[pid_hashfn(pid)];
++
++      for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ;
++
++      if (unlikely(p && !have_same_root(current, p))) {
++              read_unlock(&tasklist_lock);
++              security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
++              return 0;
++      }
++      read_unlock(&tasklist_lock);
++#endif
++      return 1;
++}
++
++int
++gr_handle_chroot_nice(void)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
++      if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
++              security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
++      if (grsec_enable_chroot_nice && (!have_same_root(p, current)
++                                       || (have_same_root(p, current)
++                                           && (niceval < task_nice(p))
++                                           && proc_is_chrooted(current)))) {
++              security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
++                             DEFAULTSECARGS);
++              return -ESRCH;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_chroot_capset(const struct task_struct *target)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
++      if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
++          !have_same_root(current, target)) {
++              security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
++                             DEFAULTSECARGS);
++              return 1;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_chroot_rawio(const struct inode *inode)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
++      if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
++          inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
++              return 1;
++#endif
++      return 0;
++}
++
++int
++gr_pid_is_chrooted(const struct task_struct *p)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
++      if (!grsec_enable_chroot_findtask || (current->pid <= 1))
++              return 0;
++
++      if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
++          child_reaper && child_reaper->fs && child_reaper->fs->root &&
++          child_reaper->fs->root->d_inode && current && current->fs &&
++          current->fs->root && current->fs->root->d_inode) {
++              if (proc_is_chrooted(current) && !have_same_root(current, p))
++                      return 1;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
++      if (!grsec_enable_chroot_fchdir)
++              return 1;
++
++      if (!proc_is_chrooted(current))
++              return 1;
++      else {
++              struct dentry *dentry = u_dentry;
++              struct vfsmount *mnt = u_mnt;
++              struct dentry *realroot;
++              struct vfsmount *realrootmnt;
++              struct dentry *currentroot;
++              struct vfsmount *currentmnt;
++
++              read_lock(&child_reaper->fs->lock);
++              realrootmnt = mntget(child_reaper->fs->rootmnt);
++              realroot = dget(child_reaper->fs->root);
++              read_unlock(&child_reaper->fs->lock);
++
++              read_lock(&current->fs->lock);
++              currentmnt = mntget(current->fs->rootmnt);
++              currentroot = dget(current->fs->root);
++              read_unlock(&current->fs->lock);
++
++              spin_lock(&dcache_lock);
++              for (;;) {
++                      if (unlikely
++                          ((dentry == realroot && mnt == realrootmnt)
++                           || (dentry == currentroot && mnt == currentmnt)))
++                              break;
++                      if (unlikely
++                          (dentry == mnt->mnt_root || IS_ROOT(dentry))) {
++                              if (mnt->mnt_parent == mnt)
++                                      break;
++                              dentry = mnt->mnt_mountpoint;
++                              mnt = mnt->mnt_parent;
++                              continue;
++                      }
++                      dentry = dentry->d_parent;
++              }
++              spin_unlock(&dcache_lock);
++
++              dput(currentroot);
++              mntput(currentmnt);
++
++              if (dentry == realroot && mnt == realrootmnt) {
++                      /* ok, they're definitely trying to fchdir outside of the
++                         chroot. */
++                      dput(realroot);
++                      mntput(realrootmnt);
++                      security_alert(GR_CHROOT_FCHDIR_MSG,
++                                     gr_to_filename(u_dentry, u_mnt),
++                                     DEFAULTSECARGS);
++                      return 0;
++              } else {
++                      dput(realroot);
++                      mntput(realrootmnt);
++                      return 1;
++              }
++      }
++#endif
++      return 1;
++}
++
++int
++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
++              const time_t shm_createtime)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
++      struct task_struct *p, **htable;
++
++      if (unlikely(!grsec_enable_chroot_shmat))
++              return 1;
++
++      if (likely(!proc_is_chrooted(current)))
++              return 1;
++
++      read_lock(&tasklist_lock);
++
++      htable = &pidhash[pid_hashfn(shm_cprid)];
++
++      for (p = *htable; p && p->pid != shm_cprid; p = p->pidhash_next) ;
++
++      if (unlikely(p && !have_same_root(current, p) &&
++                   (p->start_time < shm_createtime))) {
++              read_unlock(&tasklist_lock);
++              security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
++              return 0;
++      }
++
++      if (unlikely(!p)) {
++              htable = &pidhash[pid_hashfn(shm_lapid)];
++              for (p = *htable; p && p->pid != shm_lapid;
++                   p = p->pidhash_next) ;
++
++              if (unlikely(p && !have_same_root(current, p))) {
++                      read_unlock(&tasklist_lock);
++                      security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
++                      return 0;
++              }
++      }
++
++      read_unlock(&tasklist_lock);
++#endif
++      return 1;
++}
++
++void
++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
++      if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
++              security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
++                             DEFAULTSECARGS);
++#endif
++      return;
++}
++
++int
++gr_handle_chroot_mknod(const struct dentry *dentry,
++                     const struct vfsmount *mnt, const int mode)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
++      if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) &&
++          proc_is_chrooted(current)) {
++              security_alert(GR_MKNOD_CHROOT_MSG,
++                             gr_to_filename(dentry, mnt), DEFAULTSECARGS);
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_chroot_mount(const struct dentry *dentry,
++                     const struct vfsmount *mnt, const char *dev_name)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
++      if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
++              security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
++                             gr_to_filename(dentry, mnt), DEFAULTSECARGS);
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_chroot_pivot(void)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
++      if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
++              security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
++      if (grsec_enable_chroot_double && proc_is_chrooted(current)) {
++              security_alert(GR_CHROOT_CHROOT_MSG,
++                             gr_to_filename(dentry, mnt), DEFAULTSECARGS);
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
++
++void
++gr_handle_chroot_caps(struct task_struct *task)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
++      if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
++              task->cap_permitted =
++                  cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
++              task->cap_inheritable =
++                  cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
++              task->cap_effective =
++                  cap_drop(task->cap_effective, GR_CHROOT_CAPS);
++      }
++#endif
++      return;
++}
++
++int
++gr_handle_chroot_sysctl(const int op)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
++      if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
++          && (op & 002))
++              return -EACCES;
++#endif
++      return 0;
++}
++
++void
++gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
++      if (grsec_enable_chroot_chdir)
++              set_fs_pwd(current->fs, mnt, dentry);
++#endif
++      return;
++}
++
++int
++gr_handle_chroot_chmod(const struct dentry *dentry,
++                     const struct vfsmount *mnt, const int mode)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
++      if (grsec_enable_chroot_chmod &&
++          ((mode & S_ISUID) || (mode & S_ISGID)) &&
++          proc_is_chrooted(current)) {
++              security_alert(GR_CHMOD_CHROOT_MSG,
++                             gr_to_filename(dentry, mnt), DEFAULTSECARGS);
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_disabled.c linux-2.4.22-grsec-O1/grsecurity/grsec_disabled.c
+--- linux-2.4.22/grsecurity/grsec_disabled.c   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_disabled.c  2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,380 @@
++/* 
++ * when grsecurity is disabled, compile all external functions into nothing
++ */
++
++#include <linux/kernel.h>
++#include <linux/config.h>
++#include <linux/sched.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/kdev_t.h>
++#include <linux/net.h>
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/skbuff.h>
++#include <linux/sysctl.h>
++
++#ifdef CONFIG_SYSCTL
++__u32
++gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
++{
++      return mode;
++}
++#endif
++
++int
++gr_acl_is_enabled(void)
++{
++      return 0;
++}
++
++int
++gr_handle_rawio(const struct inode *inode)
++{
++      return 0;
++}
++
++void
++gr_acl_handle_psacct(struct task_struct *task, const long code)
++{
++      return;
++}
++
++int
++gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      return 0;
++}
++
++int
++gr_handle_mmap(const struct file *filp, const unsigned long prot)
++{
++      return 0;
++}
++
++int
++gr_handle_ptrace(struct task_struct *task, const long request)
++{
++      return 0;
++}
++
++void
++gr_learn_resource(const struct task_struct *task,
++                const int res, const unsigned long wanted)
++{
++      return;
++}
++
++int
++gr_set_acls(const int type)
++{
++      return 0;
++}
++
++int
++gr_check_hidden_task(const struct task_struct *tsk)
++{
++      return 0;
++}
++
++int
++gr_check_protected_task(const struct task_struct *task)
++{
++      return 0;
++}
++
++__inline__ void
++gr_copy_label(struct task_struct *tsk)
++{
++      return;
++}
++
++void
++gr_set_pax_flags(struct task_struct *task)
++{
++      return;
++}
++
++void
++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      return;
++}
++
++void
++gr_handle_delete(const ino_t ino, const kdev_t dev)
++{
++      return;
++}
++
++void
++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
++{
++      return;
++}
++
++void
++gr_handle_crash(struct task_struct *task, const int sig)
++{
++      return;
++}
++
++int
++gr_check_crash_exec(const struct file *filp)
++{
++      return 0;
++}
++
++int
++gr_check_crash_uid(const uid_t uid)
++{
++      return 0;
++}
++
++int
++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
++               struct dentry *old_dentry,
++               struct dentry *new_dentry,
++               struct vfsmount *mnt, const __u8 replace)
++{
++      return 0;
++}
++
++int
++gr_search_socket(const int family, const int type, const int protocol)
++{
++      return 1;
++}
++
++int
++gr_search_connectbind(const int mode, const struct socket *sock,
++                    const struct sockaddr_in *addr)
++{
++      return 1;
++}
++
++int
++gr_is_capable(const int cap)
++{
++      return 1;
++}
++
++void
++gr_handle_alertkill(void)
++{
++      return;
++}
++
++__u32
++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_hidden_file(const struct dentry * dentry,
++                        const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
++                 const int fmode)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++int
++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
++                 unsigned int *vm_flags)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_truncate(const struct dentry * dentry,
++                     const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_access(const struct dentry * dentry,
++                   const struct vfsmount * mnt, const int fmode)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
++                   mode_t mode)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
++                  mode_t mode)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++void
++grsecurity_init(void)
++{
++      return;
++}
++
++__u32
++gr_acl_handle_mknod(const struct dentry * new_dentry,
++                  const struct dentry * parent_dentry,
++                  const struct vfsmount * parent_mnt,
++                  const int mode)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_mkdir(const struct dentry * new_dentry,
++                  const struct dentry * parent_dentry,
++                  const struct vfsmount * parent_mnt)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_symlink(const struct dentry * new_dentry,
++                    const struct dentry * parent_dentry,
++                    const struct vfsmount * parent_mnt, const char *from)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_link(const struct dentry * new_dentry,
++                 const struct dentry * parent_dentry,
++                 const struct vfsmount * parent_mnt,
++                 const struct dentry * old_dentry,
++                 const struct vfsmount * old_mnt, const char *to)
++{
++      return 1;
++}
++
++int
++gr_acl_handle_rename(const struct dentry *new_dentry,
++                   const struct dentry *parent_dentry,
++                   const struct vfsmount *parent_mnt,
++                   const struct dentry *old_dentry,
++                   const struct inode *old_parent_inode,
++                   const struct vfsmount *old_mnt, const char *newname)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_filldir(const struct dentry * dentry,
++                    const struct vfsmount * mnt, const ino_t ino)
++{
++      return 1;
++}
++
++int
++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
++              const time_t shm_createtime, const uid_t cuid, const int shmid)
++{
++      return 1;
++}
++
++int
++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
++{
++      return 1;
++}
++
++int
++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
++{
++      return 1;
++}
++
++__u32
++gr_acl_handle_creat(const struct dentry * dentry,
++                  const struct dentry * p_dentry,
++                  const struct vfsmount * p_mnt, const int fmode,
++                  const int imode)
++{
++      return 1;
++}
++
++void
++gr_acl_handle_exit(void)
++{
++      return;
++}
++
++int
++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
++{
++      return 1;
++}
++
++void
++gr_set_role_label(const uid_t uid, const gid_t gid)
++{
++      return;
++}
++
++int
++gr_acl_handle_procpidmem(const struct task_struct *task)
++{
++      return 0;
++}
++
++int
++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
++{
++      return 1;
++}
++
++int
++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
++{
++      return 1;
++}
++
++void
++gr_set_kernel_label(struct task_struct *task)
++{
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_exec.c linux-2.4.22-grsec-O1/grsecurity/grsec_exec.c
+--- linux-2.4.22/grsecurity/grsec_exec.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_exec.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,70 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/types.h>
++#include <linux/grdefs.h>
++#include <linux/grinternal.h>
++#include <linux/capability.h>
++
++#include <asm/uaccess.h>
++
++int
++gr_handle_nproc(void)
++{
++#ifdef CONFIG_GRKERNSEC_EXECVE
++      if (grsec_enable_execve && current->user &&
++          (atomic_read(&current->user->processes) >
++           current->rlim[RLIMIT_NPROC].rlim_cur) &&
++          !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
++              security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
++              return -EAGAIN;
++      }
++#endif
++      return 0;
++}
++
++void
++gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
++{
++#ifdef CONFIG_GRKERNSEC_EXECLOG
++      char grarg[64] = { 0 };
++      __u8 execlen = 0;
++      unsigned int i;
++
++      if (!((grsec_enable_execlog && grsec_enable_group &&
++             in_group_p(grsec_audit_gid))
++            || (grsec_enable_execlog && !grsec_enable_group)))
++              return;
++
++      if (unlikely(!argv))
++              goto log;
++
++      for (i = 0; i < bprm->argc && execlen < 62; i++) {
++              char *p;
++              __u8 len;
++
++              if (get_user(p, argv + i))
++                      goto log;
++              if (!p)
++                      goto log;
++              len = strnlen_user(p, 62 - execlen);
++              if (len > 62 - execlen)
++                      len = 62 - execlen;
++              else if (len > 0)
++                      len--;
++              if (copy_from_user(grarg + execlen, p, len))
++                      goto log;
++              execlen += len;
++              *(grarg + execlen) = ' ';
++              *(grarg + execlen + 1) = '\0';
++              execlen++;
++      }
++
++      log:
++      security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
++                                                       bprm->file->f_vfsmnt),
++                     grarg, DEFAULTSECARGS);
++#endif
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_fifo.c linux-2.4.22-grsec-O1/grsecurity/grsec_fifo.c
+--- linux-2.4.22/grsecurity/grsec_fifo.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_fifo.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,24 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/grinternal.h>
++
++int
++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
++             const struct dentry *dir, const int flag, const int acc_mode)
++{
++#ifdef CONFIG_GRKERNSEC_FIFO
++      if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
++          !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
++          (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
++          (current->fsuid != dentry->d_inode->i_uid)) {
++              if (!permission(dentry->d_inode, acc_mode))
++                      security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
++                                     dentry->d_inode->i_uid,
++                                     dentry->d_inode->i_gid, DEFAULTSECARGS);
++              return -EACCES;
++      }
++#endif
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_fork.c linux-2.4.22-grsec-O1/grsecurity/grsec_fork.c
+--- linux-2.4.22/grsecurity/grsec_fork.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_fork.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,14 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++void
++gr_log_forkfail(const int retval)
++{
++#ifdef CONFIG_GRKERNSEC_FORKFAIL
++      if (grsec_enable_forkfail)
++              security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
++#endif
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_init.c linux-2.4.22-grsec-O1/grsecurity/grsec_init.c
+--- linux-2.4.22/grsecurity/grsec_init.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_init.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,210 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/smp_lock.h>
++#include <linux/gracl.h>
++#include <linux/slab.h>
++
++int grsec_enable_link;
++int grsec_enable_dmesg;
++int grsec_enable_fifo;
++int grsec_enable_execve;
++int grsec_enable_execlog;
++int grsec_enable_signal;
++int grsec_enable_forkfail;
++int grsec_enable_time;
++int grsec_enable_group;
++int grsec_audit_gid;
++int grsec_enable_chdir;
++int grsec_enable_audit_ipc;
++int grsec_enable_mount;
++int grsec_enable_chroot_findtask;
++int grsec_enable_chroot_mount;
++int grsec_enable_chroot_shmat;
++int grsec_enable_chroot_fchdir;
++int grsec_enable_chroot_double;
++int grsec_enable_chroot_pivot;
++int grsec_enable_chroot_chdir;
++int grsec_enable_chroot_chmod;
++int grsec_enable_chroot_mknod;
++int grsec_enable_chroot_nice;
++int grsec_enable_chroot_execlog;
++int grsec_enable_chroot_caps;
++int grsec_enable_chroot_sysctl;
++int grsec_enable_chroot_unix;
++int grsec_enable_tpe;
++int grsec_tpe_gid;
++int grsec_enable_tpe_all;
++int grsec_enable_randpid;
++int grsec_enable_randid;
++int grsec_enable_randisn;
++int grsec_enable_randsrc;
++int grsec_enable_randrpc;
++int grsec_enable_socket_all;
++int grsec_socket_all_gid;
++int grsec_enable_socket_client;
++int grsec_socket_client_gid;
++int grsec_enable_socket_server;
++int grsec_socket_server_gid;
++int grsec_lock;
++
++spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
++unsigned long grsec_alert_wtime = 0;
++unsigned long grsec_alert_fyet = 0;
++
++spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
++unsigned long grsec_alertgood_wtime = 0;
++unsigned long grsec_alertgood_fyet = 0;
++
++spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
++
++char *gr_shared_page[4][NR_CPUS];
++extern struct gr_arg *gr_usermode;
++extern unsigned char *gr_system_salt;
++extern unsigned char *gr_system_sum;
++
++void
++grsecurity_init(void)
++{
++      int i, j;
++      /* create the per-cpu shared pages */
++
++      for (j = 0; j < 4; j++) {
++              for (i = 0; i < NR_CPUS; i++) {
++                      gr_shared_page[j][i] = (char *) get_zeroed_page(GFP_KERNEL);
++                      if (!gr_shared_page[j][i]) {
++                              panic("Unable to allocate grsecurity shared page");
++                              return;
++                      }
++              }
++      }
++
++      /* allocate memory for authentication structure */
++      gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
++      gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
++      gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
++
++      if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
++              panic("Unable to allocate grsecurity authentication structure");
++              return;
++      }
++
++#ifndef CONFIG_GRKERNSEC_SYSCTL
++      grsec_lock = 1;
++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
++      grsec_enable_group = 1;
++      grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
++#endif
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
++      grsec_enable_chdir = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      grsec_enable_audit_ipc = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
++      grsec_enable_mount = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_LINK
++      grsec_enable_link = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_DMESG
++      grsec_enable_dmesg = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_FIFO
++      grsec_enable_fifo = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_EXECVE
++      grsec_enable_execve = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_EXECLOG
++      grsec_enable_execlog = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_SIGNAL
++      grsec_enable_signal = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_FORKFAIL
++      grsec_enable_forkfail = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_TIME
++      grsec_enable_time = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
++      grsec_enable_chroot_findtask = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
++      grsec_enable_chroot_unix = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
++      grsec_enable_chroot_mount = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
++      grsec_enable_chroot_fchdir = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
++      grsec_enable_chroot_shmat = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
++      grsec_enable_chroot_double = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
++      grsec_enable_chroot_pivot = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
++      grsec_enable_chroot_chdir = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
++      grsec_enable_chroot_chmod = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
++      grsec_enable_chroot_mknod = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
++      grsec_enable_chroot_nice = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
++      grsec_enable_chroot_execlog = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
++      grsec_enable_chroot_caps = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
++      grsec_enable_chroot_sysctl = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_TPE
++      grsec_enable_tpe = 1;
++      grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
++#ifdef CONFIG_GRKERNSEC_TPE_ALL
++      grsec_enable_tpe_all = 1;
++#endif
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDPID
++      grsec_enable_randpid = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDID
++      grsec_enable_randid = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDISN
++      grsec_enable_randisn = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDSRC
++      grsec_enable_randsrc = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDRPC
++      grsec_enable_randrpc = 1;
++#endif
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
++      grsec_enable_socket_all = 1;
++      grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
++#endif
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
++      grsec_enable_socket_client = 1;
++      grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
++#endif
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
++      grsec_enable_socket_server = 1;
++      grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
++#endif
++#endif
++
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_ipc.c linux-2.4.22-grsec-O1/grsecurity/grsec_ipc.c
+--- linux-2.4.22/grsecurity/grsec_ipc.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_ipc.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,81 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/ipc.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++void
++gr_log_msgget(const int ret, const int msgflg)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
++            grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
++                                        !grsec_enable_group)) && (ret >= 0)
++          && (msgflg & IPC_CREAT))
++              security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
++#endif
++      return;
++}
++
++void
++gr_log_msgrm(const uid_t uid, const uid_t cuid)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
++           grsec_enable_audit_ipc) ||
++          (grsec_enable_audit_ipc && !grsec_enable_group))
++              security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
++#endif
++      return;
++}
++
++void
++gr_log_semget(const int err, const int semflg)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
++            grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
++                                        !grsec_enable_group)) && (err >= 0)
++          && (semflg & IPC_CREAT))
++              security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
++#endif
++      return;
++}
++
++void
++gr_log_semrm(const uid_t uid, const uid_t cuid)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
++           grsec_enable_audit_ipc) ||
++          (grsec_enable_audit_ipc && !grsec_enable_group))
++              security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
++#endif
++      return;
++}
++
++void
++gr_log_shmget(const int err, const int shmflg, const size_t size)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
++            grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
++                                        !grsec_enable_group)) && (err >= 0)
++          && (shmflg & IPC_CREAT))
++              security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
++#endif
++      return;
++}
++
++void
++gr_log_shmrm(const uid_t uid, const uid_t cuid)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
++           grsec_enable_audit_ipc) ||
++          (grsec_enable_audit_ipc && !grsec_enable_group))
++              security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
++#endif
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_link.c linux-2.4.22-grsec-O1/grsecurity/grsec_link.c
+--- linux-2.4.22/grsecurity/grsec_link.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_link.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,41 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/grinternal.h>
++
++int
++gr_handle_follow_link(const struct inode *parent,
++                    const struct inode *inode,
++                    const struct dentry *dentry, const struct vfsmount *mnt)
++{
++#ifdef CONFIG_GRKERNSEC_LINK
++      if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
++          (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
++          (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
++              security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
++                             inode->i_uid, inode->i_gid, DEFAULTSECARGS);
++              return -EACCES;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_hardlink(const struct dentry *dentry,
++                 const struct vfsmount *mnt,
++                 struct inode *inode, const int mode, const char *to)
++{
++#ifdef CONFIG_GRKERNSEC_LINK
++      if (grsec_enable_link && current->fsuid != inode->i_uid &&
++          (!S_ISREG(mode) || (mode & S_ISUID) ||
++           ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
++           (permission(inode, MAY_READ | MAY_WRITE))) &&
++          !capable(CAP_FOWNER) && current->uid) {
++              security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
++                             inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_mem.c linux-2.4.22-grsec-O1/grsecurity/grsec_mem.c
+--- linux-2.4.22/grsecurity/grsec_mem.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_mem.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,54 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/grinternal.h>
++
++void
++gr_handle_ioperm(void)
++{
++      security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
++      return;
++}
++
++void
++gr_handle_iopl(void)
++{
++      security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
++      return;
++}
++
++void
++gr_handle_mem_write(void)
++{
++      security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
++      return;
++}
++
++void
++gr_handle_kmem_write(void)
++{
++      security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
++      return;
++}
++
++void
++gr_handle_open_port(void)
++{
++      security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
++      return;
++}
++
++int
++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
++{
++      if (offset < __pa(high_memory) &&
++          (pgprot_val(vma->vm_page_prot) & PROT_WRITE) &&
++          !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
++          !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
++              security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
++              return -EPERM;
++      } else if (offset < __pa(high_memory))
++              vma->vm_flags &= ~VM_MAYWRITE;
++
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_mount.c linux-2.4.22-grsec-O1/grsecurity/grsec_mount.c
+--- linux-2.4.22/grsecurity/grsec_mount.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_mount.c     2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,34 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++void
++gr_log_remount(const char *devname, const int retval)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
++      if (grsec_enable_mount && (retval >= 0))
++              security_audit(GR_REMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
++#endif
++      return;
++}
++
++void
++gr_log_unmount(const char *devname, const int retval)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
++      if (grsec_enable_mount && (retval >= 0))
++              security_audit(GR_UNMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
++#endif
++      return;
++}
++
++void
++gr_log_mount(const char *from, const char *to, const int retval)
++{
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
++      if (grsec_enable_mount && (retval >= 0))
++              security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
++#endif
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_rand.c linux-2.4.22-grsec-O1/grsecurity/grsec_rand.c
+--- linux-2.4.22/grsecurity/grsec_rand.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_rand.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,36 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/smp_lock.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++extern int last_pid;
++
++int
++gr_random_pid(spinlock_t * pid_lock)
++{
++#ifdef CONFIG_GRKERNSEC_RANDPID
++      struct task_struct *p;
++      int pid;
++
++      if (grsec_enable_randpid && current->fs->root) {
++              read_lock(&tasklist_lock);
++              spin_lock(pid_lock);
++
++            repeater:
++
++              pid = 1 + (get_random_long() % PID_MAX);
++
++              for_each_task(p) {
++                      if (p->pid == pid || p->pgrp == pid ||
++                          p->tgid == pid || p->session == pid)
++                              goto repeater;
++              }
++              last_pid = pid;
++              spin_unlock(pid_lock);
++              read_unlock(&tasklist_lock);
++              return pid;
++      }
++#endif
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_sig.c linux-2.4.22-grsec-O1/grsecurity/grsec_sig.c
+--- linux-2.4.22/grsecurity/grsec_sig.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_sig.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,47 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/grinternal.h>
++
++void
++gr_log_signal(const int sig, const struct task_struct *t)
++{
++#ifdef CONFIG_GRKERNSEC_SIGNAL
++      if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
++                                  (sig == SIGABRT) || (sig == SIGBUS))) {
++              if (t->pid == current->pid) {
++                      security_alert_good(GR_UNISIGLOG_MSG, sig,
++                                          DEFAULTSECARGS);
++              } else {
++                      security_alert_good(GR_DUALSIGLOG_MSG, sig,
++                                          gr_task_fullpath(t), t->comm,
++                                          t->pid, t->uid, t->euid, t->gid,
++                                          t->egid, gr_parent_task_fullpath(t),
++                                          t->p_pptr->comm,
++                                          t->p_pptr->pid, t->p_pptr->uid,
++                                          t->p_pptr->euid, t->p_pptr->gid,
++                                          t->p_pptr->egid, DEFAULTSECARGS);
++              }
++      }
++#endif
++      return;
++}
++
++int
++gr_handle_signal(const struct task_struct *p, const int sig)
++{
++#ifdef CONFIG_GRKERNSEC
++      if (current->pid > 1 && gr_check_protected_task(p)) {
++              security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath(p),
++                             p->comm, p->pid, p->uid,
++                             p->euid, p->gid, p->egid,
++                             gr_parent_task_fullpath(p), p->p_pptr->comm,
++                             p->p_pptr->pid, p->p_pptr->uid,
++                             p->p_pptr->euid, p->p_pptr->gid,
++                             p->p_pptr->egid, DEFAULTSECARGS);
++              return -EPERM;
++      } else if (gr_pid_is_chrooted(p)) {
++              return -EPERM;
++      }
++#endif
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_sock.c linux-2.4.22-grsec-O1/grsecurity/grsec_sock.c
+--- linux-2.4.22/grsecurity/grsec_sock.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_sock.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,123 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/file.h>
++#include <linux/net.h>
++#include <net/sock.h>
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++#include <linux/gracl.h>
++
++void
++gr_attach_curr_ip(const struct sock *sk)
++{
++#ifdef CONFIG_GRKERNSEC
++      struct task_struct *p;
++      unsigned int i;
++      struct inode *inode;
++      struct file *filp;
++      struct socket *connect_sock;
++
++      if (unlikely(sk->protocol != IPPROTO_TCP))
++              return;
++
++      read_lock(&tasklist_lock);
++      for_each_task(p) {
++              if (!p->used_connect)
++                      continue;
++              task_lock(p);
++              if (unlikely(!p->files)) {
++                      task_unlock(p);
++                      continue;
++              }
++              read_lock(&p->files->file_lock);
++              for (i = 0; i < p->files->max_fds; i++) {
++                      filp = fcheck_files(p->files, i);
++                      if (likely(!filp))
++                              continue;
++                      inode = filp->f_dentry->d_inode;
++                      if (likely(!inode || !inode->i_sock))
++                              continue;
++                      connect_sock = &inode->u.socket_i;
++                      if (unlikely(!connect_sock ||
++                                   connect_sock->sk->protocol != IPPROTO_TCP))
++                              continue;
++                      if (unlikely(sk->rcv_saddr == connect_sock->sk->daddr &&
++                                   sk->daddr == connect_sock->sk->rcv_saddr &&
++                                   ntohs(sk->sport) ==
++                                   ntohs(connect_sock->sk->dport)
++                                   && ntohs(sk->dport) ==
++                                   ntohs(connect_sock->sk->sport))) {
++                              current->curr_ip = p->curr_ip;
++                              current->used_accept = 1;
++                              read_unlock(&p->files->file_lock);
++                              task_unlock(p);
++                              read_unlock(&tasklist_lock);
++                              return;
++                      }
++              }
++              read_unlock(&p->files->file_lock);
++              task_unlock(p);
++      }
++      read_unlock(&tasklist_lock);
++
++      current->curr_ip = sk->daddr;
++      current->used_accept = 1;
++#endif
++      return;
++}
++
++int
++gr_handle_sock_all(const int family, const int type, const int protocol)
++{
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
++      if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
++          (family != AF_UNIX) && (family != AF_LOCAL)) {
++              security_alert(GR_SOCK_MSG, family, type, protocol,
++                             DEFAULTSECARGS);
++              return -EACCES;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_sock_server(const struct sockaddr *sck)
++{
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
++      if (grsec_enable_socket_server &&
++          in_group_p(grsec_socket_server_gid) &&
++          sck && (sck->sa_family != AF_UNIX) &&
++          (sck->sa_family != AF_LOCAL)) {
++              security_alert(GR_BIND_MSG, DEFAULTSECARGS);
++              return -EACCES;
++      }
++#endif
++      return 0;
++}
++
++int
++gr_handle_sock_client(const struct sockaddr *sck)
++{
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
++      if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
++          sck && (sck->sa_family != AF_UNIX) &&
++          (sck->sa_family != AF_LOCAL)) {
++              security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
++              return -EACCES;
++      }
++#endif
++      return 0;
++}
++
++__u32
++gr_cap_rtnetlink(void)
++{
++#ifdef CONFIG_GRKERNSEC
++      if (!gr_acl_is_enabled())
++              return current->cap_effective;
++      else
++              return (current->cap_effective & ~(current->acl->cap_lower));
++#else
++      return current->cap_effective;
++#endif
++}
+diff -urN linux-2.4.22/grsecurity/grsec_sysctl.c linux-2.4.22-grsec-O1/grsecurity/grsec_sysctl.c
+--- linux-2.4.22/grsecurity/grsec_sysctl.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_sysctl.c    2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,16 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/sysctl.h>
++#include <linux/grinternal.h>
++
++int
++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
++{
++#ifdef CONFIG_GRKERNSEC_SYSCTL
++      if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
++              security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
++              return -EACCES;
++      }
++#endif
++      return 0;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_time.c linux-2.4.22-grsec-O1/grsecurity/grsec_time.c
+--- linux-2.4.22/grsecurity/grsec_time.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_time.c      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,13 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/grinternal.h>
++
++void
++gr_log_timechange(void)
++{
++#ifdef CONFIG_GRKERNSEC_TIME
++      if (grsec_enable_time)
++              security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
++#endif
++      return;
++}
+diff -urN linux-2.4.22/grsecurity/grsec_tpe.c linux-2.4.22-grsec-O1/grsecurity/grsec_tpe.c
+--- linux-2.4.22/grsecurity/grsec_tpe.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsec_tpe.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,35 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/grinternal.h>
++
++extern int gr_acl_tpe_check(void);
++
++int
++gr_tpe_allow(const struct file *file)
++{
++#ifdef CONFIG_GRKERNSEC
++      struct inode *inode = file->f_dentry->d_parent->d_inode;
++
++      if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
++          (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
++                                              (inode->i_mode & S_IWOTH))))) {
++              security_alert(GR_EXEC_TPE_MSG,
++                             gr_to_filename(file->f_dentry, file->f_vfsmnt),
++                             DEFAULTSECARGS);
++              return 0;
++      }
++#ifdef CONFIG_GRKERNSEC_TPE_ALL
++      if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
++          ((inode->i_uid && (inode->i_uid != current->uid)) ||
++           (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
++              security_alert(GR_EXEC_TPE_MSG,
++                             gr_to_filename(file->f_dentry, file->f_vfsmnt),
++                             DEFAULTSECARGS);
++              return 0;
++      }
++#endif
++#endif
++      return 1;
++}
+diff -urN linux-2.4.22/grsecurity/grsum.c linux-2.4.22-grsec-O1/grsecurity/grsum.c
+--- linux-2.4.22/grsecurity/grsum.c    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/grsum.c   2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,59 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <asm/scatterlist.h>
++#include <linux/crypto.h>
++#include <linux/gracl.h>
++
++
++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
++#error "crypto and sha256 must be built into the kernel"
++#endif
++
++int
++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
++{
++      char *p;
++      struct crypto_tfm *tfm;
++      unsigned char temp_sum[GR_SHA_LEN];
++      struct scatterlist sg[2];
++      volatile int retval = 0;
++      volatile int dummy = 0;
++      unsigned int i;
++
++      tfm = crypto_alloc_tfm("sha256", 0);
++      if (tfm == NULL) {
++              /* should never happen, since sha256 should be built in */
++              return 1;
++      }
++
++      crypto_digest_init(tfm);
++
++      p = salt;
++      sg[0].page = virt_to_page(p);
++      sg[0].offset = ((long) p & ~PAGE_MASK);
++      sg[0].length = GR_SALT_LEN;
++      
++      crypto_digest_update(tfm, sg, 1);
++
++      p = entry->pw;
++      sg[0].page = virt_to_page(p);
++      sg[0].offset = ((long) p & ~PAGE_MASK);
++      sg[0].length = strlen(entry->pw);
++
++      crypto_digest_update(tfm, sg, 1);
++
++      crypto_digest_final(tfm, temp_sum);
++
++      memset(entry->pw, 0, GR_PW_LEN);
++
++      for (i = 0; i < GR_SHA_LEN; i++)
++              if (sum[i] != temp_sum[i])
++                      retval = 1;
++              else
++                      dummy = 1;      // waste a cycle
++
++      crypto_free_tfm(tfm);
++
++      return retval;
++}
+diff -urN linux-2.4.22/grsecurity/obsd_rand.c linux-2.4.22-grsec-O1/grsecurity/obsd_rand.c
+--- linux-2.4.22/grsecurity/obsd_rand.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/grsecurity/obsd_rand.c       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,195 @@
++
++/*
++ * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
++ * 
++ * Version 1.89, last modified 19-Sep-99
++ *    
++ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
++ * All rights reserved.
++ *
++ * Copyright 1998 Niels Provos <provos@citi.umich.edu>
++ * All rights reserved.
++ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
++ * such a mathematical system to generate more random (yet non-repeating)
++ * ids to solve the resolver/named problem.  But Niels designed the
++ * actual system based on the constraints.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer,
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    This product includes software developed by Niels Provos.
++ * 4. The name of the author may not be used to endorse or promote products
++ *    derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/smp_lock.h>
++#include <linux/random.h>
++#include <linux/grsecurity.h>
++
++#define RU_OUT 180
++#define RU_MAX 30000
++#define RU_GEN 2
++#define RU_N 32749
++#define RU_AGEN 7
++#define RU_M 31104
++#define PFAC_N 3
++const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
++
++static __u16 ru_x;
++static __u16 ru_seed, ru_seed2;
++static __u16 ru_a, ru_b;
++static __u16 ru_g;
++static __u16 ru_counter = 0;
++static __u16 ru_msb = 0;
++static unsigned long ru_reseed = 0;
++static __u32 tmp;
++
++#define TCP_RNDISS_ROUNDS     15
++#define TCP_RNDISS_OUT                7200
++#define TCP_RNDISS_MAX                30000
++
++static __u8 tcp_rndiss_sbox[NR_CPUS][128];
++static __u16 tcp_rndiss_msb[NR_CPUS];
++static __u16 tcp_rndiss_cnt[NR_CPUS];
++static unsigned long tcp_rndiss_reseed[NR_CPUS];
++
++static __u16 pmod(__u16, __u16, __u16);
++static void ip_initid(void);
++__u16 ip_randomid(void);
++
++static __u16
++pmod(__u16 gen, __u16 exp, __u16 mod)
++{
++      __u16 s, t, u;
++
++      s = 1;
++      t = gen;
++      u = exp;
++
++      while (u) {
++              if (u & 1)
++                      s = (s * t) % mod;
++              u >>= 1;
++              t = (t * t) % mod;
++      }
++      return (s);
++}
++
++static void
++ip_initid(void)
++{
++      __u16 j, i;
++      int noprime = 1;
++
++      ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
++
++      ru_seed = (tmp >> 16) & 0x7FFF;
++      ru_seed2 = get_random_long() & 0x7FFF;
++
++      ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
++      ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
++      while (ru_b % 3 == 0)
++              ru_b += 2;
++
++      j = (tmp = get_random_long()) % RU_N;
++      tmp = tmp >> 16;
++
++      while (noprime) {
++              for (i = 0; i < PFAC_N; i++)
++                      if (j % pfacts[i] == 0)
++                              break;
++
++              if (i >= PFAC_N)
++                      noprime = 0;
++              else
++                      j = (j + 1) % RU_N;
++      }
++
++      ru_g = pmod(RU_GEN, j, RU_N);
++      ru_counter = 0;
++
++      ru_reseed = xtime.tv_sec + RU_OUT;
++      ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
++}
++
++__u16
++ip_randomid(void)
++{
++      int i, n;
++
++      if (ru_counter >= RU_MAX || time_after(xtime.tv_sec, ru_reseed))
++              ip_initid();
++
++      if (!tmp)
++              tmp = get_random_long();
++
++      n = tmp & 0x3;
++      tmp = tmp >> 2;
++      if (ru_counter + n >= RU_MAX)
++              ip_initid();
++      for (i = 0; i <= n; i++)
++              ru_x = (ru_a * ru_x + ru_b) % RU_M;
++      ru_counter += i;
++
++      return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
++}
++
++__u16
++tcp_rndiss_encrypt(__u16 val)
++{
++      __u16 sum = 0, i;
++      int cpu = smp_processor_id();
++
++      for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
++              sum += 0x79b9;
++              val ^= ((__u16) tcp_rndiss_sbox[cpu][(val ^ sum) ^ 0x7f]) << 7;
++              val = ((val & 0xff) << 7) | (val >> 8);
++      }
++
++      return val;
++}
++
++static void
++tcp_rndiss_init(void)
++{
++      int cpu = smp_processor_id();
++
++      get_random_bytes(tcp_rndiss_sbox[cpu], sizeof (tcp_rndiss_sbox));
++      tcp_rndiss_reseed[cpu] = xtime.tv_sec + TCP_RNDISS_OUT;
++      tcp_rndiss_msb[cpu] = tcp_rndiss_msb[cpu] == 0x8000 ? 0 : 0x8000;
++      tcp_rndiss_cnt[cpu] = 0;
++}
++
++__u32
++ip_randomisn(void)
++{
++      int cpu = smp_processor_id();
++
++      if (tcp_rndiss_cnt[cpu] >= TCP_RNDISS_MAX ||
++          time_after(xtime.tv_sec, tcp_rndiss_reseed[cpu]))
++              tcp_rndiss_init();
++
++      return (((tcp_rndiss_encrypt(tcp_rndiss_cnt[cpu]++) |
++                tcp_rndiss_msb[cpu]) << 16) | (get_random_long() & 0x7fff));
++}
+diff -urN linux-2.4.22/include/asm-alpha/a.out.h linux-2.4.22-grsec-O1/include/asm-alpha/a.out.h
+--- linux-2.4.22/include/asm-alpha/a.out.h     2002-08-03 02:39:45.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-alpha/a.out.h    2003-10-21 14:24:34.000000000 +0200
+@@ -98,7 +98,7 @@
+       set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
+                          ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
+-#define STACK_TOP \
++#define __STACK_TOP \
+   (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
+ #endif
+diff -urN linux-2.4.22/include/asm-alpha/elf.h linux-2.4.22-grsec-O1/include/asm-alpha/elf.h
+--- linux-2.4.22/include/asm-alpha/elf.h       2003-08-25 13:44:43.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-alpha/elf.h      2003-10-21 14:24:34.000000000 +0200
+@@ -41,6 +41,18 @@
+ #define ELF_ET_DYN_BASE               (TASK_UNMAPPED_BASE + 0x1000000)
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
++
++#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
++#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
++#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
++#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
++#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
++#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
++#endif
++
++
+ /* $0 is set by ld.so to a pointer to a function which might be 
+    registered using atexit.  This provides a mean for the dynamic
+    linker to call DT_FINI functions for shared libraries that have
+diff -urN linux-2.4.22/include/asm-alpha/mman.h linux-2.4.22-grsec-O1/include/asm-alpha/mman.h
+--- linux-2.4.22/include/asm-alpha/mman.h      2000-03-16 23:07:09.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-alpha/mman.h     2003-10-21 14:24:34.000000000 +0200
+@@ -24,6 +24,10 @@
+ #define MAP_LOCKED    0x8000          /* lock the mapping */
+ #define MAP_NORESERVE 0x10000         /* don't check for reservations */
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++#define MAP_MIRROR    0x20000
++#endif
++
+ #define MS_ASYNC      1               /* sync memory asynchronously */
+ #define MS_SYNC               2               /* synchronous memory sync */
+ #define MS_INVALIDATE 4               /* invalidate the caches */
+diff -urN linux-2.4.22/include/asm-alpha/pgtable.h linux-2.4.22-grsec-O1/include/asm-alpha/pgtable.h
+--- linux-2.4.22/include/asm-alpha/pgtable.h   2002-08-03 02:39:45.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-alpha/pgtable.h  2003-10-21 14:24:34.000000000 +0200
+@@ -96,6 +96,17 @@
+ #define PAGE_SHARED   __pgprot(_PAGE_VALID | __ACCESS_BITS)
+ #define PAGE_COPY     __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
+ #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
++#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
++#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
++#else
++#define PAGE_SHARED_NOEXEC    PAGE_SHARED
++#define PAGE_COPY_NOEXEC      PAGE_COPY
++#define PAGE_READONLY_NOEXEC  PAGE_READONLY
++#endif
++
+ #define PAGE_KERNEL   __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
+ #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
+diff -urN linux-2.4.22/include/asm-i386/a.out.h linux-2.4.22-grsec-O1/include/asm-i386/a.out.h
+--- linux-2.4.22/include/asm-i386/a.out.h      1995-06-16 20:33:06.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-i386/a.out.h     2003-10-21 14:24:34.000000000 +0200
+@@ -19,7 +19,11 @@
+ #ifdef __KERNEL__
+-#define STACK_TOP     TASK_SIZE
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
++#else
++#define __STACK_TOP   TASK_SIZE
++#endif
+ #endif
+diff -urN linux-2.4.22/include/asm-i386/desc.h linux-2.4.22-grsec-O1/include/asm-i386/desc.h
+--- linux-2.4.22/include/asm-i386/desc.h       2001-07-26 22:40:32.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-i386/desc.h      2003-10-21 14:24:34.000000000 +0200
+@@ -46,7 +46,8 @@
+ };
+ extern struct desc_struct gdt_table[];
+-extern struct desc_struct *idt, *gdt;
++extern struct desc_struct gdt_table2[];
++extern struct desc_struct *idt, *gdt, *gdt2;
+ struct Xgt_desc_struct {
+       unsigned short size;
+@@ -55,6 +56,7 @@
+ #define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
+ #define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
++#define gdt_descr2 (*(struct Xgt_desc_struct *)((char *)&gdt2 - 2))
+ #define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3))
+@@ -67,6 +69,7 @@
+ extern struct desc_struct default_ldt[];
+ extern void set_intr_gate(unsigned int irq, void * addr);
+ extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
++extern void __set_ldt_desc(unsigned int n, void *addr, unsigned int size);
+ extern void set_tss_desc(unsigned int n, void *addr);
+ static inline void clear_LDT(void)
+@@ -94,6 +97,21 @@
+       __load_LDT(cpu);
+ }
++static inline void _load_LDT (struct mm_struct *mm)
++{
++      int cpu = smp_processor_id();
++      void *segments = mm->context.segments;
++      int count = LDT_ENTRIES;
++
++      if (!segments) {
++              segments = &default_ldt[0];
++              count = 5;
++      }
++              
++      __set_ldt_desc(cpu, segments, count);
++      __load_LDT(cpu);
++}
++
+ #endif /* !__ASSEMBLY__ */
+ #endif
+diff -urN linux-2.4.22/include/asm-i386/elf.h linux-2.4.22-grsec-O1/include/asm-i386/elf.h
+--- linux-2.4.22/include/asm-i386/elf.h        2001-11-22 20:48:29.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-i386/elf.h       2003-10-21 14:24:34.000000000 +0200
+@@ -55,7 +55,22 @@
+    the loader.  We need to make sure that it is out of the way of the program
+    that it will "exec", and that there is sufficient room for the brk.  */
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++#define ELF_ET_DYN_BASE               ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2)
++#else
+ #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE(tsk)      0x08048000UL
++
++#define PAX_DELTA_MMAP_LSB(tsk)               PAGE_SHIFT
++#define PAX_DELTA_MMAP_LEN(tsk)               16
++#define PAX_DELTA_EXEC_LSB(tsk)               PAGE_SHIFT
++#define PAX_DELTA_EXEC_LEN(tsk)               16
++#define PAX_DELTA_STACK_LSB(tsk)      PAGE_SHIFT  
++#define PAX_DELTA_STACK_LEN(tsk)      ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
++#endif
+ /* Wow, the "main" arch needs arch dependent functions too.. :) */
+diff -urN linux-2.4.22/include/asm-i386/hw_irq.h linux-2.4.22-grsec-O1/include/asm-i386/hw_irq.h
+--- linux-2.4.22/include/asm-i386/hw_irq.h     2003-08-25 13:44:43.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-i386/hw_irq.h    2003-10-21 14:24:34.000000000 +0200
+@@ -128,6 +128,7 @@
+ asmlinkage void x(void); \
+ asmlinkage void call_##x(void); \
+ __asm__( \
++"\n .text" \
+ "\n"__ALIGN_STR"\n" \
+ SYMBOL_NAME_STR(x) ":\n\t" \
+       "pushl $"#v"-256\n\t" \
+@@ -141,6 +142,7 @@
+ asmlinkage void x(struct pt_regs * regs); \
+ asmlinkage void call_##x(void); \
+ __asm__( \
++"\n .text" \
+ "\n"__ALIGN_STR"\n" \
+ SYMBOL_NAME_STR(x) ":\n\t" \
+       "pushl $"#v"-256\n\t" \
+@@ -155,6 +157,7 @@
+ #define BUILD_COMMON_IRQ() \
+ asmlinkage void call_do_IRQ(void); \
+ __asm__( \
++      "\n .text" \
+       "\n" __ALIGN_STR"\n" \
+       "common_interrupt:\n\t" \
+       SAVE_ALL \
+@@ -175,6 +178,7 @@
+ #define BUILD_IRQ(nr) \
+ asmlinkage void IRQ_NAME(nr); \
+ __asm__( \
++"\n .text" \
+ "\n"__ALIGN_STR"\n" \
+ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
+       "pushl $"#nr"-256\n\t" \
+diff -urN linux-2.4.22/include/asm-i386/mman.h linux-2.4.22-grsec-O1/include/asm-i386/mman.h
+--- linux-2.4.22/include/asm-i386/mman.h       2000-03-15 02:45:20.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-i386/mman.h      2003-10-21 14:24:34.000000000 +0200
+@@ -18,6 +18,10 @@
+ #define MAP_LOCKED    0x2000          /* pages are locked */
+ #define MAP_NORESERVE 0x4000          /* don't check for reservations */
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++#define MAP_MIRROR    0x8000
++#endif
++
+ #define MS_ASYNC      1               /* sync memory asynchronously */
+ #define MS_INVALIDATE 2               /* invalidate the caches */
+ #define MS_SYNC               4               /* synchronous memory sync */
+diff -urN linux-2.4.22/include/asm-i386/page.h linux-2.4.22-grsec-O1/include/asm-i386/page.h
+--- linux-2.4.22/include/asm-i386/page.h       2002-08-03 02:39:45.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-i386/page.h      2003-10-21 14:24:34.000000000 +0200
+@@ -78,7 +78,7 @@
+  * and CONFIG_HIGHMEM64G options in the kernel configuration.
+  */
+-#define __PAGE_OFFSET         (0xC0000000)
++#include <asm/page_offset.h>
+ /*
+  * This much address space is reserved for vmalloc() and iomap()
+diff -urN linux-2.4.22/include/asm-i386/page_offset.h linux-2.4.22-grsec-O1/include/asm-i386/page_offset.h
+--- linux-2.4.22/include/asm-i386/page_offset.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-i386/page_offset.h       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,2 @@
++#define __KERNEL_TEXT_OFFSET  (0xC0400000)
++#define __PAGE_OFFSET         (0xC0000000)
+diff -urN linux-2.4.22/include/asm-i386/pgtable.h linux-2.4.22-grsec-O1/include/asm-i386/pgtable.h
+--- linux-2.4.22/include/asm-i386/pgtable.h    2002-11-29 00:53:15.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-i386/pgtable.h   2003-10-21 14:24:34.000000000 +0200
+@@ -205,6 +205,16 @@
+ #define PAGE_COPY     __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+ #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++#define PAGE_SHARED_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
++#define PAGE_COPY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
++#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) 
++#else
++#define PAGE_SHARED_NOEXEC    PAGE_SHARED
++#define PAGE_COPY_NOEXEC      PAGE_COPY
++#define PAGE_READONLY_NOEXEC  PAGE_READONLY
++#endif
++
+ #define __PAGE_KERNEL \
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+ #define __PAGE_KERNEL_NOCACHE \
+@@ -237,18 +247,18 @@
+  * This is the closest we can get..
+  */
+ #define __P000        PAGE_NONE
+-#define __P001        PAGE_READONLY
+-#define __P010        PAGE_COPY
+-#define __P011        PAGE_COPY
++#define __P001  PAGE_READONLY_NOEXEC
++#define __P010  PAGE_COPY_NOEXEC
++#define __P011  PAGE_COPY_NOEXEC
+ #define __P100        PAGE_READONLY
+ #define __P101        PAGE_READONLY
+ #define __P110        PAGE_COPY
+ #define __P111        PAGE_COPY
+ #define __S000        PAGE_NONE
+-#define __S001        PAGE_READONLY
+-#define __S010        PAGE_SHARED
+-#define __S011        PAGE_SHARED
++#define __S001  PAGE_READONLY_NOEXEC
++#define __S010  PAGE_SHARED_NOEXEC
++#define __S011  PAGE_SHARED_NOEXEC
+ #define __S100        PAGE_READONLY
+ #define __S101        PAGE_READONLY
+ #define __S110        PAGE_SHARED
+@@ -324,7 +334,7 @@
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+ /* to find an entry in a page-table-directory. */
+-#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
++#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+ #define __pgd_offset(address) pgd_index(address)
+diff -urN linux-2.4.22/include/asm-i386/processor.h linux-2.4.22-grsec-O1/include/asm-i386/processor.h
+--- linux-2.4.22/include/asm-i386/processor.h  2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-i386/processor.h 2003-10-21 14:24:34.000000000 +0200
+@@ -261,10 +261,19 @@
+  */
+ #define TASK_SIZE     (PAGE_OFFSET)
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++#define SEGMEXEC_TASK_SIZE    ((PAGE_OFFSET) / 2)
++#endif
++
+ /* This decides where the kernel will search for a free chunk of vm
+  * space during mmap's.
+  */
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++#define TASK_UNMAPPED_BASE    ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3)
++#else
+ #define TASK_UNMAPPED_BASE    (TASK_SIZE / 3)
++#endif
+ /*
+  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
+diff -urN linux-2.4.22/include/asm-i386/system.h linux-2.4.22-grsec-O1/include/asm-i386/system.h
+--- linux-2.4.22/include/asm-i386/system.h     2003-10-20 18:59:07.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-i386/system.h    2003-10-21 14:24:34.000000000 +0200
+@@ -12,6 +12,8 @@
+ struct task_struct;   /* one of the stranger aspects of C forward declarations.. */
+ extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
++void pax_switch_segments(struct task_struct *);
++
+ #define switch_to(prev,next,last) do {                                        \
+       asm volatile("pushl %%esi\n\t"                                  \
+                    "pushl %%edi\n\t"                                  \
+diff -urN linux-2.4.22/include/asm-parisc/a.out.h linux-2.4.22-grsec-O1/include/asm-parisc/a.out.h
+--- linux-2.4.22/include/asm-parisc/a.out.h    2000-12-05 21:29:39.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-parisc/a.out.h   2003-10-21 14:24:34.000000000 +0200
+@@ -22,7 +22,7 @@
+ /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
+  * prumpf */
+-#define STACK_TOP     TASK_SIZE
++#define __STACK_TOP   TASK_SIZE
+ #endif
+diff -urN linux-2.4.22/include/asm-parisc/elf.h linux-2.4.22-grsec-O1/include/asm-parisc/elf.h
+--- linux-2.4.22/include/asm-parisc/elf.h      2002-11-29 00:53:15.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-parisc/elf.h     2003-10-21 14:24:34.000000000 +0200
+@@ -135,6 +135,17 @@
+ #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE(tsk)        0x10000UL
++
++#define PAX_DELTA_MMAP_LSB(tsk)         PAGE_SHIFT
++#define PAX_DELTA_MMAP_LEN(tsk)         16
++#define PAX_DELTA_EXEC_LSB(tsk)         PAGE_SHIFT
++#define PAX_DELTA_EXEC_LEN(tsk)         16
++#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
++#define PAX_DELTA_STACK_LEN(tsk)        16
++#endif
++
+ /* This yields a mask that user programs can use to figure out what
+    instruction set this CPU supports.  This could be done in user space,
+    but it's not easy, and we've already done it here.  */
+diff -urN linux-2.4.22/include/asm-parisc/mman.h linux-2.4.22-grsec-O1/include/asm-parisc/mman.h
+--- linux-2.4.22/include/asm-parisc/mman.h     2000-12-05 21:29:39.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-parisc/mman.h    2003-10-21 14:24:34.000000000 +0200
+@@ -18,6 +18,10 @@
+ #define MAP_NORESERVE 0x4000          /* don't check for reservations */
+ #define MAP_GROWSDOWN 0x8000          /* stack-like segment */
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++#define MAP_MIRROR    0x0400
++#endif
++
+ #define MS_SYNC               1               /* synchronous memory sync */
+ #define MS_ASYNC      2               /* sync memory asynchronously */
+ #define MS_INVALIDATE 4               /* invalidate the caches */
+diff -urN linux-2.4.22/include/asm-parisc/pgtable.h linux-2.4.22-grsec-O1/include/asm-parisc/pgtable.h
+--- linux-2.4.22/include/asm-parisc/pgtable.h  2003-06-13 16:51:38.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-parisc/pgtable.h 2003-10-21 14:24:34.000000000 +0200
+@@ -167,6 +167,17 @@
+ #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
+ #define PAGE_COPY       PAGE_EXECREAD
+ #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++#define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
++#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
++#define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
++#else
++#define PAGE_SHARED_NOEXEC    PAGE_SHARED
++#define PAGE_COPY_NOEXEC      PAGE_COPY
++#define PAGE_READONLY_NOEXEC  PAGE_READONLY
++#endif
++
+ #define PAGE_KERNEL   __pgprot(_PAGE_KERNEL)
+ #define PAGE_KERNEL_RO        __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
+ #define PAGE_KERNEL_UNC       __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
+diff -urN linux-2.4.22/include/asm-ppc/a.out.h linux-2.4.22-grsec-O1/include/asm-ppc/a.out.h
+--- linux-2.4.22/include/asm-ppc/a.out.h       2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-ppc/a.out.h      2003-10-21 14:24:34.000000000 +0200
+@@ -2,7 +2,7 @@
+ #define __PPC_A_OUT_H__
+ /* grabbed from the intel stuff  */
+-#define STACK_TOP TASK_SIZE
++#define __STACK_TOP TASK_SIZE
+ struct exec
+diff -urN linux-2.4.22/include/asm-ppc/elf.h linux-2.4.22-grsec-O1/include/asm-ppc/elf.h
+--- linux-2.4.22/include/asm-ppc/elf.h 2003-06-13 16:51:38.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-ppc/elf.h        2003-10-21 14:24:34.000000000 +0200
+@@ -46,6 +46,17 @@
+ #define ELF_ET_DYN_BASE         (0x08000000)
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE(tsk)      0x10000000UL
++
++#define PAX_DELTA_MMAP_LSB(tsk)               PAGE_SHIFT
++#define PAX_DELTA_MMAP_LEN(tsk)               15
++#define PAX_DELTA_EXEC_LSB(tsk)               PAGE_SHIFT
++#define PAX_DELTA_EXEC_LEN(tsk)               15
++#define PAX_DELTA_STACK_LSB(tsk)      PAGE_SHIFT
++#define PAX_DELTA_STACK_LEN(tsk)      15
++#endif
++
+ #define USE_ELF_CORE_DUMP
+ #define ELF_EXEC_PAGESIZE     4096
+diff -urN linux-2.4.22/include/asm-ppc/mman.h linux-2.4.22-grsec-O1/include/asm-ppc/mman.h
+--- linux-2.4.22/include/asm-ppc/mman.h        2003-06-13 16:51:38.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-ppc/mman.h       2003-10-21 14:24:34.000000000 +0200
+@@ -19,6 +19,10 @@
+ #define MAP_DENYWRITE 0x0800          /* ETXTBSY */
+ #define MAP_EXECUTABLE        0x1000          /* mark it as an executable */
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++#define MAP_MIRROR    0x0200
++#endif
++
+ #define MS_ASYNC      1               /* sync memory asynchronously */
+ #define MS_INVALIDATE 2               /* invalidate the caches */
+ #define MS_SYNC               4               /* synchronous memory sync */
+diff -urN linux-2.4.22/include/asm-ppc/pgtable.h linux-2.4.22-grsec-O1/include/asm-ppc/pgtable.h
+--- linux-2.4.22/include/asm-ppc/pgtable.h     2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-ppc/pgtable.h    2003-10-21 14:24:34.000000000 +0200
+@@ -335,6 +335,16 @@
+ #define PAGE_COPY     __pgprot(_PAGE_BASE | _PAGE_USER)
+ #define PAGE_COPY_X   __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC   __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
++# define PAGE_COPY_NOEXEC     __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
++#else
++# define PAGE_SHARED_NOEXEC   PAGE_SHARED
++# define PAGE_COPY_NOEXEC     PAGE_COPY
++# define PAGE_READONLY_NOEXEC PAGE_READONLY
++#endif
++
+ #define PAGE_KERNEL   __pgprot(_PAGE_KERNEL)
+ #define PAGE_KERNEL_RO        __pgprot(_PAGE_BASE | _PAGE_SHARED)
+ #define PAGE_KERNEL_CI        __pgprot(_PAGE_IO)
+@@ -346,21 +356,21 @@
+  * This is the closest we can get..
+  */
+ #define __P000        PAGE_NONE
+-#define __P001        PAGE_READONLY_X
+-#define __P010        PAGE_COPY
+-#define __P011        PAGE_COPY_X
+-#define __P100        PAGE_READONLY
++#define __P001        PAGE_READONLY_NOEXEC
++#define __P010        PAGE_COPY_NOEXEC
++#define __P011        PAGE_COPY_NOEXEC
++#define __P100        PAGE_READONLY_X
+ #define __P101        PAGE_READONLY_X
+-#define __P110        PAGE_COPY
++#define __P110        PAGE_COPY_X
+ #define __P111        PAGE_COPY_X
+ #define __S000        PAGE_NONE
+-#define __S001        PAGE_READONLY_X
+-#define __S010        PAGE_SHARED
+-#define __S011        PAGE_SHARED_X
+-#define __S100        PAGE_READONLY
++#define __S001        PAGE_READONLY_NOEXEC
++#define __S010        PAGE_SHARED_NOEXEC
++#define __S011        PAGE_SHARED_NOEXEC
++#define __S100        PAGE_READONLY_X
+ #define __S101        PAGE_READONLY_X
+-#define __S110        PAGE_SHARED
++#define __S110        PAGE_SHARED_X
+ #define __S111        PAGE_SHARED_X
+ #ifndef __ASSEMBLY__
+diff -urN linux-2.4.22/include/asm-sparc/a.out.h linux-2.4.22-grsec-O1/include/asm-sparc/a.out.h
+--- linux-2.4.22/include/asm-sparc/a.out.h     2000-01-13 21:03:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/asm-sparc/a.out.h    2003-10-21 14:24:34.000000000 +0200
+@@ -91,7 +91,7 @@
+ #include <asm/page.h>
+-#define STACK_TOP     (PAGE_OFFSET - PAGE_SIZE)
++#define __STACK_TOP   (PAGE_OFFSET - PAGE_SIZE)
+ #endif /* __KERNEL__ */
+diff -urN linux-2.4.22/include/asm-sparc/elf.h linux-2.4.22-grsec-O1/include/asm-sparc/elf.h
+--- linux-2.4.22/include/asm-sparc/elf.h       2000-07-12 04:02:37.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc/elf.h      2003-10-21 14:24:34.000000000 +0200
+@@ -83,6 +83,18 @@
+ #define ELF_ET_DYN_BASE         (0x08000000)
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE(tsk)      0x10000UL
++
++#define PAX_DELTA_MMAP_LSB(tsk)               PAGE_SHIFT
++#define PAX_DELTA_MMAP_LEN(tsk)               16
++#define PAX_DELTA_EXEC_LSB(tsk)               PAGE_SHIFT
++#define PAX_DELTA_EXEC_LEN(tsk)               16
++#define PAX_DELTA_STACK_LSB(tsk)      PAGE_SHIFT
++#define PAX_DELTA_STACK_LEN(tsk)      16
++#endif
++
++
+ /* This yields a mask that user programs can use to figure out what
+    instruction set this cpu supports.  This can NOT be done in userspace
+    on Sparc.  */
+diff -urN linux-2.4.22/include/asm-sparc/mman.h linux-2.4.22-grsec-O1/include/asm-sparc/mman.h
+--- linux-2.4.22/include/asm-sparc/mman.h      2003-06-13 16:51:38.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc/mman.h     2003-10-21 14:24:34.000000000 +0200
+@@ -24,6 +24,10 @@
+ #define MAP_DENYWRITE 0x0800          /* ETXTBSY */
+ #define MAP_EXECUTABLE        0x1000          /* mark it as an executable */
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++#define MAP_MIRROR    0x0400
++#endif
++
+ #define MS_ASYNC      1               /* sync memory asynchronously */
+ #define MS_INVALIDATE 2               /* invalidate the caches */
+ #define MS_SYNC               4               /* synchronous memory sync */
+diff -urN linux-2.4.22/include/asm-sparc/pgtable.h linux-2.4.22-grsec-O1/include/asm-sparc/pgtable.h
+--- linux-2.4.22/include/asm-sparc/pgtable.h   2002-08-03 02:39:45.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc/pgtable.h  2003-10-21 14:24:34.000000000 +0200
+@@ -97,6 +97,13 @@
+ BTFIXUPDEF_INT(page_shared)
+ BTFIXUPDEF_INT(page_copy)
+ BTFIXUPDEF_INT(page_readonly)
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++BTFIXUPDEF_INT(page_shared_noexec)
++BTFIXUPDEF_INT(page_copy_noexec)
++BTFIXUPDEF_INT(page_readonly_noexec)
++#endif
++
+ BTFIXUPDEF_INT(page_kernel)
+ #define PMD_SHIFT             BTFIXUP_SIMM13(pmd_shift)
+@@ -118,6 +125,16 @@
+ #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
+ #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++#define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
++#define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
++#define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
++#else
++#define PAGE_SHARED_NOEXEC    PAGE_SHARED
++#define PAGE_COPY_NOEXEC      PAGE_COPY
++#define PAGE_READONLY_NOEXEC  PAGE_READONLY
++#endif
++
+ extern unsigned long page_kernel;
+ #ifdef MODULE
+diff -urN linux-2.4.22/include/asm-sparc/pgtsrmmu.h linux-2.4.22-grsec-O1/include/asm-sparc/pgtsrmmu.h
+--- linux-2.4.22/include/asm-sparc/pgtsrmmu.h  2000-07-18 21:29:47.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc/pgtsrmmu.h 2003-10-21 14:24:34.000000000 +0200
+@@ -73,6 +73,15 @@
+                                   SRMMU_EXEC | SRMMU_REF)
+ #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+                                   SRMMU_EXEC | SRMMU_REF)
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
++                                         SRMMU_WRITE | SRMMU_REF)
++#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
++                                         SRMMU_REF)
++#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
++                                         SRMMU_REF)
++#endif
++
+ #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
+                                   SRMMU_DIRTY | SRMMU_REF)
+diff -urN linux-2.4.22/include/asm-sparc/uaccess.h linux-2.4.22-grsec-O1/include/asm-sparc/uaccess.h
+--- linux-2.4.22/include/asm-sparc/uaccess.h   2003-06-13 16:51:38.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc/uaccess.h  2003-10-21 14:24:34.000000000 +0200
+@@ -39,7 +39,7 @@
+  * No one can read/write anything from userland in the kernel space by setting
+  * large size and address near to PAGE_OFFSET - a fault will break his intentions.
+  */
+-#define __user_ok(addr,size) ((addr) < STACK_TOP)
++#define __user_ok(addr,size) ((addr) < __STACK_TOP)
+ #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+ #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
+ #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+diff -urN linux-2.4.22/include/asm-sparc64/a.out.h linux-2.4.22-grsec-O1/include/asm-sparc64/a.out.h
+--- linux-2.4.22/include/asm-sparc64/a.out.h   2001-04-27 07:17:26.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc64/a.out.h  2003-10-21 14:24:34.000000000 +0200
+@@ -95,7 +95,7 @@
+ #ifdef __KERNEL__
+-#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
++#define __STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
+ #endif
+diff -urN linux-2.4.22/include/asm-sparc64/elf.h linux-2.4.22-grsec-O1/include/asm-sparc64/elf.h
+--- linux-2.4.22/include/asm-sparc64/elf.h     2003-06-13 16:51:38.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc64/elf.h    2003-10-21 14:24:34.000000000 +0200
+@@ -82,6 +82,17 @@
+ #define ELF_ET_DYN_BASE         0x0000010000000000UL
+ #endif
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 0x10000UL : 0x100000UL)
++
++#define PAX_DELTA_MMAP_LSB(tsk)         (PAGE_SHIFT + 1)
++#define PAX_DELTA_MMAP_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
++#define PAX_DELTA_EXEC_LSB(tsk)         (PAGE_SHIFT + 1)
++#define PAX_DELTA_EXEC_LEN(tsk)         ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 )
++#define PAX_DELTA_STACK_LSB(tsk)        PAGE_SHIFT
++#define PAX_DELTA_STACK_LEN(tsk)        ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 15 : 29 )
++#endif
++
+ /* This yields a mask that user programs can use to figure out what
+    instruction set this cpu supports.  */
+diff -urN linux-2.4.22/include/asm-sparc64/mman.h linux-2.4.22-grsec-O1/include/asm-sparc64/mman.h
+--- linux-2.4.22/include/asm-sparc64/mman.h    2003-06-13 16:51:38.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc64/mman.h   2003-10-21 14:24:34.000000000 +0200
+@@ -24,6 +24,10 @@
+ #define MAP_DENYWRITE 0x0800          /* ETXTBSY */
+ #define MAP_EXECUTABLE        0x1000          /* mark it as an executable */
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++#define MAP_MIRROR    0x0400
++#endif
++
+ #define MS_ASYNC      1               /* sync memory asynchronously */
+ #define MS_INVALIDATE 2               /* invalidate the caches */
+ #define MS_SYNC               4               /* synchronous memory sync */
+diff -urN linux-2.4.22/include/asm-sparc64/pgtable.h linux-2.4.22-grsec-O1/include/asm-sparc64/pgtable.h
+--- linux-2.4.22/include/asm-sparc64/pgtable.h 2002-08-03 02:39:45.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/asm-sparc64/pgtable.h        2003-10-21 14:24:34.000000000 +0200
+@@ -122,7 +122,8 @@
+ #define _PAGE_G               0x0000000000000001      /* Global                             */
+ /* Here are the SpitFire software bits we use in the TTE's. */
+-#define _PAGE_MODIFIED        0x0000000000000800      /* Modified Page (ie. dirty)          */
++#define _PAGE_MODIFIED        0x0000000000001000      /* Modified Page (ie. dirty)          */
++#define _PAGE_EXEC    0x0000000000000800      /* Executable SW bit                  */
+ #define _PAGE_ACCESSED        0x0000000000000400      /* Accessed Page (ie. referenced)     */
+ #define _PAGE_READ    0x0000000000000200      /* Readable SW Bit                    */
+ #define _PAGE_WRITE   0x0000000000000100      /* Writable SW Bit                    */
+@@ -150,16 +151,30 @@
+ /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
+ #define PAGE_SHARED   __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
+-                                __ACCESS_BITS | _PAGE_WRITE)
++                                __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
+ #define PAGE_COPY     __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
+-                                __ACCESS_BITS)
++                                __ACCESS_BITS | _PAGE_EXEC)
+ #define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
+-                                __ACCESS_BITS)
++                                __ACCESS_BITS | _PAGE_EXEC)
+ #define PAGE_KERNEL   __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
+-                                __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
++                                __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \
++                                _PAGE_EXEC)
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++#define PAGE_SHARED_NOEXEC    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
++                                      __ACCESS_BITS | _PAGE_WRITE)
++#define PAGE_COPY_NOEXEC      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
++                                      __ACCESS_BITS)
++#define PAGE_READONLY_NOEXEC  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
++                                      __ACCESS_BITS)
++#else
++#define PAGE_SHARED_NOEXEC     PAGE_SHARED
++#define PAGE_COPY_NOEXEC       PAGE_COPY
++#define PAGE_READONLY_NOEXEC   PAGE_READONLY
++#endif
+ #define PAGE_INVALID  __pgprot (0)
+@@ -170,18 +185,18 @@
+ #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
+ #define __P000        PAGE_NONE
+-#define __P001        PAGE_READONLY
+-#define __P010        PAGE_COPY
+-#define __P011        PAGE_COPY
++#define __P001        PAGE_READONLY_NOEXEC
++#define __P010        PAGE_COPY_NOEXEC
++#define __P011        PAGE_COPY_NOEXEC
+ #define __P100        PAGE_READONLY
+ #define __P101        PAGE_READONLY
+ #define __P110        PAGE_COPY
+ #define __P111        PAGE_COPY
+ #define __S000        PAGE_NONE
+-#define __S001        PAGE_READONLY
+-#define __S010        PAGE_SHARED
+-#define __S011        PAGE_SHARED
++#define __S001        PAGE_READONLY_NOEXEC
++#define __S010        PAGE_SHARED_NOEXEC
++#define __S011        PAGE_SHARED_NOEXEC
+ #define __S100        PAGE_READONLY
+ #define __S101        PAGE_READONLY
+ #define __S110        PAGE_SHARED
+diff -urN linux-2.4.22/include/linux/a.out.h linux-2.4.22-grsec-O1/include/linux/a.out.h
+--- linux-2.4.22/include/linux/a.out.h 2001-11-22 20:46:18.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/a.out.h        2003-10-21 14:24:34.000000000 +0200
+@@ -7,6 +7,16 @@
+ #include <asm/a.out.h>
++#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK
++#define __DELTA_STACK (current->mm->delta_stack)
++#else
++#define __DELTA_STACK 0UL
++#endif
++
++#ifndef STACK_TOP
++#define STACK_TOP     (__STACK_TOP - __DELTA_STACK)
++#endif
++
+ #endif /* __STRUCT_EXEC_OVERRIDE__ */
+ /* these go in the N_MACHTYPE field */
+@@ -37,6 +47,14 @@
+   M_MIPS2 = 152               /* MIPS R6000/R4000 binary */
+ };
++/* Constants for the N_FLAGS field */
++#define F_PAX_PAGEEXEC 1      /* Paging based non-executable pages */
++#define F_PAX_EMUTRAMP 2      /* Emulate trampolines */
++#define F_PAX_MPROTECT 4      /* Restrict mprotect() */
++#define F_PAX_RANDMMAP 8      /* Randomize mmap() base */   
++#define F_PAX_RANDEXEC 16     /* Randomize ET_EXEC base */
++#define F_PAX_SEGMEXEC 32     /* Segmentation based non-executable pages */
++
+ #if !defined (N_MAGIC)
+ #define N_MAGIC(exec) ((exec).a_info & 0xffff)
+ #endif
+diff -urN linux-2.4.22/include/linux/binfmts.h linux-2.4.22-grsec-O1/include/linux/binfmts.h
+--- linux-2.4.22/include/linux/binfmts.h       2003-10-20 18:59:10.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/linux/binfmts.h      2003-10-21 14:24:34.000000000 +0200
+@@ -61,6 +61,8 @@
+ extern int do_coredump(long signr, struct pt_regs * regs);
+ extern void set_binfmt(struct linux_binfmt *new);
++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
++void pax_report_insns(void *pc);
+ #if 0
+ /* this went away now */
+diff -urN linux-2.4.22/include/linux/elf.h linux-2.4.22-grsec-O1/include/linux/elf.h
+--- linux-2.4.22/include/linux/elf.h   2002-11-29 00:53:15.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/elf.h  2003-10-21 14:24:34.000000000 +0200
+@@ -117,6 +117,8 @@
+ #define DT_DEBUG      21
+ #define DT_TEXTREL    22
+ #define DT_JMPREL     23
++#define DT_FLAGS      30
++#define DF_TEXTREL    0x00000004
+ #define DT_LOPROC     0x70000000
+ #define DT_HIPROC     0x7fffffff
+ #define DT_MIPS_RLD_VERSION   0x70000001
+@@ -255,6 +257,13 @@
+ #define R_MIPS_LOVENDOR               100
+ #define R_MIPS_HIVENDOR               127
++/* Constants for the e_flags field */
++#define EF_PAX_PAGEEXEC               1       /* Paging based non-executable pages */
++#define EF_PAX_EMUTRAMP               2       /* Emulate trampolines */
++#define EF_PAX_MPROTECT               4       /* Restrict mprotect() */
++#define EF_PAX_RANDMMAP               8       /* Randomize mmap() base */ 
++#define EF_PAX_RANDEXEC                     16      /* Randomize ET_EXEC base */
++#define EF_PAX_SEGMEXEC                     32      /* Segmentation based non-executable pages */
+ /*
+  * Sparc ELF relocation types
+@@ -550,6 +559,8 @@
+ #define       EI_VERSION      6
+ #define       EI_PAD          7
++#define EI_PAX                14
++
+ #define       ELFMAG0         0x7f            /* EI_MAG */
+ #define       ELFMAG1         'E'
+ #define       ELFMAG2         'L'
+@@ -597,6 +608,7 @@
+ #define elfhdr                elf32_hdr
+ #define elf_phdr      elf32_phdr
+ #define elf_note      elf32_note
++#define elf_dyn               Elf32_Dyn
+ #else
+@@ -604,6 +616,7 @@
+ #define elfhdr                elf64_hdr
+ #define elf_phdr      elf64_phdr
+ #define elf_note      elf64_note
++#define elf_dyn               Elf64_Dyn
+ #endif
+diff -urN linux-2.4.22/include/linux/fs.h linux-2.4.22-grsec-O1/include/linux/fs.h
+--- linux-2.4.22/include/linux/fs.h    2003-10-20 18:59:08.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/linux/fs.h   2003-10-21 14:24:34.000000000 +0200
+@@ -1167,7 +1167,7 @@
+ asmlinkage long sys_open(const char *, int, int);
+ asmlinkage long sys_close(unsigned int);      /* yes, it's really unsigned */
+-extern int do_truncate(struct dentry *, loff_t start);
++extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
+ extern struct file *filp_open(const char *, int, int);
+ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
+diff -urN linux-2.4.22/include/linux/gracl.h linux-2.4.22-grsec-O1/include/linux/gracl.h
+--- linux-2.4.22/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/gracl.h        2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,212 @@
++#ifndef GR_ACL_H
++#define GR_ACL_H
++#endif
++#include <linux/grdefs.h>
++#include <linux/resource.h>
++
++#include <asm/resource.h>
++
++/* * * * * * * * * * * * * * * * * * * * *
++ * grsecurity ACL System
++ * Main header file
++ * Purpose: define most gracl data structures 
++ * * * * * * * * * * * * * * * * * * * * */
++
++/* Major status information */
++
++#define GR_VERSION  "grsecurity 2.0"
++
++enum {
++
++      SHUTDOWN = 0,
++      ENABLE = 1,
++      SPROLE = 2,
++      RELOAD = 3,
++      SEGVMOD = 4,
++      STATUS = 5,
++      UNSPROLE = 6
++};
++
++/* Password setup definitions
++ * kernel/grhash.c */
++enum {
++      GR_PW_LEN = 128,
++      GR_SALT_LEN = 16,
++      GR_SHA_LEN = 32,
++};
++
++enum {
++      GR_SPROLE_LEN = 64,
++};
++
++/* Begin Data Structures */
++
++struct sprole_pw {
++      unsigned char *rolename;
++      unsigned char salt[GR_SALT_LEN];
++      unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
++};
++
++struct name_entry {
++      ino_t inode;
++      kdev_t device;
++      char *name;
++      __u16 len;
++};
++
++struct acl_role_db {
++      struct acl_role_label **r_hash;
++      __u32 r_size;
++};
++
++struct name_db {
++      struct name_entry **n_hash;
++      __u32 n_size;
++};
++
++struct crash_uid {
++      uid_t uid;
++      unsigned long expires;
++};
++
++/* Userspace Grsecurity ACL data structures */
++struct acl_subject_label {
++      char *filename;
++      ino_t inode;
++      kdev_t device;
++      __u32 mode;
++      __u32 cap_raise;
++      __u32 cap_lower;
++
++      struct rlimit res[RLIM_NLIMITS + 1];
++      __u16 resmask;
++
++      __u32 ip_proto[8];
++      __u32 ip_type;
++      struct acl_ip_label **ips;
++      __u32 ip_num;
++
++      __u32 crashes;
++      unsigned long expires;
++
++      struct acl_subject_label *parent_subject;
++      struct acl_object_label *proc_object;
++      struct acl_ip_label *ip_object;
++      struct acl_subject_label *prev;
++      struct acl_subject_label *next;
++
++      struct acl_object_label **obj_hash;
++      __u32 obj_hash_size;
++};
++
++struct role_allowed_ip {
++      __u32 addr;
++      __u32 netmask;
++
++      struct role_allowed_ip *prev;
++      struct role_allowed_ip *next;
++};
++
++struct role_transition {
++      char *rolename;
++
++      struct role_transition *prev;
++      struct role_transition *next;
++};
++
++struct acl_role_label {
++      char *rolename;
++      uid_t uidgid;
++      __u16 roletype;
++
++      __u16 auth_attempts;
++      unsigned long expires;
++
++      struct acl_subject_label *root_label;
++      struct acl_subject_label *proc_subject;
++
++      struct acl_role_label *prev;
++      struct acl_role_label *next;
++
++      struct role_transition *transitions;
++      struct role_allowed_ip *allowed_ips;
++      struct acl_subject_label **subj_hash;
++      __u32 subj_hash_size;
++};
++
++struct user_acl_role_db {
++      struct acl_role_label **r_table;
++      __u32 r_entries;        /* number of entries in table */
++      __u32 s_entries;        /* total number of subject acls */
++      __u32 i_entries;        /* total number of ip acls */
++      __u32 o_entries;        /* Total number of object acls */
++      __u32 a_entries;        /* total number of allowed ips */
++      __u32 t_entries;        /* total number of transitions */
++};
++
++struct acl_object_label {
++      char *filename;
++      ino_t inode;
++      kdev_t device;
++      __u32 mode;
++
++      struct acl_subject_label *nested;
++
++      /* next two structures not used */
++
++      struct acl_object_label *prev;
++      struct acl_object_label *next;
++};
++
++struct acl_ip_label {
++      __u32 addr;
++      __u32 netmask;
++      __u16 low, high;
++      __u8 mode;
++      __u32 type;
++      __u32 proto[8];
++
++      /* next two structures not used */
++
++      struct acl_ip_label *prev;
++      struct acl_ip_label *next;
++};
++
++struct gr_arg {
++      struct user_acl_role_db role_db;
++      unsigned char pw[GR_PW_LEN];
++      unsigned char salt[GR_SALT_LEN];
++      unsigned char sum[GR_SHA_LEN];
++      unsigned char sp_role[GR_SPROLE_LEN];
++      struct sprole_pw *sprole_pws;
++      __u16 num_sprole_pws;
++      kdev_t segv_device;
++      ino_t segv_inode;
++      uid_t segv_uid;
++      __u16 mode;
++};
++
++/* End Data Structures Section */
++
++/* Hash functions generated by empirical testing by Brad Spengler
++   Makes good use of the low bits of the inode.  Generally 0-1 times
++   in loop for successful match.  0-3 for unsuccessful match.
++   Shift/add algorithm with modulus of table size and an XOR*/
++
++static __inline__ unsigned long
++rhash(const uid_t uid, const __u16 type, const unsigned long sz)
++{
++      return (((uid << type) + (uid ^ type)) % sz);
++}
++
++static __inline__ unsigned long
++fhash(const ino_t ino, const kdev_t dev, const unsigned long sz)
++{
++      return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
++}
++
++static __inline__ unsigned long
++nhash(const char *name, const __u16 len, const unsigned long sz)
++{
++      return full_name_hash(name, len) % sz;
++}
+diff -urN linux-2.4.22/include/linux/gralloc.h linux-2.4.22-grsec-O1/include/linux/gralloc.h
+--- linux-2.4.22/include/linux/gralloc.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/gralloc.h      2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,8 @@
++#ifndef __GRALLOC_H
++#define __GRALLOC_H
++
++void acl_free_all(void);
++int acl_alloc_stack_init(unsigned long size);
++void *acl_alloc(unsigned long len);
++
++#endif
+diff -urN linux-2.4.22/include/linux/grdefs.h linux-2.4.22-grsec-O1/include/linux/grdefs.h
+--- linux-2.4.22/include/linux/grdefs.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/grdefs.h       2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,104 @@
++#ifndef GRDEFS_H
++#define GRDEFS_H
++
++/* Begin grsecurity status declarations */
++
++enum {
++      GR_READY = 0x01,
++      GR_STATUS_INIT = 0x00   // disabled state
++};
++
++/* Begin  ACL declarations */
++
++/* Role flags */
++
++enum {
++      GR_ROLE_USER = 0x0001,
++      GR_ROLE_GROUP = 0x0002,
++      GR_ROLE_DEFAULT = 0x0004,
++      GR_ROLE_SPECIAL = 0x0008,
++      GR_ROLE_AUTH = 0x0010,
++      GR_ROLE_NOPW = 0x0020,
++      GR_ROLE_GOD = 0x0040,
++      GR_ROLE_LEARN = 0x0080,
++      GR_ROLE_TPE = 0x0100
++};
++
++/* ACL Subject and Object mode flags */
++enum {
++      GR_DELETED = 0x00000080
++};
++
++/* ACL Object-only mode flags */
++enum {
++      GR_READ = 0x00000001,
++      GR_APPEND = 0x00000002,
++      GR_WRITE = 0x00000004,
++      GR_EXEC = 0x00000008,
++      GR_FIND = 0x00000010,
++      GR_INHERIT = 0x00000040,
++      GR_PTRACERD = 0x00000100,
++      GR_SETID = 0x00000200,
++      GR_CREATE = 0x00000400,
++      GR_DELETE = 0x00000800,
++      GR_AUDIT_READ = 0x00001000,
++      GR_AUDIT_APPEND = 0x00002000,
++      GR_AUDIT_WRITE = 0x0004000,
++      GR_AUDIT_EXEC = 0x00008000,
++      GR_AUDIT_FIND = 0x00010000,
++      GR_AUDIT_INHERIT = 0x00020000,
++      GR_AUDIT_SETID = 0x00400000,
++      GR_AUDIT_CREATE = 0x00800000,
++      GR_AUDIT_DELETE = 0x01000000,
++      GR_SUPPRESS = 0x02000000,
++      GR_NOLEARN = 0x04000000
++};
++
++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
++                 GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
++                 GR_AUDIT_CREATE | GR_AUDIT_DELETE)
++
++/* ACL subject-only mode flags */
++enum {
++      GR_KILL = 0x00000001,
++      GR_VIEW = 0x00000002,
++      GR_PROTECTED = 0x00000100,
++      GR_LEARN = 0x00000200,
++      GR_OVERRIDE = 0x00000400,
++      /* just a placeholder, this mode is only used in userspace */
++      GR_DUMMY = 0x00000800,
++
++      GR_PAXPAGE = 0x00001000,
++      GR_PAXSEGM = 0x00002000,
++      GR_PAXGCC = 0x00004000,
++      GR_PAXRANDMMAP = 0x00008000,
++      GR_PAXRANDEXEC = 0x00010000,
++      GR_PAXMPROTECT = 0x00020000,
++      GR_PROTSHM = 0x00040000,
++      GR_KILLPROC = 0x00080000,
++      GR_KILLIPPROC = 0x00100000,
++      /* just a placeholder, this mode is only used in userspace */
++      GR_NOTROJAN = 0x00200000,
++      GR_PROTPROCFD = 0x00400000,
++      GR_PROCACCT = 0x00800000
++};
++
++#define GR_CRASH_RES  11
++#define GR_UIDTABLE_MAX 500
++
++/* begin resource learning section */
++enum {
++      GR_RLIM_CPU_BUMP = 60,
++      GR_RLIM_FSIZE_BUMP = 50000,
++      GR_RLIM_DATA_BUMP = 10000,
++      GR_RLIM_STACK_BUMP = 1000,
++      GR_RLIM_CORE_BUMP = 10000,
++      GR_RLIM_RSS_BUMP = 500000,
++      GR_RLIM_NPROC_BUMP = 1,
++      GR_RLIM_NOFILE_BUMP = 5,
++      GR_RLIM_MEMLOCK_BUMP = 50000,
++      GR_RLIM_AS_BUMP = 500000,
++      GR_RLIM_LOCKS_BUMP = 2
++};
++
++#endif
+diff -urN linux-2.4.22/include/linux/grinternal.h linux-2.4.22-grsec-O1/include/linux/grinternal.h
+--- linux-2.4.22/include/linux/grinternal.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/grinternal.h   2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,193 @@
++#ifndef __GRINTERNAL_H
++#define __GRINTERNAL_H
++
++#ifdef CONFIG_GRKERNSEC
++
++#include <linux/grdefs.h>
++#include <linux/grmsg.h>
++
++extern void gr_add_learn_entry(const char *fmt, ...);
++extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
++                          const struct vfsmount *mnt);
++extern __u32 gr_check_create(const struct dentry *new_dentry,
++                           const struct dentry *parent,
++                           const struct vfsmount *mnt, const __u32 mode);
++extern int gr_check_protected_task(const struct task_struct *task);
++extern __inline__ __u32 to_gr_audit(const __u32 reqmode);
++extern int gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
++                          struct dentry *old_dentry,
++                          struct dentry *new_dentry,
++                          struct vfsmount *mnt, const __u8 replace);
++extern int gr_set_acls(const int type);
++
++extern void gr_handle_alertkill(void);
++extern char *gr_to_filename(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++extern char *gr_to_filename1(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++extern char *gr_to_filename2(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++extern char *gr_to_filename3(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++
++extern int grsec_enable_link;
++extern int grsec_enable_fifo;
++extern int grsec_enable_execve;
++extern int grsec_enable_forkbomb;
++extern int grsec_forkbomb_gid;
++extern int grsec_forkbomb_sec;
++extern int grsec_forkbomb_max;
++extern int grsec_enable_execlog;
++extern int grsec_enable_signal;
++extern int grsec_enable_forkfail;
++extern int grsec_enable_time;
++extern int grsec_enable_chroot_shmat;
++extern int grsec_enable_chroot_findtask;
++extern int grsec_enable_chroot_mount;
++extern int grsec_enable_chroot_double;
++extern int grsec_enable_chroot_pivot;
++extern int grsec_enable_chroot_chdir;
++extern int grsec_enable_chroot_chmod;
++extern int grsec_enable_chroot_mknod;
++extern int grsec_enable_chroot_fchdir;
++extern int grsec_enable_chroot_nice;
++extern int grsec_enable_chroot_execlog;
++extern int grsec_enable_chroot_caps;
++extern int grsec_enable_chroot_sysctl;
++extern int grsec_enable_chroot_unix;
++extern int grsec_enable_tpe;
++extern int grsec_tpe_gid;
++extern int grsec_enable_tpe_all;
++extern int grsec_enable_sidcaps;
++extern int grsec_enable_randpid;
++extern int grsec_enable_socket_all;
++extern int grsec_socket_all_gid;
++extern int grsec_enable_socket_client;
++extern int grsec_socket_client_gid;
++extern int grsec_enable_socket_server;
++extern int grsec_socket_server_gid;
++extern int grsec_audit_gid;
++extern int grsec_enable_group;
++extern int grsec_enable_audit_ipc;
++extern int grsec_enable_mount;
++extern int grsec_enable_chdir;
++extern int grsec_lock;
++
++extern struct task_struct *child_reaper;
++
++extern spinlock_t grsec_alert_lock;
++extern unsigned long grsec_alert_wtime;
++extern unsigned long grsec_alert_fyet;
++
++extern spinlock_t grsec_alertgood_lock;
++extern unsigned long grsec_alertgood_wtime;
++extern unsigned long grsec_alertgood_fyet;
++
++extern spinlock_t grsec_audit_lock;
++
++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
++                      gr_to_filename2(tsk->exec_file->f_dentry, \
++                      tsk->exec_file->f_vfsmnt) : "/")
++
++#define gr_parent_task_fullpath(tsk) (tsk->p_pptr->exec_file ? \
++                      gr_to_filename3(tsk->p_pptr->exec_file->f_dentry, \
++                      tsk->p_pptr->exec_file->f_vfsmnt) : "/")
++
++#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && \
++                        ((tsk_a->fs->root->d_inode->i_dev != \
++                        child_reaper->fs->root->d_inode->i_dev) || \
++                        (tsk_a->fs->root->d_inode->i_ino != \
++                        child_reaper->fs->root->d_inode->i_ino)))
++
++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_dev == \
++                        tsk_b->fs->root->d_inode->i_dev) && \
++                        (tsk_a->fs->root->d_inode->i_ino == \
++                        tsk_b->fs->root->d_inode->i_ino))
++
++#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
++                     current->pid, current->uid, \
++                     current->euid, current->gid, current->egid, \
++                     gr_parent_task_fullpath(current), \
++                     current->p_pptr->comm, current->p_pptr->pid, \
++                     current->p_pptr->uid, current->p_pptr->euid, \
++                     current->p_pptr->gid, current->p_pptr->egid
++
++#define GR_CHROOT_CAPS ( \
++      CAP_TO_MASK(CAP_FOWNER) | \
++      CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
++      CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
++      CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
++      CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
++      CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
++      CAP_TO_MASK(CAP_IPC_OWNER))
++
++#define security_alert_good(normal_msg,args...) \
++({ \
++      spin_lock(&grsec_alertgood_lock); \
++      \
++      if (!grsec_alertgood_wtime || jiffies - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
++          grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet = 0; \
++          if (current->curr_ip) \
++              printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
++          else \
++              printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
++      } else if((jiffies - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
++          grsec_alertgood_fyet++; \
++          if (current->curr_ip) \
++              printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
++          else \
++              printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
++      } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
++          grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet++; \
++          printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
++                  "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
++      } \
++      \
++      spin_unlock(&grsec_alertgood_lock); \
++})
++
++#define security_alert(normal_msg,args...) \
++({ \
++      spin_lock(&grsec_alert_lock); \
++      \
++      if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
++          grsec_alert_wtime = jiffies; grsec_alert_fyet = 0; \
++          if (current->curr_ip) \
++              printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
++          else \
++              printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
++      } else if((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
++          grsec_alert_fyet++; \
++          if (current->curr_ip) \
++              printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
++          else \
++              printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
++      } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
++          grsec_alert_wtime = jiffies; grsec_alert_fyet++; \
++          printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
++                  "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
++      } \
++      \
++      gr_handle_alertkill(); \
++      spin_unlock(&grsec_alert_lock); \
++})
++
++#define security_audit(normal_msg,args...) \
++({ \
++      spin_lock(&grsec_audit_lock); \
++      if (current->curr_ip) \
++              printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
++                     NIPQUAD(current->curr_ip) , ## args); \
++      else \
++              printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
++      spin_unlock(&grsec_audit_lock); \
++})
++
++#define security_learn(normal_msg,args...) \
++({ \
++      gr_add_learn_entry(normal_msg "\n", ## args); \
++})
++
++#endif
++
++#endif
+diff -urN linux-2.4.22/include/linux/grmsg.h linux-2.4.22-grsec-O1/include/linux/grmsg.h
+--- linux-2.4.22/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/grmsg.h        2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,104 @@
++#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d, parent %.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d"
++#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d"
++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
++#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
++#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
++#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
++#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
++#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
++#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
++#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
++#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%u.%u.%u.%u"
++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
++#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
++#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
++#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
++#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution of [%.16s:%lu] for %lu seconds"
++#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
++#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
++#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
++#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
++#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
++#define GR_INITF_ACL_MSG "init_variables() failed %s"
++#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader"
++#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
++#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
++#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
++#define GR_ENABLE_ACL_MSG "Loaded %s"
++#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
++#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
++#define GR_RELOAD_ACL_MSG "Reloaded %s"
++#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
++#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
++#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
++#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
++#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
++#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
++#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
++#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
++#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
++#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
++#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
++#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
++#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
++#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
++#define GR_TIME_MSG "time set by " DEFAULTSECMSG
++#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
++#define GR_SOCK_MSG "attempted socket(%d,%d,%d) by " DEFAULTSECMSG
++#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
++#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
++#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
++#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
++#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%u.%u.%u.%u\t%u\t%u\t%u\t%u\t%u.%u.%u.%u"
++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
++#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
++#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
++#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
++#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
++#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
+diff -urN linux-2.4.22/include/linux/grsecurity.h linux-2.4.22-grsec-O1/include/linux/grsecurity.h
+--- linux-2.4.22/include/linux/grsecurity.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/linux/grsecurity.h   2003-10-21 14:24:34.000000000 +0200
+@@ -0,0 +1,174 @@
++#ifndef GR_SECURITY_H
++#define GR_SECURITY_H
++
++extern int gr_pid_is_chrooted(const struct task_struct *p);
++extern int gr_handle_chroot_nice(void);
++extern int gr_handle_chroot_sysctl(const int op);
++extern int gr_handle_chroot_capset(const struct task_struct *target);
++extern int gr_handle_chroot_setpriority(const struct task_struct *p,
++                                      const int niceval);
++extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
++extern int gr_handle_chroot_chroot(const struct dentry *dentry,
++                                 const struct vfsmount *mnt);
++extern void gr_handle_chroot_caps(struct task_struct *task);
++extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
++extern int gr_handle_chroot_chmod(const struct dentry *dentry,
++                                const struct vfsmount *mnt, const int mode);
++extern int gr_handle_chroot_mknod(const struct dentry *dentry,
++                                const struct vfsmount *mnt, const int mode);
++extern int gr_handle_chroot_mount(const struct dentry *dentry,
++                                const struct vfsmount *mnt,
++                                const char *dev_name);
++extern int gr_handle_chroot_pivot(void);
++extern int gr_handle_chroot_unix(const pid_t pid);
++
++extern int gr_handle_rawio(const struct inode *inode);
++extern int gr_handle_nproc(void);
++
++extern void gr_handle_ioperm(void);
++extern void gr_handle_iopl(void);
++
++extern int gr_tpe_allow(const struct file *file);
++
++extern int gr_random_pid(spinlock_t * pid_lock);
++
++extern void gr_log_forkfail(const int retval);
++extern void gr_log_timechange(void);
++extern void gr_log_signal(const int sig, const struct task_struct *t);
++extern void gr_log_chdir(const struct dentry *dentry,
++                       const struct vfsmount *mnt);
++extern void gr_log_chroot_exec(const struct dentry *dentry,
++                             const struct vfsmount *mnt);
++extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
++extern void gr_log_remount(const char *devname, const int retval);
++extern void gr_log_unmount(const char *devname, const int retval);
++extern void gr_log_mount(const char *from, const char *to, const int retval);
++extern void gr_log_msgget(const int ret, const int msgflg);
++extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
++extern void gr_log_semget(const int err, const int semflg);
++extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
++extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
++extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
++
++extern int gr_handle_follow_link(const struct inode *parent,
++                               const struct inode *inode,
++                               const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++extern int gr_handle_fifo(const struct dentry *dentry,
++                        const struct vfsmount *mnt,
++                        const struct dentry *dir, const int flag,
++                        const int acc_mode);
++extern int gr_handle_hardlink(const struct dentry *dentry,
++                            const struct vfsmount *mnt,
++                            struct inode *inode,
++                            const int mode, const char *to);
++
++extern int gr_is_capable(const int cap);
++extern void gr_learn_resource(const struct task_struct *task, const int limit,
++                            const unsigned long wanted);
++extern void gr_copy_label(struct task_struct *tsk);
++extern void gr_handle_crash(struct task_struct *task, const int sig);
++extern int gr_handle_signal(const struct task_struct *p, const int sig);
++extern int gr_check_crash_uid(const uid_t uid);
++extern int gr_check_protected_task(const struct task_struct *task);
++extern int gr_acl_handle_mmap(const struct file *file,
++                            const unsigned long prot);
++extern int gr_acl_handle_mprotect(const struct file *file,
++                                const unsigned long prot);
++extern int gr_check_hidden_task(const struct task_struct *tsk);
++extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
++                                  const struct vfsmount *mnt);
++extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++extern __u32 gr_acl_handle_access(const struct dentry *dentry,
++                                const struct vfsmount *mnt, const int fmode);
++extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
++                                const struct vfsmount *mnt, mode_t mode);
++extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
++                               const struct vfsmount *mnt, mode_t mode);
++extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++extern int gr_handle_ptrace_exec(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++extern int gr_handle_ptrace(struct task_struct *task, const long request);
++extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
++extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
++                                const struct vfsmount *mnt);
++extern int gr_check_crash_exec(const struct file *filp);
++extern int gr_acl_is_enabled(void);
++extern void gr_set_kernel_label(struct task_struct *task);
++extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
++                            const gid_t gid);
++extern void gr_set_proc_label(const struct dentry *dentry,
++                            const struct vfsmount *mnt);
++extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
++                                     const struct vfsmount *mnt);
++extern __u32 gr_acl_handle_open(const struct dentry *dentry,
++                              const struct vfsmount *mnt, const int fmode);
++extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
++                               const struct dentry *p_dentry,
++                               const struct vfsmount *p_mnt, const int fmode,
++                               const int imode);
++extern void gr_handle_create(const struct dentry *dentry,
++                           const struct vfsmount *mnt);
++extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
++                               const struct dentry *parent_dentry,
++                               const struct vfsmount *parent_mnt,
++                               const int mode);
++extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
++                               const struct dentry *parent_dentry,
++                               const struct vfsmount *parent_mnt);
++extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++extern void gr_handle_delete(const ino_t ino, const kdev_t dev);
++extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
++                                const struct vfsmount *mnt);
++extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
++                                 const struct dentry *parent_dentry,
++                                 const struct vfsmount *parent_mnt,
++                                 const char *from);
++extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
++                              const struct dentry *parent_dentry,
++                              const struct vfsmount *parent_mnt,
++                              const struct dentry *old_dentry,
++                              const struct vfsmount *old_mnt, const char *to);
++extern int gr_acl_handle_rename(struct dentry *new_dentry,
++                              struct dentry *parent_dentry,
++                              const struct vfsmount *parent_mnt,
++                              struct dentry *old_dentry,
++                              struct inode *old_parent_inode,
++                              struct vfsmount *old_mnt, const char *newname);
++extern __u32 gr_check_link(const struct dentry *new_dentry,
++                         const struct dentry *parent_dentry,
++                         const struct vfsmount *parent_mnt,
++                         const struct dentry *old_dentry,
++                         const struct vfsmount *old_mnt);
++extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
++                                 const struct vfsmount *mnt, const ino_t ino);
++extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
++                              const struct vfsmount *mnt);
++extern void gr_set_pax_flags(struct task_struct *task);
++extern void gr_acl_handle_exit(void);
++extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
++extern int gr_acl_handle_procpidmem(const struct task_struct *task);
++extern __u32 gr_cap_rtnetlink(void);
++
++#ifdef CONFIG_GRKERNSEC
++extern void gr_handle_mem_write(void);
++extern void gr_handle_kmem_write(void);
++extern void gr_handle_open_port(void);
++extern int gr_handle_mem_mmap(const unsigned long offset,
++                            struct vm_area_struct *vma);
++
++extern __u16 ip_randomid(void);
++extern __u32 ip_randomisn(void);
++extern unsigned long get_random_long(void);
++
++extern int grsec_enable_dmesg;
++extern int grsec_enable_randid;
++extern int grsec_enable_randisn;
++extern int grsec_enable_randsrc;
++extern int grsec_enable_randrpc;
++#endif
++
++#endif
+diff -urN linux-2.4.22/include/linux/kernel.h linux-2.4.22-grsec-O1/include/linux/kernel.h
+--- linux-2.4.22/include/linux/kernel.h        2003-10-20 18:58:49.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/linux/kernel.h       2003-10-21 14:24:34.000000000 +0200
+@@ -71,14 +71,17 @@
+ extern long long simple_strtoll(const char *,char **,unsigned int);
+ extern int sprintf(char * buf, const char * fmt, ...)
+       __attribute__ ((format (printf, 2, 3)));
+-extern int vsprintf(char *buf, const char *, va_list);
++extern int vsprintf(char *buf, const char *, va_list)
++      __attribute__ ((format (printf, 2, 0)));
+ extern int snprintf(char * buf, size_t size, const char * fmt, ...)
+       __attribute__ ((format (printf, 3, 4)));
+-extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
++extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
++      __attribute__ ((format (printf, 3, 0)));
+ extern int sscanf(const char *, const char *, ...)
+       __attribute__ ((format (scanf,2,3)));
+-extern int vsscanf(const char *, const char *, va_list);
++extern int vsscanf(const char *, const char *, va_list)
++      __attribute__ ((format (scanf, 2, 0)));
+ extern void qsort(void *, size_t, size_t, int (*)(const void *,const void *));
+diff -urN linux-2.4.22/include/linux/mm.h linux-2.4.22-grsec-O1/include/linux/mm.h
+--- linux-2.4.22/include/linux/mm.h    2003-10-20 18:58:48.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/linux/mm.h   2003-10-21 14:24:34.000000000 +0200
+@@ -22,9 +22,13 @@
+ extern struct list_head active_list;
+ extern struct list_head inactive_list;
++extern void gr_learn_resource(const struct task_struct * task, const int limit,
++                            const unsigned long wanted);
++
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+ #include <asm/atomic.h>
++#include <asm/mman.h>
+ /*
+  * Linux kernel virtual memory manager primitives.
+@@ -104,6 +108,33 @@
+ #define VM_DONTEXPAND 0x00040000      /* Cannot expand with mremap() */
+ #define VM_RESERVED   0x00080000      /* Don't unmap it from swap_out */
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++#define VM_MIRROR     0x00100000      /* vma is mirroring another */
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++#define VM_MAYNOTWRITE        0x00200000      /* vma cannot be granted VM_WRITE any more */
++#endif
++
++#ifdef ARCH_STACK_GROWSUP
++#define __VM_STACK_FLAGS      0x00000233
++#else
++#define __VM_STACK_FLAGS      0x00000133
++#endif
++
++#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++#define VM_STACK_FLAGS        (__VM_STACK_FLAGS | \
++                      ((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
++                      ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
++#else
++#define VM_STACK_FLAGS        (__VM_STACK_FLAGS | VM_MAYEXEC | \
++                      ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
++#endif
++#else
++#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_EXEC | VM_MAYEXEC)
++#endif
++
+ #ifndef VM_STACK_FLAGS
+ #define VM_STACK_FLAGS        0x00000177
+ #endif
+@@ -568,22 +599,50 @@
+                                  unsigned long prot, unsigned long flag,
+                                  unsigned long pgoff);
++extern int do_munmap(struct mm_struct *, unsigned long, size_t);
++
+ static inline unsigned long do_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+ {
+       unsigned long ret = -EINVAL;
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      if ((current->flags & PF_PAX_SEGMEXEC) &&
++         (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
++              goto out;
++#endif
++
+       if ((offset + PAGE_ALIGN(len)) < offset)
+               goto out;
+       if (!(offset & ~PAGE_MASK))
+               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
+                                   offset >> PAGE_SHIFT);
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++#define BAD_ADDR(x)   ((unsigned long)(x) > TASK_SIZE)
++      if ((current->flags & PF_PAX_SEGMEXEC) && !BAD_ADDR(ret) &&
++          (prot & PROT_EXEC) && ((flag & MAP_TYPE) == MAP_PRIVATE)
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++          && (!(current->flags & PF_PAX_MPROTECT) || (file && !(prot & PROT_WRITE)))
++#endif
++         )
++      {
++              unsigned long ret_m;
++              ret_m = do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flag | MAP_MIRROR | MAP_FIXED, ret);
++              if (BAD_ADDR(ret_m)) {
++                      do_munmap(current->mm, ret, len);
++                      ret = ret_m;
++              }
++      }
++#undef BAD_ADDR
++#endif
++
+ out:
+       return ret;
+ }
+-extern int do_munmap(struct mm_struct *, unsigned long, size_t);
+-
+ extern unsigned long do_brk(unsigned long, unsigned long);
+ static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev)
+@@ -596,6 +655,12 @@
+ static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
+ {
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      if ((vma->vm_flags | vm_flags) & VM_MIRROR)
++              return 0;
++#endif
++
+       if (!vma->vm_file && vma->vm_flags == vm_flags)
+               return 1;
+       else
+@@ -649,7 +714,12 @@
+       return gfp_mask;
+ }
+-      
++
++/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
++extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
++extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
++                                           struct vm_area_struct **pprev);
++
+ /* vma is the first one with  address < vma->vm_end,
+  * and even  address < vma->vm_start. Have to extend vma. */
+ static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
+@@ -664,11 +734,51 @@
+       address &= PAGE_MASK;
+       spin_lock(&vma->vm_mm->page_table_lock);
+       grow = (vma->vm_start - address) >> PAGE_SHIFT;
++
++      gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address);
++      gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT);
++      gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT);
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (vma->vm_flags & VM_MIRROR) {
++              struct vm_area_struct * vma_m;
++              unsigned long address_m;
++
++              address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
++              vma_m = find_vma(vma->vm_mm, address_m);
++              if (!vma_m || vma_m->vm_start != address_m || !(vma_m->vm_flags & VM_MIRROR) ||
++                  vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start) {
++                      spin_unlock(&vma->vm_mm->page_table_lock);
++                      printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
++                             address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
++                      return -ENOMEM;
++              }
++
++              address_m = address + (unsigned long)vma->vm_private_data;
++              if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
++                  ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
++                  ((vma_m->vm_flags & VM_LOCKED) && ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
++                   current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
++                      spin_unlock(&vma->vm_mm->page_table_lock);
++                      return -ENOMEM;
++              }
++
++              vma_m->vm_start = address_m;
++              vma_m->vm_pgoff -= grow;
++              vma_m->vm_mm->total_vm += grow;
++              if (vma_m->vm_flags & VM_LOCKED)
++                      vma_m->vm_mm->locked_vm += grow;
++      } else
++#endif
++
+       if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
+-          ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
++          ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur ||
++          ((vma->vm_flags & VM_LOCKED) && ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
++           current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
+               spin_unlock(&vma->vm_mm->page_table_lock);
+               return -ENOMEM;
+       }
++
+       vma->vm_start = address;
+       vma->vm_pgoff -= grow;
+       vma->vm_mm->total_vm += grow;
+@@ -678,11 +788,6 @@
+       return 0;
+ }
+-/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
+-extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
+-extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
+-                                           struct vm_area_struct **pprev);
+-
+ /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
+    NULL if none.  Assume start_addr < end_addr. */
+ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
+diff -urN linux-2.4.22/include/linux/proc_fs.h linux-2.4.22-grsec-O1/include/linux/proc_fs.h
+--- linux-2.4.22/include/linux/proc_fs.h       2003-10-20 18:59:10.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/linux/proc_fs.h      2003-10-21 14:24:34.000000000 +0200
+@@ -143,6 +143,9 @@
+ extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
+               struct proc_dir_entry *,kdev_t);
+ extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
++#ifdef CONFIG_GRKERNSEC_PROC
++extern struct proc_dir_entry *proc_priv_mkdir(const char *, struct proc_dir_entry *);
++#endif
+ static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
+       mode_t mode, struct proc_dir_entry *base, 
+diff -urN linux-2.4.22/include/linux/sched.h linux-2.4.22-grsec-O1/include/linux/sched.h
+--- linux-2.4.22/include/linux/sched.h 2003-10-20 18:59:09.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/linux/sched.h        2003-10-21 14:24:34.000000000 +0200
+@@ -28,6 +28,9 @@
+ #include <linux/securebits.h>
+ #include <linux/fs_struct.h>
++extern int gr_is_capable(const int cap);
++extern int gr_pid_is_chrooted(const struct task_struct *p);
++
+ struct exec_domain;
+ /*
+@@ -250,6 +253,20 @@
+       unsigned long cpu_vm_mask;
+       unsigned long swap_address;
++#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE
++      unsigned long call_dl_resolve;
++#endif
++
++#if defined(CONFIG_PPC32) && defined(CONFIG_GRKERNSEC_PAX_EMUSIGRT)
++      unsigned long call_syscall;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_PAX_ASLR
++      unsigned long delta_mmap;               /* PaX: randomized offset */
++      unsigned long delta_exec;               /* PaX: randomized offset */
++      unsigned long delta_stack;              /* PaX: randomized offset */
++#endif
++ 
+       unsigned dumpable:1;
+       /* Architecture-specific MM context */
+@@ -422,7 +439,7 @@
+       int (*notifier)(void *priv);
+       void *notifier_data;
+       sigset_t *notifier_mask;
+-      
++
+ /* Thread group tracking */
+       u32 parent_exec_id;
+       u32 self_exec_id;
+@@ -433,6 +450,19 @@
+ /* journalling filesystem info */
+       void *journal_info;
++
++#ifdef CONFIG_GRKERNSEC
++/* added by grsecurity's ACL system */        
++      struct acl_subject_label *acl;
++      struct acl_role_label *role;
++      struct file *exec_file;
++      u32 curr_ip;
++      u16 acl_role_id;        
++      u8 acl_sp_role:1;       
++      u8 used_accept:1;       
++      u8 used_connect:1;      
++      u8 is_writable:1;
++#endif
+ };
+ /*
+@@ -454,6 +484,13 @@
+ #define PF_USEDFPU    0x00100000      /* task used FPU this quantum (SMP) */
++#define PF_PAX_PAGEEXEC       0x01000000      /* Paging based non-executable pages */
++#define PF_PAX_EMUTRAMP       0x02000000      /* Emulate trampolines */
++#define PF_PAX_MPROTECT       0x04000000      /* Restrict mprotect() */
++#define PF_PAX_RANDMMAP       0x08000000      /* Randomize mmap() base */
++#define PF_PAX_RANDEXEC             0x10000000      /* Randomize ET_EXEC base */
++#define PF_PAX_SEGMEXEC             0x20000000      /* Segmentation based non-executable pages */
++
+ /*
+  * Ptrace flags
+  */
+@@ -574,6 +611,8 @@
+       *p->pidhash_pprev = p->pidhash_next;
+ }
++#include <asm/current.h>
++
+ static inline task_t *find_task_by_pid(int pid)
+ {
+       task_t *p, **htable = &pidhash[pid_hashfn(pid)];
+@@ -581,6 +620,8 @@
+       for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
+               ;
++      if(gr_pid_is_chrooted(p)) p = NULL;
++
+       return p;
+ }
+@@ -588,8 +629,6 @@
+ extern struct user_struct * alloc_uid(uid_t);
+ extern void free_uid(struct user_struct *);
+-#include <asm/current.h>
+-
+ extern unsigned long volatile jiffies;
+ extern unsigned long itimer_ticks;
+ extern unsigned long itimer_next;
+@@ -756,7 +795,7 @@
+ static inline int capable(int cap)
+ {
+ #if 1 /* ok now */
+-      if (cap_raised(current->cap_effective, cap))
++      if (cap_raised(current->cap_effective, cap) && gr_is_capable(cap))
+ #else
+       if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
+ #endif
+diff -urN linux-2.4.22/include/linux/sysctl.h linux-2.4.22-grsec-O1/include/linux/sysctl.h
+--- linux-2.4.22/include/linux/sysctl.h        2003-10-20 18:59:00.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/linux/sysctl.h       2003-10-21 14:24:34.000000000 +0200
+@@ -127,6 +127,7 @@
+       KERN_CORE_PATTERN=56,   /* string: pattern for core-files */
+       KERN_PPC_L3CR=57,       /* l3cr register on PPC */
+       KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
++      KERN_GRSECURITY=68,     /* grsecurity */
+ };
+diff -urN linux-2.4.22/include/net/inetpeer.h linux-2.4.22-grsec-O1/include/net/inetpeer.h
+--- linux-2.4.22/include/net/inetpeer.h        2002-02-25 20:38:13.000000000 +0100
++++ linux-2.4.22-grsec-O1/include/net/inetpeer.h       2003-10-21 14:24:34.000000000 +0200
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ #include <linux/spinlock.h>
++
+ #include <asm/atomic.h>
+ struct inet_peer
+@@ -34,6 +35,11 @@
+ /* can be called with or without local BH being disabled */
+ struct inet_peer      *inet_getpeer(__u32 daddr, int create);
++#ifdef CONFIG_GRKERNSEC_RANDID
++extern int grsec_enable_randid;
++extern __u16 ip_randomid(void);
++#endif
++
+ extern spinlock_t inet_peer_unused_lock;
+ extern struct inet_peer *inet_peer_unused_head;
+ extern struct inet_peer **inet_peer_unused_tailp;
+@@ -58,7 +64,14 @@
+       __u16 id;
+       spin_lock_bh(&inet_peer_idlock);
+-      id = p->ip_id_count++;
++
++#ifdef CONFIG_GRKERNSEC_RANDID
++      if(grsec_enable_randid)
++              id = htons(ip_randomid());
++      else
++#endif
++              id = p->ip_id_count++;
++
+       spin_unlock_bh(&inet_peer_idlock);
+       return id;
+ }
+diff -urN linux-2.4.22/include/net/ip.h linux-2.4.22-grsec-O1/include/net/ip.h
+--- linux-2.4.22/include/net/ip.h      2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/include/net/ip.h     2003-10-21 14:24:34.000000000 +0200
+@@ -64,6 +64,11 @@
+       void                    (*destructor)(struct sock *);
+ };
++#ifdef CONFIG_GRKERNSEC_RANDID
++extern int grsec_enable_randid;
++extern __u16 ip_randomid(void);
++#endif
++
+ extern struct ip_ra_chain *ip_ra_chain;
+ extern rwlock_t ip_ra_lock;
+@@ -197,7 +202,13 @@
+                * does not change, they drop every other packet in
+                * a TCP stream using header compression.
+                */
+-              iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
++
++#ifdef CONFIG_GRKERNSEC_RANDID
++              if(grsec_enable_randid)
++                      iph->id = htons(ip_randomid());
++              else
++#endif
++                      iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
+       } else
+               __ip_select_ident(iph, dst);
+ }
+diff -urN linux-2.4.22/init/main.c linux-2.4.22-grsec-O1/init/main.c
+--- linux-2.4.22/init/main.c   2003-10-20 18:59:08.000000000 +0200
++++ linux-2.4.22-grsec-O1/init/main.c  2003-10-21 14:24:34.000000000 +0200
+@@ -27,6 +27,7 @@
+ #include <linux/iobuf.h>
+ #include <linux/bootmem.h>
+ #include <linux/tty.h>
++#include <linux/grsecurity.h>
+ #include <asm/io.h>
+ #include <asm/bugs.h>
+@@ -112,6 +113,8 @@
+ extern void ipc_init(void);
+ #endif
++extern void grsecurity_init(void);
++
+ /*
+  * Boot command-line arguments
+  */
+@@ -563,6 +566,7 @@
+       do_basic_setup();
+       prepare_namespace();
++      grsecurity_init();
+       /*
+        * Ok, we have completed the initial bootup, and
+diff -urN linux-2.4.22/ipc/msg.c linux-2.4.22-grsec-O1/ipc/msg.c
+--- linux-2.4.22/ipc/msg.c     2003-06-13 16:51:39.000000000 +0200
++++ linux-2.4.22-grsec-O1/ipc/msg.c    2003-10-21 14:24:34.000000000 +0200
+@@ -22,6 +22,7 @@
+ #include <linux/init.h>
+ #include <linux/proc_fs.h>
+ #include <linux/list.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include "util.h"
+@@ -326,6 +327,9 @@
+               msg_unlock(id);
+       }
+       up(&msg_ids.sem);
++
++      gr_log_msgget(ret, msgflg);
++
+       return ret;
+ }
+@@ -560,6 +564,8 @@
+               break;
+       }
+       case IPC_RMID:
++              gr_log_msgrm(ipcp->uid, ipcp->cuid);
++
+               freeque (msqid); 
+               break;
+       }
+diff -urN linux-2.4.22/ipc/sem.c linux-2.4.22-grsec-O1/ipc/sem.c
+--- linux-2.4.22/ipc/sem.c     2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/ipc/sem.c    2003-10-21 14:24:34.000000000 +0200
+@@ -63,6 +63,7 @@
+ #include <linux/init.h>
+ #include <linux/proc_fs.h>
+ #include <linux/time.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include "util.h"
+@@ -182,6 +183,9 @@
+       }
+       up(&sem_ids.sem);
++
++      gr_log_semget(err, semflg);
++
+       return err;
+ }
+@@ -724,6 +728,8 @@
+       switch(cmd){
+       case IPC_RMID:
++              gr_log_semrm(ipcp->uid, ipcp->cuid);
++
+               freeary(semid);
+               err = 0;
+               break;
+diff -urN linux-2.4.22/ipc/shm.c linux-2.4.22-grsec-O1/ipc/shm.c
+--- linux-2.4.22/ipc/shm.c     2002-08-03 02:39:46.000000000 +0200
++++ linux-2.4.22-grsec-O1/ipc/shm.c    2003-10-21 14:24:34.000000000 +0200
+@@ -23,6 +23,7 @@
+ #include <linux/mman.h>
+ #include <linux/proc_fs.h>
+ #include <asm/uaccess.h>
++#include <linux/grsecurity.h>
+ #include "util.h"
+@@ -38,8 +39,21 @@
+       time_t                  shm_ctim;
+       pid_t                   shm_cprid;
+       pid_t                   shm_lprid;
++
++#ifdef CONFIG_GRKERNSEC
++      time_t                  shm_createtime;
++      pid_t                   shm_lapid;
++#endif
+ };
++#ifdef CONFIG_GRKERNSEC
++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
++                          const time_t shm_createtime, const uid_t cuid,
++                          const int shmid);
++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
++                    const time_t shm_createtime);
++#endif
++
+ #define shm_flags     shm_perm.mode
+ static struct file_operations shm_file_operations;
+@@ -209,6 +223,9 @@
+       shp->shm_lprid = 0;
+       shp->shm_atim = shp->shm_dtim = 0;
+       shp->shm_ctim = CURRENT_TIME;
++#ifdef CONFIG_GRKERNSEC
++      shp->shm_createtime = CURRENT_TIME;
++#endif
+       shp->shm_segsz = size;
+       shp->shm_nattch = 0;
+       shp->id = shm_buildid(id,shp->shm_perm.seq);
+@@ -254,6 +271,9 @@
+               shm_unlock(id);
+       }
+       up(&shm_ids.sem);
++
++      gr_log_shmget(err, shmflg, size);
++
+       return err;
+ }
+@@ -509,6 +529,9 @@
+                       err=-EPERM;
+                       goto out_unlock_up;
+               }
++
++              gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
++
+               if (shp->shm_nattch){
+                       shp->shm_flags |= SHM_DEST;
+                       /* Do not find it any more */
+@@ -622,9 +645,28 @@
+               shm_unlock(shmid);
+               return -EACCES;
+       }
++
++#ifdef CONFIG_GRKERNSEC
++      if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
++                           shp->shm_perm.cuid, shmid)) {
++              shm_unlock(shmid);
++              return -EACCES;
++      }
++
++      if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
++              shm_unlock(shmid);
++              return -EACCES;
++      }
++#endif
++
+       file = shp->shm_file;
+       size = file->f_dentry->d_inode->i_size;
+       shp->shm_nattch++;
++
++#ifdef CONFIG_GRKERNSEC
++      shp->shm_lapid = current->pid;
++#endif
++
+       shm_unlock(shmid);
+       down_write(&current->mm->mmap_sem);
+diff -urN linux-2.4.22/kernel/capability.c linux-2.4.22-grsec-O1/kernel/capability.c
+--- linux-2.4.22/kernel/capability.c   2003-10-20 18:58:34.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/capability.c  2003-10-21 14:24:34.000000000 +0200
+@@ -7,6 +7,7 @@
+ #include <linux/mm.h>
+ #include <asm/uaccess.h>
++#include <linux/grsecurity.h>
+ unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
+@@ -170,6 +171,10 @@
+              target = current;
+      }
++     if (gr_handle_chroot_capset(target)) {
++           error = -ESRCH;
++           goto out;
++     }
+      /* verify restrictions on target's new Inheritable set */
+      if (!cap_issubset(inheritable,
+diff -urN linux-2.4.22/kernel/exit.c linux-2.4.22-grsec-O1/kernel/exit.c
+--- linux-2.4.22/kernel/exit.c 2003-10-20 18:59:07.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/exit.c        2003-10-21 14:25:43.000000000 +0200
+@@ -7,6 +7,7 @@
+ #include <linux/config.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
++#include <linux/file.h>
+ #include <linux/smp_lock.h>
+ #include <linux/module.h>
+ #include <linux/completion.h>
+@@ -16,6 +17,7 @@
+ #ifdef CONFIG_BSD_PROCESS_ACCT
+ #include <linux/acct.h>
+ #endif
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -139,12 +141,21 @@
+ {
+       write_lock_irq(&tasklist_lock);
++#ifdef CONFIG_GRKERNSEC
++      if (current->exec_file) {
++              fput(current->exec_file);
++              current->exec_file = NULL;
++      }
++#endif
++
+       /* Reparent to init */
+       REMOVE_LINKS(current);
+       current->p_pptr = child_reaper;
+       current->p_opptr = child_reaper;
+       SET_LINKS(current);
++      gr_set_kernel_label(current);
++
+       /* Set the exit signal to SIGCHLD so we signal init on exit */
+       current->exit_signal = SIGCHLD;
+@@ -485,6 +496,11 @@
+ #ifdef CONFIG_BSD_PROCESS_ACCT
+       acct_process(code);
+ #endif
++#include <linux/grsecurity.h>
++
++      gr_acl_handle_psacct(tsk, code);
++      gr_acl_handle_exit();
++
+       __exit_mm(tsk);
+       lock_kernel();
+diff -urN linux-2.4.22/kernel/fork.c linux-2.4.22-grsec-O1/kernel/fork.c
+--- linux-2.4.22/kernel/fork.c 2003-10-20 18:58:49.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/fork.c        2003-10-21 14:24:34.000000000 +0200
+@@ -22,6 +22,7 @@
+ #include <linux/namespace.h>
+ #include <linux/personality.h>
+ #include <linux/compiler.h>
++#include <linux/grsecurity.h>
+ #include <asm/pgtable.h>
+ #include <asm/pgalloc.h>
+@@ -94,6 +95,10 @@
+       if (flags & CLONE_PID)
+               return current->pid;
++      pid = gr_random_pid(&lastpid_lock);
++      if (pid)
++              return pid;
++
+       spin_lock(&lastpid_lock);
+       beginpid = last_pid;
+       if((++last_pid) & 0xffff8000) {
+@@ -669,6 +674,9 @@
+        * friends to set the per-user process limit to something lower
+        * than the amount of processes root is running. -- Rik
+        */
++
++      gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes));
++
+       if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
+                     && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
+               goto bad_fork_free;
+@@ -751,6 +759,7 @@
+       retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
+       if (retval)
+               goto bad_fork_cleanup_namespace;
++      gr_copy_label(p);
+       p->semundo = NULL;
+       
+       /* Our parent execution domain becomes current domain
+@@ -853,6 +862,9 @@
+       free_uid(p->user);
+ bad_fork_free:
+       free_task_struct(p);
++
++      gr_log_forkfail(retval);
++
+       goto fork_out;
+ }
+diff -urN linux-2.4.22/kernel/ksyms.c linux-2.4.22-grsec-O1/kernel/ksyms.c
+--- linux-2.4.22/kernel/ksyms.c        2003-10-20 18:59:10.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/ksyms.c       2003-10-21 14:24:34.000000000 +0200
+@@ -50,6 +50,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/dnotify.h>
+ #include <linux/crc32.h>
++#include <linux/grsecurity.h>
+ #include <asm/checksum.h>
+ #if defined(CONFIG_PROC_FS)
+@@ -622,3 +623,9 @@
+ /* To match ksyms with System.map */
+ extern const char _end[];
+ EXPORT_SYMBOL(_end);
++
++/* grsecurity */
++EXPORT_SYMBOL(gr_is_capable);
++EXPORT_SYMBOL(gr_pid_is_chrooted);
++EXPORT_SYMBOL(gr_learn_resource);
++EXPORT_SYMBOL(gr_set_kernel_label);
+diff -urN linux-2.4.22/kernel/module.c linux-2.4.22-grsec-O1/kernel/module.c
+--- linux-2.4.22/kernel/module.c       2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/module.c      2003-10-21 14:24:34.000000000 +0200
+@@ -900,6 +900,11 @@
+       struct module *mod;
+       int err;
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++      if (!capable(CAP_SYS_MODULE))
++              return -EPERM;
++#endif
++
+       lock_kernel();
+       if (name_user == NULL)
+               mod = &kernel_module;
+@@ -969,6 +974,11 @@
+       int i;
+       struct kernel_sym ksym;
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++      if (!capable(CAP_SYS_MODULE))
++              return 0;
++#endif
++
+       lock_kernel();
+       for (mod = module_list, i = 0; mod; mod = mod->next) {
+               /* include the count for the module name! */
+diff -urN linux-2.4.22/kernel/printk.c linux-2.4.22-grsec-O1/kernel/printk.c
+--- linux-2.4.22/kernel/printk.c       2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/printk.c      2003-10-21 14:24:34.000000000 +0200
+@@ -27,6 +27,7 @@
+ #include <linux/interrupt.h>                  /* For in_interrupt() */
+ #include <linux/config.h>
+ #include <linux/delay.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+@@ -293,6 +294,11 @@
+ asmlinkage long sys_syslog(int type, char * buf, int len)
+ {
++#ifdef CONFIG_GRKERNSEC_DMESG
++      if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
++              return -EPERM;
++      else
++#endif
+       if ((type != 3) && !capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       return do_syslog(type, buf, len);
+diff -urN linux-2.4.22/kernel/sched.c linux-2.4.22-grsec-O1/kernel/sched.c
+--- linux-2.4.22/kernel/sched.c        2003-10-20 18:59:07.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/sched.c       2003-10-21 14:24:34.000000000 +0200
+@@ -25,6 +25,7 @@
+ #include <asm/mmu_context.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/completion.h>
++#include <linux/grsecurity.h>
+ /*
+  * Convert user-nice values [ -20 ... 0 ... 19 ]
+@@ -1192,6 +1193,9 @@
+                       return -EPERM;
+               if (increment < -40)
+                       increment = -40;
++
++              if (gr_handle_chroot_nice())
++                      return -EPERM;
+       }
+       if (increment > 40)
+               increment = 40;
+diff -urN linux-2.4.22/kernel/signal.c linux-2.4.22-grsec-O1/kernel/signal.c
+--- linux-2.4.22/kernel/signal.c       2003-10-20 18:59:07.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/signal.c      2003-10-21 14:24:34.000000000 +0200
+@@ -13,6 +13,8 @@
+ #include <linux/smp_lock.h>
+ #include <linux/init.h>
+ #include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+@@ -553,6 +555,8 @@
+       if (!sig || !t->sig)
+               goto out_nolock;
++      gr_log_signal(sig, t);
++
+       spin_lock_irqsave(&t->sigmask_lock, flags);
+       handle_stop_signal(sig, t);
+@@ -602,6 +606,8 @@
+       recalc_sigpending(t);
+       spin_unlock_irqrestore(&t->sigmask_lock, flags);
++      gr_handle_crash(t, sig);
++
+       return send_sig_info(sig, info, t);
+ }
+@@ -621,9 +627,13 @@
+               read_lock(&tasklist_lock);
+               for_each_task(p) {
+                       if (p->pgrp == pgrp && thread_group_leader(p)) {
+-                              int err = send_sig_info(sig, info, p);
+-                              if (retval)
+-                                      retval = err;
++                              if (gr_handle_signal(p, sig))
++                                      retval = -EPERM;
++                              else {
++                                      int err = send_sig_info(sig, info, p);
++                                      if (retval)
++                                              retval = err;
++                              }
+                       }
+               }
+               read_unlock(&tasklist_lock);
+@@ -674,7 +684,10 @@
+                        if (tg)
+                                p = tg;
+                 }
+-              error = send_sig_info(sig, info, p);
++              if (gr_handle_signal(p, sig))
++                      error = -EPERM;
++              else
++                      error = send_sig_info(sig, info, p);
+       }
+       read_unlock(&tasklist_lock);
+       return error;
+@@ -699,10 +712,14 @@
+               read_lock(&tasklist_lock);
+               for_each_task(p) {
+                       if (p->pid > 1 && p != current && thread_group_leader(p)) {
+-                              int err = send_sig_info(sig, info, p);
+-                              ++count;
+-                              if (err != -EPERM)
+-                                      retval = err;
++                              if (gr_handle_signal(p, sig))
++                                      retval = -EPERM;
++                              else {
++                                      int err = send_sig_info(sig, info, p);
++                                      ++count;
++                                      if (err != -EPERM)
++                                              retval = err;
++                              }
+                       }
+               }
+               read_unlock(&tasklist_lock);
+diff -urN linux-2.4.22/kernel/sys.c linux-2.4.22-grsec-O1/kernel/sys.c
+--- linux-2.4.22/kernel/sys.c  2003-10-20 18:58:34.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/sys.c 2003-10-21 14:24:34.000000000 +0200
+@@ -4,6 +4,7 @@
+  *  Copyright (C) 1991, 1992  Linus Torvalds
+  */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/utsname.h>
+@@ -14,6 +15,7 @@
+ #include <linux/prctl.h>
+ #include <linux/init.h>
+ #include <linux/highuid.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -239,6 +241,12 @@
+               }
+               if (error == -ESRCH)
+                       error = 0;
++
++              if (gr_handle_chroot_setpriority(p, niceval)) {
++                      read_unlock(&tasklist_lock);
++                      return -ESRCH;
++              }
++
+               if (niceval < task_nice(p) && !capable(CAP_SYS_NICE))
+                       error = -EACCES;
+               else
+@@ -425,6 +433,9 @@
+       if (rgid != (gid_t) -1 ||
+           (egid != (gid_t) -1 && egid != old_rgid))
+               current->sgid = new_egid;
++
++      gr_set_role_label(current, current->uid, new_rgid);
++
+       current->fsgid = new_egid;
+       current->egid = new_egid;
+       current->gid = new_rgid;
+@@ -447,6 +458,9 @@
+                       current->mm->dumpable=0;
+                       wmb();
+               }
++
++              gr_set_role_label(current, current->uid, gid);
++
+               current->gid = current->egid = current->sgid = current->fsgid = gid;
+       }
+       else if ((gid == current->gid) || (gid == current->sgid))
+@@ -530,6 +544,9 @@
+               current->mm->dumpable = 0;
+               wmb();
+       }
++
++      gr_set_role_label(current, new_ruid, current->gid);
++
+       current->uid = new_ruid;
+       current->user = new_user;
+       free_uid(old_user);
+@@ -626,6 +643,9 @@
+       } else if ((uid != current->uid) && (uid != new_suid))
+               return -EPERM;
++      if (gr_check_crash_uid(uid))
++              return -EPERM;
++
+       if (old_euid != uid)
+       {
+               current->mm->dumpable = 0;
+@@ -722,8 +742,10 @@
+               current->egid = egid;
+       }
+       current->fsgid = current->egid;
+-      if (rgid != (gid_t) -1)
++      if (rgid != (gid_t) -1) {
++              gr_set_role_label(current, current->uid, rgid);
+               current->gid = rgid;
++      }
+       if (sgid != (gid_t) -1)
+               current->sgid = sgid;
+       return 0;
+@@ -1146,6 +1168,10 @@
+        if (new_rlim.rlim_cur > new_rlim.rlim_max)
+                return -EINVAL;
+       old_rlim = current->rlim + resource;
++
++      if (old_rlim->rlim_max < old_rlim->rlim_cur)
++              return -EINVAL;
++
+       if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
+            (new_rlim.rlim_max > old_rlim->rlim_max)) &&
+           !capable(CAP_SYS_RESOURCE))
+diff -urN linux-2.4.22/kernel/sysctl.c linux-2.4.22-grsec-O1/kernel/sysctl.c
+--- linux-2.4.22/kernel/sysctl.c       2003-10-20 18:59:00.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/sysctl.c      2003-10-21 14:24:34.000000000 +0200
+@@ -38,6 +38,15 @@
+ #endif
+ #if defined(CONFIG_SYSCTL)
++#include <linux/grsecurity.h>
++#include <linux/grinternal.h>
++
++extern int gr_proc_handler(ctl_table * table, int write, struct file * filp,
++                         void * buffer, size_t * lenp);
++extern __u32 gr_handle_sysctl(const ctl_table * table, const void *oldval,
++                            const void *newval);
++extern int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op);
++extern int gr_handle_chroot_sysctl(const int op);
+ /* External variables not in a header file. */
+ extern int panic_timeout;
+@@ -126,6 +135,8 @@
+ static ctl_table dev_table[];
+ extern ctl_table random_table[];
++static ctl_table grsecurity_table[];
++
+ /* /proc declarations: */
+ #ifdef CONFIG_PROC_FS
+@@ -272,8 +283,191 @@
+       {KERN_EXCEPTION_TRACE,"exception-trace",
+        &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
+ #endif        
++#ifdef CONFIG_GRKERNSEC_SYSCTL
++      {KERN_GRSECURITY, "grsecurity", NULL, 0, 0500, grsecurity_table},
++#endif
++      {0}
++};
++
++#ifdef CONFIG_GRKERNSEC_SYSCTL
++enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL, 
++GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
++GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
++GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS, 
++GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS, 
++GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
++GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
++GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
++GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
++GS_FINDTASK, GS_LOCK};
++
++static ctl_table grsecurity_table[] = {
++#ifdef CONFIG_GRKERNSEC_LINK
++      {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int),
++       0600, NULL, &proc_dointvec}, 
++#endif
++#ifdef CONFIG_GRKERNSEC_FIFO
++      {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_EXECVE
++      {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_EXECLOG
++      {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_SIGNAL
++      {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_FORKFAIL
++      {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_TIME
++      {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
++      {GS_CHROOT_SHMAT, "chroot_deny_shmat", &grsec_enable_chroot_shmat, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
++      {GS_CHROOT_UNIX, "chroot_deny_unix", &grsec_enable_chroot_unix, sizeof(int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
++      {GS_CHROOT_MNT, "chroot_deny_mount", &grsec_enable_chroot_mount, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
++      {GS_CHROOT_FCHDIR, "chroot_deny_fchdir", &grsec_enable_chroot_fchdir, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
++      {GS_CHROOT_DBL, "chroot_deny_chroot", &grsec_enable_chroot_double, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
++      {GS_CHROOT_PVT, "chroot_deny_pivot", &grsec_enable_chroot_pivot, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
++      {GS_CHROOT_CD, "chroot_enforce_chdir", &grsec_enable_chroot_chdir, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
++      {GS_CHROOT_CM, "chroot_deny_chmod", &grsec_enable_chroot_chmod, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
++      {GS_CHROOT_MK, "chroot_deny_mknod", &grsec_enable_chroot_mknod, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
++      {GS_CHROOT_NI, "chroot_restrict_nice", &grsec_enable_chroot_nice, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
++      {GS_CHROOT_EXECLOG, "chroot_execlog",
++       &grsec_enable_chroot_execlog, sizeof (int),
++         0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
++      {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
++      {GS_CHROOT_SYSCTL, "chroot_deny_sysctl", &grsec_enable_chroot_sysctl, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_TPE
++      {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int),
++       0600, NULL, &proc_dointvec},
++      {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_TPE_ALL
++      {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDPID
++      {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDID
++      {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDSRC
++      {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDISN
++      {GS_RANDISN, "rand_isns", &grsec_enable_randisn, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
++      {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int),
++       0600, NULL, &proc_dointvec},
++      {GS_SOCKET_ALL_GID, "socket_all_gid",
++       &grsec_socket_all_gid, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
++      {GS_SOCKET_CLIENT, "socket_client", 
++       &grsec_enable_socket_client, sizeof (int),
++       0600, NULL, &proc_dointvec},
++      {GS_SOCKET_CLIENT_GID, "socket_client_gid", 
++       &grsec_socket_client_gid, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
++      {GS_SOCKET_SERVER, "socket_server", 
++       &grsec_enable_socket_server, sizeof (int),
++       0600, NULL, &proc_dointvec},
++      {GS_SOCKET_SERVER_GID, "socket_server_gid",
++       &grsec_socket_server_gid, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
++      {GS_GROUP, "audit_group", &grsec_enable_group, sizeof (int),
++       0600, NULL, &proc_dointvec},
++      {GS_GID, "audit_gid",
++       &grsec_audit_gid, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
++      {GS_ACHDIR, "audit_chdir", &grsec_enable_chdir, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
++      {GS_AMOUNT, "audit_mount", &grsec_enable_mount, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
++      {GS_AIPC, "audit_ipc", &grsec_enable_audit_ipc, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_DMESG
++      {GS_AIPC, "dmesg", &grsec_enable_dmesg, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDRPC
++      {GS_RANDRPC, "rand_rpc", &grsec_enable_randrpc, sizeof (int),
++       0600, NULL, &proc_dointvec},
++#endif
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
++      {GS_FINDTASK, "chroot_findtask", &grsec_enable_chroot_findtask, 
++       sizeof (int), 0600, NULL, &proc_dointvec},
++#endif
++      {GS_LOCK, "grsec_lock", &grsec_lock, sizeof (int), 0600, NULL,
++       &proc_dointvec},
+       {0}
+ };
++#endif
+ static ctl_table vm_table[] = {
+       {VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0644, NULL,
+@@ -410,6 +604,11 @@
+ static inline int ctl_perm(ctl_table *table, int op)
+ {
++      if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
++              return -EACCES;
++      if (gr_handle_chroot_sysctl(op))
++              return -EACCES;
++
+       return test_perm(table->mode, op);
+ }
+@@ -443,6 +642,10 @@
+                               table = table->child;
+                               goto repeat;
+                       }
++
++                      if (!gr_handle_sysctl(table, oldval, newval))
++                              return -EACCES;
++
+                       error = do_sysctl_strategy(table, name, nlen,
+                                                  oldval, oldlenp,
+                                                  newval, newlen, context);
+diff -urN linux-2.4.22/kernel/time.c linux-2.4.22-grsec-O1/kernel/time.c
+--- linux-2.4.22/kernel/time.c 2002-11-29 00:53:15.000000000 +0100
++++ linux-2.4.22-grsec-O1/kernel/time.c        2003-10-21 14:24:34.000000000 +0200
+@@ -27,6 +27,7 @@
+ #include <linux/mm.h>
+ #include <linux/timex.h>
+ #include <linux/smp_lock.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+@@ -89,6 +90,9 @@
+       time_maxerror = NTP_PHASE_LIMIT;
+       time_esterror = NTP_PHASE_LIMIT;
+       write_unlock_irq(&xtime_lock);
++
++      gr_log_timechange();
++
+       return 0;
+ }
+@@ -167,6 +171,8 @@
+                * globally block out interrupts when it runs.
+                */
+               do_settimeofday(tv);
++
++              gr_log_timechange();
+       }
+       return 0;
+ }
+diff -urN linux-2.4.22/kernel/timer.c linux-2.4.22-grsec-O1/kernel/timer.c
+--- linux-2.4.22/kernel/timer.c        2003-10-20 18:59:07.000000000 +0200
++++ linux-2.4.22-grsec-O1/kernel/timer.c       2003-10-21 14:24:34.000000000 +0200
+@@ -565,6 +565,9 @@
+       psecs = (p->times.tms_utime += user);
+       psecs += (p->times.tms_stime += system);
++
++      gr_learn_resource(p, RLIMIT_CPU, psecs / HZ);
++
+       if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
+               /* Send SIGXCPU every second.. */
+               if (!(psecs % HZ))
+diff -urN linux-2.4.22/mm/filemap.c linux-2.4.22-grsec-O1/mm/filemap.c
+--- linux-2.4.22/mm/filemap.c  2003-10-20 18:59:09.000000000 +0200
++++ linux-2.4.22-grsec-O1/mm/filemap.c 2003-10-21 14:24:35.000000000 +0200
+@@ -2258,6 +2258,12 @@
+       }
+       if (!mapping->a_ops->readpage)
+               return -ENOEXEC;
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      if (current->flags & PF_PAX_PAGEEXEC)
++              vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
++#endif
++
+       UPDATE_ATIME(inode);
+       vma->vm_ops = &generic_file_vm_ops;
+       return 0;
+@@ -2542,6 +2548,7 @@
+       error = -EIO;
+       rlim_rss = current->rlim ?  current->rlim[RLIMIT_RSS].rlim_cur :
+                               LONG_MAX; /* default: see resource.h */
++      gr_learn_resource(current, RLIMIT_RSS, vma->vm_mm->rss + (end - start));
+       if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
+               return error;
+@@ -3017,6 +3024,7 @@
+       err = -EFBIG;
+       
+       if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
++              gr_learn_resource(current, RLIMIT_FSIZE, pos);
+               if (pos >= limit) {
+                       send_sig(SIGXFSZ, current, 0);
+                       goto out;
+@@ -3052,6 +3060,7 @@
+        */
+        
+       if (!S_ISBLK(inode->i_mode)) {
++              gr_learn_resource(current, RLIMIT_FSIZE, *count + (u32)pos);
+               if (pos >= inode->i_sb->s_maxbytes)
+               {
+                       if (*count || pos > inode->i_sb->s_maxbytes) {
+diff -urN linux-2.4.22/mm/memory.c linux-2.4.22-grsec-O1/mm/memory.c
+--- linux-2.4.22/mm/memory.c   2002-11-29 00:53:15.000000000 +0100
++++ linux-2.4.22-grsec-O1/mm/memory.c  2003-10-21 14:24:35.000000000 +0200
+@@ -925,6 +925,65 @@
+       establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
+ }
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++/* PaX: if vma is mirrored, synchronize the mirror's PTE
++ *
++ * mm->page_table_lock is held on entry and is not released on exit or inside
++ * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
++ */
++static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
++       unsigned long address, pte_t *pte)
++{
++      unsigned long address_m;
++      struct vm_area_struct * vma_m = NULL;
++      pte_t * pte_m, entry_m;
++      struct page * page_m;
++
++      if (!(vma->vm_flags & VM_MIRROR))
++              return;
++
++      address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
++      vma_m = find_vma(mm, address_m);
++      if (!vma_m || vma_m->vm_start != address_m)
++              return;
++
++      address_m = address + (unsigned long)vma->vm_private_data;
++
++      {
++              pgd_t *pgd_m;
++              pmd_t *pmd_m;
++
++              pgd_m = pgd_offset(mm, address_m);
++              pmd_m = pmd_offset(pgd_m, address_m);
++              pte_m = pte_offset(pmd_m, address_m);
++      }
++
++      if (pte_present(*pte_m)) {
++              flush_cache_page(vma_m, address_m);
++              flush_icache_page(vma_m, pte_page(*pte_m));
++      }
++      entry_m = ptep_get_and_clear(pte_m);
++      if (pte_present(entry_m))
++              flush_tlb_page(vma_m, address_m);  
++
++      if (pte_none(entry_m)) {
++              ++mm->rss;
++      } else if (pte_present(entry_m)) {
++              page_cache_release(pte_page(entry_m));
++      } else {
++              free_swap_and_cache(pte_to_swp_entry(entry_m));
++              ++mm->rss;
++      }
++
++      page_m = pte_page(*pte);
++      page_cache_get(page_m);
++      entry_m = mk_pte(page_m, vma_m->vm_page_prot);
++      if (pte_write(*pte))
++              entry_m = pte_mkdirty(pte_mkwrite(entry_m));
++      establish_pte(vma_m, address_m, pte_m, entry_m);  
++}                      
++#endif
++
+ /*
+  * This routine handles present pages, when users try to write
+  * to a shared page. It is done by copying the page to a new address
+@@ -988,6 +1047,11 @@
+               /* Free the old page.. */
+               new_page = old_page;
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++              pax_mirror_fault(mm, vma, address, page_table);
++#endif
++
+       }
+       spin_unlock(&mm->page_table_lock);
+       page_cache_release(new_page);
+@@ -1065,6 +1129,7 @@
+ do_expand:
+       limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
++      gr_learn_resource(current, RLIMIT_FSIZE, offset);
+       if (limit != RLIM_INFINITY && offset > limit)
+               goto out_sig;
+       if (offset > inode->i_sb->s_maxbytes)
+@@ -1178,6 +1243,11 @@
+       /* No need to invalidate - it was non-present before */
+       update_mmu_cache(vma, address, pte);
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      pax_mirror_fault(mm, vma, address, page_table);
++#endif
++
+       spin_unlock(&mm->page_table_lock);
+       return ret;
+ }
+@@ -1223,6 +1293,11 @@
+       /* No need to invalidate - it was non-present before */
+       update_mmu_cache(vma, addr, entry);
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      pax_mirror_fault(mm, vma, addr, page_table);
++#endif
++
+       spin_unlock(&mm->page_table_lock);
+       return 1;       /* Minor fault */
+@@ -1303,6 +1378,11 @@
+       /* no need to invalidate: a not-present page shouldn't be cached */
+       update_mmu_cache(vma, address, entry);
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      pax_mirror_fault(mm, vma, address, page_table);
++#endif
++
+       spin_unlock(&mm->page_table_lock);
+       return 2;       /* Major fault */
+ }
+@@ -1367,6 +1447,11 @@
+       pgd_t *pgd;
+       pmd_t *pmd;
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      unsigned long address_m = 0UL;
++      struct vm_area_struct * vma_m = NULL;
++#endif
++
+       current->state = TASK_RUNNING;
+       pgd = pgd_offset(mm, address);
+@@ -1375,6 +1460,47 @@
+        * and the SMP-safe atomic PTE updates.
+        */
+       spin_lock(&mm->page_table_lock);
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (vma->vm_flags & VM_MIRROR) {
++              pgd_t *pgd_m;
++              pmd_t *pmd_m;
++              pte_t *pte_m;
++
++              address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
++              vma_m = find_vma(mm, address_m);
++
++              /* PaX: sanity checks */
++              if (!vma_m) {
++                      spin_unlock(&mm->page_table_lock);
++                      printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
++                             address, vma, address_m, vma_m);
++                      return 0;
++              } else if (!(vma_m->vm_flags & VM_MIRROR) ||
++                         vma_m->vm_start != address_m ||
++                         vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
++              {
++                      spin_unlock(&mm->page_table_lock);
++                      printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
++                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
++                      return 0;
++              }
++
++              address_m = address + (unsigned long)vma->vm_private_data;
++              pgd_m = pgd_offset(mm, address_m);
++              pmd_m = pmd_alloc(mm, pgd_m, address_m);
++              if (!pmd_m) {
++                      spin_unlock(&mm->page_table_lock);
++                      return -1;
++              }
++              pte_m = pte_alloc(mm, pmd_m, address_m);
++              if (!pte_m) {
++                      spin_unlock(&mm->page_table_lock);
++                      return -1;
++              }
++      }                       
++#endif
++
+       pmd = pmd_alloc(mm, pgd, address);
+       if (pmd) {
+diff -urN linux-2.4.22/mm/mlock.c linux-2.4.22-grsec-O1/mm/mlock.c
+--- linux-2.4.22/mm/mlock.c    2001-09-18 00:30:23.000000000 +0200
++++ linux-2.4.22-grsec-O1/mm/mlock.c   2003-10-21 14:24:35.000000000 +0200
+@@ -114,9 +114,35 @@
+       return 0;
+ }
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++static int __mlock_fixup(struct vm_area_struct * vma,
++      unsigned long start, unsigned long end, unsigned int newflags);
+ static int mlock_fixup(struct vm_area_struct * vma, 
+       unsigned long start, unsigned long end, unsigned int newflags)
+ {
++      if (vma->vm_flags & VM_MIRROR) {
++              struct vm_area_struct * vma_m;
++              unsigned long start_m, end_m;
++
++              start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
++              vma_m = find_vma(vma->vm_mm, start_m);
++              if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
++                      start_m = start + (unsigned long)vma->vm_private_data;
++                      end_m = end + (unsigned long)vma->vm_private_data;
++                      __mlock_fixup(vma_m, start_m, end_m, newflags);
++              } else
++                      printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
++      }
++      return __mlock_fixup(vma, start, end, newflags);
++}
++
++static int __mlock_fixup(struct vm_area_struct * vma,
++      unsigned long start, unsigned long end, unsigned int newflags)
++#else
++static int mlock_fixup(struct vm_area_struct * vma,
++      unsigned long start, unsigned long end, unsigned int newflags)
++#endif
++{
+       int pages, retval;
+       if (newflags == vma->vm_flags)
+@@ -209,6 +235,7 @@
+       lock_limit >>= PAGE_SHIFT;
+       /* check against resource limits */
++      gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
+       if (locked > lock_limit)
+               goto out;
+@@ -276,6 +303,7 @@
+       lock_limit >>= PAGE_SHIFT;
+       ret = -ENOMEM;
++      gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm);
+       if (current->mm->total_vm > lock_limit)
+               goto out;
+diff -urN linux-2.4.22/mm/mmap.c linux-2.4.22-grsec-O1/mm/mmap.c
+--- linux-2.4.22/mm/mmap.c     2003-10-20 18:58:35.000000000 +0200
++++ linux-2.4.22-grsec-O1/mm/mmap.c    2003-10-21 14:24:35.000000000 +0200
+@@ -14,6 +14,8 @@
+ #include <linux/file.h>
+ #include <linux/fs.h>
+ #include <linux/personality.h>
++#include <linux/random.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+@@ -168,6 +170,7 @@
+       /* Check against rlimit.. */
+       rlim = current->rlim[RLIMIT_DATA].rlim_cur;
++      gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data);
+       if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
+               goto out;
+@@ -205,6 +208,11 @@
+               _trans(prot, PROT_WRITE, VM_WRITE) |
+               _trans(prot, PROT_EXEC, VM_EXEC);
+       flag_bits =
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++              _trans(flags, MAP_MIRROR, VM_MIRROR) |
++#endif
++
+               _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
+               _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
+               _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
+@@ -401,6 +409,28 @@
+       int error;
+       rb_node_t ** rb_link, * rb_parent;
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      struct vm_area_struct * vma_m = NULL;
++      
++      if (flags & MAP_MIRROR) {
++              /* PaX: sanity checks, to be removed when proved to be stable */
++              if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
++                      return -EINVAL;
++
++              vma_m = find_vma(mm, pgoff);
++
++              if (!vma_m ||
++                  vma_m->vm_start != pgoff ||
++                  (vma_m->vm_flags & VM_MIRROR) ||
++                  (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
++                      return -EINVAL;
++
++              file = vma_m->vm_file;
++              pgoff = vma_m->vm_pgoff;
++              len = vma_m->vm_end - vma_m->vm_start;
++      }
++#endif
++
+       if (file && (!file->f_op || !file->f_op->mmap))
+               return -ENODEV;
+@@ -433,10 +463,32 @@
+        */
+       vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
++#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
++      if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++              if (current->flags & PF_PAX_MPROTECT) {
++                      if (!file || (prot & PROT_WRITE))
++                              vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
++                      else
++                              vm_flags &= ~VM_MAYWRITE;
++
++#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC
++                      if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
++                              vma_m->vm_flags &= ~VM_MAYWRITE;
++#endif
++
++              }
++#endif
++
++      }
++#endif
++
+       /* mlock MCL_FUTURE? */
+       if (vm_flags & VM_LOCKED) {
+               unsigned long locked = mm->locked_vm << PAGE_SHIFT;
+               locked += len;
++              gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+                       return -EAGAIN;
+       }
+@@ -481,6 +533,9 @@
+               }
+       }
++      if (!gr_acl_handle_mmap(file, prot))
++              return -EACCES;
++
+       /* Clear old maps */
+ munmap_back:
+       vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
+@@ -491,10 +546,16 @@
+       }
+       /* Check against address space limit. */
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (!(vm_flags & VM_MIRROR)) {
++#endif
++      gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
+       if ((mm->total_vm << PAGE_SHIFT) + len
+           > current->rlim[RLIMIT_AS].rlim_cur)
+               return -ENOMEM;
+-
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      }
++#endif
+       /* Private writable mapping? Check memory availability.. */
+       if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
+           !(flags & MAP_NORESERVE)                             &&
+@@ -518,6 +579,13 @@
+       vma->vm_start = addr;
+       vma->vm_end = addr + len;
+       vma->vm_flags = vm_flags;
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
++              vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
++      else
++#endif
++
+       vma->vm_page_prot = protection_map[vm_flags & 0x0f];
+       vma->vm_ops = NULL;
+       vma->vm_pgoff = pgoff;
+@@ -546,6 +614,14 @@
+                       goto free_vma;
+       }
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (flags & MAP_MIRROR) {
++              vma_m->vm_flags |= VM_MIRROR;
++              vma_m->vm_private_data = (void *)(vma->vm_start - vma_m->vm_start);
++              vma->vm_private_data = (void *)(vma_m->vm_start - vma->vm_start);
++      }
++#endif
++
+       /* Can addr have changed??
+        *
+        * Answer: Yes, several device drivers can do it in their
+@@ -581,6 +657,9 @@
+               atomic_inc(&file->f_dentry->d_inode->i_writecount);
+ out:  
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (!(flags & MAP_MIRROR))
++#endif
+       mm->total_vm += len >> PAGE_SHIFT;
+       if (vm_flags & VM_LOCKED) {
+               mm->locked_vm += len >> PAGE_SHIFT;
+@@ -617,20 +696,49 @@
+ {
+       struct vm_area_struct *vma;
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE)
++              return -ENOMEM;
++      else
++#endif
++
+       if (len > TASK_SIZE)
+               return -ENOMEM;
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
++#endif
++
+       if (addr) {
+               addr = PAGE_ALIGN(addr);
+               vma = find_vma(current->mm, addr);
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++              if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)                
++                      return -ENOMEM;
++#endif
++
+               if (TASK_SIZE - len >= addr &&
+                   (!vma || addr + len <= vma->vm_start))
+                       return addr;
+       }
+       addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
++#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP
++      /* PaX: randomize base address if requested */
++      if (current->flags & PF_PAX_RANDMMAP)
++              addr += current->mm->delta_mmap;
++#endif
++
+       for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+               /* At this point:  (!vma || addr < vma->vm_end). */
++
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++              if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)
++                      return -ENOMEM;
++              else
++#endif
++
+               if (TASK_SIZE - len < addr)
+                       return -ENOMEM;
+               if (!vma || addr + len <= vma->vm_start)
+@@ -792,6 +900,9 @@
+       struct vm_area_struct *mpnt;
+       unsigned long end = addr + len;
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (!(area->vm_flags & VM_MIRROR))
++#endif
+       area->vm_mm->total_vm -= len >> PAGE_SHIFT;
+       if (area->vm_flags & VM_LOCKED)
+               area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
+@@ -917,6 +1028,83 @@
+       }
+ }
++static inline struct vm_area_struct *unmap_vma(struct mm_struct *mm,
++      unsigned long addr, size_t len, struct vm_area_struct *mpnt,
++      struct vm_area_struct *extra)
++{
++      unsigned long st, end, size;
++      struct file *file = NULL;
++
++      st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
++      end = addr+len;
++      end = end > mpnt->vm_end ? mpnt->vm_end : end;
++      size = end - st;
++
++      if (mpnt->vm_flags & VM_DENYWRITE &&
++          (st != mpnt->vm_start || end != mpnt->vm_end) &&
++          (file = mpnt->vm_file) != NULL) {
++              atomic_dec(&file->f_dentry->d_inode->i_writecount);
++      }
++      remove_shared_vm_struct(mpnt);
++      zap_page_range(mm, st, size);
++
++      /*
++       * Fix the mapping, and free the old area if it wasn't reused.
++       */
++      extra = unmap_fixup(mm, mpnt, st, size, extra);
++      if (file)
++              atomic_inc(&file->f_dentry->d_inode->i_writecount);
++      return extra;
++}
++       
++static struct vm_area_struct *unmap_vma_list(struct mm_struct *mm,
++      unsigned long addr, size_t len, struct vm_area_struct *free,
++      struct vm_area_struct *extra, struct vm_area_struct *prev)
++{
++      struct vm_area_struct *mpnt;
++
++      /* Ok - we have the memory areas we should free on the 'free' list,
++       * so release them, and unmap the page range..
++       * If the one of the segments is only being partially unmapped,
++       * it will put new vm_area_struct(s) into the address space.
++       * In that case we have to be careful with VM_DENYWRITE.
++       */
++      while ((mpnt = free) != NULL) {
++              free = free->vm_next;
++              extra = unmap_vma(mm, addr, len, mpnt, extra);
++      }
++
++      free_pgtables(mm, prev, addr, addr+len);
++
++      return extra;
++}
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++static struct vm_area_struct *unmap_vma_mirror_list(struct mm_struct *mm,
++      unsigned long addr, size_t len, struct vm_area_struct *free_m,
++      struct vm_area_struct *extra_m)
++{
++      struct vm_area_struct *mpnt, *prev;
++
++      while ((mpnt = free_m) != NULL) {
++              unsigned long addr_m, start, end;
++
++              free_m = free_m->vm_next;
++
++              addr_m = addr - (unsigned long)mpnt->vm_private_data;
++              start = addr_m < mpnt->vm_start ? mpnt->vm_start : addr_m;
++              end = addr_m+len;
++              end = end > mpnt->vm_end ? mpnt->vm_end : end;
++              find_vma_prev(mm, mpnt->vm_start, &prev);
++              extra_m = unmap_vma(mm, addr_m, len, mpnt, extra_m);
++
++              free_pgtables(mm, prev, start, end);
++      }               
++
++      return extra_m;
++}
++#endif
++
+ /* Munmap is split into 2 main parts -- this part which finds
+  * what needs doing, and the areas themselves, which do the
+  * work.  This now handles partial unmappings.
+@@ -926,6 +1114,10 @@
+ {
+       struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      struct vm_area_struct *free_m, *extra_m;
++#endif
++
+       if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr)
+               return -EINVAL;
+@@ -958,60 +1150,69 @@
+       if (!extra)
+               return -ENOMEM;
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) { 
++              extra_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
++              if (!extra_m) {
++                      kmem_cache_free(vm_area_cachep, extra);
++                      return -ENOMEM;
++              }
++      } else
++              extra_m = NULL;
++
++      free_m = NULL;
++#endif
++
+       npp = (prev ? &prev->vm_next : &mm->mmap);
+       free = NULL;
+       spin_lock(&mm->page_table_lock);
+       for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) {
++              mm->map_count--;
+               *npp = mpnt->vm_next;
+               mpnt->vm_next = free;
+               free = mpnt;
+               rb_erase(&mpnt->vm_rb, &mm->mm_rb);
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++              if (free->vm_flags & VM_MIRROR) {
++                      struct vm_area_struct *mpnt_m, *prev_m, **npp_m;
++                      unsigned long addr_m = free->vm_start + (unsigned long)free->vm_private_data;
++
++                      mm->mmap_cache = NULL;  /* Kill the cache. */
++                      mpnt_m = find_vma_prev(mm, addr_m, &prev_m);
++                      if (mpnt_m && mpnt_m->vm_start == addr_m && (mpnt_m->vm_flags & VM_MIRROR)) {
++                              mm->map_count--;
++                              npp_m = (prev_m ? &prev_m->vm_next : &mm->mmap);
++                              *npp_m = mpnt_m->vm_next;
++                              mpnt_m->vm_next = free_m;
++                              free_m = mpnt_m;
++                              rb_erase(&mpnt_m->vm_rb, &mm->mm_rb);
++                      } else
++                              printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, free->vm_start);
++              }
++#endif
++
+       }
+       mm->mmap_cache = NULL;  /* Kill the cache. */
+       spin_unlock(&mm->page_table_lock);
+-      /* Ok - we have the memory areas we should free on the 'free' list,
+-       * so release them, and unmap the page range..
+-       * If the one of the segments is only being partially unmapped,
+-       * it will put new vm_area_struct(s) into the address space.
+-       * In that case we have to be careful with VM_DENYWRITE.
+-       */
+-      while ((mpnt = free) != NULL) {
+-              unsigned long st, end, size;
+-              struct file *file = NULL;
+-
+-              free = free->vm_next;
++      extra = unmap_vma_list(mm, addr, len, free, extra, prev);
+-              st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
+-              end = addr+len;
+-              end = end > mpnt->vm_end ? mpnt->vm_end : end;
+-              size = end - st;
+-
+-              if (mpnt->vm_flags & VM_DENYWRITE &&
+-                  (st != mpnt->vm_start || end != mpnt->vm_end) &&
+-                  (file = mpnt->vm_file) != NULL) {
+-                      atomic_dec(&file->f_dentry->d_inode->i_writecount);
+-              }
+-              remove_shared_vm_struct(mpnt);
+-              mm->map_count--;
+-
+-              zap_page_range(mm, st, size);
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      extra_m = unmap_vma_mirror_list(mm, addr, len, free_m, extra_m);
++#endif
+-              /*
+-               * Fix the mapping, and free the old area if it wasn't reused.
+-               */
+-              extra = unmap_fixup(mm, mpnt, st, size, extra);
+-              if (file)
+-                      atomic_inc(&file->f_dentry->d_inode->i_writecount);
+-      }
+       validate_mm(mm);
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (extra_m)
++              kmem_cache_free(vm_area_cachep, extra_m);
++#endif
++
+       /* Release the extra vma struct if it wasn't used */
+       if (extra)
+               kmem_cache_free(vm_area_cachep, extra);
+-      free_pgtables(mm, prev, addr, addr+len);
+-
+       return 0;
+ }
+@@ -1020,8 +1221,15 @@
+       int ret;
+       struct mm_struct *mm = current->mm;
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      if ((current->flags & PF_PAX_SEGMEXEC) &&
++          (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
++              return -EINVAL;
++#endif
++
+       down_write(&mm->mmap_sem);
+       ret = do_munmap(mm, addr, len);
++
+       up_write(&mm->mmap_sem);
+       return ret;
+ }
+@@ -1048,6 +1256,7 @@
+       if (mm->def_flags & VM_LOCKED) {
+               unsigned long locked = mm->locked_vm << PAGE_SHIFT;
+               locked += len;
++              gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+                       return -EAGAIN;
+       }
+@@ -1064,6 +1273,7 @@
+       }
+       /* Check against address space limits *after* clearing old maps... */
++      gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
+       if ((mm->total_vm << PAGE_SHIFT) + len
+           > current->rlim[RLIMIT_AS].rlim_cur)
+               return -ENOMEM;
+@@ -1076,6 +1286,17 @@
+       flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
++#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC)
++      if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
++              flags &= ~VM_EXEC;
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++              if (current->flags & PF_PAX_MPROTECT)
++                      flags &= ~VM_MAYEXEC;
++#endif
++
++      }
++#endif
+       /* Can we just expand an old anonymous mapping? */
+       if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
+               goto out;
+@@ -1091,6 +1312,12 @@
+       vma->vm_start = addr;
+       vma->vm_end = addr + len;
+       vma->vm_flags = flags;
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
++              vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
++      else
++#endif
+       vma->vm_page_prot = protection_map[flags & 0x0f];
+       vma->vm_ops = NULL;
+       vma->vm_pgoff = 0;
+diff -urN linux-2.4.22/mm/mprotect.c linux-2.4.22-grsec-O1/mm/mprotect.c
+--- linux-2.4.22/mm/mprotect.c 2003-10-20 18:58:48.000000000 +0200
++++ linux-2.4.22-grsec-O1/mm/mprotect.c        2003-10-21 14:24:35.000000000 +0200
+@@ -7,6 +7,12 @@
+ #include <linux/smp_lock.h>
+ #include <linux/shm.h>
+ #include <linux/mman.h>
++#include <linux/grsecurity.h>
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++#include <linux/elf.h>
++#include <linux/fs.h>
++#endif
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+@@ -236,9 +242,40 @@
+       return 0;
+ }
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
++      unsigned long start, unsigned long end, unsigned int newflags);
++
+ static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
+       unsigned long start, unsigned long end, unsigned int newflags)
+ {
++      if (vma->vm_flags & VM_MIRROR) {
++              struct vm_area_struct * vma_m, * prev_m;
++              unsigned long start_m, end_m;
++
++              start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
++              vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
++              if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
++                      start_m = start + (unsigned long)vma->vm_private_data;
++                      end_m = end + (unsigned long)vma->vm_private_data;
++                      if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
++                              __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
++                      else
++                              __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
++              } else
++                      printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
++      }
++
++      return __mprotect_fixup(vma, pprev, start, end, newflags);
++}
++
++static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
++      unsigned long start, unsigned long end, unsigned int newflags)
++#else
++static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
++      unsigned long start, unsigned long end, unsigned int newflags)
++#endif
++{
+       pgprot_t newprot;
+       int error;
+@@ -246,6 +283,12 @@
+               *pprev = vma;
+               return 0;
+       }
++
++#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC
++      if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
++              newprot = protection_map[(newflags | VM_EXEC) & 0xf];
++      else
++#endif
+       newprot = protection_map[newflags & 0xf];
+       if (start == vma->vm_start) {
+               if (end == vma->vm_end)
+@@ -264,6 +307,68 @@
+       return 0;
+ }
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++/* PaX: non-PIC ELF libraries need relocations on their executable segments
++ * therefore we'll grant them VM_MAYWRITE once during their life.
++ *
++ * The checks favor ld-linux.so behaviour which operates on a per ELF segment
++ * basis because we want to allow the common case and not the special ones.
++ */
++static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
++{
++      struct elfhdr elf_h;
++      struct elf_phdr elf_p, p_dyn;
++      elf_dyn dyn;
++      unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
++
++#ifndef CONFIG_GRKERNSEC_PAX_NOELFRELOCS
++      if ((vma->vm_start != start) ||
++          !vma->vm_file ||
++          !(vma->vm_flags & VM_MAYEXEC) ||
++          (vma->vm_flags & VM_MAYNOTWRITE))
++#endif
++
++              return;
++
++      if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
++          memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
++
++#ifdef CONFIG_GRKERNSEC_PAX_ETEXECRELOCS
++          (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
++#else
++          elf_h.e_type != ET_DYN ||
++#endif
++
++          !elf_check_arch(&elf_h) ||
++          elf_h.e_phentsize != sizeof(struct elf_phdr) ||
++          elf_h.e_phnum > j)
++              return;
++
++      for (i = 0UL; i < elf_h.e_phnum; i++) {
++              if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
++                      return;
++              if (elf_p.p_type == PT_DYNAMIC) {
++                      p_dyn = elf_p;
++                      j = i;
++              }
++      }
++      if (elf_h.e_phnum <= j)
++              return;
++
++      i = 0UL;
++      do {
++              if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
++                      return;
++              if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
++                      vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
++                      return;
++              }
++              i++;
++      } while (dyn.d_tag != DT_NULL);
++      return;
++}
++#endif
++
+ long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
+                unsigned long prot)
+ {
+@@ -289,6 +394,16 @@
+       if (!vma || vma->vm_start > start)
+               goto out;
++      if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
++              error = -EACCES;
++              goto out;
++      }
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++      if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
++              pax_handle_maywrite(vma, start);
++#endif
++
+       for (nstart = start ; ; ) {
+               unsigned int newflags;
+               int last = 0;
+@@ -306,6 +421,13 @@
+                       if (error < 0)
+                               goto out;
+               }
++
++#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT
++              /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
++              if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
++                      newflags &= ~VM_MAYWRITE;
++#endif
++
+               if (vma->vm_end > end) {
+                       error = mprotect_fixup(vma, &prev, nstart, end, newflags);
+                       goto out;
+diff -urN linux-2.4.22/mm/mremap.c linux-2.4.22-grsec-O1/mm/mremap.c
+--- linux-2.4.22/mm/mremap.c   2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/mm/mremap.c  2003-10-21 14:24:35.000000000 +0200
+@@ -193,7 +193,9 @@
+               }
+               do_munmap(current->mm, addr, old_len);
+-
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++              if (!(new_vma->vm_flags & VM_MIRROR))
++#endif
+               current->mm->total_vm += new_len >> PAGE_SHIFT;
+               if (vm_locked) {
+                       current->mm->locked_vm += new_len >> PAGE_SHIFT;
+@@ -232,6 +234,13 @@
+       old_len = PAGE_ALIGN(old_len);
+       new_len = PAGE_ALIGN(new_len);
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++      if ((current->flags & PF_PAX_SEGMEXEC) &&
++          (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
++           old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len))
++              goto out;
++#endif
++
+       /* new_addr is only valid if MREMAP_FIXED is specified */
+       if (flags & MREMAP_FIXED) {
+               if (new_addr & ~PAGE_MASK)
+@@ -242,6 +251,12 @@
+               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
+                       goto out;
++#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC
++              if ((current->flags & PF_PAX_SEGMEXEC) &&
++                  (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len))
++                      goto out;
++#endif
++
+               /* Check if the location we're moving into overlaps the
+                * old location at all, and fail if it does.
+                */
+@@ -272,6 +287,13 @@
+       vma = find_vma(current->mm, addr);
+       if (!vma || vma->vm_start > addr)
+               goto out;
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
++          (vma->vm_flags & VM_MIRROR))
++              return -EINVAL;
++#endif
++
+       /* We can't remap across vm area boundaries */
+       if (old_len > vma->vm_end - addr)
+               goto out;
+@@ -283,13 +305,22 @@
+               unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+               locked += new_len - old_len;
+               ret = -EAGAIN;
++              gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+                       goto out;
+       }
+       ret = -ENOMEM;
++
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      if (!(vma->vm_flags & VM_MIRROR)) {
++#endif   
++      gr_learn_resource(current, RLIMIT_AS, (current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len));
+       if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
+           > current->rlim[RLIMIT_AS].rlim_cur)
+               goto out;
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++      }
++#endif
+       /* Private writable mapping? Check memory availability.. */
+       if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
+           !(flags & MAP_NORESERVE)                             &&
+@@ -311,6 +342,9 @@
+                       spin_lock(&vma->vm_mm->page_table_lock);
+                       vma->vm_end = addr + new_len;
+                       spin_unlock(&vma->vm_mm->page_table_lock);
++#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC)
++                      if (!(vma->vm_flags & VM_MIRROR))
++#endif   
+                       current->mm->total_vm += pages;
+                       if (vma->vm_flags & VM_LOCKED) {
+                               current->mm->locked_vm += pages;
+diff -urN linux-2.4.22/net/ipv4/af_inet.c linux-2.4.22-grsec-O1/net/ipv4/af_inet.c
+--- linux-2.4.22/net/ipv4/af_inet.c    2003-10-20 18:58:34.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/ipv4/af_inet.c   2003-10-21 14:24:35.000000000 +0200
+@@ -83,6 +83,7 @@
+ #include <linux/init.h>
+ #include <linux/poll.h>
+ #include <linux/netfilter_ipv4.h>
++#include <linux/grsecurity.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+@@ -374,7 +375,12 @@
+       else
+               sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
+-      sk->protinfo.af_inet.id = 0;
++#ifdef CONFIG_GRKERNSEC_RANDID
++      if(grsec_enable_randid)
++              sk->protinfo.af_inet.id = htons(ip_randomid());
++      else
++#endif
++              sk->protinfo.af_inet.id = 0;
+       sock_init_data(sock,sk);
+diff -urN linux-2.4.22/net/ipv4/icmp.c linux-2.4.22-grsec-O1/net/ipv4/icmp.c
+--- linux-2.4.22/net/ipv4/icmp.c       2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/ipv4/icmp.c      2003-10-21 14:24:35.000000000 +0200
+@@ -87,6 +87,8 @@
+ #include <linux/errno.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
++#include <linux/grsecurity.h>
++
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <net/checksum.h>
+@@ -715,6 +717,7 @@
+               icmp_param.data.icmph=*skb->h.icmph;
+               icmp_param.data.icmph.type=ICMP_ECHOREPLY;
++
+               icmp_param.skb=skb;
+               icmp_param.offset=0;
+               icmp_param.data_len=skb->len;
+diff -urN linux-2.4.22/net/ipv4/ip_output.c linux-2.4.22-grsec-O1/net/ipv4/ip_output.c
+--- linux-2.4.22/net/ipv4/ip_output.c  2003-10-20 18:58:57.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/ipv4/ip_output.c 2003-10-21 14:24:35.000000000 +0200
+@@ -77,6 +77,7 @@
+ #include <linux/netfilter_ipv4.h>
+ #include <linux/mroute.h>
+ #include <linux/netlink.h>
++#include <linux/grsecurity.h>
+ /*
+  *      Shall we try to damage output packets if routing dev changes?
+@@ -514,7 +515,13 @@
+        *      Begin outputting the bytes.
+        */
+-      id = sk->protinfo.af_inet.id++;
++#ifdef CONFIG_GRKERNSEC_RANDID
++      if(grsec_enable_randid) { 
++              id = htons(ip_randomid());      
++              sk->protinfo.af_inet.id = htons(ip_randomid());
++      } else
++#endif
++              id = sk->protinfo.af_inet.id++;
+       do {
+               char *data;
+diff -urN linux-2.4.22/net/ipv4/netfilter/Config.in linux-2.4.22-grsec-O1/net/ipv4/netfilter/Config.in
+--- linux-2.4.22/net/ipv4/netfilter/Config.in  2003-10-20 18:58:59.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/ipv4/netfilter/Config.in 2003-10-21 14:24:35.000000000 +0200
+@@ -74,6 +74,7 @@
+   dep_tristate '  TTL match support' CONFIG_IP_NF_MATCH_TTL $CONFIG_IP_NF_IPTABLES
+   dep_tristate '  address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES
+   dep_tristate '  tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES
++  dep_tristate '  stealth match support' CONFIG_IP_NF_MATCH_STEALTH $CONFIG_IP_NF_IPTABLES
+   dep_tristate '  realm match support' CONFIG_IP_NF_MATCH_REALM $CONFIG_IP_NF_IPTABLES
+   if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
+     dep_tristate '  Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES
+diff -urN linux-2.4.22/net/ipv4/netfilter/Makefile linux-2.4.22-grsec-O1/net/ipv4/netfilter/Makefile
+--- linux-2.4.22/net/ipv4/netfilter/Makefile   2003-10-20 18:58:57.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/ipv4/netfilter/Makefile  2003-10-21 14:24:35.000000000 +0200
+@@ -175,6 +175,7 @@
+ obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
+ obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
+ obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
+ obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
+diff -urN linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c linux-2.4.22-grsec-O1/net/ipv4/netfilter/ipt_stealth.c
+--- linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.22-grsec-O1/net/ipv4/netfilter/ipt_stealth.c     2003-10-21 14:24:35.000000000 +0200
+@@ -0,0 +1,109 @@
++/* Kernel module to add stealth support.
++ *
++ * Copyright (C) 2002 Brad Spengler  <spender@grsecurity.net>
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/skbuff.h>
++#include <linux/net.h>
++#include <linux/sched.h>
++#include <linux/inet.h>
++#include <linux/stddef.h>
++
++#include <net/ip.h>
++#include <net/sock.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++#include <net/route.h>
++#include <net/inet_common.h>
++
++#include <linux/netfilter_ipv4/ip_tables.h>
++
++MODULE_LICENSE("GPL");
++
++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
++
++static int
++match(const struct sk_buff *skb,
++      const struct net_device *in,
++      const struct net_device *out,
++      const void *matchinfo,
++      int offset,
++      const void *hdr,
++      u_int16_t datalen,
++      int *hotdrop)
++{
++      struct iphdr *ip = skb->nh.iph;
++      struct tcphdr *th = (struct tcphdr *) hdr;
++      struct udphdr *uh = (struct udphdr *) hdr;
++      struct sock *sk = NULL;
++
++      if (!ip || !hdr || offset) return 0;
++
++      switch(ip->protocol) {
++      case IPPROTO_TCP:
++              if (datalen < sizeof(struct tcphdr)) {
++                      *hotdrop = 1;
++                      return 0;
++              }
++              if (!(th->syn && !th->ack)) return 0;
++              sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th->dest), ((struct rtable*)skb->dst)->rt_iif);    
++              break;
++      case IPPROTO_UDP:
++              if (datalen < sizeof(struct udphdr)) {
++                      *hotdrop = 1;
++                      return 0;
++              }
++              sk = udp_v4_lookup(ip->saddr, uh->source, ip->daddr, uh->dest, skb->dev->ifindex);
++              break;
++      default:
++              return 0;
++      }
++
++      if(!sk) // port is being listened on, match this
++              return 1;
++      else {
++              sock_put(sk);
++              return 0;
++      }
++}
++
++/* Called when user tries to insert an entry of this type. */
++static int
++checkentry(const char *tablename,
++           const struct ipt_ip *ip,
++           void *matchinfo,
++           unsigned int matchsize,
++           unsigned int hook_mask)
++{
++        if (matchsize != IPT_ALIGN(0))
++                return 0;
++
++      if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
++              ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
++              && (hook_mask & (1 << NF_IP_LOCAL_IN)))
++                      return 1;
++
++      printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
++
++        return 0;
++}
++
++
++static struct ipt_match stealth_match
++= { { NULL, NULL }, "stealth", &match, &checkentry, NULL, THIS_MODULE };
++
++static int __init init(void)
++{
++      return ipt_register_match(&stealth_match);
++}
++
++static void __exit fini(void)
++{
++      ipt_unregister_match(&stealth_match);
++}
++
++module_init(init);
++module_exit(fini);
+diff -urN linux-2.4.22/net/ipv4/tcp_ipv4.c linux-2.4.22-grsec-O1/net/ipv4/tcp_ipv4.c
+--- linux-2.4.22/net/ipv4/tcp_ipv4.c   2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/ipv4/tcp_ipv4.c  2003-10-21 14:24:35.000000000 +0200
+@@ -67,6 +67,7 @@
+ #include <linux/inet.h>
+ #include <linux/stddef.h>
+ #include <linux/ipsec.h>
++#include <linux/grsecurity.h>
+ extern int sysctl_ip_dynaddr;
+ extern int sysctl_ip_default_ttl;
+@@ -221,9 +222,18 @@
+               spin_lock(&tcp_portalloc_lock);
+               rover = tcp_port_rover;
+-              do {    rover++;
+-                      if ((rover < low) || (rover > high))
+-                              rover = low;
++                do {
++#ifdef CONFIG_GRKERNSEC_RANDSRC
++                      if (grsec_enable_randsrc && (high > low)) {
++                              rover = low + (get_random_long() % (high - low));
++                      } else
++#endif
++                      {
++                              rover++;
++                              if ((rover < low) || (rover > high))
++                                      rover = low;
++                      }
++
+                       head = &tcp_bhash[tcp_bhashfn(rover)];
+                       spin_lock(&head->lock);
+                       for (tb = head->chain; tb; tb = tb->next)
+@@ -546,6 +556,11 @@
+ static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
+ {
++#ifdef CONFIG_GRKERNSEC_RANDISN
++      if (likely(grsec_enable_randisn))
++              return ip_randomisn();
++      else
++#endif
+       return secure_tcp_sequence_number(skb->nh.iph->daddr,
+                                         skb->nh.iph->saddr,
+                                         skb->h.th->dest,
+@@ -681,9 +696,16 @@
+               rover = tcp_port_rover;
+               do {
+-                      rover++;
+-                      if ((rover < low) || (rover > high))
+-                              rover = low;
++#ifdef CONFIG_GRKERNSEC_RANDSRC
++                      if(grsec_enable_randsrc && (high > low)) {
++                              rover = low + (get_random_long() % (high - low));
++                      } else
++#endif
++                      {
++                              rover++;
++                              if ((rover < low) || (rover > high))
++                                      rover = low;
++                      }
+                       head = &tcp_bhash[tcp_bhashfn(rover)];
+                       spin_lock(&head->lock);         
+@@ -844,11 +866,22 @@
+       if (err)
+               goto failure;
+-      if (!tp->write_seq)
++      if (!tp->write_seq) {
++#ifdef CONFIG_GRKERNSEC_RANDISN
++              if (likely(grsec_enable_randisn))
++                      tp->write_seq = ip_randomisn();
++              else
++#endif
+               tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
+                                                          sk->sport, usin->sin_port);
++      }
+-      sk->protinfo.af_inet.id = tp->write_seq^jiffies;
++#ifdef CONFIG_GRKERNSEC_RANDID
++      if(grsec_enable_randid)
++              sk->protinfo.af_inet.id = htons(ip_randomid());
++      else
++#endif
++              sk->protinfo.af_inet.id = tp->write_seq^jiffies;
+       err = tcp_connect(sk);
+       if (err)
+@@ -1570,7 +1603,13 @@
+       newtp->ext_header_len = 0;
+       if (newsk->protinfo.af_inet.opt)
+               newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen;
+-      newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
++
++#ifdef CONFIG_GRKERNSEC_RANDID
++      if(grsec_enable_randid)
++              newsk->protinfo.af_inet.id = htons(ip_randomid());
++      else
++#endif
++              newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
+       tcp_sync_mss(newsk, dst->pmtu);
+       newtp->advmss = dst->advmss;
+diff -urN linux-2.4.22/net/ipv4/udp.c linux-2.4.22-grsec-O1/net/ipv4/udp.c
+--- linux-2.4.22/net/ipv4/udp.c        2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/ipv4/udp.c       2003-10-21 14:24:35.000000000 +0200
+@@ -91,6 +91,7 @@
+ #include <net/ipv6.h>
+ #include <net/protocol.h>
+ #include <linux/skbuff.h>
++#include <linux/grsecurity.h>
+ #include <net/sock.h>
+ #include <net/udp.h>
+ #include <net/icmp.h>
+@@ -98,6 +99,11 @@
+ #include <net/inet_common.h>
+ #include <net/checksum.h>
++extern int gr_search_udp_recvmsg(const struct sock *sk,
++                                      const struct sk_buff *skb);
++extern int gr_search_udp_sendmsg(const struct sock *sk,
++                                      const struct sockaddr_in *addr);
++
+ /*
+  *    Snmp MIB for the UDP layer
+  */
+@@ -478,9 +484,16 @@
+               ufh.uh.dest = usin->sin_port;
+               if (ufh.uh.dest == 0)
+                       return -EINVAL;
++
++              if (!gr_search_udp_sendmsg(sk, usin))
++                      return -EPERM;
+       } else {
+               if (sk->state != TCP_ESTABLISHED)
+                       return -EDESTADDRREQ;
++
++              if (!gr_search_udp_sendmsg(sk, NULL))
++                      return -EPERM;
++
+               ufh.daddr = sk->daddr;
+               ufh.uh.dest = sk->dport;
+               /* Open fast path for connected socket.
+@@ -488,6 +501,7 @@
+                */
+               connected = 1;
+       }
++
+       ipc.addr = sk->saddr;
+       ufh.uh.source = sk->sport;
+@@ -659,6 +673,11 @@
+       if (!skb)
+               goto out;
+   
++      if (!gr_search_udp_recvmsg(sk, skb)) {
++              err = -EPERM;
++              goto out_free;
++      }
++
+       copied = skb->len - sizeof(struct udphdr);
+       if (copied > len) {
+               copied = len;
+@@ -763,7 +782,13 @@
+       sk->daddr = rt->rt_dst;
+       sk->dport = usin->sin_port;
+       sk->state = TCP_ESTABLISHED;
+-      sk->protinfo.af_inet.id = jiffies;
++
++#ifdef CONFIG_GRKERNSEC_RANDID
++      if(grsec_enable_randid)
++              sk->protinfo.af_inet.id = htons(ip_randomid());
++      else
++#endif
++              sk->protinfo.af_inet.id = jiffies;
+       sk_dst_set(sk, &rt->u.dst);
+       return(0);
+diff -urN linux-2.4.22/net/netlink/af_netlink.c linux-2.4.22-grsec-O1/net/netlink/af_netlink.c
+--- linux-2.4.22/net/netlink/af_netlink.c      2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/netlink/af_netlink.c     2003-10-21 14:24:35.000000000 +0200
+@@ -40,6 +40,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/smp_lock.h>
+ #include <linux/notifier.h>
++#include <linux/grsecurity.h>
+ #include <net/sock.h>
+ #include <net/scm.h>
+@@ -625,7 +626,8 @@
+          check them, when this message will be delivered
+          to corresponding kernel module.   --ANK (980802)
+        */
+-      NETLINK_CB(skb).eff_cap = current->cap_effective;
++
++      NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
+       err = -EFAULT;
+       if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
+diff -urN linux-2.4.22/net/netsyms.c linux-2.4.22-grsec-O1/net/netsyms.c
+--- linux-2.4.22/net/netsyms.c 2003-10-20 18:59:08.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/netsyms.c        2003-10-21 14:24:35.000000000 +0200
+@@ -24,6 +24,7 @@
+ #include <net/checksum.h>
+ #include <linux/etherdevice.h>
+ #include <net/route.h>
++#include <linux/grsecurity.h>
+ #ifdef CONFIG_HIPPI
+ #include <linux/hippidevice.h>
+ #endif
+@@ -613,6 +614,51 @@
+ EXPORT_SYMBOL(softnet_data);
++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
++#if !defined (CONFIG_IPV6_MODULE) && !defined (CONFIG_KHTTPD) && !defined (CONFIG_KHTTPD_MODULE)
++EXPORT_SYMBOL(tcp_v4_lookup_listener);
++#endif
++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
++#if !defined(CONFIG_IP_NF_MATCH_OWNER) && !defined(CONFIG_IP_NF_MATCH_OWNER_MODULE)
++EXPORT_SYMBOL(udp_v4_lookup);
++#endif
++#endif
++
++#if defined(CONFIG_GRKERNSEC_RANDID)
++EXPORT_SYMBOL(ip_randomid);
++#endif
++#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
++EXPORT_SYMBOL(get_random_long);
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDISN
++EXPORT_SYMBOL(ip_randomisn);
++EXPORT_SYMBOL(grsec_enable_randisn);
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDID
++EXPORT_SYMBOL(grsec_enable_randid);
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDSRC
++EXPORT_SYMBOL(grsec_enable_randsrc);
++#endif
++#ifdef CONFIG_GRKERNSEC_RANDRPC
++EXPORT_SYMBOL(grsec_enable_randrpc);
++#endif
++
++EXPORT_SYMBOL(gr_cap_rtnetlink);
++
++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
++
++EXPORT_SYMBOL(gr_search_udp_recvmsg);
++EXPORT_SYMBOL(gr_search_udp_sendmsg);
++
++#ifdef CONFIG_UNIX_MODULE
++EXPORT_SYMBOL(gr_acl_handle_unix);
++EXPORT_SYMBOL(gr_acl_handle_mknod);
++EXPORT_SYMBOL(gr_handle_chroot_unix);
++EXPORT_SYMBOL(gr_handle_create);
++#endif
++
+ #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
+ #include <net/iw_handler.h>
+ EXPORT_SYMBOL(wireless_send_event);
+diff -urN linux-2.4.22/net/socket.c linux-2.4.22-grsec-O1/net/socket.c
+--- linux-2.4.22/net/socket.c  2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/socket.c 2003-10-21 14:24:35.000000000 +0200
+@@ -85,6 +85,18 @@
+ #include <net/scm.h>
+ #include <linux/netfilter.h>
++extern void gr_attach_curr_ip(const struct sock *sk);
++extern int gr_handle_sock_all(const int family, const int type,
++                            const int protocol);
++extern int gr_handle_sock_server(const struct sockaddr *sck);  
++extern int gr_handle_sock_client(const struct sockaddr *sck);
++extern int gr_search_connect(const struct socket * sock,
++                           const struct sockaddr_in * addr);  
++extern int gr_search_bind(const struct socket * sock,
++                        const struct sockaddr_in * addr);
++extern int gr_search_socket(const int domain, const int type,
++                          const int protocol);
++
+ static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
+ static ssize_t sock_read(struct file *file, char *buf,
+                        size_t size, loff_t *ppos);
+@@ -699,6 +711,7 @@
+ int sock_close(struct inode *inode, struct file *filp)
+ {
++      struct socket *sock;
+       /*
+        *      It was possible the inode is NULL we were 
+        *      closing an unfinished socket. 
+@@ -709,8 +722,21 @@
+               printk(KERN_DEBUG "sock_close: NULL inode\n");
+               return 0;
+       }
++      sock = socki_lookup(inode);
++
+       sock_fasync(-1, filp, 0);
++
++#ifdef CONFIG_GRKERNSEC
++      if (unlikely(current->used_accept && sock->sk &&
++                   (sock->sk->protocol == IPPROTO_TCP) &&
++                   (sock->sk->daddr == current->curr_ip))) {
++              current->used_accept = 0;
++              current->curr_ip = 0;
++      }
++#endif
++
+       sock_release(socki_lookup(inode));
++
+       return 0;
+ }
+@@ -903,6 +929,16 @@
+       int retval;
+       struct socket *sock;
++      if(!gr_search_socket(family, type, protocol)) {
++              retval = -EACCES;
++              goto out;
++      }
++
++      if (gr_handle_sock_all(family, type, protocol)) {
++              retval = -EACCES;
++              goto out;
++      }
++
+       retval = sock_create(family, type, protocol, &sock);
+       if (retval < 0)
+               goto out;
+@@ -998,12 +1034,26 @@
+ {
+       struct socket *sock;
+       char address[MAX_SOCK_ADDR];
++      struct sockaddr * sck;
+       int err;
+       if((sock = sockfd_lookup(fd,&err))!=NULL)
+       {
+-              if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
++              if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
++                      sck = (struct sockaddr *) address;
++
++                      if(!gr_search_bind(sock, (struct sockaddr_in *) sck)) {
++                              sockfd_put(sock);
++                              return -EACCES;
++                      }
++
++                      if (gr_handle_sock_server(sck)) {
++                              sockfd_put(sock);
++                              return -EACCES;
++                      }
++
+                       err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
++              }
+               sockfd_put(sock);
+       }                       
+       return err;
+@@ -1079,6 +1129,8 @@
+       if ((err = sock_map_fd(newsock)) < 0)
+               goto out_release;
++      gr_attach_curr_ip(newsock->sk);
++
+ out_put:
+       sockfd_put(sock);
+ out:
+@@ -1106,6 +1158,7 @@
+ {
+       struct socket *sock;
+       char address[MAX_SOCK_ADDR];
++      struct sockaddr * sck;
+       int err;
+       sock = sockfd_lookup(fd, &err);
+@@ -1114,6 +1167,24 @@
+       err = move_addr_to_kernel(uservaddr, addrlen, address);
+       if (err < 0)
+               goto out_put;
++
++      sck = (struct sockaddr *) address;
++
++      if (!gr_search_connect(sock, (struct sockaddr_in *) sck)) {
++              err = -EACCES;
++              goto out_put;
++      }
++
++      if (gr_handle_sock_client(sck)) {
++              err = -EACCES;
++              goto out_put;
++      }
++
++#ifdef CONFIG_GRKERNSEC
++      if (sock->sk->protocol == IPPROTO_TCP)
++              current->used_connect = 1;
++#endif
++
+       err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
+                                sock->file->f_flags);
+ out_put:
+@@ -1333,6 +1404,14 @@
+               err=sock->ops->shutdown(sock, how);
+               sockfd_put(sock);
+       }
++
++#ifdef CONFIG_GRKERNSEC
++      if (likely(!err && current->used_accept)) {
++              current->used_accept = 0;
++              current->curr_ip = 0;
++      }
++#endif
++
+       return err;
+ }
+diff -urN linux-2.4.22/net/sunrpc/xprt.c linux-2.4.22-grsec-O1/net/sunrpc/xprt.c
+--- linux-2.4.22/net/sunrpc/xprt.c     2003-08-25 13:44:44.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/sunrpc/xprt.c    2003-10-21 14:24:35.000000000 +0200
+@@ -59,6 +59,7 @@
+ #include <linux/unistd.h>
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/file.h>
++#include <linux/grsecurity.h>
+ #include <net/sock.h>
+ #include <net/checksum.h>
+@@ -1290,6 +1291,12 @@
+       }
+       ret = xid++;
+       spin_unlock(&xid_lock);
++
++#ifdef CONFIG_GRKERNSEC_RANDRPC
++      if (grsec_enable_randrpc)
++              ret = (u32) get_random_long();
++#endif
++
+       return ret;
+ }
+diff -urN linux-2.4.22/net/unix/af_unix.c linux-2.4.22-grsec-O1/net/unix/af_unix.c
+--- linux-2.4.22/net/unix/af_unix.c    2003-10-20 18:59:10.000000000 +0200
++++ linux-2.4.22-grsec-O1/net/unix/af_unix.c   2003-10-21 14:24:35.000000000 +0200
+@@ -109,6 +109,7 @@
+ #include <linux/poll.h>
+ #include <linux/smp_lock.h>
+ #include <linux/rtnetlink.h>
++#include <linux/grsecurity.h>
+ #include <asm/checksum.h>
+@@ -599,6 +600,11 @@
+               if (err)
+                       goto put_fail;
++              if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
++                      err = -EACCES;
++                      goto put_fail;
++              }
++              
+               err = -ECONNREFUSED;
+               if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
+                       goto put_fail;
+@@ -622,6 +628,13 @@
+               if (u) {
+                       struct dentry *dentry;
+                       dentry = u->protinfo.af_unix.dentry;
++
++                      if (!gr_handle_chroot_unix(u->peercred.pid)) {
++                              err = -EPERM;
++                              sock_put(u);
++                              goto fail;
++                      }
++
+                       if (dentry)
+                               UPDATE_ATIME(dentry->d_inode);
+               } else
+@@ -720,9 +733,19 @@
+                * All right, let's create it.
+                */
+               mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask);
++      
++              if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
++                      err = -EACCES;
++                      goto out_mknod_dput;
++              }       
++
+               err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
++
+               if (err)
+                       goto out_mknod_dput;
++
++              gr_handle_create(dentry, nd.mnt);
++
+               up(&nd.dentry->d_inode->i_sem);
+               dput(nd.dentry);
+               nd.dentry = dentry;
+@@ -740,6 +763,10 @@
+                       goto out_unlock;
+               }
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
++              sk->peercred.pid = current->pid;
++#endif
++
+               list = &unix_socket_table[addr->hash];
+       } else {
+               list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
+@@ -866,6 +893,9 @@
+       int st;
+       int err;
+       long timeo;
++#ifdef CONFIG_GRKERNSEC
++      struct task_struct *p, **htable;
++#endif
+       err = unix_mkname(sunaddr, addr_len, &hash);
+       if (err < 0)
+@@ -989,6 +1019,17 @@
+       /* Set credentials */
+       sk->peercred = other->peercred;
++#ifdef CONFIG_GRKERNSEC
++      read_lock(&tasklist_lock);
++      htable = &pidhash[pid_hashfn(other->peercred.pid)];
++      for (p = *htable; p && p->pid != other->peercred.pid; p = p->pidhash_next);
++      if (p) {
++              p->curr_ip = current->curr_ip;
++              p->used_accept = 1;
++      }
++      read_unlock(&tasklist_lock);
++#endif
++
+       sock_hold(newsk);
+       unix_peer(sk)=newsk;
+       sock->state=SS_CONNECTED;
index 189e2e35d94588018488b84e2b22470dfbab51ed..0fe667a5c8b0369e9113119c5a3a49f5505d22f3 100644 (file)
@@ -7,33 +7,26 @@ CONFIG_GRKERNSEC=y
 # CONFIG_GRKERNSEC_HI is not set
 CONFIG_GRKERNSEC_CUSTOM=y
 
-CONFIG_IP_NF_MATCH_STEALTH=m
-
-# CONFIG_GRKERNSEC_PAX_NOEXEC is not set
-# CONFIG_GRKERNSEC_PAX_ASLR is not set
-
 #
-# Buffer Overflow Protection
+# Address Space Protection
 #
-CONFIG_GRKERNSEC_STACK=y
-CONFIG_GRKERNSEC_STACK_GCC=y
+# CONFIG_GRKERNSEC_PAX_NOEXEC is not set
+CONFIG_GRKERNSEC_PAX_ASLR=y
+# CONFIG_GRKERNSEC_PAX_RANDKSTACK is not set
+CONFIG_GRKERNSEC_PAX_RANDUSTACK=y
+CONFIG_GRKERNSEC_PAX_RANDMMAP=y
 CONFIG_GRKERNSEC_KMEM=y
-CONFIG_GRKERNSEC_KSYMS=y
-# CONFIG_GRKERNSEC_PAX_RANDMMAP is not set
+# CONFIG_GRKERNSEC_IO is not set
+CONFIG_GRKERNSEC_PROC_MEMMAP=y
+# CONFIG_GRKERNSEC_HIDESYM is not set
 
 #
-# ACL options
+# Role Based Access Control Options
 #
-# CONFIG_GR_DEBUG is not set
-# CONFIG_GRKERNSEC_ACL_CAPLOG is not set
-CONFIG_GR_MAXTRIES=3
-CONFIG_GR_TIMEOUT=30
+CONFIG_GRKERNSEC_ACL_HIDEKERN=y
+CONFIG_GRKERNSEC_ACL_MAXTRIES=3
+CONFIG_GRKERNSEC_ACL_TIMEOUT=30
 
-#
-# Access Control Lists
-#
-# CONFIG_OBV_PROC is not set
-# CONFIG_GRKERNSEC_ACL is not set
 #
 # Filesystem Protections
 #
@@ -42,44 +35,39 @@ CONFIG_GRKERNSEC_PROC=y
 CONFIG_GRKERNSEC_PROC_USERGROUP=y
 CONFIG_GRKERNSEC_PROC_GID=17
 CONFIG_GRKERNSEC_PROC_ADD=y
-# CONFIG_GRKERNSEC_PROC_MEMMAP is not set
 CONFIG_GRKERNSEC_LINK=y
 CONFIG_GRKERNSEC_FIFO=y
 CONFIG_GRKERNSEC_FD=y
 CONFIG_GRKERNSEC_CHROOT=y
-CONFIG_GRKERNSEC_CHROOT_SIG=y
 CONFIG_GRKERNSEC_CHROOT_MOUNT=y
 CONFIG_GRKERNSEC_CHROOT_DOUBLE=y
 CONFIG_GRKERNSEC_CHROOT_PIVOT=y
 CONFIG_GRKERNSEC_CHROOT_CHDIR=y
-CONFIG_GRKERNSEC_CHROOT_FCHDIR=y
 CONFIG_GRKERNSEC_CHROOT_CHMOD=y
+CONFIG_GRKERNSEC_CHROOT_FCHDIR=y
 CONFIG_GRKERNSEC_CHROOT_MKNOD=y
+CONFIG_GRKERNSEC_CHROOT_SHMAT=y
+CONFIG_GRKERNSEC_CHROOT_UNIX=y
 CONFIG_GRKERNSEC_CHROOT_FINDTASK=y
-CONFIG_GRKERNSEC_CHROOT_PTRACE=y
 CONFIG_GRKERNSEC_CHROOT_NICE=y
-CONFIG_GRKERNSEC_CHROOT_EXECLOG=y
-CONFIG_GRKERNSEC_AUDIT_CHDIR=y
-CONFIG_GRKERNSEC_AUDIT_MOUNT=y
-CONFIG_GRKERNSEC_AUDIT_IPC=y
-CONFIG_GRKERNSEC_AUDIT_PTRACE=y
+CONFIG_GRKERNSEC_CHROOT_SYSCTL=y
 CONFIG_GRKERNSEC_CHROOT_CAPS=y
-CONFIG_GRKERNSEC_KBMAP=y
 
 #
 # Kernel Auditing
 #
 CONFIG_GRKERNSEC_AUDIT_GROUP=y
 CONFIG_GRKERNSEC_AUDIT_GID=1007
-
-#
-# Security Logging
-#
 CONFIG_GRKERNSEC_EXECLOG=y
-CONFIG_GRKERNSEC_SUID=y
+CONFIG_GRKERNSEC_RESLOG=y
+CONFIG_GRKERNSEC_CHROOT_EXECLOG=y
+CONFIG_GRKERNSEC_AUDIT_CHDIR=y
+CONFIG_GRKERNSEC_AUDIT_MOUNT=y
+CONFIG_GRKERNSEC_AUDIT_IPC=y
 CONFIG_GRKERNSEC_SIGNAL=y
 CONFIG_GRKERNSEC_FORKFAIL=y
 CONFIG_GRKERNSEC_TIME=y
+CONFIG_GRKERNSEC_PROC_IPADDR=y
 
 #
 # Executable Protections
@@ -87,58 +75,25 @@ CONFIG_GRKERNSEC_TIME=y
 CONFIG_GRKERNSEC_EXECVE=y
 CONFIG_GRKERNSEC_DMESG=y
 CONFIG_GRKERNSEC_RANDPID=y
-CONFIG_GRKERNSEC_IPC=y
-CONFIG_GRKERNSEC_TTYROOT=y
-CONFIG_GRKERNSEC_TTYROOT_PHYS=y
-CONFIG_GRKERNSEC_TTYROOT_SERIAL=y
-CONFIG_GRKERNSEC_TTYROOT_PSEUDO=y
-CONFIG_GRKERNSEC_FORKBOMB=y
-CONFIG_GRKERNSEC_FORKBOMB_GID=65504
-CONFIG_GRKERNSEC_FORKBOMB_SEC=40
-CONFIG_GRKERNSEC_FORKBOMB_MAX=20
 CONFIG_GRKERNSEC_TPE=y
-CONFIG_GRKERNSEC_TPE_GLIBC=y
 CONFIG_GRKERNSEC_TPE_ALL=y
 CONFIG_GRKERNSEC_TPE_GID=65500
 
 #
 # Network Protections
 #
+CONFIG_GRKERNSEC_RANDNET=y
 CONFIG_GRKERNSEC_RANDID=y
+CONFIG_GRKERNSEC_RANDISN=y
 CONFIG_GRKERNSEC_RANDSRC=y
 CONFIG_GRKERNSEC_RANDRPC=y
-CONFIG_GRKERNSEC_RANDBIND=y
-CONFIG_GRKERNSEC_RANDPING=y
-CONFIG_GRKERNSEC_RANDTTL=y
-CONFIG_GRKERNSEC_RANDTTL_THRESH=64
-CONFIG_GRKERNSEC_RANDNET=y
 CONFIG_GRKERNSEC_SOCKET=y
 CONFIG_GRKERNSEC_SOCKET_ALL=y
-CONFIG_GRKERNSEC_SOCKET_ALL_GID=1004
-CONFIG_GRKERNSEC_ALL_GID=65501
+CONFIG_GRKERNSEC_SOCKET_ALL_GID=65501
 CONFIG_GRKERNSEC_SOCKET_CLIENT=y
-CONFIG_GRKERNSEC_SOCKET_CLIENT_GID=1003
-CONFIG_GRKERNSEC_CLIENT_GID=65502
+CONFIG_GRKERNSEC_SOCKET_CLIENT_GID=65502
 CONFIG_GRKERNSEC_SOCKET_SERVER=y
-CONFIG_GRKERNSEC_SOCKET_SERVER_GID=1002
-CONFIG_GRKERNSEC_SERVER_GID=65503
-CONFIG_GRKERNSEC_PTRACE=y
-CONFIG_GRKERNSEC_PTRACE_GROUP=y
-CONFIG_GRKERNSEC_PTRACE_GID=1008
-CONFIG_GRKERNSEC_STEALTH=y
-CONFIG_GRKERNSEC_STEALTH_RST=y
-CONFIG_GRKERNSEC_STEALTH_UDP=y
-CONFIG_GRKERNSEC_STEALTH_ICMP=y
-CONFIG_GRKERNSEC_STEALTH_IGMP=y
-CONFIG_GRKERNSEC_STEALTH_FLAGS=y
-
-#
-# Network Logging
-#
-CONFIG_GRKERNSEC_STEALTH_ICMP_LOG=y
-CONFIG_GRKERNSEC_STEALTH_RST_LOG=y
-CONFIG_GRKERNSEC_STEALTH_UDP_LOG=y
-CONFIG_GRKERNSEC_STEALTH_FLAGS_LOG=y
+CONFIG_GRKERNSEC_SOCKET_SERVER_GID=65503
 
 #
 # Sysctl support
@@ -146,22 +101,9 @@ CONFIG_GRKERNSEC_STEALTH_FLAGS_LOG=y
 CONFIG_GRKERNSEC_SYSCTL=y
 
 #
-# Miscellaneous Enhancements
+# Logging options
 #
-CONFIG_GRKERNSEC_COREDUMP=y
 CONFIG_GRKERNSEC_FLOODTIME=30
 CONFIG_GRKERNSEC_FLOODBURST=4
 
-# 1.9.8-rc1
-CONFIG_GRKERNSEC_MEM=y
-CONFIG_GRKERNSEC_ACL_HIDEKERN=y
-CONFIG_GRKERNSEC_RESLOG=y
-# CONFIG_GRKERNSEC_IO is not set
-CONFIG_GRKERNSEC_ACL_MAXTRIES=3
-CONFIG_GRKERNSEC_ACL_TIMEOUT=30
-# CONFIG_GRKERNSEC_CHROOT_SHMAT is not set
-CONFIG_GRKERNSEC_CHROOT_UNIX=y
-CONFIG_GRKERNSEC_CHROOT_SYSCTL=y
-CONFIG_GRKERNSEC_RANDISN=y
-# CONFIG_GRKERNSEC_HIDESYM is not set
-CONFIG_GRKERNSEC_PROC_IPADDR=y
+CONFIG_IP_NF_MATCH_STEALTH=m
This page took 2.350751 seconds and 4 git commands to generate.