summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Kinard <kumba@gentoo.org>2004-02-23 10:59:14 +0000
committerJoshua Kinard <kumba@gentoo.org>2004-02-23 10:59:14 +0000
commitff6b4b7d1f7f0327d940ee9259a7d77be1c099e0 (patch)
treea6bd224b3a3ad78fba0059305a5331cc2c761078 /sys-kernel/mips-sources
parentMore cleanups, mainly in renaming the security-based patches to include their... (diff)
downloadgentoo-2-ff6b4b7d1f7f0327d940ee9259a7d77be1c099e0.tar.gz
gentoo-2-ff6b4b7d1f7f0327d940ee9259a7d77be1c099e0.tar.bz2
gentoo-2-ff6b4b7d1f7f0327d940ee9259a7d77be1c099e0.zip
Just realized the pax patch is way too big for the tree, removed until a more elegant way of including it can be devised.
Diffstat (limited to 'sys-kernel/mips-sources')
-rw-r--r--sys-kernel/mips-sources/ChangeLog7
-rw-r--r--sys-kernel/mips-sources/Manifest5
-rw-r--r--sys-kernel/mips-sources/files/pax-linux-2.4.25-200402192035.patch8597
-rw-r--r--sys-kernel/mips-sources/mips-sources-2.4.25.ebuild9
4 files changed, 10 insertions, 8608 deletions
diff --git a/sys-kernel/mips-sources/ChangeLog b/sys-kernel/mips-sources/ChangeLog
index 429c1e6ee2a4..97dbe81b952e 100644
--- a/sys-kernel/mips-sources/ChangeLog
+++ b/sys-kernel/mips-sources/ChangeLog
@@ -1,6 +1,11 @@
# ChangeLog for sys-kernel/mips-sources
# Copyright 2002-2004 Gentoo Technologies, Inc.; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-kernel/mips-sources/ChangeLog,v 1.26 2004/02/23 10:48:55 kumba Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-kernel/mips-sources/ChangeLog,v 1.27 2004/02/23 10:59:14 kumba Exp $
+
+ 23 Feb 2004; Joshua Kinard <kumba@gentoo.org> mips-sources-2.4.25.ebuild,
+ files/pax-linux-2.4.25-200402192035.patch:
+ Just realized the pax patch is way too big for the tree, removed until a more
+ elegant way of including it can be devised.
*mips-sources-2.4.25 (23 Feb 2004)
diff --git a/sys-kernel/mips-sources/Manifest b/sys-kernel/mips-sources/Manifest
index baa39dc1dba7..6d88c4c11a13 100644
--- a/sys-kernel/mips-sources/Manifest
+++ b/sys-kernel/mips-sources/Manifest
@@ -1,9 +1,9 @@
-MD5 7198fe4dee68c23d3cde981830003056 ChangeLog 8805
+MD5 2cf5d8a3c5fdc071c1264cf8dbc47dfe ChangeLog 9053
MD5 ad25a2a0b6ade60c13ad8040f3c319c6 metadata.xml 378
MD5 f68ccd8232d3fad9033d4bad71f68dbf mips-sources-2.4.21-r7.ebuild 2311
MD5 827706c9fd682fa87523068eae0ae756 mips-sources-2.4.22-r10.ebuild 2139
MD5 b26e5e89167ed7dbe332e080fb1a7e1d mips-sources-2.4.23-r6.ebuild 2925
-MD5 e36930b56e543566ea859addde717eed mips-sources-2.4.25.ebuild 2112
+MD5 f930528ecf4b7fbba19d94c4cbbd54a6 mips-sources-2.4.25.ebuild 1949
MD5 e300a3e148a7dcc38a0e099494fb6cb3 files/bigendian-byteorder-fix.patch 1557
MD5 0a3a1be2517b274c5a0c0748a437b6bd files/digest-mips-sources-2.4.21-r7 219
MD5 93f8e3701539d6699921e4becaa72f2d files/digest-mips-sources-2.4.22-r10 218
@@ -14,7 +14,6 @@ MD5 6ff178aa1398ac2347921194944376f8 files/mipscvs-2.4.23-makefile-fix.patch 190
MD5 a361526659bf1585152b2c819e329941 files/mipscvs-2.4.23-makefile-inlinelimit.patch 1314
MD5 fbb6766828584e454bf053286aad6207 files/mipscvs-2.4.25-makefile-fix.patch 428
MD5 95ba3093147f4188db0ea4949e4317cf files/mipscvs-2.4.25-makefile-inlinelimit.patch 1588
-MD5 b0d077b1ad269163db41ecf3156654f4 files/pax-linux-2.4.25-200402192035.patch 278052
MD5 e637c6fa41097ea2c4693d0766f2e1c5 files/CAN-2003-0961-do_brk.patch 242
MD5 5e4b24d4c540af721c5bc7e3ad77f40b files/CAN-2003-0985-mremap.patch 414
MD5 1f646066ee81f7aea1f79a79e38a252d files/rtc-fixes.patch 2125
diff --git a/sys-kernel/mips-sources/files/pax-linux-2.4.25-200402192035.patch b/sys-kernel/mips-sources/files/pax-linux-2.4.25-200402192035.patch
deleted file mode 100644
index 689f1fad03f6..000000000000
--- a/sys-kernel/mips-sources/files/pax-linux-2.4.25-200402192035.patch
+++ /dev/null
@@ -1,8597 +0,0 @@
-diff -Nurp linux-2.4.25/Documentation/Configure.help linux-2.4.25-pax/Documentation/Configure.help
---- linux-2.4.25/Documentation/Configure.help 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/Documentation/Configure.help 2004-02-19 11:12:52.000000000 -0500
-@@ -28732,6 +28732,304 @@ CONFIG_SOUND_WM97XX
-
- If unsure, say N.
-
-+Support soft mode
-+CONFIG_PAX_SOFTMODE
-+ Enabling this option will allow you to run PaX in soft mode, that
-+ is, PaX features will not be enforced by default, only on executables
-+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
-+ is the only way to mark executables for soft mode use.
-+
-+ Soft mode can be activated by using the "pax_softmode=1" kernel command
-+ line option on boot. Furthermore you can control various PaX features
-+ at runtime via the entries in /proc/sys/kernel/pax.
-+
-+Use legacy ELF header marking
-+CONFIG_PAX_EI_PAX
-+ Enabling this option will allow you to control PaX features on
-+ a per executable basis. The control flags will be read from
-+ an otherwise reserved part of the ELF header. This marking has
-+ numerous drawbacks (no support for soft-mode, toolchain does not
-+ know about the non-standard use of the ELF header) therefore it
-+ has been deprecated in favour of PT_PAX_FLAGS support.
-+
-+ You should enable this option only if your toolchain does not yet
-+ support the new control flag location (PT_PAX_FLAGS) or you still
-+ have applications not marked by PT_PAX_FLAGS.
-+
-+ Note that if you enable PT_PAX_FLAGS marking support as well,
-+ it will override the legacy EI_PAX marks.
-+
-+Use ELF program header marking
-+CONFIG_PAX_PT_PAX_FLAGS
-+ Enabling this option will allow you to control PaX features on
-+ a per executable basis. The control flags will be read from
-+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
-+ has the benefits of supporting both soft mode and being fully
-+ integrated into the toolchain (the binutils patch is available
-+ from http://pax.grsecurity.net).
-+
-+ Note that if you enable the legacy EI_PAX marking support as well,
-+ it will be overriden by the PT_PAX_FLAGS marking.
-+
-+MAC system integration
-+CONFIG_PAX_NO_ACL_FLAGS
-+ Mandatory Access Control systems have the option of controlling
-+ PaX flags on a per executable basis, choose the method supported
-+ by your particular system.
-+
-+ - "none": if your MAC system does not interact with PaX,
-+ - "direct": if your MAC system defines pax_set_flags() itself,
-+ - "hook": if your MAC system uses the pax_set_flags_func callback.
-+
-+ NOTE: this option is for developers/integrators only.
-+
-+Enforce non-executable pages
-+CONFIG_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.
-+
-+ The 'chpax' utility available at http://pax.grsecurity.net/
-+ allows you to control this and other features on a per file basis.
-+
-+Paging based non-executable pages
-+CONFIG_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, ia64, parisc, sparc, sparc64 and x86_64 there is no
-+ performance impact. On ppc there is a slight performance impact.
-+
-+Segmentation based non-executable pages
-+CONFIG_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_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_PAX_PAGEEXEC or CONFIG_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_PAX_PAGEEXEC and CONFIG_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_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_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.
-+
-+Disallow ELF text relocations
-+CONFIG_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.tar.gz package
-+ referenced there has already been updated to support this).
-+
-+Allow ELF ET_EXEC text relocations
-+CONFIG_PAX_ETEXECRELOCS
-+ On some architectures there are incorrectly created applications
-+ that require text relocations and would not work without enabling
-+ this option. If you are an alpha, ia64 or parisc 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_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.
-+
-+Enforce non-executable kernel pages
-+CONFIG_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_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 Nergal's
-+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
-+ (http://www.grsecurity.net/) 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_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_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 mmap() base
-+CONFIG_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://pax.grsecurity.net/et_dyn.tar.gz 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.
-+
-+Randomize ET_EXEC base
-+CONFIG_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.
-+
- #
- # A couple of things I keep forgetting:
- # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
-diff -Nurp linux-2.4.25/arch/alpha/config.in linux-2.4.25-pax/arch/alpha/config.in
---- linux-2.4.25/arch/alpha/config.in 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/alpha/config.in 2004-02-19 11:12:52.000000000 -0500
-@@ -466,5 +466,63 @@ int 'Kernel messages buffer length shift
-
- endmenu
-
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+# bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+# if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+# bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+# fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+# bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+ bool ' Automatically emulate ELF PLT' CONFIG_PAX_EMUPLT
-+ bool ' Allow ELF ET_EXEC text relocations' CONFIG_PAX_ETEXECRELOCS
-+ fi
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-+
- source crypto/Config.in
- source lib/Config.in
-diff -Nurp linux-2.4.25/arch/alpha/kernel/osf_sys.c linux-2.4.25-pax/arch/alpha/kernel/osf_sys.c
---- linux-2.4.25/arch/alpha/kernel/osf_sys.c 2003-06-13 10:51:29.000000000 -0400
-+++ linux-2.4.25-pax/arch/alpha/kernel/osf_sys.c 2004-02-19 11:12:52.000000000 -0500
-@@ -230,6 +230,11 @@ asmlinkage unsigned long osf_mmap(unsign
- struct file *file = NULL;
- unsigned long ret = -EBADF;
-
-+#ifdef CONFIG_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",
-@@ -1357,6 +1362,10 @@ arch_get_unmapped_area(struct file *filp
- merely specific addresses, but regions of memory -- perhaps
- this feature should be incorporated into all ports? */
-
-+#ifdef CONFIG_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 +1373,15 @@ arch_get_unmapped_area(struct file *filp
- }
-
- /* 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_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 -Nurp linux-2.4.25/arch/alpha/mm/fault.c linux-2.4.25-pax/arch/alpha/mm/fault.c
---- linux-2.4.25/arch/alpha/mm/fault.c 2002-11-28 18:53:08.000000000 -0500
-+++ linux-2.4.25-pax/arch/alpha/mm/fault.c 2004-02-19 11:12:52.000000000 -0500
-@@ -53,6 +53,139 @@ __load_new_mm_context(struct mm_struct *
- __reload_thread(&current->thread);
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * 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_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_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,34 @@ do_page_fault(unsigned long address, uns
- good_area:
- info.si_code = SEGV_ACCERR;
- if (cause < 0) {
-- if (!(vma->vm_flags & VM_EXEC))
-+ if (!(vma->vm_flags & VM_EXEC)) {
-+
-+#ifdef CONFIG_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_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/i386/Makefile linux-2.4.25-pax/arch/i386/Makefile
---- linux-2.4.25/arch/i386/Makefile 2003-06-13 10:51:29.000000000 -0400
-+++ linux-2.4.25-pax/arch/i386/Makefile 2004-02-19 11:12:52.000000000 -0500
-@@ -114,6 +114,9 @@ arch/i386/mm: dummy
-
- MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-
-+arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE
-+ $(CPP) -C -P -I$(HPATH) -D__KERNEL__ -imacros $(HPATH)/linux/config.h -imacros $(HPATH)/asm-i386/segment.h -imacros $(HPATH)/asm-i386/page.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds
-+
- vmlinux: arch/i386/vmlinux.lds
-
- FORCE: ;
-@@ -150,6 +153,7 @@ archclean:
- @$(MAKEBOOT) clean
-
- archmrproper:
-+ rm -f arch/i386/vmlinux.lds
-
- archdep:
- @$(MAKEBOOT) dep
-diff -Nurp linux-2.4.25/arch/i386/boot/bootsect.S linux-2.4.25-pax/arch/i386/boot/bootsect.S
---- linux-2.4.25/arch/i386/boot/bootsect.S 2003-08-25 07:44:39.000000000 -0400
-+++ linux-2.4.25-pax/arch/i386/boot/bootsect.S 2004-02-19 11:12:52.000000000 -0500
-@@ -237,7 +237,7 @@ rp_read:
- #ifdef __BIG_KERNEL__
- # look in setup.S for bootsect_kludge
- bootsect_kludge = 0x220 # 0x200 + 0x20 which is the size of the
-- lcall bootsect_kludge # bootsector + bootsect_kludge offset
-+ lcall *bootsect_kludge # bootsector + bootsect_kludge offset
- #else
- movw %es, %ax
- subw $SYSSEG, %ax
-diff -Nurp linux-2.4.25/arch/i386/boot/setup.S linux-2.4.25-pax/arch/i386/boot/setup.S
---- linux-2.4.25/arch/i386/boot/setup.S 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/boot/setup.S 2004-02-19 11:12:52.000000000 -0500
-@@ -637,7 +637,7 @@ edd_done:
- cmpw $0, %cs:realmode_swtch
- jz rmodeswtch_normal
-
-- lcall %cs:realmode_swtch
-+ lcall *%cs:realmode_swtch
-
- jmp rmodeswtch_end
-
-diff -Nurp linux-2.4.25/arch/i386/config.in linux-2.4.25-pax/arch/i386/config.in
---- linux-2.4.25/arch/i386/config.in 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/config.in 2004-02-19 11:12:52.000000000 -0500
-@@ -99,6 +99,7 @@ if [ "$CONFIG_M586MMX" = "y" ]; then
- fi
- if [ "$CONFIG_M686" = "y" ]; then
- define_int CONFIG_X86_L1_CACHE_SHIFT 5
-+ define_bool CONFIG_X86_ALIGNMENT_16 y
- define_bool CONFIG_X86_HAS_TSC y
- define_bool CONFIG_X86_GOOD_APIC y
- bool 'PGE extensions (not for Cyrix/Transmeta)' CONFIG_X86_PGE
-@@ -108,6 +109,7 @@ if [ "$CONFIG_M686" = "y" ]; then
- fi
- if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
- define_int CONFIG_X86_L1_CACHE_SHIFT 5
-+ define_bool CONFIG_X86_ALIGNMENT_16 y
- define_bool CONFIG_X86_HAS_TSC y
- define_bool CONFIG_X86_GOOD_APIC y
- define_bool CONFIG_X86_PGE y
-@@ -116,6 +118,7 @@ if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
- fi
- if [ "$CONFIG_MPENTIUM4" = "y" ]; then
- define_int CONFIG_X86_L1_CACHE_SHIFT 7
-+ define_bool CONFIG_X86_ALIGNMENT_16 y
- define_bool CONFIG_X86_HAS_TSC y
- define_bool CONFIG_X86_GOOD_APIC y
- define_bool CONFIG_X86_PGE y
-@@ -135,6 +138,7 @@ if [ "$CONFIG_MK8" = "y" ]; then
- fi
- if [ "$CONFIG_MK7" = "y" ]; then
- define_int CONFIG_X86_L1_CACHE_SHIFT 6
-+ define_bool CONFIG_X86_ALIGNMENT_16 y
- define_bool CONFIG_X86_HAS_TSC y
- define_bool CONFIG_X86_GOOD_APIC y
- define_bool CONFIG_X86_USE_3DNOW y
-@@ -485,5 +489,78 @@ int 'Kernel messages buffer length shift
-
- endmenu
-
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ if [ "$CONFIG_M586" = "y" -o \
-+ "$CONFIG_M586TSC" = "y" -o \
-+ "$CONFIG_M586MMX" = "y" -o \
-+ "$CONFIG_M686" = "y" -o \
-+ "$CONFIG_MPENTIUMIII" = "y" -o \
-+ "$CONFIG_MPENTIUM4" = "y" -o \
-+ "$CONFIG_MK7" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ fi
-+ bool 'Segmentation based non-executable pages' CONFIG_PAX_SEGMEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" -o "$CONFIG_PAX_SEGMEXEC" = "y" ]; then
-+ bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+ if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+ bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+ fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+ bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+ fi
-+ fi
-+ if [ "$CONFIG_MODULES" = "n" ]; then
-+ bool 'Enforce non-executable kernel pages' CONFIG_PAX_KERNEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ if [ "$CONFIG_X86_TSC" = "y" ]; then
-+ bool ' Randomize kernel stack base' CONFIG_PAX_RANDKSTACK
-+ fi
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" -o "$CONFIG_PAX_SEGMEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-+
- source crypto/Config.in
- source lib/Config.in
-diff -Nurp linux-2.4.25/arch/i386/kernel/apm.c linux-2.4.25-pax/arch/i386/kernel/apm.c
---- linux-2.4.25/arch/i386/kernel/apm.c 2003-08-25 07:44:39.000000000 -0400
-+++ linux-2.4.25-pax/arch/i386/kernel/apm.c 2004-02-19 11:12:52.000000000 -0500
-@@ -614,7 +614,7 @@ static u8 apm_bios_call(u32 func, u32 eb
- __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 @@ static u8 apm_bios_call_simple(u32 func,
- __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 @@ static int __init apm_init(void)
- __va((unsigned long)0x40 << 4));
- _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4));
-
-+#ifdef CONFIG_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 @@ static int __init apm_init(void)
- __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_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 @@ static int __init apm_init(void)
- _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_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 @@ static int __init apm_init(void)
- (apm_info.bios.cseg_16_len - 1) & 0xffff);
- _set_limit((char *)&gdt[APM_DS >> 3],
- (apm_info.bios.dseg_len - 1) & 0xffff);
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/i386/kernel/entry.S linux-2.4.25-pax/arch/i386/kernel/entry.S
---- linux-2.4.25/arch/i386/kernel/entry.S 2003-06-13 10:51:29.000000000 -0400
-+++ linux-2.4.25-pax/arch/i386/kernel/entry.S 2004-02-19 11:12:52.000000000 -0500
-@@ -209,6 +209,17 @@ ENTRY(system_call)
- jae badsys
- call *SYMBOL_NAME(sys_call_table)(,%eax,4)
- movl %eax,EAX(%esp) # save the return value
-+
-+#ifdef CONFIG_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)
-@@ -389,8 +400,56 @@ ENTRY(alignment_check)
- jmp error_code
-
- ENTRY(page_fault)
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ ALIGN
-+ pushl $ SYMBOL_NAME(pax_do_page_fault)
-+#else
- pushl $ SYMBOL_NAME(do_page_fault)
-+#endif
-+
-+#ifndef CONFIG_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
-@@ -402,7 +461,7 @@ ENTRY(spurious_interrupt_bug)
- 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 -Nurp linux-2.4.25/arch/i386/kernel/head.S linux-2.4.25-pax/arch/i386/kernel/head.S
---- linux-2.4.25/arch/i386/kernel/head.S 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/head.S 2004-02-19 11:12:52.000000000 -0500
-@@ -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 @@ startup_32:
- PRESENT+RW+USER */
- 2: stosl
- add $0x1000,%eax
-- cmp $empty_zero_page-__PAGE_OFFSET,%edi
-+ cmp $0x00c00007,%eax
- jne 2b
-
- /*
-@@ -100,9 +101,19 @@ startup_32:
- movl %eax,%cr0 /* ..and set paging (PG) bit */
- jmp 1f /* flush the prefetch-queue */
- 1:
-+
-+#if !defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_SMP)
-+
-+#ifdef CONFIG_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 @@ startup_32:
- */
- 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 @@ L6:
- 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 @@ rp_sidt:
- 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 @@ ignore_int:
- 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 @@ gdt_descr:
- SYMBOL_NAME(gdt):
- .long SYMBOL_NAME(gdt_table)
-
-+#ifdef CONFIG_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 @@ ENTRY(_stext)
- * in the text section because it has alignment requirements
- * that we cannot fulfill any other way.
- */
--.data
-+.section .rodata,"a"
-
- ALIGN
- /*
-@@ -430,19 +461,62 @@ ALIGN
- */
- ENTRY(gdt_table)
- .quad 0x0000000000000000 /* NULL descriptor */
-+
-+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
-+ .quad 0x00cf9b000000ffff /* 0x08 kernel 4GB code at 0x00000000 */
-+#else
- .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 */
-+#endif
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ .quad 0xc0cf9b400000ffff /* 0x10 kernel 4GB code at 0xc0400000 */
-+#else
-+ .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 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 */
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ENTRY(gdt_table2)
-+ .quad 0x0000000000000000 /* NULL descriptor */
-+
-+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
-+ .quad 0x00cf9b000000ffff /* 0x08 kernel 4GB code at 0x00000000 */
-+#else
-+ .quad 0x0000000000000000 /* not used */
-+#endif
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ .quad 0xc0cf9b400000ffff /* 0x10 kernel 4GB code at 0xc0400000 */
-+#else
-+ .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 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 -Nurp linux-2.4.25/arch/i386/kernel/i386_ksyms.c linux-2.4.25-pax/arch/i386/kernel/i386_ksyms.c
---- linux-2.4.25/arch/i386/kernel/i386_ksyms.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/i386_ksyms.c 2004-02-19 11:12:52.000000000 -0500
-@@ -74,6 +74,11 @@ EXPORT_SYMBOL(pm_power_off);
- EXPORT_SYMBOL(get_cmos_time);
- EXPORT_SYMBOL(apm_info);
- EXPORT_SYMBOL(gdt);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+EXPORT_SYMBOL(gdt2);
-+#endif
-+
- EXPORT_SYMBOL(empty_zero_page);
-
- #ifdef CONFIG_DEBUG_IOVIRT
-diff -Nurp linux-2.4.25/arch/i386/kernel/ldt.c linux-2.4.25-pax/arch/i386/kernel/ldt.c
---- linux-2.4.25/arch/i386/kernel/ldt.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/ldt.c 2004-02-19 11:12:52.000000000 -0500
-@@ -151,7 +151,7 @@ static int read_default_ldt(void * ptr,
- {
- int err;
- unsigned long size;
-- void *address;
-+ const void *address;
-
- err = 0;
- address = &default_ldt[0];
-@@ -214,6 +214,13 @@ static int write_ldt(void * ptr, unsigne
- }
- }
-
-+#ifdef CONFIG_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) |
-@@ -224,7 +231,7 @@ static int write_ldt(void * ptr, unsigne
- ((ldt_info.seg_not_present ^ 1) << 15) |
- (ldt_info.seg_32bit << 22) |
- (ldt_info.limit_in_pages << 23) |
-- 0x7000;
-+ 0x7100;
- if (!oldmode)
- entry_2 |= (ldt_info.useable << 20);
-
-diff -Nurp linux-2.4.25/arch/i386/kernel/pci-pc.c linux-2.4.25-pax/arch/i386/kernel/pci-pc.c
---- linux-2.4.25/arch/i386/kernel/pci-pc.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/pci-pc.c 2004-02-19 11:12:52.000000000 -0500
-@@ -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 @@ union bios32 {
- * the array there.
- */
-
-+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
-+#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 unsigned long bios32_service(unsi
- 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;
-
-diff -Nurp linux-2.4.25/arch/i386/kernel/process.c linux-2.4.25-pax/arch/i386/kernel/process.c
---- linux-2.4.25/arch/i386/kernel/process.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/process.c 2004-02-19 11:12:52.000000000 -0500
-@@ -209,18 +209,18 @@ __setup("reboot=", reboot_setup);
- doesn't work with at least one type of 486 motherboard. It is easy
- to stop this code working; hence the copious comments. */
-
--static unsigned long long
-+static const unsigned long long
- real_mode_gdt_entries [3] =
- {
- 0x0000000000000000ULL, /* Null descriptor */
-- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
-- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
-+ 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
-+ 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
- };
-
- static struct
- {
- unsigned short size __attribute__ ((packed));
-- unsigned long long * base __attribute__ ((packed));
-+ const unsigned long long * base __attribute__ ((packed));
- }
- real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
- real_mode_idt = { 0x3ff, 0 },
-@@ -552,7 +552,7 @@ int copy_thread(int nr, unsigned long cl
- {
- struct pt_regs * childregs;
-
-- childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
-+ childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p - sizeof(unsigned long))) - 1;
- struct_cpy(childregs, regs);
- childregs->eax = 0;
- childregs->esp = esp;
-@@ -613,6 +613,16 @@ void dump_thread(struct pt_regs * regs,
- dump->u_fpvalid = dump_fpu (regs, &dump->i387);
- }
-
-+#ifdef CONFIG_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
- */
-@@ -652,6 +662,10 @@ void __switch_to(struct task_struct *pre
-
- unlazy_fpu(prev_p);
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ pax_switch_segments(next_p);
-+#endif
-+
- /*
- * Reload esp0, LDT and the page table pointer:
- */
-@@ -792,3 +806,30 @@ unsigned long get_wchan(struct task_stru
- }
- #undef last_sched
- #undef first_sched
-+
-+#ifdef CONFIG_PAX_RANDKSTACK
-+asmlinkage void pax_randomize_kstack(void)
-+{
-+ struct tss_struct *tss = init_tss + smp_processor_id();
-+ unsigned long time;
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (!pax_aslr)
-+ return;
-+#endif
-+
-+ rdtscl(time);
-+
-+ /* P4 seems to return a 0 LSB, ignore it */
-+#ifdef CONFIG_MPENTIUM4
-+ time &= 0x3EUL;
-+ time <<= 1;
-+#else
-+ time &= 0x1FUL;
-+ time <<= 2;
-+#endif
-+
-+ tss->esp0 ^= time;
-+ current->thread.esp0 = tss->esp0;
-+}
-+#endif
-diff -Nurp linux-2.4.25/arch/i386/kernel/setup.c linux-2.4.25-pax/arch/i386/kernel/setup.c
---- linux-2.4.25/arch/i386/kernel/setup.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/setup.c 2004-02-19 11:12:52.000000000 -0500
-@@ -3191,7 +3191,7 @@ void __init cpu_init (void)
- set_tss_desc(nr,t);
- gdt_table[__TSS(nr)].b &= 0xfffffdff;
- load_TR(nr);
-- load_LDT(&init_mm.context);
-+ _load_LDT(&init_mm.context);
-
- /*
- * Clear all 6 debug registers:
-@@ -3257,7 +3257,16 @@ int __init ppro_with_ram_bug(void)
- printk(KERN_INFO "Your Pentium Pro seems ok.\n");
- return 0;
- }
--
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+static int __init setup_pax_softmode(char *str)
-+{
-+ get_option (&str, &pax_softmode);
-+ return 1;
-+}
-+__setup("pax_softmode=", setup_pax_softmode);
-+#endif
-+
- /*
- * Local Variables:
- * mode:c
-diff -Nurp linux-2.4.25/arch/i386/kernel/sys_i386.c linux-2.4.25-pax/arch/i386/kernel/sys_i386.c
---- linux-2.4.25/arch/i386/kernel/sys_i386.c 2003-08-25 07:44:39.000000000 -0400
-+++ linux-2.4.25-pax/arch/i386/kernel/sys_i386.c 2004-02-19 11:12:52.000000000 -0500
-@@ -48,6 +48,11 @@ static inline long do_mmap2(
- int error = -EBADF;
- struct file * file = NULL;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-@@ -56,7 +61,7 @@ static inline long do_mmap2(
- }
-
- down_write(&current->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+ error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT);
- up_write(&current->mm->mmap_sem);
-
- if (file)
-diff -Nurp linux-2.4.25/arch/i386/kernel/trampoline.S linux-2.4.25-pax/arch/i386/kernel/trampoline.S
---- linux-2.4.25/arch/i386/kernel/trampoline.S 2002-11-28 18:53:09.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/trampoline.S 2004-02-19 11:12:52.000000000 -0500
-@@ -54,7 +54,7 @@ r_base = .
- 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 -Nurp linux-2.4.25/arch/i386/kernel/traps.c linux-2.4.25-pax/arch/i386/kernel/traps.c
---- linux-2.4.25/arch/i386/kernel/traps.c 2002-11-28 18:53:09.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/kernel/traps.c 2004-02-19 11:12:52.000000000 -0500
-@@ -54,7 +54,7 @@ asmlinkage int system_call(void);
- asmlinkage void lcall7(void);
- asmlinkage void lcall27(void);
-
--struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
-+const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 } };
-
- /*
-@@ -228,14 +228,23 @@ void show_registers(struct pt_regs *regs
- show_stack((unsigned long*)esp);
-
- printk("\nCode: ");
-+
-+#ifndef CONFIG_PAX_KERNEXEC
- if(regs->eip < PAGE_OFFSET)
- goto bad;
-+#endif
-
- for(i=0;i<20;i++)
- {
- unsigned char c;
-+
-+#ifdef CONFIG_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 @@ static void handle_BUG(struct pt_regs *r
-
- eip = regs->eip;
-
-+#ifdef CONFIG_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 @@ static void handle_BUG(struct pt_regs *r
- if (__get_user(line, (unsigned short *)(eip + 2)))
- goto bug;
- if (__get_user(file, (char **)(eip + 4)) ||
-+
-+#ifdef CONFIG_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);
-@@ -422,6 +442,13 @@ gp_in_kernel:
- regs->eip = fixup;
- return;
- }
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
-+ die("PAX: suspicious general protection fault", regs, error_code);
-+ else
-+#endif
-+
- die("general protection fault", regs, error_code);
- }
- }
-@@ -527,13 +554,12 @@ asmlinkage void do_debug(struct pt_regs
- {
- 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 */
-@@ -826,7 +852,7 @@ static void __init set_system_gate(unsig
- _set_gate(idt_table+n,15,3,addr);
- }
-
--static void __init set_call_gate(void *a, void *addr)
-+static void __init set_call_gate(const void *a, void *addr)
- {
- _set_gate(a,12,3,addr);
- }
-@@ -852,14 +878,58 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
- "rorl $16,%%eax" \
- : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
-
--void set_tss_desc(unsigned int n, void *addr)
-+void set_tss_desc(unsigned int n, const void *addr)
- {
- _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
-+
-+#ifdef CONFIG_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)
-+void __set_ldt_desc(unsigned int n, const void *addr, unsigned int size)
- {
- _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
-+#endif
-+
-+}
-+
-+void set_ldt_desc(unsigned int n, const void *addr, unsigned int size)
-+{
-+
-+#ifdef CONFIG_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_PAX_SEGMEXEC
-+ _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
-+#endif
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/i386/mm/fault.c linux-2.4.25-pax/arch/i386/mm/fault.c
---- linux-2.4.25/arch/i386/mm/fault.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/mm/fault.c 2004-02-19 11:12:52.000000000 -0500
-@@ -19,6 +19,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>
-@@ -127,6 +129,10 @@ void bust_spinlocks(int yes)
- asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
- extern unsigned long idt;
-
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_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
-@@ -137,23 +143,32 @@ extern unsigned long idt;
- * 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_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_PAX_PAGEEXEC
- unsigned long address;
-+#endif
- unsigned long page;
- unsigned long fixup;
- int write;
- siginfo_t info;
-
-+#ifndef CONFIG_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;
-
-@@ -258,7 +273,7 @@ good_area:
- tsk->thread.screen_bitmap |= 1 << bit;
- }
- up_read(&mm->mmap_sem);
-- return;
-+ return 0;
-
- /*
- * Something tried to access memory that isn't in our memory map..
-@@ -269,6 +284,41 @@ bad_area:
-
- /* User mode accesses just cause a SIGSEGV */
- if (error_code & 4) {
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+
-+#if defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
-+ switch (pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 5:
-+ return 0;
-+#endif
-+
-+#ifdef CONFIG_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;
- /* Kernel addresses are always protection faults */
- tsk->thread.error_code = error_code | (address >= TASK_SIZE);
-@@ -278,7 +328,7 @@ bad_area:
- /* info.si_code has been set above */
- info.si_addr = (void *)address;
- force_sig_info(SIGSEGV, &info, tsk);
-- return;
-+ return 0;
- }
-
- /*
-@@ -291,7 +341,7 @@ bad_area:
-
- if (nr == 6) {
- do_invalid_op(regs, 0);
-- return;
-+ return 0;
- }
- }
-
-@@ -299,7 +349,7 @@ no_context:
- /* Are we prepared to handle this kernel fault? */
- if ((fixup = search_exception_table(regs->eip)) != 0) {
- regs->eip = fixup;
-- return;
-+ return 0;
- }
-
- /*
-@@ -311,6 +361,13 @@ no_context:
-
- if (address < PAGE_SIZE)
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-+
-+#ifdef CONFIG_PAX_KERNEXEC
-+ else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET)
-+ 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);
-@@ -363,7 +420,7 @@ do_sigbus:
- /* Kernel mode? Handle exceptions or die */
- if (!(error_code & 4))
- goto no_context;
-- return;
-+ return 0;
-
- vmalloc_fault:
- {
-@@ -396,6 +453,454 @@ vmalloc_fault:
- pte_k = pte_offset(pmd_k, address);
- if (!pte_present(*pte_k))
- goto no_context;
-- return;
-+ return 0;
-+ }
-+}
-+
-+#ifdef CONFIG_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
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+/*
-+ * 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
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
-+#endif
-+
-+ int err;
-+
-+#ifdef CONFIG_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_PAX_EMUTRAMP
-+
-+#ifndef CONFIG_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_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_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_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);
-+
-+ do { /* PaX: gcc trampoline emulation #3 */
-+ unsigned char mov, jmp;
-+ char offset;
-+ 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-3));
-+ err |= get_user(offset, (char *)(ret-1));
-+ if (err)
-+ break;
-+
-+ if ((mov & 0xF8) == 0xB8 &&
-+ jmp == 0xE9 &&
-+ call == 0x55FF)
-+ {
-+ unsigned long addr;
-+
-+ err = get_user(addr, (unsigned long*)(regs->ebp + (unsigned long)(long)offset));
-+ if (err || regs->eip != addr)
-+ break;
-+
-+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
-+ regs->eip += addr2 + 10;
-+ return 4;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: gcc trampoline emulation #4 */
-+ unsigned char mov, jmp, sib;
-+ char offset;
-+ 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-4));
-+ err |= get_user(sib, (unsigned char *)(ret-2));
-+ err |= get_user(offset, (char *)(ret-1));
-+ if (err)
-+ break;
-+
-+ if ((mov & 0xF8) == 0xB8 &&
-+ jmp == 0xE9 &&
-+ call == 0x54FF &&
-+ sib == 0x24)
-+ {
-+ unsigned long addr;
-+
-+ err = get_user(addr, (unsigned long*)(regs->esp + 4 + (unsigned long)(long)offset));
-+ if (err || regs->eip != addr)
-+ break;
-+
-+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
-+ regs->eip += addr2 + 10;
-+ return 4;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: gcc trampoline emulation #5 */
-+ unsigned char mov, jmp, sib;
-+ unsigned long addr1, addr2, ret, offset;
-+ 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-7));
-+ err |= get_user(sib, (unsigned char *)(ret-5));
-+ err |= get_user(offset, (unsigned long *)(ret-4));
-+ if (err)
-+ break;
-+
-+ if ((mov & 0xF8) == 0xB8 &&
-+ jmp == 0xE9 &&
-+ call == 0x94FF &&
-+ sib == 0x24)
-+ {
-+ unsigned long addr;
-+
-+ err = get_user(addr, (unsigned long*)(regs->esp + 4 + offset));
-+ if (err || regs->eip != addr)
-+ break;
-+
-+ ((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_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_PAX_RANDEXEC
-+ case 5:
-+ return 0;
-+#endif
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/i386/mm/init.c linux-2.4.25-pax/arch/i386/mm/init.c
---- linux-2.4.25/arch/i386/mm/init.c 2003-06-13 10:51:29.000000000 -0400
-+++ linux-2.4.25-pax/arch/i386/mm/init.c 2004-02-19 11:12:52.000000000 -0500
-@@ -37,6 +37,7 @@
- #include <asm/e820.h>
- #include <asm/apic.h>
- #include <asm/tlb.h>
-+#include <asm/desc.h>
-
- mmu_gather_t mmu_gathers[NR_CPUS];
- unsigned long highstart_pfn, highend_pfn;
-@@ -122,7 +123,7 @@ void show_mem(void)
-
- /* 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,
-@@ -521,7 +522,7 @@ void __init mem_init(void)
- 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",
-@@ -589,6 +590,38 @@ void free_initmem(void)
- totalram_pages++;
- }
- printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
-+
-+#ifdef CONFIG_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);
-+
-+#ifdef CONFIG_PCI_BIOS
-+ printk(KERN_INFO "PAX: warning, PCI BIOS might still be in use, keeping flat KERNEL_CS.\n");
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ gdt_table2[2].a = (gdt_table2[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
-+ gdt_table2[2].b = (gdt_table2[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
-+#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 -Nurp linux-2.4.25/arch/i386/vmlinux.lds linux-2.4.25-pax/arch/i386/vmlinux.lds
---- linux-2.4.25/arch/i386/vmlinux.lds 2002-02-25 14:37:53.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/vmlinux.lds 1969-12-31 19:00:00.000000000 -0500
-@@ -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 -Nurp linux-2.4.25/arch/i386/vmlinux.lds.S linux-2.4.25-pax/arch/i386/vmlinux.lds.S
---- linux-2.4.25/arch/i386/vmlinux.lds.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.4.25-pax/arch/i386/vmlinux.lds.S 2004-02-19 11:12:52.000000000 -0500
-@@ -0,0 +1,125 @@
-+/* 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 */
-+ LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
-+ 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)
-+ *(.data.pg0)
-+ *(.data.pg1)
-+ *(.data.pg2)
-+ }
-+
-+ _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.init) }
-+ . = ALIGN(16);
-+ __setup_start = .;
-+ .setup.init : { *(.setup.init) }
-+ __setup_end = .;
-+ __initcall_start = .;
-+ .initcall.init : { *(.initcall.init) }
-+ __initcall_end = .;
-+
-+#ifdef CONFIG_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);
-+ . += __KERNEL_TEXT_OFFSET;
-+ .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_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 -Nurp linux-2.4.25/arch/ia64/config.in linux-2.4.25-pax/arch/ia64/config.in
---- linux-2.4.25/arch/ia64/config.in 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/ia64/config.in 2004-02-19 11:12:52.000000000 -0500
-@@ -319,3 +319,60 @@ fi
- int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
-
- endmenu
-+
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+# bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+# if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+# bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+# fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+ bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+# bool ' Automatically emulate ELF PLT' CONFIG_PAX_EMUPLT
-+ bool ' Allow ELF ET_EXEC text relocations' CONFIG_PAX_ETEXECRELOCS
-+ fi
-+ fi
-+ fi
-+fi
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-diff -Nurp linux-2.4.25/arch/ia64/ia32/binfmt_elf32.c linux-2.4.25-pax/arch/ia64/ia32/binfmt_elf32.c
---- linux-2.4.25/arch/ia64/ia32/binfmt_elf32.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/ia64/ia32/binfmt_elf32.c 2004-02-19 11:12:52.000000000 -0500
-@@ -51,6 +51,17 @@ static void elf32_set_personality (void)
- #undef SET_PERSONALITY
- #define SET_PERSONALITY(ex, ibcs2) elf32_set_personality()
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) IA32_PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) IA32_PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) IA32_PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
-+#endif
-+
- /* Ugly but avoids duplication */
- #include "../../../fs/binfmt_elf.c"
-
-@@ -180,8 +191,15 @@ ia32_setup_arg_pages (struct linux_binpr
- mpnt->vm_mm = current->mm;
- mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
- mpnt->vm_end = IA32_STACK_TOP;
-- mpnt->vm_page_prot = PAGE_COPY;
- mpnt->vm_flags = VM_STACK_FLAGS;
-+
-+#ifdef CONFIG_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;
- mpnt->vm_file = NULL;
-diff -Nurp linux-2.4.25/arch/ia64/ia32/sys_ia32.c linux-2.4.25-pax/arch/ia64/ia32/sys_ia32.c
---- linux-2.4.25/arch/ia64/ia32/sys_ia32.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/ia64/ia32/sys_ia32.c 2004-02-19 11:12:52.000000000 -0500
-@@ -534,6 +534,11 @@ sys32_mmap (struct mmap_arg_struct *arg)
-
- flags = a.flags;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(a.fd);
-@@ -555,6 +560,11 @@ sys32_mmap2 (unsigned int addr, unsigned
- struct file *file = NULL;
- unsigned long retval;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-diff -Nurp linux-2.4.25/arch/ia64/kernel/sys_ia64.c linux-2.4.25-pax/arch/ia64/kernel/sys_ia64.c
---- linux-2.4.25/arch/ia64/kernel/sys_ia64.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/ia64/kernel/sys_ia64.c 2004-02-19 11:12:52.000000000 -0500
-@@ -34,6 +34,13 @@ arch_get_unmapped_area (struct file *fil
- if (rgn_index(addr)==REGION_HPAGE)
- addr = 0;
- #endif
-+
-+#ifdef CONFIG_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;
-
-@@ -180,6 +187,11 @@ do_mmap2 (unsigned long addr, unsigned l
- unsigned long roff;
- struct file *file = 0;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-diff -Nurp linux-2.4.25/arch/ia64/mm/fault.c linux-2.4.25-pax/arch/ia64/mm/fault.c
---- linux-2.4.25/arch/ia64/mm/fault.c 2003-08-25 07:44:39.000000000 -0400
-+++ linux-2.4.25-pax/arch/ia64/mm/fault.c 2004-02-19 11:12:52.000000000 -0500
-@@ -70,6 +70,53 @@ mapped_kernel_page_is_present (unsigned
- return pte_present(pte);
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * PaX: decide what to do with offenders (regs->cr_iip = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+ int err;
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->cr_iip >= current->mm->start_code &&
-+ regs->cr_iip < current->mm->end_code)
-+ {
-+#if 0
-+ /* PaX: this needs fixing */
-+ if (regs->b0 == regs->cr_iip)
-+ return 1;
-+#endif
-+ regs->cr_iip += current->mm->delta_exec;
-+ return 2;
-+ }
-+ }
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 8; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned int*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- void
- ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
- {
-@@ -122,9 +169,31 @@ ia64_do_page_fault (unsigned long addres
- | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
- | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
-
-- if ((vma->vm_flags & mask) != mask)
-+ if ((vma->vm_flags & mask) != mask) {
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
-+ if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->cr_iip)
-+ goto bad_area;
-+
-+ up_read(&mm->mmap_sem);
-+ switch(pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 2:
-+ return;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
-+ do_exit(SIGKILL);
-+ }
-+#endif
-+
- goto bad_area;
-
-+ }
-+
- survive:
- /*
- * If for any reason at all we couldn't handle the fault, make
-diff -Nurp linux-2.4.25/arch/mips/config-shared.in linux-2.4.25-pax/arch/mips/config-shared.in
---- linux-2.4.25/arch/mips/config-shared.in 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/mips/config-shared.in 2004-02-19 11:12:52.000000000 -0500
-@@ -1132,5 +1132,62 @@ int 'Kernel messages buffer length shift
-
- endmenu
-
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+# bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+# if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+# bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+# fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+ bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+# bool ' Automatically emulate ELF PLT' CONFIG_PAX_EMUPLT
-+ fi
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+ if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+# if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+# bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+# fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-+
- source crypto/Config.in
- source lib/Config.in
-diff -Nurp linux-2.4.25/arch/mips/kernel/syscall.c linux-2.4.25-pax/arch/mips/kernel/syscall.c
---- linux-2.4.25/arch/mips/kernel/syscall.c 2003-08-25 07:44:40.000000000 -0400
-+++ linux-2.4.25-pax/arch/mips/kernel/syscall.c 2004-02-19 11:12:52.000000000 -0500
-@@ -82,6 +82,11 @@ unsigned long arch_get_unmapped_area(str
- do_color_align = 0;
- if (filp || (flags & MAP_SHARED))
- do_color_align = 1;
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
-+#endif
-+
- if (addr) {
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
-@@ -92,6 +97,13 @@ unsigned long arch_get_unmapped_area(str
- (!vmm || addr + len <= vmm->vm_start))
- return addr;
- }
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
-+ else
-+#endif
-+
- addr = TASK_UNMAPPED_BASE;
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
-diff -Nurp linux-2.4.25/arch/mips/mm/fault.c linux-2.4.25-pax/arch/mips/mm/fault.c
---- linux-2.4.25/arch/mips/mm/fault.c 2003-08-25 07:44:40.000000000 -0400
-+++ linux-2.4.25-pax/arch/mips/mm/fault.c 2004-02-19 11:12:53.000000000 -0500
-@@ -69,6 +69,24 @@ void bust_spinlocks(int yes)
- }
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+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,
- * and the problem, and then passes it off to one of the appropriate
-diff -Nurp linux-2.4.25/arch/mips64/kernel/binfmt_elfn32.c linux-2.4.25-pax/arch/mips64/kernel/binfmt_elfn32.c
---- linux-2.4.25/arch/mips64/kernel/binfmt_elfn32.c 2003-08-25 07:44:40.000000000 -0400
-+++ linux-2.4.25-pax/arch/mips64/kernel/binfmt_elfn32.c 2004-02-19 11:12:53.000000000 -0500
-@@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
- #undef ELF_ET_DYN_BASE
- #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#endif
-+
- #include <asm/processor.h>
- #include <linux/module.h>
- #include <linux/config.h>
-diff -Nurp linux-2.4.25/arch/mips64/kernel/binfmt_elfo32.c linux-2.4.25-pax/arch/mips64/kernel/binfmt_elfo32.c
---- linux-2.4.25/arch/mips64/kernel/binfmt_elfo32.c 2003-08-25 07:44:40.000000000 -0400
-+++ linux-2.4.25-pax/arch/mips64/kernel/binfmt_elfo32.c 2004-02-19 11:12:53.000000000 -0500
-@@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
- #undef ELF_ET_DYN_BASE
- #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#endif
-+
- #include <asm/processor.h>
- #include <linux/module.h>
- #include <linux/config.h>
-diff -Nurp linux-2.4.25/arch/mips64/kernel/syscall.c linux-2.4.25-pax/arch/mips64/kernel/syscall.c
---- linux-2.4.25/arch/mips64/kernel/syscall.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/mips64/kernel/syscall.c 2004-02-19 11:12:53.000000000 -0500
-@@ -77,6 +77,11 @@ unsigned long arch_get_unmapped_area(str
- do_color_align = 0;
- if (filp || (flags & MAP_SHARED))
- do_color_align = 1;
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
-+#endif
-+
- if (addr) {
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
-@@ -87,6 +92,13 @@ unsigned long arch_get_unmapped_area(str
- (!vmm || addr + len <= vmm->vm_start))
- return addr;
- }
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
-+ else
-+#endif
-+
- addr = TASK_UNMAPPED_BASE;
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
-diff -Nurp linux-2.4.25/arch/mips64/mm/fault.c linux-2.4.25-pax/arch/mips64/mm/fault.c
---- linux-2.4.25/arch/mips64/mm/fault.c 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/mips64/mm/fault.c 2004-02-19 11:12:53.000000000 -0500
-@@ -90,6 +90,24 @@ void bust_spinlocks(int yes)
- }
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+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,
- * and the problem, and then passes it off to one of the appropriate
-diff -Nurp linux-2.4.25/arch/parisc/config.in linux-2.4.25-pax/arch/parisc/config.in
---- linux-2.4.25/arch/parisc/config.in 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/parisc/config.in 2004-02-19 11:12:53.000000000 -0500
-@@ -202,5 +202,67 @@ int 'Kernel messages buffer length shift
-
- endmenu
-
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+ if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+ bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+ fi
-+ bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+ if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+ bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+ fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+# bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+ bool ' Automatically emulate ELF PLT' CONFIG_PAX_EMUPLT
-+ bool ' Allow ELF ET_EXEC text relocations' CONFIG_PAX_ETEXECRELOCS
-+ fi
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-+
- source crypto/Config.in
- source lib/Config.in
-diff -Nurp linux-2.4.25/arch/parisc/kernel/sys_parisc.c linux-2.4.25-pax/arch/parisc/kernel/sys_parisc.c
---- linux-2.4.25/arch/parisc/kernel/sys_parisc.c 2002-11-28 18:53:10.000000000 -0500
-+++ linux-2.4.25-pax/arch/parisc/kernel/sys_parisc.c 2004-02-19 11:12:53.000000000 -0500
-@@ -90,6 +90,11 @@ unsigned long arch_get_unmapped_area(str
- inode = filp->f_dentry->d_inode;
- }
-
-+#ifdef CONFIG_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,6 +109,12 @@ static unsigned long do_mmap2(unsigned l
- {
- struct file * file = NULL;
- unsigned long error = -EBADF;
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
-diff -Nurp linux-2.4.25/arch/parisc/kernel/sys_parisc32.c linux-2.4.25-pax/arch/parisc/kernel/sys_parisc32.c
---- linux-2.4.25/arch/parisc/kernel/sys_parisc32.c 2003-06-13 10:51:31.000000000 -0400
-+++ linux-2.4.25-pax/arch/parisc/kernel/sys_parisc32.c 2004-02-19 11:12:53.000000000 -0500
-@@ -185,6 +185,11 @@ do_execve32(char * filename, u32 * argv,
- return retval;
-
- bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+ bprm.p -= (pax_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));
-diff -Nurp linux-2.4.25/arch/parisc/kernel/traps.c linux-2.4.25-pax/arch/parisc/kernel/traps.c
---- linux-2.4.25/arch/parisc/kernel/traps.c 2003-08-25 07:44:40.000000000 -0400
-+++ linux-2.4.25-pax/arch/parisc/kernel/traps.c 2004-02-19 11:12:53.000000000 -0500
-@@ -637,9 +637,7 @@ void handle_interruption(int code, struc
-
- 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 -Nurp linux-2.4.25/arch/parisc/mm/fault.c linux-2.4.25-pax/arch/parisc/mm/fault.c
---- linux-2.4.25/arch/parisc/mm/fault.c 2003-06-13 10:51:31.000000000 -0400
-+++ linux-2.4.25-pax/arch/parisc/mm/fault.c 2004-02-19 11:12:53.000000000 -0500
-@@ -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 @@ parisc_acctyp(unsigned long code, unsign
- }
- #endif
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * 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
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+ int err;
-+
-+#ifdef CONFIG_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_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_PAX_EMUTRAMP
-+
-+#ifndef CONFIG_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 @@ good_area:
-
- 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_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_PAX_RANDEXEC
-+ case 4:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/ppc/config.in linux-2.4.25-pax/arch/ppc/config.in
---- linux-2.4.25/arch/ppc/config.in 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/ppc/config.in 2004-02-19 11:12:53.000000000 -0500
-@@ -634,3 +634,61 @@ fi
- int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
-
- endmenu
-+
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+ if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+ bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+ fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+# bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+ bool ' Automatically emulate ELF PLT' CONFIG_PAX_EMUPLT
-+ fi
-+ define_bool CONFIG_PAX_SYSCALL y
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-diff -Nurp linux-2.4.25/arch/ppc/kernel/head_4xx.S linux-2.4.25-pax/arch/ppc/kernel/head_4xx.S
---- linux-2.4.25/arch/ppc/kernel/head_4xx.S 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/ppc/kernel/head_4xx.S 2004-02-19 11:12:53.000000000 -0500
-@@ -296,15 +296,12 @@ label:
-
- /* Most of the Linux PTE is ready to load into the TLB LO.
- * We set ZSEL, where only the LS-bit determines user access.
-- * We set execute, because we don't have the granularity to
-- * properly set this at the page level (Linux problem).
- * If shared is set, we cause a zero PID->TID load.
- * Many of these bits are software only. Bits we don't set
- * here we (properly should) assume have the appropriate value.
- */
- li r22, 0x0ce2
- andc r21, r21, r22 /* Make sure 20, 21 are zero */
-- ori r21, r21, _PAGE_HWEXEC /* make it executable */
-
- /* find the TLB index that caused the fault. It has to be here.
- */
-@@ -783,7 +780,6 @@ finish_tlb_load:
- stw r23, tlb_4xx_index@l(0)
-
- 6:
-- ori r21, r21, _PAGE_HWEXEC /* make it executable */
- tlbwe r21, r23, TLB_DATA /* Load TLB LO */
-
- /* Create EPN. This is the faulting address plus a static
-diff -Nurp linux-2.4.25/arch/ppc/kernel/syscalls.c linux-2.4.25-pax/arch/ppc/kernel/syscalls.c
---- linux-2.4.25/arch/ppc/kernel/syscalls.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/ppc/kernel/syscalls.c 2004-02-19 11:12:53.000000000 -0500
-@@ -191,6 +191,11 @@ do_mmap2(unsigned long addr, size_t len,
- struct file * file = NULL;
- int ret = -EBADF;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- if (!(file = fget(fd)))
-@@ -202,7 +207,7 @@ do_mmap2(unsigned long addr, size_t len,
- goto out;
-
- down_write(&current->mm->mmap_sem);
-- ret = do_mmap_pgoff(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 -Nurp linux-2.4.25/arch/ppc/mm/fault.c linux-2.4.25-pax/arch/ppc/mm/fault.c
---- linux-2.4.25/arch/ppc/mm/fault.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/ppc/mm/fault.c 2004-02-19 11:12:53.000000000 -0500
-@@ -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 @@ extern void die_if_kernel(char *, struct
- void bad_page_fault(struct pt_regs *, unsigned long, int sig);
- void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
-
-+#ifdef CONFIG_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_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_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_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_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 @@ void do_page_fault(struct pt_regs *regs,
- * 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 || CONFIG_BOOKE */
-@@ -245,6 +602,38 @@ bad_area:
-
- /* User mode accesses cause a SIGSEGV */
- if (user_mode(regs)) {
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (current->flags & PF_PAX_PAGEEXEC) {
-+ if ((regs->trap == 0x400) && (regs->nip == address)) {
-+ switch (pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ case 4:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 5:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/sparc/config.in linux-2.4.25-pax/arch/sparc/config.in
---- linux-2.4.25/arch/sparc/config.in 2004-02-18 08:36:30.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc/config.in 2004-02-19 11:12:53.000000000 -0500
-@@ -280,5 +280,65 @@ int 'Kernel messages buffer length shift
-
- endmenu
-
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+# bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+# if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+# bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+# fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+# bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+ bool ' Automatically emulate ELF PLT' CONFIG_PAX_EMUPLT
-+ if [ "$CONFIG_PAX_EMUPLT" = "y" ]; then
-+ define_bool CONFIG_PAX_DLRESOLVE y
-+ fi
-+ fi
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-+
- source crypto/Config.in
- source lib/Config.in
-diff -Nurp linux-2.4.25/arch/sparc/kernel/sys_sparc.c linux-2.4.25-pax/arch/sparc/kernel/sys_sparc.c
---- linux-2.4.25/arch/sparc/kernel/sys_sparc.c 2003-08-25 07:44:40.000000000 -0400
-+++ linux-2.4.25-pax/arch/sparc/kernel/sys_sparc.c 2004-02-19 11:12:53.000000000 -0500
-@@ -54,6 +54,13 @@ unsigned long arch_get_unmapped_area(str
- return -ENOMEM;
- if (ARCH_SUN4C_SUN4 && len > 0x20000000)
- return -ENOMEM;
-+
-+#ifdef CONFIG_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 +232,11 @@ static unsigned long do_mmap2(unsigned l
- struct file * file = NULL;
- unsigned long retval = -EBADF;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
-diff -Nurp linux-2.4.25/arch/sparc/kernel/sys_sunos.c linux-2.4.25-pax/arch/sparc/kernel/sys_sunos.c
---- linux-2.4.25/arch/sparc/kernel/sys_sunos.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc/kernel/sys_sunos.c 2004-02-19 11:12:53.000000000 -0500
-@@ -68,6 +68,11 @@ asmlinkage unsigned long sunos_mmap(unsi
- struct file * file = NULL;
- unsigned long retval, ret_type;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if(flags & MAP_NORESERVE) {
- static int cnt;
- if (cnt++ < 10)
-diff -Nurp linux-2.4.25/arch/sparc/mm/fault.c linux-2.4.25-pax/arch/sparc/mm/fault.c
---- linux-2.4.25/arch/sparc/mm/fault.c 2003-06-13 10:51:32.000000000 -0400
-+++ linux-2.4.25-pax/arch/sparc/mm/fault.c 2004-02-19 11:12:53.000000000 -0500
-@@ -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,265 @@ asmlinkage int lookup_fault(unsigned lon
- return 0;
- }
-
-+#ifdef CONFIG_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_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_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 | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U);
-+ 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 || (ba & 0xFFF80000U) == 0x30680000U) &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned int addr, save, call;
-+
-+ if ((ba & 0xFFC00000U) == 0x30800000U)
-+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
-+ else
-+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 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 +525,29 @@ good_area:
- if(!(vma->vm_flags & VM_WRITE))
- goto bad_area;
- } else {
-+
-+#ifdef CONFIG_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_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ return;
-+#endif
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/sparc/mm/init.c linux-2.4.25-pax/arch/sparc/mm/init.c
---- linux-2.4.25/arch/sparc/mm/init.c 2002-11-28 18:53:12.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc/mm/init.c 2004-02-19 11:12:53.000000000 -0500
-@@ -350,17 +350,17 @@ void __init paging_init(void)
-
- /* 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 -Nurp linux-2.4.25/arch/sparc/mm/srmmu.c linux-2.4.25-pax/arch/sparc/mm/srmmu.c
---- linux-2.4.25/arch/sparc/mm/srmmu.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc/mm/srmmu.c 2004-02-19 11:12:53.000000000 -0500
-@@ -2047,6 +2047,13 @@ void __init ld_mmu_srmmu(void)
- 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_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 -Nurp linux-2.4.25/arch/sparc64/config.in linux-2.4.25-pax/arch/sparc64/config.in
---- linux-2.4.25/arch/sparc64/config.in 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc64/config.in 2004-02-19 11:12:53.000000000 -0500
-@@ -316,5 +316,65 @@ int 'Kernel messages buffer length shift
-
- endmenu
-
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+# bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+# if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+# bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+# fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+# bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+ bool ' Automatically emulate ELF PLT' CONFIG_PAX_EMUPLT
-+ if [ "$CONFIG_PAX_EMUPLT" = "y" ]; then
-+ define_bool CONFIG_PAX_DLRESOLVE y
-+ fi
-+ fi
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-+
- source crypto/Config.in
- source lib/Config.in
-diff -Nurp linux-2.4.25/arch/sparc64/kernel/itlb_base.S linux-2.4.25-pax/arch/sparc64/kernel/itlb_base.S
---- linux-2.4.25/arch/sparc64/kernel/itlb_base.S 2003-06-13 10:51:32.000000000 -0400
-+++ linux-2.4.25-pax/arch/sparc64/kernel/itlb_base.S 2004-02-19 11:12:53.000000000 -0500
-@@ -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 @@ winfix_trampoline:
- nop
- nop
- nop
-- nop
-- nop
- CREATE_VPTE_NOP
-
- #undef CREATE_VPTE_OFFSET1
-diff -Nurp linux-2.4.25/arch/sparc64/kernel/sys_sparc.c linux-2.4.25-pax/arch/sparc64/kernel/sys_sparc.c
---- linux-2.4.25/arch/sparc64/kernel/sys_sparc.c 2003-08-25 07:44:40.000000000 -0400
-+++ linux-2.4.25-pax/arch/sparc64/kernel/sys_sparc.c 2004-02-19 11:12:53.000000000 -0500
-@@ -63,6 +63,13 @@ unsigned long arch_get_unmapped_area(str
- task_size = 0xf0000000UL;
- if (len > task_size || len > -PAGE_OFFSET)
- return -ENOMEM;
-+
-+#ifdef CONFIG_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,6 +296,11 @@ asmlinkage unsigned long sys_mmap(unsign
- struct file * file = NULL;
- unsigned long retval = -EBADF;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
-diff -Nurp linux-2.4.25/arch/sparc64/kernel/sys_sparc32.c linux-2.4.25-pax/arch/sparc64/kernel/sys_sparc32.c
---- linux-2.4.25/arch/sparc64/kernel/sys_sparc32.c 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc64/kernel/sys_sparc32.c 2004-02-19 11:12:53.000000000 -0500
-@@ -3235,6 +3235,11 @@ do_execve32(char * filename, u32 * argv,
- int i;
-
- bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+ bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
-+#endif
-+
- memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
-
- file = open_exec(filename);
-diff -Nurp linux-2.4.25/arch/sparc64/kernel/sys_sunos32.c linux-2.4.25-pax/arch/sparc64/kernel/sys_sunos32.c
---- linux-2.4.25/arch/sparc64/kernel/sys_sunos32.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc64/kernel/sys_sunos32.c 2004-02-19 11:12:53.000000000 -0500
-@@ -68,6 +68,11 @@ asmlinkage u32 sunos_mmap(u32 addr, u32
- struct file *file = NULL;
- unsigned long retval, ret_type;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- if(flags & MAP_NORESERVE) {
- static int cnt;
- if (cnt++ < 10)
-diff -Nurp linux-2.4.25/arch/sparc64/mm/fault.c linux-2.4.25-pax/arch/sparc64/mm/fault.c
---- linux-2.4.25/arch/sparc64/mm/fault.c 2002-11-28 18:53:12.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc64/mm/fault.c 2004-02-19 11:12:53.000000000 -0500
-@@ -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,361 @@ cannot_handle:
- unhandled_fault (address, current, regs);
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_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)
-+{
-+
-+#ifdef CONFIG_PAX_EMUPLT
-+ int err;
-+#endif
-+
-+#ifdef CONFIG_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_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 | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL);
-+ 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: patched PLT emulation #4 */
-+ unsigned int mov1, call, mov2;
-+
-+ err = get_user(mov1, (unsigned int*)regs->tpc);
-+ err |= get_user(call, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
-+
-+ if (err)
-+ break;
-+
-+ if (mov1 == 0x8210000FU &&
-+ (call & 0xC0000000U) == 0x40000000U &&
-+ mov2 == 0x9E100001U)
-+ {
-+ unsigned long addr;
-+
-+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
-+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: patched PLT emulation #5 */
-+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
-+
-+ err = get_user(sethi1, (unsigned int*)regs->tpc);
-+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(or1, (unsigned int*)(regs->tpc+8));
-+ err |= get_user(or2, (unsigned int*)(regs->tpc+12));
-+ err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
-+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
-+ err |= get_user(nop, (unsigned int*)(regs->tpc+24));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
-+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
-+ (or1 & 0xFFFFE000U) == 0x82106000U &&
-+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
-+ sllx == 0x83287020 &&
-+ jmpl == 0x81C04005U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long addr;
-+
-+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
-+ regs->u_regs[UREG_G1] <<= 32;
-+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
-+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
-+ regs->tpc = addr;
-+ regs->tnpc = addr+4;
-+ return 2;
-+ }
-+ } while (0);
-+
-+ do { /* PaX: patched PLT emulation #6 */
-+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
-+
-+ err = get_user(sethi1, (unsigned int*)regs->tpc);
-+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
-+ err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
-+ err |= get_user(or, (unsigned int*)(regs->tpc+12));
-+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
-+ err |= get_user(nop, (unsigned int*)(regs->tpc+20));
-+
-+ if (err)
-+ break;
-+
-+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
-+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
-+ sllx == 0x83287020 &&
-+ (or & 0xFFFFE000U) == 0x8A116000U &&
-+ jmpl == 0x81C04005U &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long addr;
-+
-+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
-+ regs->u_regs[UREG_G1] <<= 32;
-+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
-+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
-+ 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 || (ba & 0xFFF80000U) == 0x30680000U) &&
-+ nop == 0x01000000U)
-+ {
-+ unsigned long addr;
-+ unsigned int save, call;
-+
-+ if ((ba & 0xFFC00000U) == 0x30800000U)
-+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
-+ else
-+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 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 +696,7 @@ asmlinkage void do_sparc64_fault(struct
-
- if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
- regs->tpc &= 0xffffffff;
-+ regs->tnpc &= 0xffffffff;
- address &= 0xffffffff;
- }
-
-@@ -346,6 +705,34 @@ asmlinkage void do_sparc64_fault(struct
- if (!vma)
- goto bad_area;
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ /* PaX: detect ITLB misses on non-exec pages */
-+ 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_PAX_EMUPLT
-+ case 2:
-+ case 3:
-+ goto fault_done;
-+#endif
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/arch/sparc64/solaris/misc.c linux-2.4.25-pax/arch/sparc64/solaris/misc.c
---- linux-2.4.25/arch/sparc64/solaris/misc.c 2002-11-28 18:53:12.000000000 -0500
-+++ linux-2.4.25-pax/arch/sparc64/solaris/misc.c 2004-02-19 11:12:53.000000000 -0500
-@@ -53,6 +53,11 @@ static u32 do_solaris_mmap(u32 addr, u32
- struct file *file = NULL;
- unsigned long retval, ret_type;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- /* Do we need it here? */
- set_personality(PER_SVR4);
- if (flags & MAP_NORESERVE) {
-diff -Nurp linux-2.4.25/arch/x86_64/config.in linux-2.4.25-pax/arch/x86_64/config.in
---- linux-2.4.25/arch/x86_64/config.in 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/arch/x86_64/config.in 2004-02-19 11:12:53.000000000 -0500
-@@ -251,4 +251,60 @@ int 'Kernel messages buffer length shift
-
- endmenu
-
-+mainmenu_option next_comment
-+comment 'PaX options'
-+
-+mainmenu_option next_comment
-+comment 'PaX Control'
-+bool 'Support soft mode' CONFIG_PAX_SOFTMODE
-+bool 'Use legacy ELF header marking' CONFIG_PAX_EI_PAX
-+bool 'Use ELF program header marking' CONFIG_PAX_PT_PAX_FLAGS
-+choice 'MAC system integration' \
-+ "none CONFIG_PAX_NO_ACL_FLAGS \
-+ direct CONFIG_PAX_HAVE_ACL_FLAGS \
-+ hook CONFIG_PAX_HOOK_ACL_FLAGS" none
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Non-executable pages'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Enforce non-executable pages' CONFIG_PAX_NOEXEC
-+ if [ "$CONFIG_PAX_NOEXEC" = "y" ]; then
-+ bool 'Paging based non-executable pages' CONFIG_PAX_PAGEEXEC
-+ if [ "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+# bool ' Emulate trampolines' CONFIG_PAX_EMUTRAMP
-+# if [ "$CONFIG_PAX_EMUTRAMP" = "y" ]; then
-+# bool ' Automatically emulate sigreturn trampolines' CONFIG_PAX_EMUSIGRT
-+# fi
-+ bool ' Restrict mprotect()' CONFIG_PAX_MPROTECT
-+ if [ "$CONFIG_PAX_MPROTECT" = "y" ]; then
-+ bool ' Disallow ELF text relocations' CONFIG_PAX_NOELFRELOCS
-+ fi
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+mainmenu_option next_comment
-+comment 'Address Space Layout Randomization'
-+if [ "$CONFIG_PAX_EI_PAX" = "y" -o \
-+ "$CONFIG_PAX_PT_PAX_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HAVE_ACL_FLAGS" = "y" -o \
-+ "$CONFIG_PAX_HOOK_ACL_FLAGS" = "y" ]; then
-+ bool 'Address Space Layout Randomization' CONFIG_PAX_ASLR
-+ if [ "$CONFIG_PAX_ASLR" = "y" ]; then
-+ bool ' Randomize user stack base' CONFIG_PAX_RANDUSTACK
-+ bool ' Randomize mmap() base' CONFIG_PAX_RANDMMAP
-+ if [ "$CONFIG_PAX_RANDMMAP" = "y" -a "$CONFIG_PAX_PAGEEXEC" = "y" ]; then
-+ bool ' Randomize ET_EXEC base' CONFIG_PAX_RANDEXEC
-+ fi
-+ fi
-+fi
-+endmenu
-+
-+endmenu
-+
- source lib/Config.in
-diff -Nurp linux-2.4.25/arch/x86_64/ia32/ia32_binfmt.c linux-2.4.25-pax/arch/x86_64/ia32/ia32_binfmt.c
---- linux-2.4.25/arch/x86_64/ia32/ia32_binfmt.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/x86_64/ia32/ia32_binfmt.c 2004-02-19 11:12:53.000000000 -0500
-@@ -28,7 +28,14 @@ struct elf_phdr;
-
- #define ELF_NAME "elf/i386"
-
--#define IA32_STACK_TOP IA32_PAGE_OFFSET
-+#ifdef CONFIG_PAX_RANDUSTACK
-+#define __IA32_DELTA_STACK (current->mm->delta_stack)
-+#else
-+#define __IA32_DELTA_STACK 0UL
-+#endif
-+
-+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
-+
- #define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000)
-
- #undef ELF_ARCH
-@@ -129,6 +136,17 @@ struct elf_prpsinfo
- #include <asm/ia32.h>
- #include <linux/elf.h>
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 0x08048000UL : 0x400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24)
-+#endif
-+
- typedef struct user_i387_ia32_struct elf_fpregset_t;
- typedef struct user32_fxsr_struct elf_fpxregset_t;
-
-@@ -243,7 +261,13 @@ int ia32_setup_arg_pages(struct linux_bi
- mpnt->vm_mm = current->mm;
- mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
- mpnt->vm_end = IA32_STACK_TOP;
-- mpnt->vm_flags = vm_stack_flags32;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ mpnt->vm_flags = VM_STACK_FLAGS;
-+#else
-+ mpnt->vm_flags = vm_stack_flags32;
-+#endif
-+
- mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ?
- PAGE_COPY_EXEC : PAGE_COPY;
- mpnt->vm_ops = NULL;
-diff -Nurp linux-2.4.25/arch/x86_64/ia32/sys_ia32.c linux-2.4.25-pax/arch/x86_64/ia32/sys_ia32.c
---- linux-2.4.25/arch/x86_64/ia32/sys_ia32.c 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/arch/x86_64/ia32/sys_ia32.c 2004-02-19 11:12:53.000000000 -0500
-@@ -2107,6 +2107,11 @@ asmlinkage long sys32_mmap2(unsigned lon
- unsigned long error;
- struct file * file = NULL;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ return -EINVAL;
-+#endif
-+
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
-diff -Nurp linux-2.4.25/arch/x86_64/kernel/setup64.c linux-2.4.25-pax/arch/x86_64/kernel/setup64.c
---- linux-2.4.25/arch/x86_64/kernel/setup64.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/x86_64/kernel/setup64.c 2004-02-19 11:12:53.000000000 -0500
-@@ -36,8 +36,15 @@ struct desc_ptr idt_descr = { 256 * 16,
- correct flags everywhere. */
- unsigned long __supported_pte_mask = ~0UL;
- static int do_not_nx __initdata = 0;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+unsigned long vm_stack_flags = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
-+unsigned long vm_stack_flags32 = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
-+#else
- unsigned long vm_stack_flags = __VM_STACK_FLAGS;
- unsigned long vm_stack_flags32 = __VM_STACK_FLAGS;
-+#endif
-+
- unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS;
- unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS;
- unsigned long vm_force_exec32 = PROT_EXEC;
-diff -Nurp linux-2.4.25/arch/x86_64/kernel/sys_x86_64.c linux-2.4.25-pax/arch/x86_64/kernel/sys_x86_64.c
---- linux-2.4.25/arch/x86_64/kernel/sys_x86_64.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/x86_64/kernel/sys_x86_64.c 2004-02-19 11:12:53.000000000 -0500
-@@ -46,6 +46,11 @@ long sys_mmap(unsigned long addr, unsign
- if (off & ~PAGE_MASK)
- goto out;
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (flags & MAP_MIRROR)
-+ goto out;
-+#endif
-+
- error = -EBADF;
- file = NULL;
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-@@ -72,6 +77,13 @@ unsigned long arch_get_unmapped_area(str
- unsigned long end = TASK_SIZE;
-
- if (current->thread.flags & THREAD_IA32) {
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = TASK_UNMAPPED_32 + current->mm->delta_mmap;
-+ else
-+#endif
-+
- if (!addr)
- addr = TASK_UNMAPPED_32;
- end = 0xffff0000;
-@@ -82,10 +94,24 @@ unsigned long arch_get_unmapped_area(str
- base down for this case. This may give conflicts
- with the heap, but we assume that malloc falls back
- to mmap. Give it 1GB of playground for now. -AK */
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = 0x40000000 + (current->mm->delta_mmap & 0x0FFFFFFFU);
-+ else
-+#endif
-+
- if (!addr)
- addr = 0x40000000;
- end = 0x80000000;
- } else {
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
-+ addr = TASK_UNMAPPED_64 + current->mm->delta_mmap;
-+ else
-+#endif
-+
- if (!addr)
- addr = TASK_UNMAPPED_64;
- end = TASK_SIZE;
-diff -Nurp linux-2.4.25/arch/x86_64/mm/fault.c linux-2.4.25-pax/arch/x86_64/mm/fault.c
---- linux-2.4.25/arch/x86_64/mm/fault.c 2003-11-28 13:26:19.000000000 -0500
-+++ linux-2.4.25-pax/arch/x86_64/mm/fault.c 2004-02-19 11:12:53.000000000 -0500
-@@ -173,6 +173,62 @@ static int is_prefetch(struct pt_regs *r
- return prefetch;
- }
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+/*
-+ * PaX: decide what to do with offenders (regs->rip = fault address)
-+ *
-+ * returns 1 when task should be killed
-+ * 2 when legitimate ET_EXEC was detected
-+ */
-+static int pax_handle_fetch_fault(struct pt_regs *regs)
-+{
-+ int err;
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ if (current->flags & PF_PAX_RANDEXEC) {
-+ if (regs->rip >= current->mm->start_code &&
-+ regs->rip < current->mm->end_code)
-+ {
-+ if (current->thread.flags & THREAD_IA32) {
-+ unsigned int esp_4;
-+
-+ err = get_user(esp_4, (unsigned int*)(regs->rsp-4UL));
-+ if (err || esp_4 == regs->rip)
-+ return 1;
-+ } else {
-+ unsigned long esp_8;
-+
-+ err = get_user(esp_8, (unsigned long*)(regs->rsp-8UL));
-+ if (err || esp_8 == regs->rip)
-+ return 1;
-+ }
-+
-+ regs->rip += current->mm->delta_exec;
-+ return 2;
-+ }
-+ }
-+#endif
-+
-+ return 1;
-+}
-+
-+void pax_report_insns(void *pc)
-+{
-+ unsigned long i;
-+
-+ printk(KERN_ERR "PAX: bytes at PC: ");
-+ for (i = 0; i < 20; i++) {
-+ unsigned int c;
-+ if (get_user(c, (unsigned char*)pc+i)) {
-+ printk("<invalid address>.");
-+ break;
-+ }
-+ printk("%08x ", c);
-+ }
-+ printk("\n");
-+}
-+#endif
-+
- int page_fault_trace;
- int exception_trace = 1;
-
-@@ -267,6 +323,23 @@ again:
- * we can handle it..
- */
- good_area:
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if ((current->flags & PF_PAX_PAGEEXEC) && (error_code & 16) && !(vma->vm_flags & VM_EXEC)) {
-+ up_read(&mm->mmap_sem);
-+ switch(pax_handle_fetch_fault(regs)) {
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ case 2:
-+ return;
-+#endif
-+
-+ }
-+ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
-+ do_exit(SIGKILL);
-+ }
-+#endif
-+
- info.si_code = SEGV_ACCERR;
- write = 0;
- switch (error_code & 3) {
-diff -Nurp linux-2.4.25/drivers/char/mem.c linux-2.4.25-pax/drivers/char/mem.c
---- linux-2.4.25/drivers/char/mem.c 2003-11-28 13:26:20.000000000 -0500
-+++ linux-2.4.25-pax/drivers/char/mem.c 2004-02-19 11:12:53.000000000 -0500
-@@ -402,7 +402,23 @@ static inline size_t read_zero_pagealign
- count = size;
-
- zap_page_range(mm, addr, count);
-- zeromap_page_range(addr, count, PAGE_COPY);
-+ zeromap_page_range(addr, count, vma->vm_page_prot);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if (vma->vm_flags & VM_MIRROR) {
-+ unsigned long addr_m;
-+ struct vm_area_struct * vma_m;
-+
-+ addr_m = vma->vm_start + (unsigned long)vma->vm_private_data;
-+ vma_m = find_vma(mm, addr_m);
-+ if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
-+ addr_m = addr + (unsigned long)vma->vm_private_data;
-+ zap_page_range(mm, addr_m, count);
-+ } else
-+ printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
-+ addr, vma->vm_start);
-+ }
-+#endif
-
- size -= count;
- buf += count;
-diff -Nurp linux-2.4.25/drivers/char/random.c linux-2.4.25-pax/drivers/char/random.c
---- linux-2.4.25/drivers/char/random.c 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/drivers/char/random.c 2004-02-19 11:12:53.000000000 -0500
-@@ -2310,7 +2310,27 @@ __u32 check_tcp_syn_cookie(__u32 cookie,
- }
- #endif
-
-+#ifdef CONFIG_PAX_ASLR
-+unsigned long pax_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
-
- #ifndef CONFIG_ARCH_S390
- EXPORT_SYMBOL(add_keyboard_randomness);
-diff -Nurp linux-2.4.25/fs/Makefile linux-2.4.25-pax/fs/Makefile
---- linux-2.4.25/fs/Makefile 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/fs/Makefile 2004-02-19 11:12:53.000000000 -0500
-@@ -7,7 +7,7 @@
-
- O_TARGET := fs.o
-
--export-objs := filesystems.o open.o dcache.o buffer.o dquot.o
-+export-objs := filesystems.o open.o dcache.o buffer.o dquot.o exec.o
- mod-subdirs := nls
-
- obj-y := open.o read_write.o devices.o file_table.o buffer.o \
-diff -Nurp linux-2.4.25/fs/binfmt_aout.c linux-2.4.25-pax/fs/binfmt_aout.c
---- linux-2.4.25/fs/binfmt_aout.c 2001-11-02 20:39:20.000000000 -0500
-+++ linux-2.4.25-pax/fs/binfmt_aout.c 2004-02-19 11:12:53.000000000 -0500
-@@ -307,6 +307,24 @@ static int load_aout_binary(struct linux
- current->mm->mmap = NULL;
- compute_creds(bprm);
- current->flags &= ~PF_FORKNOEXEC;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
-+ current->flags |= PF_PAX_PAGEEXEC;
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
-+ current->flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_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 +411,7 @@ static int load_aout_binary(struct linux
-
- 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 -Nurp linux-2.4.25/fs/binfmt_elf.c linux-2.4.25-pax/fs/binfmt_elf.c
---- linux-2.4.25/fs/binfmt_elf.c 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/fs/binfmt_elf.c 2004-02-19 11:12:53.000000000 -0500
-@@ -33,10 +33,12 @@
- #include <linux/smp_lock.h>
- #include <linux/compiler.h>
- #include <linux/highmem.h>
-+#include <linux/random.h>
-
- #include <asm/uaccess.h>
- #include <asm/param.h>
- #include <asm/pgalloc.h>
-+#include <asm/system.h>
-
- #define DLINFO_ITEMS 13
-
-@@ -86,6 +88,12 @@ static void set_brk(unsigned long start,
- if (end <= start)
- return;
- do_brk(start, end - start);
-+
-+#ifdef CONFIG_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
-+
- }
-
-
-@@ -414,6 +422,204 @@ out:
- return elf_entry;
- }
-
-+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
-+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (elf_phdata->p_flags & PF_PAGEEXEC)
-+ pax_flags |= PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (elf_phdata->p_flags & PF_SEGMEXEC) {
-+ pax_flags &= ~PF_PAX_PAGEEXEC;
-+ pax_flags |= PF_PAX_SEGMEXEC;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if (elf_phdata->p_flags & PF_EMUTRAMP)
-+ pax_flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if (elf_phdata->p_flags & PF_MPROTECT)
-+ pax_flags |= PF_PAX_MPROTECT;
-+#endif
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (elf_phdata->p_flags & PF_RANDMMAP)
-+ pax_flags |= PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (elf_phdata->p_flags & PF_RANDEXEC)
-+ pax_flags |= PF_PAX_RANDEXEC;
-+#endif
-+
-+ return pax_flags;
-+}
-+#endif
-+
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
-+ pax_flags |= PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC)) {
-+ pax_flags &= ~PF_PAX_PAGEEXEC;
-+ pax_flags |= PF_PAX_SEGMEXEC;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
-+ pax_flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
-+ pax_flags |= PF_PAX_MPROTECT;
-+#endif
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (!(elf_phdata->p_flags & PF_NORANDMMAP))
-+ pax_flags |= PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (!(elf_phdata->p_flags & PF_NORANDEXEC))
-+ pax_flags |= PF_PAX_RANDEXEC;
-+#endif
-+
-+ return pax_flags;
-+}
-+#endif
-+
-+#ifdef CONFIG_PAX_EI_PAX
-+static int pax_parse_ei_pax(const struct elfhdr * const elf_ex)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
-+ pax_flags |= PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
-+ pax_flags &= ~PF_PAX_PAGEEXEC;
-+ pax_flags |= PF_PAX_SEGMEXEC;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
-+ pax_flags |= PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
-+ pax_flags |= PF_PAX_MPROTECT;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
-+ pax_flags |= PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if ((elf_ex->e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex->e_type == ET_EXEC) &&
-+ (pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)))
-+ pax_flags |= PF_PAX_RANDEXEC;
-+#endif
-+
-+ return pax_flags;
-+}
-+#endif
-+
-+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
-+static int pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
-+{
-+ unsigned long pax_flags = 0UL;
-+
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+ unsigned long i;
-+#endif
-+
-+#ifdef CONFIG_PAX_EI_PAX
-+ pax_flags = pax_parse_ei_pax(elf_ex);
-+#endif
-+
-+#ifdef CONFIG_PAX_PT_PAX_FLAGS
-+ for (i = 0UL; i < elf_ex->e_phnum; i++)
-+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
-+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
-+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
-+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
-+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
-+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)) ||
-+ ((elf_phdata[i].p_flags & PF_RANDEXEC) && ((elf_phdata[i].p_flags & PF_NORANDEXEC) || elf_ex->e_type == ET_DYN)) ||
-+ (!(elf_phdata[i].p_flags & PF_NORANDEXEC) && (elf_ex->e_type == ET_DYN)))
-+ return -EINVAL;
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_softmode)
-+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
-+ else
-+#endif
-+
-+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
-+ break;
-+ }
-+#endif
-+
-+ if (0 > pax_check_flags(&pax_flags))
-+ return -EINVAL;
-+
-+ current->flags |= pax_flags;
-+ return 0;
-+}
-+#endif
-+
- /*
- * These are the functions used to load ELF style executables and shared
- * libraries. There is no binary dependent code anywhere else.
-@@ -446,7 +652,12 @@ static int load_elf_binary(struct linux_
- struct exec interp_ex;
- char passed_fileno[6];
- struct files_struct *files;
--
-+
-+#ifdef CONFIG_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);
-
-@@ -622,7 +833,44 @@ static int load_elf_binary(struct linux_
- current->mm->end_data = 0;
- current->mm->end_code = 0;
- current->mm->mmap = NULL;
-+
-+#ifdef CONFIG_PAX_ASLR
-+ current->mm->delta_mmap = 0UL;
-+ current->mm->delta_exec = 0UL;
-+ current->mm->delta_stack = 0UL;
-+#endif
-+
- current->flags &= ~PF_FORKNOEXEC;
-+
-+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
-+ if (0 > pax_parse_elf_flags(&elf_ex, elf_phdata)) {
-+ send_sig(SIGKILL, current, 0);
-+ goto out_free_dentry;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
-+ pax_set_flags(bprm);
-+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
-+ if (pax_set_flags_func)
-+ (*pax_set_flags_func)(bprm);
-+#endif
-+
-+#ifdef CONFIG_PAX_DLRESOLVE
-+ if (current->flags & PF_PAX_PAGEEXEC)
-+ current->mm->call_dl_resolve = 0UL;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+ if (current->flags & PF_PAX_RANDMMAP) {
-+#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
-+
-+ current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
-+ current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
-+ current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
-+ }
-+#endif
-+
- elf_entry = (unsigned long) elf_ex.e_entry;
-
- /* Do this so that we can load the interpreter, if need be. We will
-@@ -631,7 +879,7 @@ static int load_elf_binary(struct linux_
- retval = setup_arg_pages(bprm);
- if (retval < 0) {
- send_sig(SIGKILL, current, 0);
-- return retval;
-+ goto out_free_dentry;
- }
-
- current->mm->start_stack = bprm->p;
-@@ -678,11 +926,85 @@ static int load_elf_binary(struct linux_
- 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_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_PAX_RANDEXEC
-+ if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
-+ error = -ENOMEM;
-+
-+#ifdef CONFIG_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_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ unsigned long addr, len;
-+
-+ 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_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_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;
-@@ -693,6 +1015,11 @@ static int load_elf_binary(struct linux_
- load_addr += load_bias;
- reloc_func_desc = load_addr;
- }
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ current->mm->delta_exec = load_addr_random - load_addr;
-+#endif
-+
- }
- k = elf_ppnt->p_vaddr;
- if (k < start_code) start_code = k;
-@@ -719,6 +1046,24 @@ static int load_elf_binary(struct linux_
- start_data += load_bias;
- end_data += load_bias;
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ if (current->flags & PF_PAX_RANDMMAP)
-+ elf_brk += pax_delta_mask(pax_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,
-@@ -767,13 +1112,6 @@ static int load_elf_binary(struct linux_
- 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);
-@@ -810,6 +1148,10 @@ static int load_elf_binary(struct linux_
- ELF_PLAT_INIT(regs, reloc_func_desc);
- #endif
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ pax_switch_segments(current);
-+#endif
-+
- start_thread(regs, elf_entry, bprm->p);
- if (current->ptrace & PT_PTRACED)
- send_sig(SIGTRAP, current, 0);
-diff -Nurp linux-2.4.25/fs/exec.c linux-2.4.25-pax/fs/exec.c
---- linux-2.4.25/fs/exec.c 2004-02-18 08:36:31.000000000 -0500
-+++ linux-2.4.25-pax/fs/exec.c 2004-02-19 11:12:53.000000000 -0500
-@@ -37,6 +37,7 @@
- #include <linux/personality.h>
- #include <linux/swap.h>
- #include <linux/utsname.h>
-+#include <linux/random.h>
- #define __NO_VERSION__
- #include <linux/module.h>
-
-@@ -56,6 +57,20 @@ int core_setuid_ok = 0;
- static struct linux_binfmt *formats;
- static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
-
-+#ifdef CONFIG_PAX_SOFTMODE
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
-+unsigned int pax_aslr=1;
-+#endif
-+
-+unsigned int pax_softmode;
-+#endif
-+
-+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
-+void (*pax_set_flags_func)(struct linux_binprm * bprm);
-+EXPORT_SYMBOL(pax_set_flags_func);
-+#endif
-+
- int register_binfmt(struct linux_binfmt * fmt)
- {
- struct linux_binfmt ** tmp = &formats;
-@@ -290,8 +305,14 @@ void put_dirty_page(struct task_struct *
- struct vm_area_struct *vma;
- pgprot_t prot = PAGE_COPY;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (page_count(page) != 1 && (!(tsk->flags & PF_PAX_SEGMEXEC) || page_count(page) != 2))
-+#else
- if (page_count(page) != 1)
-+#endif
-+
- printk(KERN_ERR "mem_map disagrees with %p at %08lx\n", page, address);
-+
- pgd = pgd_offset(tsk->mm, address);
-
- spin_lock(&tsk->mm->page_table_lock);
-@@ -303,9 +324,19 @@ void put_dirty_page(struct task_struct *
- goto out;
- if (!pte_none(*pte))
- goto out;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (page_count(page) == 1) {
-+#endif
-+
- lru_cache_add(page);
- flush_dcache_page(page);
- flush_page_to_ram(page);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ }
-+#endif
-+
- /* lookup is cheap because there is only a single entry in the list */
- vma = find_vma(tsk->mm, address);
- if (vma)
-@@ -329,6 +360,10 @@ int setup_arg_pages(struct linux_binprm
- struct vm_area_struct *mpnt;
- int i;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ struct vm_area_struct *mpnt_m = NULL;
-+#endif
-+
- stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
-
- bprm->p += stack_base;
-@@ -339,13 +374,30 @@ int setup_arg_pages(struct linux_binprm
- mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
- if (!mpnt)
- return -ENOMEM;
--
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
-+ mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+ if (!mpnt_m) {
-+ kmem_cache_free(vm_area_cachep, mpnt);
-+ return -ENOMEM;
-+ }
-+ }
-+#endif
-+
- down_write(&current->mm->mmap_sem);
- {
- mpnt->vm_mm = current->mm;
- mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
- mpnt->vm_end = STACK_TOP;
- mpnt->vm_flags = VM_STACK_FLAGS;
-+
-+#ifdef CONFIG_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;
-@@ -353,6 +405,25 @@ int setup_arg_pages(struct linux_binprm
- mpnt->vm_private_data = (void *) 0;
- insert_vm_struct(current->mm, mpnt);
- current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (mpnt_m) {
-+ *mpnt_m = *mpnt;
-+ if (!(VM_STACK_FLAGS & VM_EXEC)) {
-+ mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
-+ mpnt_m->vm_page_prot = PAGE_NONE;
-+ }
-+ mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
-+ mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
-+ mpnt_m->vm_flags |= VM_MIRROR;
-+ mpnt->vm_flags |= VM_MIRROR;
-+ mpnt_m->vm_private_data = (void *)(mpnt->vm_start - mpnt_m->vm_start);
-+ mpnt->vm_private_data = (void *)(mpnt_m->vm_start - mpnt->vm_start);
-+ insert_vm_struct(current->mm, mpnt_m);
-+ current->mm->total_vm = (mpnt_m->vm_end - mpnt_m->vm_start) >> PAGE_SHIFT;
-+ }
-+#endif
-+
- }
-
- for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-@@ -360,6 +431,14 @@ int setup_arg_pages(struct linux_binprm
- if (page) {
- bprm->page[i] = NULL;
- put_dirty_page(current,page,stack_base);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (mpnt_m) {
-+ page_cache_get(page);
-+ put_dirty_page(current,page,stack_base + SEGMEXEC_TASK_SIZE);
-+ }
-+#endif
-+
- }
- stack_base += PAGE_SIZE;
- }
-@@ -615,6 +694,30 @@ int flush_old_exec(struct linux_binprm *
- }
- current->comm[i] = '\0';
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ current->flags &= ~PF_PAX_PAGEEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ current->flags &= ~PF_PAX_EMUTRAMP;
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ current->flags &= ~PF_PAX_MPROTECT;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+ current->flags &= ~PF_PAX_RANDMMAP;
-+#endif
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ current->flags &= ~PF_PAX_RANDEXEC;
-+#endif
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ current->flags &= ~PF_PAX_SEGMEXEC;
-+#endif
-+
- flush_thread();
-
- de_thread(current);
-@@ -920,6 +1023,16 @@ int do_execve(char * filename, char ** a
- return retval;
-
- bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ if (pax_aslr)
-+#endif
-+
-+ bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
-+#endif
-+
- memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
-
- bprm.file = file;
-@@ -1102,6 +1215,123 @@ void format_corename(char *corename, con
- *out_ptr = 0;
- }
-
-+int pax_check_flags(unsigned long * flags)
-+{
-+ int retval = 0;
-+
-+#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
-+ if (*flags & PF_PAX_SEGMEXEC)
-+ {
-+ *flags &= ~PF_PAX_SEGMEXEC;
-+ retval = -EINVAL;
-+ }
-+#endif
-+
-+ if ((*flags & PF_PAX_PAGEEXEC)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+ && (*flags & PF_PAX_SEGMEXEC)
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_PAGEEXEC;
-+ retval = -EINVAL;
-+ }
-+
-+ if ((*flags & PF_PAX_MPROTECT)
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_MPROTECT;
-+ retval = -EINVAL;
-+ }
-+
-+ if ((*flags & PF_PAX_EMUTRAMP)
-+
-+#ifdef CONFIG_PAX_EMUTRAMP
-+ && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_EMUTRAMP;
-+ retval = -EINVAL;
-+ }
-+
-+ if ((*flags & PF_PAX_RANDEXEC)
-+
-+#ifdef CONFIG_PAX_RANDEXEC
-+ && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
-+#endif
-+
-+ )
-+ {
-+ *flags &= ~PF_PAX_RANDEXEC;
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+EXPORT_SYMBOL(pax_check_flags);
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_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_exec = (char*)__get_free_page(GFP_ATOMIC);
-+ char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
-+ char* path_exec=NULL;
-+ char* path_fault=NULL;
-+ unsigned long start=0UL, end=0UL, offset=0UL;
-+
-+ if (buffer_exec && buffer_fault) {
-+ struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
-+
-+ down_read(&mm->mmap_sem);
-+ vma = mm->mmap;
-+ while (vma && (!vma_exec || !vma_fault)) {
-+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
-+ vma_exec = vma;
-+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
-+ vma_fault = vma;
-+ vma = vma->vm_next;
-+ }
-+ if (vma_exec) {
-+ path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
-+ if (IS_ERR(path_exec))
-+ path_exec = "<path too long>";
-+ }
-+ if (vma_fault) {
-+ start = vma_fault->vm_start;
-+ end = vma_fault->vm_end;
-+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
-+ if (vma_fault->vm_file) {
-+ path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
-+ if (IS_ERR(path_fault))
-+ path_fault = "<path too long>";
-+ } else
-+ path_fault = "<anonymous mapping>";
-+ }
-+ up_read(&mm->mmap_sem);
-+ }
-+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
-+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
-+ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
-+ tsk->uid, tsk->euid, pc, sp);
-+ if (buffer_exec) free_page((unsigned long)buffer_exec);
-+ if (buffer_fault) free_page((unsigned long)buffer_fault);
-+ pax_report_insns(pc);
-+ do_coredump(SIGKILL, regs);
-+}
-+#endif
-+
- int do_coredump(long signr, struct pt_regs * regs)
- {
- struct linux_binfmt * binfmt;
-diff -Nurp linux-2.4.25/fs/proc/array.c linux-2.4.25-pax/fs/proc/array.c
---- linux-2.4.25/fs/proc/array.c 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/fs/proc/array.c 2004-02-19 11:12:53.000000000 -0500
-@@ -530,9 +530,17 @@ static int show_map(struct seq_file *m,
- seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
- map->vm_start,
- map->vm_end,
-+
-+#if 1
-+ flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
-+ flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
-+ flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
-+#else
- flags & VM_READ ? 'r' : '-',
- flags & VM_WRITE ? 'w' : '-',
- flags & VM_EXEC ? 'x' : '-',
-+#endif
-+
- flags & VM_MAYSHARE ? 's' : 'p',
- map->vm_pgoff << PAGE_SHIFT,
- MAJOR(dev), MINOR(dev), ino, &len);
-diff -Nurp linux-2.4.25/include/asm-alpha/a.out.h linux-2.4.25-pax/include/asm-alpha/a.out.h
---- linux-2.4.25/include/asm-alpha/a.out.h 2002-08-02 20:39:45.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-alpha/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -98,7 +98,7 @@ struct exec
- 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 -Nurp linux-2.4.25/include/asm-alpha/elf.h linux-2.4.25-pax/include/asm-alpha/elf.h
---- linux-2.4.25/include/asm-alpha/elf.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-alpha/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -41,6 +41,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
-
- #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-alpha/mman.h linux-2.4.25-pax/include/asm-alpha/mman.h
---- linux-2.4.25/include/asm-alpha/mman.h 2000-03-16 17:07:09.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-alpha/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -24,6 +24,10 @@
- #define MAP_LOCKED 0x8000 /* lock the mapping */
- #define MAP_NORESERVE 0x10000 /* don't check for reservations */
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-alpha/page.h linux-2.4.25-pax/include/asm-alpha/page.h
---- linux-2.4.25/include/asm-alpha/page.h 2002-08-02 20:39:45.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-alpha/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -101,6 +101,15 @@ extern __inline__ int get_order(unsigned
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _ALPHA_PAGE_H */
-diff -Nurp linux-2.4.25/include/asm-alpha/pgtable.h linux-2.4.25-pax/include/asm-alpha/pgtable.h
---- linux-2.4.25/include/asm-alpha/pgtable.h 2002-08-02 20:39:45.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-alpha/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -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_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 -Nurp linux-2.4.25/include/asm-i386/a.out.h linux-2.4.25-pax/include/asm-i386/a.out.h
---- linux-2.4.25/include/asm-i386/a.out.h 1995-06-16 14:33:06.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-i386/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -19,7 +19,11 @@ struct exec
-
- #ifdef __KERNEL__
-
--#define STACK_TOP TASK_SIZE
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
-+#else
-+#define __STACK_TOP TASK_SIZE
-+#endif
-
- #endif
-
-diff -Nurp linux-2.4.25/include/asm-i386/desc.h linux-2.4.25-pax/include/asm-i386/desc.h
---- linux-2.4.25/include/asm-i386/desc.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-i386/desc.h 2004-02-19 11:12:53.000000000 -0500
-@@ -46,7 +46,8 @@ struct desc_struct {
- };
-
- 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 @@ struct Xgt_desc_struct {
-
- #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))
-
-@@ -64,10 +66,11 @@ struct Xgt_desc_struct {
- * This is the ldt that every process will get unless we need
- * something other than this.
- */
--extern struct desc_struct default_ldt[];
-+extern const 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_tss_desc(unsigned int n, void *addr);
-+extern void set_ldt_desc(unsigned int n, const void *addr, unsigned int size);
-+extern void __set_ldt_desc(unsigned int n, const void *addr, unsigned int size);
-+extern void set_tss_desc(unsigned int n, const void *addr);
-
- static inline void clear_LDT(void)
- {
-@@ -82,7 +85,7 @@ static inline void clear_LDT(void)
- static inline void load_LDT (mm_context_t *pc)
- {
- int cpu = smp_processor_id();
-- void *segments = pc->ldt;
-+ const void *segments = pc->ldt;
- int count = pc->size;
-
- if (!count) {
-@@ -94,6 +97,21 @@ static inline void load_LDT (mm_context_
- __load_LDT(cpu);
- }
-
-+static inline void _load_LDT (mm_context_t *pc)
-+{
-+ int cpu = smp_processor_id();
-+ const void *segments = pc->ldt;
-+ int count = pc->size;
-+
-+ if (!count) {
-+ segments = &default_ldt[0];
-+ count = 5;
-+ }
-+
-+ __set_ldt_desc(cpu, segments, count);
-+ __load_LDT(cpu);
-+}
-+
- #endif /* !__ASSEMBLY__ */
-
- #endif
-diff -Nurp linux-2.4.25/include/asm-i386/elf.h linux-2.4.25-pax/include/asm-i386/elf.h
---- linux-2.4.25/include/asm-i386/elf.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-i386/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -55,7 +55,22 @@ typedef struct user_fxsr_struct elf_fpxr
- 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_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_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 -Nurp linux-2.4.25/include/asm-i386/hw_irq.h linux-2.4.25-pax/include/asm-i386/hw_irq.h
---- linux-2.4.25/include/asm-i386/hw_irq.h 2003-08-25 07:44:43.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-i386/hw_irq.h 2004-02-19 11:12:53.000000000 -0500
-@@ -128,6 +128,7 @@ extern char _stext, _etext;
- 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 @@ SYMBOL_NAME_STR(x) ":\n\t" \
- 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 @@ SYMBOL_NAME_STR(x) ":\n\t" \
- #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 @@ __asm__( \
- #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 -Nurp linux-2.4.25/include/asm-i386/mman.h linux-2.4.25-pax/include/asm-i386/mman.h
---- linux-2.4.25/include/asm-i386/mman.h 2000-03-14 20:45:20.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-i386/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -18,6 +18,10 @@
- #define MAP_LOCKED 0x2000 /* pages are locked */
- #define MAP_NORESERVE 0x4000 /* don't check for reservations */
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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 -Nurp linux-2.4.25/include/asm-i386/page.h linux-2.4.25-pax/include/asm-i386/page.h
---- linux-2.4.25/include/asm-i386/page.h 2002-08-02 20:39:45.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-i386/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -80,6 +80,12 @@ typedef struct { unsigned long pgprot; }
-
- #define __PAGE_OFFSET (0xC0000000)
-
-+#ifdef CONFIG_PAX_KERNEXEC
-+#define __KERNEL_TEXT_OFFSET (0xC0400000)
-+#else
-+#define __KERNEL_TEXT_OFFSET (0)
-+#endif
-+
- /*
- * This much address space is reserved for vmalloc() and iomap()
- * as well as fixmap mappings.
-@@ -137,6 +143,15 @@ static __inline__ int get_order(unsigned
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __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_MAYEXEC | ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _I386_PAGE_H */
-diff -Nurp linux-2.4.25/include/asm-i386/pgtable.h linux-2.4.25-pax/include/asm-i386/pgtable.h
---- linux-2.4.25/include/asm-i386/pgtable.h 2002-11-28 18:53:15.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-i386/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -205,6 +205,16 @@ extern void pgtable_cache_init(void);
- #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
- #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-
-+#ifdef CONFIG_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 @@ extern void pgtable_cache_init(void);
- * 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 @@ static inline pte_t pte_modify(pte_t pte
- ((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 -Nurp linux-2.4.25/include/asm-i386/processor.h linux-2.4.25-pax/include/asm-i386/processor.h
---- linux-2.4.25/include/asm-i386/processor.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-i386/processor.h 2004-02-19 11:12:53.000000000 -0500
-@@ -261,10 +261,19 @@ extern unsigned int mca_pentium_flag;
- */
- #define TASK_SIZE (PAGE_OFFSET)
-
-+#ifdef CONFIG_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_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 -Nurp linux-2.4.25/include/asm-i386/system.h linux-2.4.25-pax/include/asm-i386/system.h
---- linux-2.4.25/include/asm-i386/system.h 2003-08-25 07:44:43.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-i386/system.h 2004-02-19 11:12:53.000000000 -0500
-@@ -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 prepare_to_switch() do { } while(0)
- #define switch_to(prev,next,last) do { \
- asm volatile("pushl %%esi\n\t" \
-diff -Nurp linux-2.4.25/include/asm-ia64/elf.h linux-2.4.25-pax/include/asm-ia64/elf.h
---- linux-2.4.25/include/asm-ia64/elf.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ia64/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -41,6 +41,16 @@
- */
- #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
-+#endif
-
- /*
- * We use (abuse?) this macro to insert the (empty) vm_area that is
-diff -Nurp linux-2.4.25/include/asm-ia64/ia32.h linux-2.4.25-pax/include/asm-ia64/ia32.h
---- linux-2.4.25/include/asm-ia64/ia32.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ia64/ia32.h 2004-02-19 11:12:53.000000000 -0500
-@@ -367,7 +367,14 @@ struct old_linux32_dirent {
- #define ELF_ARCH EM_386
-
- #define IA32_PAGE_OFFSET 0xc0000000
--#define IA32_STACK_TOP IA32_PAGE_OFFSET
-+
-+#ifdef CONFIG_PAX_RANDUSTACK
-+#define __IA32_DELTA_STACK (current->mm->delta_stack)
-+#else
-+#define __IA32_DELTA_STACK 0UL
-+#endif
-+
-+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
-
- /*
- * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
-diff -Nurp linux-2.4.25/include/asm-ia64/mman.h linux-2.4.25-pax/include/asm-ia64/mman.h
---- linux-2.4.25/include/asm-ia64/mman.h 2001-01-04 15:50:17.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ia64/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -26,6 +26,10 @@
- #define MAP_WRITECOMBINED 0x10000 /* write-combine the area */
- #define MAP_NONCACHED 0x20000 /* don't cache the memory */
-
-+#ifdef CONFIG_PAX_RANDEXEC
-+#define MAP_MIRROR 0x40000
-+#endif
-+
- #define MS_ASYNC 1 /* sync memory asynchronously */
- #define MS_INVALIDATE 2 /* invalidate the caches */
- #define MS_SYNC 4 /* synchronous memory sync */
-diff -Nurp linux-2.4.25/include/asm-ia64/page.h linux-2.4.25-pax/include/asm-ia64/page.h
---- linux-2.4.25/include/asm-ia64/page.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ia64/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -184,4 +184,13 @@ get_order (unsigned long size)
- (((current->thread.flags & IA64_THREAD_XSTACK) != 0) \
- ? VM_EXEC : 0))
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* _ASM_IA64_PAGE_H */
-diff -Nurp linux-2.4.25/include/asm-ia64/pgtable.h linux-2.4.25-pax/include/asm-ia64/pgtable.h
---- linux-2.4.25/include/asm-ia64/pgtable.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ia64/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -114,6 +114,17 @@
- #define PAGE_SHARED __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
- #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
- #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
-+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
-+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
-+#else
-+# define PAGE_SHARED_NOEXEC PAGE_SHARED
-+# define PAGE_READONLY_NOEXEC PAGE_READONLY
-+# define PAGE_COPY_NOEXEC PAGE_COPY
-+#endif
-+
- #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
- #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
- #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
-diff -Nurp linux-2.4.25/include/asm-ia64/ustack.h linux-2.4.25-pax/include/asm-ia64/ustack.h
---- linux-2.4.25/include/asm-ia64/ustack.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ia64/ustack.h 2004-02-19 11:12:53.000000000 -0500
-@@ -11,6 +11,6 @@
- #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
- /* Make a default stack size of 2GB */
- #define DEFAULT_USER_STACK_SIZE (1UL << 31)
--#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
-+#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
-
- #endif /* _ASM_IA64_USTACK_H */
-diff -Nurp linux-2.4.25/include/asm-mips/a.out.h linux-2.4.25-pax/include/asm-mips/a.out.h
---- linux-2.4.25/include/asm-mips/a.out.h 1995-12-13 05:39:45.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-mips/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -19,7 +19,7 @@ struct exec
-
- #ifdef __KERNEL__
-
--#define STACK_TOP TASK_SIZE
-+#define __STACK_TOP TASK_SIZE
-
- #endif
-
-diff -Nurp linux-2.4.25/include/asm-mips/elf.h linux-2.4.25-pax/include/asm-mips/elf.h
---- linux-2.4.25/include/asm-mips/elf.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-mips/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -107,6 +107,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
-
- #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) 0x00400000UL
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (27 - PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (27 - PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (27 - PAGE_SHIFT)
-+#endif
-+
- #ifdef __KERNEL__
- #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
- #endif
-diff -Nurp linux-2.4.25/include/asm-mips/page.h linux-2.4.25-pax/include/asm-mips/page.h
---- linux-2.4.25/include/asm-mips/page.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-mips/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -135,6 +135,15 @@ static __inline__ int get_order(unsigned
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
- #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
-
-diff -Nurp linux-2.4.25/include/asm-mips64/a.out.h linux-2.4.25-pax/include/asm-mips64/a.out.h
---- linux-2.4.25/include/asm-mips64/a.out.h 2003-08-25 07:44:44.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-mips64/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -26,7 +26,7 @@ struct exec
-
- #ifdef __KERNEL__
-
--#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
-+#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
-
- #endif
-
-diff -Nurp linux-2.4.25/include/asm-mips64/elf.h linux-2.4.25-pax/include/asm-mips64/elf.h
---- linux-2.4.25/include/asm-mips64/elf.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-mips64/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -107,6 +107,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
- #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
- #endif
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
-+#endif
-+
- #ifdef __KERNEL__
- #define SET_PERSONALITY(ex, ibcs2) \
- do { current->thread.mflags &= ~MF_ABI_MASK; \
-diff -Nurp linux-2.4.25/include/asm-mips64/page.h linux-2.4.25-pax/include/asm-mips64/page.h
---- linux-2.4.25/include/asm-mips64/page.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-mips64/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -148,6 +148,15 @@ static __inline__ int get_order(unsigned
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* defined (__KERNEL__) */
-
- #endif /* _ASM_PAGE_H */
-diff -Nurp linux-2.4.25/include/asm-parisc/a.out.h linux-2.4.25-pax/include/asm-parisc/a.out.h
---- linux-2.4.25/include/asm-parisc/a.out.h 2000-12-05 15:29:39.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-parisc/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -22,7 +22,7 @@ struct exec
- /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
- * prumpf */
-
--#define STACK_TOP TASK_SIZE
-+#define __STACK_TOP TASK_SIZE
-
- #endif
-
-diff -Nurp linux-2.4.25/include/asm-parisc/elf.h linux-2.4.25-pax/include/asm-parisc/elf.h
---- linux-2.4.25/include/asm-parisc/elf.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-parisc/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -135,6 +135,17 @@ struct pt_regs; /* forward declaration..
-
- #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-parisc/mman.h linux-2.4.25-pax/include/asm-parisc/mman.h
---- linux-2.4.25/include/asm-parisc/mman.h 2000-12-05 15:29:39.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-parisc/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -18,6 +18,10 @@
- #define MAP_NORESERVE 0x4000 /* don't check for reservations */
- #define MAP_GROWSDOWN 0x8000 /* stack-like segment */
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-parisc/page.h linux-2.4.25-pax/include/asm-parisc/page.h
---- linux-2.4.25/include/asm-parisc/page.h 2002-11-28 18:53:15.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-parisc/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -117,6 +117,15 @@ extern int npmem_ranges;
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _PARISC_PAGE_H */
-diff -Nurp linux-2.4.25/include/asm-parisc/pgtable.h linux-2.4.25-pax/include/asm-parisc/pgtable.h
---- linux-2.4.25/include/asm-parisc/pgtable.h 2003-06-13 10:51:38.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-parisc/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -167,6 +167,17 @@ extern void *vmalloc_start;
- #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_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 -Nurp linux-2.4.25/include/asm-ppc/a.out.h linux-2.4.25-pax/include/asm-ppc/a.out.h
---- linux-2.4.25/include/asm-ppc/a.out.h 2003-08-25 07:44:44.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-ppc/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -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 -Nurp linux-2.4.25/include/asm-ppc/elf.h linux-2.4.25-pax/include/asm-ppc/elf.h
---- linux-2.4.25/include/asm-ppc/elf.h 2003-06-13 10:51:38.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-ppc/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -46,6 +46,17 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
-
- #define ELF_ET_DYN_BASE (0x08000000)
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-ppc/mman.h linux-2.4.25-pax/include/asm-ppc/mman.h
---- linux-2.4.25/include/asm-ppc/mman.h 2003-06-13 10:51:38.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-ppc/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -19,6 +19,10 @@
- #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
- #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-ppc/page.h linux-2.4.25-pax/include/asm-ppc/page.h
---- linux-2.4.25/include/asm-ppc/page.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ppc/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -171,5 +171,14 @@ extern __inline__ int get_order(unsigned
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
- #endif /* _PPC_PAGE_H */
-diff -Nurp linux-2.4.25/include/asm-ppc/pgtable.h linux-2.4.25-pax/include/asm-ppc/pgtable.h
---- linux-2.4.25/include/asm-ppc/pgtable.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-ppc/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -394,11 +394,21 @@ extern unsigned long vmalloc_start;
-
- #define PAGE_NONE __pgprot(_PAGE_BASE)
- #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
--#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
- #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
--#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
-+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
- #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
--#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
-+
-+#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
-+# 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)
-@@ -411,21 +421,21 @@ extern unsigned long vmalloc_start;
- * 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 -Nurp linux-2.4.25/include/asm-sparc/a.out.h linux-2.4.25-pax/include/asm-sparc/a.out.h
---- linux-2.4.25/include/asm-sparc/a.out.h 2000-01-13 15:03:00.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-sparc/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -91,7 +91,7 @@ struct relocation_info /* used when head
-
- #include <asm/page.h>
-
--#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
-+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
-
- #endif /* __KERNEL__ */
-
-diff -Nurp linux-2.4.25/include/asm-sparc/elf.h linux-2.4.25-pax/include/asm-sparc/elf.h
---- linux-2.4.25/include/asm-sparc/elf.h 2000-07-11 22:02:37.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -83,6 +83,17 @@ typedef struct {
-
- #define ELF_ET_DYN_BASE (0x08000000)
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-sparc/mman.h linux-2.4.25-pax/include/asm-sparc/mman.h
---- linux-2.4.25/include/asm-sparc/mman.h 2003-06-13 10:51:38.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -24,6 +24,10 @@
- #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
- #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-sparc/page.h linux-2.4.25-pax/include/asm-sparc/page.h
---- linux-2.4.25/include/asm-sparc/page.h 2002-08-02 20:39:45.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -182,6 +182,15 @@ extern __inline__ int get_order(unsigned
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif /* _SPARC_PAGE_H */
-diff -Nurp linux-2.4.25/include/asm-sparc/pgtable.h linux-2.4.25-pax/include/asm-sparc/pgtable.h
---- linux-2.4.25/include/asm-sparc/pgtable.h 2002-08-02 20:39:45.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -97,6 +97,13 @@ BTFIXUPDEF_INT(page_none)
- BTFIXUPDEF_INT(page_shared)
- BTFIXUPDEF_INT(page_copy)
- BTFIXUPDEF_INT(page_readonly)
-+
-+#ifdef CONFIG_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 @@ BTFIXUPDEF_INT(page_kernel)
- #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
- #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-sparc/pgtsrmmu.h linux-2.4.25-pax/include/asm-sparc/pgtsrmmu.h
---- linux-2.4.25/include/asm-sparc/pgtsrmmu.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-sparc/pgtsrmmu.h 2004-02-19 11:12:53.000000000 -0500
-@@ -76,6 +76,16 @@
- SRMMU_EXEC | SRMMU_REF)
- #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
- SRMMU_EXEC | SRMMU_REF)
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-sparc/uaccess.h linux-2.4.25-pax/include/asm-sparc/uaccess.h
---- linux-2.4.25/include/asm-sparc/uaccess.h 2003-06-13 10:51:38.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc/uaccess.h 2004-02-19 11:12:53.000000000 -0500
-@@ -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 -Nurp linux-2.4.25/include/asm-sparc64/a.out.h linux-2.4.25-pax/include/asm-sparc64/a.out.h
---- linux-2.4.25/include/asm-sparc64/a.out.h 2001-04-27 01:17:26.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc64/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -95,7 +95,7 @@ struct relocation_info /* used when head
-
- #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 -Nurp linux-2.4.25/include/asm-sparc64/elf.h linux-2.4.25-pax/include/asm-sparc64/elf.h
---- linux-2.4.25/include/asm-sparc64/elf.h 2003-06-13 10:51:38.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc64/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -82,6 +82,16 @@ typedef struct {
- #define ELF_ET_DYN_BASE 0x0000010000000000UL
- #endif
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-sparc64/mman.h linux-2.4.25-pax/include/asm-sparc64/mman.h
---- linux-2.4.25/include/asm-sparc64/mman.h 2003-06-13 10:51:38.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc64/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -24,6 +24,10 @@
- #define MAP_DENYWRITE 0x0800 /* ETXTBSY */
- #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-sparc64/page.h linux-2.4.25-pax/include/asm-sparc64/page.h
---- linux-2.4.25/include/asm-sparc64/page.h 2003-08-25 07:44:44.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc64/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -160,6 +160,15 @@ extern __inline__ int get_order(unsigned
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#endif
-+
- #endif /* !(__KERNEL__) */
-
- #endif /* !(_SPARC64_PAGE_H) */
-diff -Nurp linux-2.4.25/include/asm-sparc64/pgtable.h linux-2.4.25-pax/include/asm-sparc64/pgtable.h
---- linux-2.4.25/include/asm-sparc64/pgtable.h 2002-08-02 20:39:45.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-sparc64/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -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_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 -Nurp linux-2.4.25/include/asm-x86_64/a.out.h linux-2.4.25-pax/include/asm-x86_64/a.out.h
---- linux-2.4.25/include/asm-x86_64/a.out.h 2002-11-28 18:53:15.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-x86_64/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -23,7 +23,7 @@ struct exec
-
- #ifdef __KERNEL__
-
--#define STACK_TOP TASK_SIZE
-+#define __STACK_TOP TASK_SIZE
-
- #endif
-
-diff -Nurp linux-2.4.25/include/asm-x86_64/elf.h linux-2.4.25-pax/include/asm-x86_64/elf.h
---- linux-2.4.25/include/asm-x86_64/elf.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-x86_64/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -68,6 +68,17 @@ typedef struct user_fxsr_struct elf_fpxr
-
- #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
-
-+#ifdef CONFIG_PAX_ASLR
-+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 0x08048000UL : 0x400000UL)
-+
-+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24)
-+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24)
-+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
-+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->thread.flags & THREAD_IA32 ? 16 : 24)
-+#endif
-+
- /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
- now struct_user_regs, they are different). Assumes current is the process
- getting dumped. */
-diff -Nurp linux-2.4.25/include/asm-x86_64/mman.h linux-2.4.25-pax/include/asm-x86_64/mman.h
---- linux-2.4.25/include/asm-x86_64/mman.h 2002-11-28 18:53:15.000000000 -0500
-+++ linux-2.4.25-pax/include/asm-x86_64/mman.h 2004-02-19 11:12:53.000000000 -0500
-@@ -19,6 +19,10 @@
- #define MAP_LOCKED 0x2000 /* pages are locked */
- #define MAP_NORESERVE 0x4000 /* don't check for reservations */
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/include/asm-x86_64/page.h linux-2.4.25-pax/include/asm-x86_64/page.h
---- linux-2.4.25/include/asm-x86_64/page.h 2003-08-25 07:44:44.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-x86_64/page.h 2004-02-19 11:12:53.000000000 -0500
-@@ -142,6 +142,16 @@ extern __inline__ int get_order(unsigned
-
- #define __VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-+
-+#ifdef CONFIG_PAX_PAGEEXEC
-+#define VM_DATA_DEFAULT_FLAGS __VM_DATA_DEFAULT_FLAGS
-+#ifdef CONFIG_PAX_MPROTECT
-+#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
-+ ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#else
-+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
-+#endif
-+#else
- #define __VM_STACK_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-@@ -149,6 +159,7 @@ extern __inline__ int get_order(unsigned
- ((current->thread.flags & THREAD_IA32) ? vm_data_default_flags32 : \
- vm_data_default_flags)
- #define VM_STACK_FLAGS vm_stack_flags
-+#endif
-
- #endif /* __KERNEL__ */
-
-diff -Nurp linux-2.4.25/include/asm-x86_64/pgtable.h linux-2.4.25-pax/include/asm-x86_64/pgtable.h
---- linux-2.4.25/include/asm-x86_64/pgtable.h 2003-08-25 07:44:44.000000000 -0400
-+++ linux-2.4.25-pax/include/asm-x86_64/pgtable.h 2004-02-19 11:12:53.000000000 -0500
-@@ -240,6 +240,8 @@ extern inline void pgd_clear (pgd_t * pg
- __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
- #define PAGE_EXECONLY PAGE_READONLY_EXEC
-
-+#define PAGE_READONLY_NOEXEC PAGE_READONLY
-+
- #define PAGE_LARGE (_PAGE_PSE|_PAGE_PRESENT)
-
- #define __PAGE_KERNEL \
-diff -Nurp linux-2.4.25/include/linux/a.out.h linux-2.4.25-pax/include/linux/a.out.h
---- linux-2.4.25/include/linux/a.out.h 2001-11-22 14:46:18.000000000 -0500
-+++ linux-2.4.25-pax/include/linux/a.out.h 2004-02-19 11:12:53.000000000 -0500
-@@ -7,6 +7,16 @@
-
- #include <asm/a.out.h>
-
-+#ifdef CONFIG_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 @@ enum machine_type {
- 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 -Nurp linux-2.4.25/include/linux/binfmts.h linux-2.4.25-pax/include/linux/binfmts.h
---- linux-2.4.25/include/linux/binfmts.h 2001-11-22 14:46:19.000000000 -0500
-+++ linux-2.4.25-pax/include/linux/binfmts.h 2004-02-19 11:12:53.000000000 -0500
-@@ -59,6 +59,8 @@ extern void compute_creds(struct linux_b
- 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 -Nurp linux-2.4.25/include/linux/elf.h linux-2.4.25-pax/include/linux/elf.h
---- linux-2.4.25/include/linux/elf.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/linux/elf.h 2004-02-19 11:12:53.000000000 -0500
-@@ -34,6 +34,10 @@ typedef __s64 Elf64_Sxword;
- #define PT_MIPS_REGINFO 0x70000000
- #define PT_MIPS_OPTIONS 0x70000001
-
-+#define PT_LOOS 0x60000000
-+#define PT_GNU_STACK (PT_LOOS + 0x474e551)
-+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
-+
- /* Flags in the e_flags field of the header */
- #define EF_MIPS_NOREORDER 0x00000001
- #define EF_MIPS_PIC 0x00000002
-@@ -44,6 +48,14 @@ typedef __s64 Elf64_Sxword;
- #define EF_MIPS_ABI 0x0000f000
- #define EF_MIPS_ARCH 0xf0000000
-
-+/* 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 */
-+
- /* These constants define the different elf file types */
- #define ET_NONE 0
- #define ET_REL 1
-@@ -122,6 +134,8 @@ typedef __s64 Elf64_Sxword;
- #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
-@@ -458,6 +472,19 @@ typedef struct elf64_hdr {
- #define PF_W 0x2
- #define PF_X 0x1
-
-+#define PF_PAGEEXEC (1 << 4) /* Enable PAGEEXEC */
-+#define PF_NOPAGEEXEC (1 << 5) /* Disable PAGEEXEC */
-+#define PF_SEGMEXEC (1 << 6) /* Enable SEGMEXEC */
-+#define PF_NOSEGMEXEC (1 << 7) /* Disable SEGMEXEC */
-+#define PF_MPROTECT (1 << 8) /* Enable MPROTECT */
-+#define PF_NOMPROTECT (1 << 9) /* Disable MPROTECT */
-+#define PF_RANDEXEC (1 << 10) /* Enable RANDEXEC */
-+#define PF_NORANDEXEC (1 << 11) /* Disable RANDEXEC */
-+#define PF_EMUTRAMP (1 << 12) /* Enable EMUTRAMP */
-+#define PF_NOEMUTRAMP (1 << 13) /* Disable EMUTRAMP */
-+#define PF_RANDMMAP (1 << 14) /* Enable RANDMMAP */
-+#define PF_NORANDMMAP (1 << 15) /* Disable RANDMMAP */
-+
- typedef struct elf32_phdr{
- Elf32_Word p_type;
- Elf32_Off p_offset;
-@@ -555,6 +582,8 @@ typedef struct elf64_shdr {
- #define EI_VERSION 6
- #define EI_PAD 7
-
-+#define EI_PAX 14
-+
- #define ELFMAG0 0x7f /* EI_MAG */
- #define ELFMAG1 'E'
- #define ELFMAG2 'L'
-@@ -602,6 +631,7 @@ extern Elf32_Dyn _DYNAMIC [];
- #define elfhdr elf32_hdr
- #define elf_phdr elf32_phdr
- #define elf_note elf32_note
-+#define elf_dyn Elf32_Dyn
-
- #else
-
-@@ -609,6 +639,7 @@ extern Elf64_Dyn _DYNAMIC [];
- #define elfhdr elf64_hdr
- #define elf_phdr elf64_phdr
- #define elf_note elf64_note
-+#define elf_dyn Elf64_Dyn
-
- #endif
-
-diff -Nurp linux-2.4.25/include/linux/mm.h linux-2.4.25-pax/include/linux/mm.h
---- linux-2.4.25/include/linux/mm.h 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/include/linux/mm.h 2004-02-19 11:12:53.000000000 -0500
-@@ -25,6 +25,7 @@ extern struct list_head inactive_list;
- #include <asm/page.h>
- #include <asm/pgtable.h>
- #include <asm/atomic.h>
-+#include <asm/mman.h>
-
- /*
- * Linux kernel virtual memory manager primitives.
-@@ -104,9 +105,29 @@ struct vm_area_struct {
- #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
- #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+#define VM_MIRROR 0x00100000 /* vma is mirroring another */
-+#endif
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+#define VM_MAYNOTWRITE 0x00200000 /* vma cannot be granted VM_WRITE any more */
-+#endif
-+
-+#ifdef __VM_STACK_FLAGS
-+#ifdef ARCH_STACK_GROWSUP
-+#define VM_STACK_FLAGS (0x00000233 | __VM_STACK_FLAGS)
-+#else
-+#define VM_STACK_FLAGS (0x00000133 | __VM_STACK_FLAGS)
-+#endif
-+#endif
-+
- #ifndef VM_STACK_FLAGS
-+#ifdef ARCH_STACK_GROWSUP
-+#define VM_STACK_FLAGS 0x00000277
-+#else
- #define VM_STACK_FLAGS 0x00000177
- #endif
-+#endif
-
- #define VM_READHINTMASK (VM_SEQ_READ | VM_RAND_READ)
- #define VM_ClearReadHint(v) (v)->vm_flags &= ~VM_READHINTMASK
-@@ -556,21 +577,50 @@ extern unsigned long do_mmap_pgoff(struc
- unsigned long len, 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_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(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE)
-+ if ((current->flags & PF_PAX_SEGMEXEC) && !BAD_ADDR(ret) && ((flag & MAP_TYPE) == MAP_PRIVATE)
-+
-+#ifdef CONFIG_PAX_MPROTECT
-+ && (!(current->flags & PF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
-+#endif
-+
-+ )
-+ {
-+ unsigned long ret_m;
-+ prot = prot & PROT_EXEC ? prot : PROT_NONE;
-+ 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)
-@@ -583,6 +633,12 @@ static inline void __vma_unlink(struct m
-
- static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
- {
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((vma->vm_flags | vm_flags) & VM_MIRROR)
-+ return 0;
-+#endif
-+
- if (!vma->vm_file && vma->vm_flags == vm_flags)
- return 1;
- else
-@@ -636,7 +692,12 @@ static inline unsigned int pf_gfp_mask(u
-
- 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)
-@@ -651,8 +712,43 @@ static inline int expand_stack(struct vm
- address &= PAGE_MASK;
- spin_lock(&vma->vm_mm->page_table_lock);
- grow = (vma->vm_start - address) >> PAGE_SHIFT;
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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;
- }
-@@ -665,11 +761,6 @@ static inline int expand_stack(struct vm
- 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 -Nurp linux-2.4.25/include/linux/random.h linux-2.4.25-pax/include/linux/random.h
---- linux-2.4.25/include/linux/random.h 2000-01-25 17:13:46.000000000 -0500
-+++ linux-2.4.25-pax/include/linux/random.h 2004-02-19 11:12:53.000000000 -0500
-@@ -72,6 +72,8 @@ extern __u32 secure_tcpv6_sequence_numbe
-
- extern __u32 secure_ipv6_id(__u32 *daddr);
-
-+extern unsigned long pax_get_random_long(void);
-+
- #ifndef MODULE
- extern struct file_operations random_fops, urandom_fops;
- #endif
-diff -Nurp linux-2.4.25/include/linux/sched.h linux-2.4.25-pax/include/linux/sched.h
---- linux-2.4.25/include/linux/sched.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/linux/sched.h 2004-02-19 11:12:53.000000000 -0500
-@@ -231,6 +231,21 @@ struct mm_struct {
-
- /* Architecture-specific MM context */
- mm_context_t context;
-+
-+#ifdef CONFIG_PAX_DLRESOLVE
-+ unsigned long call_dl_resolve;
-+#endif
-+
-+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
-+ unsigned long call_syscall;
-+#endif
-+
-+#ifdef CONFIG_PAX_ASLR
-+ unsigned long delta_mmap; /* randomized offset */
-+ unsigned long delta_exec; /* randomized offset */
-+ unsigned long delta_stack; /* randomized offset */
-+#endif
-+
- };
-
- extern int mmlist_nr;
-@@ -436,6 +451,29 @@ struct task_struct {
-
- #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 */
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
-+extern unsigned int pax_aslr;
-+#endif
-+
-+extern unsigned int pax_softmode;
-+#endif
-+
-+extern int pax_check_flags(unsigned long *);
-+
-+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
-+extern void pax_set_flags(struct linux_binprm * bprm);
-+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
-+extern void (*pax_set_flags_func)(struct linux_binprm * bprm);
-+#endif
-+
- /*
- * Ptrace flags
- */
-diff -Nurp linux-2.4.25/include/linux/sysctl.h linux-2.4.25-pax/include/linux/sysctl.h
---- linux-2.4.25/include/linux/sysctl.h 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/include/linux/sysctl.h 2004-02-19 11:12:53.000000000 -0500
-@@ -128,8 +128,19 @@ enum
- KERN_PPC_L3CR=57, /* l3cr register on PPC */
- KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
- KERN_CORE_SETUID=59, /* int: set to allow core dumps of setuid apps */
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ KERN_PAX=69, /* PaX control */
-+#endif
-+
- };
-
-+#ifdef CONFIG_PAX_SOFTMODE
-+enum {
-+ PAX_ASLR=1, /* PaX: disable/enable all randomization features */
-+ PAX_SOFTMODE=2 /* PaX: disable/enable soft mode */
-+};
-+#endif
-
- /* CTL_VM names: */
- enum
-diff -Nurp linux-2.4.25/kernel/sysctl.c linux-2.4.25-pax/kernel/sysctl.c
---- linux-2.4.25/kernel/sysctl.c 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/kernel/sysctl.c 2004-02-19 11:12:53.000000000 -0500
-@@ -127,6 +127,17 @@ static ctl_table debug_table[];
- static ctl_table dev_table[];
- extern ctl_table random_table[];
-
-+#ifdef CONFIG_PAX_SOFTMODE
-+static ctl_table pax_table[] = {
-+
-+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
-+ {PAX_ASLR, "aslr", &pax_aslr, sizeof(unsigned int), 0600, NULL, &proc_dointvec},
-+#endif
-+
-+ {PAX_SOFTMODE, "softmode", &pax_softmode, sizeof(unsigned int), 0600, NULL, &proc_dointvec}
-+};
-+#endif
-+
- /* /proc declarations: */
-
- #ifdef CONFIG_PROC_FS
-@@ -275,6 +286,11 @@ static ctl_table kern_table[] = {
- {KERN_EXCEPTION_TRACE,"exception-trace",
- &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
- #endif
-+
-+#ifdef CONFIG_PAX_SOFTMODE
-+ {KERN_PAX,"pax",NULL,0,0500,pax_table},
-+#endif
-+
- {0}
- };
-
-diff -Nurp linux-2.4.25/mm/filemap.c linux-2.4.25-pax/mm/filemap.c
---- linux-2.4.25/mm/filemap.c 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/mm/filemap.c 2004-02-19 11:12:53.000000000 -0500
-@@ -2324,6 +2324,12 @@ int generic_file_mmap(struct file * file
- }
- if (!mapping->a_ops->readpage)
- return -ENOEXEC;
-+
-+#ifdef CONFIG_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;
-@@ -2553,8 +2559,42 @@ static long madvise_fixup_middle(struct
- * We can potentially split a vm area into separate
- * areas, each area with its own behavior.
- */
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+static long __madvise_behavior(struct vm_area_struct * vma,
-+ unsigned long start, unsigned long end, int behavior);
-+
-+static long madvise_behavior(struct vm_area_struct * vma,
-+ unsigned long start, unsigned long end, int behavior)
-+{
-+ if (vma->vm_flags & VM_MIRROR) {
-+ struct vm_area_struct * vma_m, * prev_m;
-+ unsigned long start_m, end_m;
-+ int error;
-+
-+ 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;
-+ error = __madvise_behavior(vma_m, start_m, end_m, behavior);
-+ if (error)
-+ return error;
-+ } else {
-+ printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ return __madvise_behavior(vma, start, end, behavior);
-+}
-+
-+static long __madvise_behavior(struct vm_area_struct * vma,
-+ unsigned long start, unsigned long end, int behavior)
-+#else
- static long madvise_behavior(struct vm_area_struct * vma,
- unsigned long start, unsigned long end, int behavior)
-+#endif
- {
- int error = 0;
-
-diff -Nurp linux-2.4.25/mm/memory.c linux-2.4.25-pax/mm/memory.c
---- linux-2.4.25/mm/memory.c 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/mm/memory.c 2004-02-19 11:12:53.000000000 -0500
-@@ -925,6 +925,65 @@ static inline void break_cow(struct vm_a
- establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
- }
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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 @@ static int do_wp_page(struct mm_struct *
-
- /* Free the old page.. */
- new_page = old_page;
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pax_mirror_fault(mm, vma, address, page_table);
-+#endif
-+
- }
- spin_unlock(&mm->page_table_lock);
- page_cache_release(new_page);
-@@ -1178,6 +1242,11 @@ static int do_swap_page(struct mm_struct
-
- /* No need to invalidate - it was non-present before */
- update_mmu_cache(vma, address, pte);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pax_mirror_fault(mm, vma, address, page_table);
-+#endif
-+
- spin_unlock(&mm->page_table_lock);
- return ret;
- }
-@@ -1223,6 +1292,11 @@ static int do_anonymous_page(struct mm_s
-
- /* No need to invalidate - it was non-present before */
- update_mmu_cache(vma, addr, entry);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pax_mirror_fault(mm, vma, addr, page_table);
-+#endif
-+
- spin_unlock(&mm->page_table_lock);
- return 1; /* Minor fault */
-
-@@ -1304,6 +1378,11 @@ static int do_no_page(struct mm_struct *
-
- /* no need to invalidate: a not-present page shouldn't be cached */
- update_mmu_cache(vma, address, entry);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ pax_mirror_fault(mm, vma, address, page_table);
-+#endif
-+
- spin_unlock(&mm->page_table_lock);
- return 2; /* Major fault */
- }
-@@ -1368,6 +1447,11 @@ int handle_mm_fault(struct mm_struct *mm
- pgd_t *pgd;
- pmd_t *pmd;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ unsigned long address_m = 0UL;
-+ struct vm_area_struct * vma_m = NULL;
-+#endif
-+
- current->state = TASK_RUNNING;
- pgd = pgd_offset(mm, address);
-
-@@ -1376,6 +1460,47 @@ int handle_mm_fault(struct mm_struct *mm
- * and the SMP-safe atomic PTE updates.
- */
- spin_lock(&mm->page_table_lock);
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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 -Nurp linux-2.4.25/mm/mlock.c linux-2.4.25-pax/mm/mlock.c
---- linux-2.4.25/mm/mlock.c 2001-09-17 18:30:23.000000000 -0400
-+++ linux-2.4.25-pax/mm/mlock.c 2004-02-19 11:12:53.000000000 -0500
-@@ -114,8 +114,40 @@ static inline int mlock_fixup_middle(str
- return 0;
- }
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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;
-+ int error;
-+
-+ 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;
-+ error = __mlock_fixup(vma_m, start_m, end_m, newflags);
-+ if (error)
-+ return error;
-+ } else {
-+ printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
-+ return -ENOMEM;
-+ }
-+ }
-+ 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;
-
-@@ -159,6 +191,17 @@ static int do_mlock(unsigned long start,
- return -EINVAL;
- if (end == start)
- return 0;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (end > SEGMEXEC_TASK_SIZE)
-+ return -EINVAL;
-+ } else
-+#endif
-+
-+ if (end > TASK_SIZE)
-+ return -EINVAL;
-+
- vma = find_vma(current->mm, start);
- if (!vma || vma->vm_start > start)
- return -ENOMEM;
-@@ -253,6 +296,16 @@ static int do_mlockall(int flags)
- for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
- unsigned int newflags;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (vma->vm_end > SEGMEXEC_TASK_SIZE)
-+ break;
-+ } else
-+#endif
-+
-+ if (vma->vm_end > TASK_SIZE)
-+ break;
-+
- newflags = vma->vm_flags | VM_LOCKED;
- if (!(flags & MCL_CURRENT))
- newflags &= ~VM_LOCKED;
-diff -Nurp linux-2.4.25/mm/mmap.c linux-2.4.25-pax/mm/mmap.c
---- linux-2.4.25/mm/mmap.c 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/mm/mmap.c 2004-02-19 11:12:53.000000000 -0500
-@@ -206,6 +206,11 @@ static inline unsigned long calc_vm_flag
- _trans(prot, PROT_WRITE, VM_WRITE) |
- _trans(prot, PROT_EXEC, VM_EXEC);
- flag_bits =
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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 +406,28 @@ unsigned long do_mmap_pgoff(struct file
- int error;
- rb_node_t ** rb_link, * rb_parent;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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) {
- if (!file->f_op || !file->f_op->mmap)
- return -ENODEV;
-@@ -438,6 +465,27 @@ unsigned long do_mmap_pgoff(struct file
- */
- vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
-
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
-+
-+#ifdef CONFIG_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_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;
-@@ -523,6 +571,13 @@ munmap_back:
- vma->vm_start = addr;
- vma->vm_end = addr + len;
- vma->vm_flags = vm_flags;
-+
-+#ifdef CONFIG_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;
-@@ -551,6 +606,14 @@ munmap_back:
- goto free_vma;
- }
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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
-@@ -622,20 +685,49 @@ static inline unsigned long arch_get_unm
- {
- struct vm_area_struct *vma;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE)
-+ return -ENOMEM;
-+ else
-+#endif
-+
- if (len > TASK_SIZE)
- return -ENOMEM;
-
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
-+#endif
-+
- if (addr) {
- addr = PAGE_ALIGN(addr);
- vma = find_vma(current->mm, addr);
-+
-+#ifdef CONFIG_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_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_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)
-@@ -922,6 +1014,83 @@ no_mmaps:
- }
- }
-
-+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_PAX_SEGMEXEC) || defined(CONFIG_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.
-@@ -931,6 +1100,10 @@ int do_munmap(struct mm_struct *mm, unsi
- {
- struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ struct vm_area_struct *free_m, *extra_m;
-+#endif
-+
- if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr)
- return -EINVAL;
-
-@@ -963,60 +1136,69 @@ int do_munmap(struct mm_struct *mm, unsi
- if (!extra)
- return -ENOMEM;
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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_PAX_SEGMEXEC) || defined(CONFIG_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_PAX_SEGMEXEC) || defined(CONFIG_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_PAX_SEGMEXEC) || defined(CONFIG_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;
- }
-
-@@ -1025,6 +1207,12 @@ asmlinkage long sys_munmap(unsigned long
- int ret;
- struct mm_struct *mm = current->mm;
-
-+#ifdef CONFIG_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);
-@@ -1047,6 +1235,13 @@ unsigned long do_brk(unsigned long addr,
- if (!len)
- return addr;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if ((addr + len) > SEGMEXEC_TASK_SIZE || (addr + len) < addr)
-+ return -EINVAL;
-+ } else
-+#endif
-+
- if ((addr + len) > TASK_SIZE || (addr + len) < addr)
- return -EINVAL;
-
-@@ -1084,6 +1279,18 @@ unsigned long do_brk(unsigned long addr,
-
- flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
-
-+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
-+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
-+ flags &= ~VM_EXEC;
-+
-+#ifdef CONFIG_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;
-@@ -1099,6 +1306,13 @@ unsigned long do_brk(unsigned long addr,
- vma->vm_start = addr;
- vma->vm_end = addr + len;
- vma->vm_flags = flags;
-+
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/mm/mprotect.c linux-2.4.25-pax/mm/mprotect.c
---- linux-2.4.25/mm/mprotect.c 2003-11-28 13:26:21.000000000 -0500
-+++ linux-2.4.25-pax/mm/mprotect.c 2004-02-19 11:12:53.000000000 -0500
-@@ -8,6 +8,11 @@
- #include <linux/shm.h>
- #include <linux/mman.h>
-
-+#ifdef CONFIG_PAX_MPROTECT
-+#include <linux/elf.h>
-+#include <linux/fs.h>
-+#endif
-+
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
- #include <asm/pgtable.h>
-@@ -236,6 +241,44 @@ static inline int mprotect_fixup_middle(
- return 0;
- }
-
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_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;
-+ int error;
-+
-+ 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))
-+ error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
-+ else
-+ error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
-+ if (error)
-+ return error;
-+ } else {
-+ printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ 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)
-+{
-+ pgprot_t newprot;
-+ int error;
-+#else
- static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
- unsigned long start, unsigned long end, unsigned int newflags)
- {
-@@ -246,6 +289,14 @@ static int mprotect_fixup(struct vm_area
- *pprev = vma;
- return 0;
- }
-+#endif
-+
-+#ifdef CONFIG_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 +315,68 @@ static int mprotect_fixup(struct vm_area
- return 0;
- }
-
-+#ifdef CONFIG_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 favour 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_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_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
-+
- asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
- {
- unsigned long nstart, end, tmp;
-@@ -276,6 +389,17 @@ asmlinkage long sys_mprotect(unsigned lo
- end = start + len;
- if (end < start)
- return -ENOMEM;
-+
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (end > SEGMEXEC_TASK_SIZE)
-+ return -EINVAL;
-+ } else
-+#endif
-+
-+ if (end > TASK_SIZE)
-+ return -EINVAL;
-+
- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
- return -EINVAL;
- if (end == start)
-@@ -288,6 +412,11 @@ asmlinkage long sys_mprotect(unsigned lo
- if (!vma || vma->vm_start > start)
- goto out;
-
-+#ifdef CONFIG_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;
-@@ -300,6 +429,12 @@ asmlinkage long sys_mprotect(unsigned lo
- goto out;
- }
-
-+#ifdef CONFIG_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 -Nurp linux-2.4.25/mm/mremap.c linux-2.4.25-pax/mm/mremap.c
---- linux-2.4.25/mm/mremap.c 2004-02-18 08:36:32.000000000 -0500
-+++ linux-2.4.25-pax/mm/mremap.c 2004-02-19 11:12:53.000000000 -0500
-@@ -232,6 +232,18 @@ unsigned long do_mremap(unsigned long ad
- old_len = PAGE_ALIGN(old_len);
- new_len = PAGE_ALIGN(new_len);
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
-+ old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)
-+ goto out;
-+ } else
-+#endif
-+
-+ if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
-+ old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
-+ goto out;
-+
- /* new_addr is only valid if MREMAP_FIXED is specified */
- if (flags & MREMAP_FIXED) {
- if (new_addr & ~PAGE_MASK)
-@@ -239,6 +251,13 @@ unsigned long do_mremap(unsigned long ad
- if (!(flags & MREMAP_MAYMOVE))
- goto out;
-
-+#ifdef CONFIG_PAX_SEGMEXEC
-+ if (current->flags & PF_PAX_SEGMEXEC) {
-+ if (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)
-+ goto out;
-+ } else
-+#endif
-+
- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
- goto out;
- /*
-@@ -283,6 +302,16 @@ unsigned long do_mremap(unsigned long ad
- vma = find_vma(current->mm, addr);
- if (!vma || vma->vm_start > addr)
- goto out;
-+
-+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
-+ if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
-+ (vma->vm_flags & VM_MIRROR))
-+ {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+#endif
-+
- /* We can't remap across vm area boundaries */
- if (old_len > vma->vm_end - addr)
- goto out;
diff --git a/sys-kernel/mips-sources/mips-sources-2.4.25.ebuild b/sys-kernel/mips-sources/mips-sources-2.4.25.ebuild
index 87b2ee8f9067..382f8cc373ce 100644
--- a/sys-kernel/mips-sources/mips-sources-2.4.25.ebuild
+++ b/sys-kernel/mips-sources/mips-sources-2.4.25.ebuild
@@ -1,6 +1,6 @@
# Copyright 1999-2004 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-kernel/mips-sources/mips-sources-2.4.25.ebuild,v 1.1 2004/02/23 10:48:55 kumba Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-kernel/mips-sources/mips-sources-2.4.25.ebuild,v 1.2 2004/02/23 10:59:14 kumba Exp $
# Version Data
@@ -9,7 +9,6 @@ CVSDATE="20040222"
EXTRAVERSION="-mipscvs-${CVSDATE}"
KV="${OKV}${EXTRAVERSION}"
COBALTPATCHVER="1.1"
-PAXDATE="200402192035"
# Miscellaneous stuff
S=${WORKDIR}/linux-${OKV}-${CVSDATE}
@@ -24,8 +23,7 @@ inherit kernel eutils
# 2) linux-mips.org CVS snapshot diff from 28 Nov 2003
# 3) patch to fix arch/mips[64]/Makefile to pass appropriate CFLAGS
# 4) patch to fix the mips64 Makefile to allow building of mips64 kernels
-# 5) added PaX patch (http://pax.grsecurity.net)
-# 6) Patches for Cobalt support
+# 5) Patches for Cobalt support
DESCRIPTION="Linux-Mips CVS sources for MIPS-based machines, dated ${CVSDATE}"
@@ -52,9 +50,6 @@ src_unpack() {
# Patch to fix mips64 Makefile so that -finline-limit=10000 gets added to CFLAGS
epatch ${FILESDIR}/mipscvs-${OKV}-makefile-inlinelimit.patch
- # Add in PaX support to the kernel
- epatch ${FILESDIR}/pax-linux-${OKV}-${PAXDATE}.patch
-
# Cobalt Patches
if [ "${PROFILE_ARCH}" = "cobalt" ]; then
echo -e ""