diff -urN linux-2.6.0-test9/arch/i386/Kconfig linux-2.6.0-test9-aslr26/arch/i386/Kconfig
--- linux-2.6.0-test9/arch/i386/Kconfig	2003-10-25 20:43:01.000000000 +0200
+++ linux-2.6.0-test9-aslr26/arch/i386/Kconfig	2003-10-27 22:43:13.000000000 +0100
@@ -1236,6 +1236,8 @@
 
 source "security/Kconfig"
 
+source "security/pax/Kconfig"
+	
 source "crypto/Kconfig"
 
 source "lib/Kconfig"
diff -urN linux-2.6.0-test9/drivers/char/random.c linux-2.6.0-test9-aslr26/drivers/char/random.c
--- linux-2.6.0-test9/drivers/char/random.c	2003-10-25 20:42:53.000000000 +0200
+++ linux-2.6.0-test9-aslr26/drivers/char/random.c	2003-10-27 22:43:13.000000000 +0100
@@ -2461,3 +2461,25 @@
 	return (cookie - tmp[17]) & COOKIEMASK;	/* Leaving the data behind */
 }
 #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.tv_sec;
+	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
diff -urN linux-2.6.0-test9/fs/binfmt_elf.c linux-2.6.0-test9-aslr26/fs/binfmt_elf.c
--- linux-2.6.0-test9/fs/binfmt_elf.c	2003-10-25 20:43:32.000000000 +0200
+++ linux-2.6.0-test9-aslr26/fs/binfmt_elf.c	2003-10-27 22:43:13.000000000 +0100
@@ -36,10 +36,12 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/security.h>
+#include <linux/random.h>
 
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/pgalloc.h>
+#include <asm/system.h>
 
 #include <linux/elf.h>
 
@@ -88,7 +90,10 @@
 	end = ELF_PAGEALIGN(end);
 	if (end > start)
 		do_brk(start, end - start);
+#ifndef CONFIG_PAX_RANDMMAP
+	/* We don't want it to be aligned or we'll loose randomization */
 	current->mm->start_brk = current->mm->brk = end;
+#endif
 }
 
 
@@ -636,8 +641,30 @@
 	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;
 
+#ifdef CONFIG_PAX_ASLR
+
+	if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_RANDMMAP)) {
+
+		current->flags |= PF_PAX_RANDMMAP;
+
+#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
+
+		current->mm->delta_mmap = pax_delta_mask(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
+
+	
 	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
 	   may depend on the personality.  */
 	SET_PERSONALITY(elf_ex, ibcs2_interpreter);
@@ -696,6 +723,13 @@
 			   base, as well as whatever program they might try to exec.  This
 			   is because the brk will follow the loader, and is not movable.  */
 			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
+#ifdef CONFIG_PAX_RANDMMAP
+			/* PAX: randmize ET_DYN base address at the normal ET_EXEC default base address */
+			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);
@@ -782,6 +816,14 @@
 	current->mm->end_data = end_data;
 	current->mm->start_stack = bprm->p;
 
+#ifdef CONFIG_PAX_RANDMMAP
+	elf_brk += pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
+	/* Use the old (2.4) behaviour, set mm->*brk here and not in set_brk(),
+	 * and don't align it */
+	current->mm->start_brk = current->mm->brk = elf_brk;
+#undef pax_delta_mask
+#endif
+
 	/* Calling set_brk effectively mmaps the pages that we need
 	 * for the bss and break sections
 	 */
diff -urN linux-2.6.0-test9/fs/exec.c linux-2.6.0-test9-aslr26/fs/exec.c
--- linux-2.6.0-test9/fs/exec.c	2003-10-25 20:43:25.000000000 +0200
+++ linux-2.6.0-test9-aslr26/fs/exec.c	2003-10-27 22:43:13.000000000 +0100
@@ -45,6 +45,7 @@
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/rmap-locking.h>
+#include <linux/random.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
@@ -1078,8 +1079,13 @@
 	retval = PTR_ERR(file);
 	if (IS_ERR(file))
 		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]));
 
 	bprm.file = file;
diff -urN linux-2.6.0-test9/include/asm-i386/a.out.h linux-2.6.0-test9-aslr26/include/asm-i386/a.out.h
--- linux-2.6.0-test9/include/asm-i386/a.out.h	2003-10-25 20:43:27.000000000 +0200
+++ linux-2.6.0-test9-aslr26/include/asm-i386/a.out.h	2003-10-27 22:43:13.000000000 +0100
@@ -19,7 +19,7 @@
 
 #ifdef __KERNEL__
 
-#define STACK_TOP	TASK_SIZE
+#define __STACK_TOP	TASK_SIZE
 
 #endif
 
diff -urN linux-2.6.0-test9/include/asm-i386/elf.h linux-2.6.0-test9-aslr26/include/asm-i386/elf.h
--- linux-2.6.0-test9/include/asm-i386/elf.h	2003-10-25 20:44:04.000000000 +0200
+++ linux-2.6.0-test9-aslr26/include/asm-i386/elf.h	2003-10-27 22:43:13.000000000 +0100
@@ -72,6 +72,21 @@
 
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 
+#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
+/* If SEGMEXEC is implemented, don't forget to change this */
+#define PAX_DELTA_STACK_LEN(tsk)	16
+
+#endif
+
+
 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
    now struct_user_regs, they are different) */
 
diff -urN linux-2.6.0-test9/include/linux/a.out.h linux-2.6.0-test9-aslr26/include/linux/a.out.h
--- linux-2.6.0-test9/include/linux/a.out.h	2003-10-25 20:43:56.000000000 +0200
+++ linux-2.6.0-test9-aslr26/include/linux/a.out.h	2003-10-27 22:43:13.000000000 +0100
@@ -7,6 +7,17 @@
 
 #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
+/* If STACK_TOP is'nt defined, then our arch has PaX support and __STACK_TOP */
+#define STACK_TOP		(__STACK_TOP - __DELTA_STACK)
+#endif
+
 #endif /* __STRUCT_EXEC_OVERRIDE__ */
 
 /* these go in the N_MACHTYPE field */
diff -urN linux-2.6.0-test9/include/linux/elf.h linux-2.6.0-test9-aslr26/include/linux/elf.h
--- linux-2.6.0-test9/include/linux/elf.h	2003-10-25 20:43:01.000000000 +0200
+++ linux-2.6.0-test9-aslr26/include/linux/elf.h	2003-10-27 22:43:13.000000000 +0100
@@ -35,6 +35,14 @@
 #define PT_HIPROC  0x7fffffff
 #define PT_GNU_EH_FRAME		0x6474e550
 
+/* 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
@@ -363,6 +371,8 @@
 #define	EI_OSABI	7
 #define	EI_PAD		8
 
+#define EI_PAX		14
+
 #define	ELFMAG0		0x7f		/* EI_MAG */
 #define	ELFMAG1		'E'
 #define	ELFMAG2		'L'
diff -urN linux-2.6.0-test9/include/linux/random.h linux-2.6.0-test9-aslr26/include/linux/random.h
--- linux-2.6.0-test9/include/linux/random.h	2003-10-25 20:44:55.000000000 +0200
+++ linux-2.6.0-test9-aslr26/include/linux/random.h	2003-10-27 22:43:13.000000000 +0100
@@ -69,6 +69,8 @@
 
 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 -urN linux-2.6.0-test9/include/linux/sched.h linux-2.6.0-test9-aslr26/include/linux/sched.h
--- linux-2.6.0-test9/include/linux/sched.h	2003-10-25 20:42:56.000000000 +0200
+++ linux-2.6.0-test9-aslr26/include/linux/sched.h	2003-10-27 22:43:13.000000000 +0100
@@ -209,6 +209,13 @@
 
 	unsigned long saved_auxv[40]; /* for /proc/PID/auxv */
 
+#ifdef CONFIG_PAX_ASLR
+	unsigned long delta_mmap;
+	unsigned long delta_exec;
+	unsigned long delta_stack;
+#endif
+
+	
 	unsigned dumpable:1;
 #ifdef CONFIG_HUGETLB_PAGE
 	int used_hugetlb;
@@ -500,6 +507,13 @@
 #define PF_LESS_THROTTLE 0x00100000	/* Throttle me less: I clean memory */
 #define PF_SYNCWRITE	0x00200000	/* I am doing a sync write */
 
+#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_SMP
 extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
 #else
diff -urN linux-2.6.0-test9/mm/mmap.c linux-2.6.0-test9-aslr26/mm/mmap.c
--- linux-2.6.0-test9/mm/mmap.c	2003-10-25 20:43:57.000000000 +0200
+++ linux-2.6.0-test9-aslr26/mm/mmap.c	2003-10-27 22:43:13.000000000 +0100
@@ -733,6 +733,10 @@
 	if (len > TASK_SIZE)
 		return -ENOMEM;
 
+/* PAX: Ignore the hint if it's NOT an anonymous mapping (linuxthread bug) and if RANDMMAP is not disabled */
+#ifdef CONFIG_PAX_RANDMMAP
+	if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
+#endif
 	if (addr) {
 		addr = PAGE_ALIGN(addr);
 		vma = find_vma(mm, addr);
@@ -740,8 +744,19 @@
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
-	start_addr = addr = mm->free_area_cache;
 
+/* PAX: Disable the nice optimisation when we want to randomize */
+#ifdef CONFIG_PAX_RANDMMAP
+
+	if (current->flags & PF_PAX_RANDMMAP)
+		/* and add the delta */
+		start_addr = addr = PAGE_ALIGN(TASK_UNMAPPED_BASE) + current->mm->delta_mmap;
+	else
+#endif
+		start_addr = addr = mm->free_area_cache;
+
+	
+	
 full_search:
 	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
 		/* At this point:  (!vma || addr < vma->vm_end). */
diff -urN linux-2.6.0-test9/security/pax/Kconfig linux-2.6.0-test9-aslr26/security/pax/Kconfig
--- linux-2.6.0-test9/security/pax/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.0-test9-aslr26/security/pax/Kconfig	2003-10-27 22:43:13.000000000 +0100
@@ -0,0 +1,66 @@
+menu "PaX options"
+
+config PAX_ASLR	
+	bool "Address Space Layout Randomization"
+	help
+          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/ NOT PORTED FOR NOW) 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 (NOT PORTED FOR NOW)
+           - 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.
+
+config PAX_RANDUSTACK
+	bool "Randomize user stack base"
+	depends on PAX_ASLR
+	help
+          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.
+
+config PAX_RANDMMAP
+	bool "Randomize mmap() base"
+	depends on PAX_ASLR
+	help
+          By saying Y here the kernel will use a randomized base address for
+          mmap() requests that do not specify one themselves.  As a result
+          all dynamically loaded libraries will appear at random addresses
+          and therefore be harder to exploit by a technique where an attacker
+          attempts to execute library code for his purposes (e.g. spawn a
+          shell from an exploited program that is running at an elevated
+          privilege level).
+
+          Furthermore, if a program is relinked as a dynamic ELF file, its
+          base address will be randomized as well, completing the full
+          randomization of the address space layout.  Attacking such programs
+          becomes a guess game.  You can find an example of doing this at
+          http://pageexec.virtualave.net/et_dyn.zip and practical samples at
+          http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
+
+          NOTE: you can use the 'chpax' utility to control this feature
+          on a per file basis.	  
+endmenu
+
