rpms/kernel/devel linux-2.6.11-devmem.patch, NONE, 1.1 linux-2.6.11-execshield.patch, NONE, 1.1 patch-2.6.12-rc1.bz2.sign, NONE, 1.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Fri Mar 18 21:55:25 UTC 2005


Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv8130

Added Files:
	linux-2.6.11-devmem.patch linux-2.6.11-execshield.patch 
	patch-2.6.12-rc1.bz2.sign 
Log Message:
new bits


linux-2.6.11-devmem.patch:
 linux-1050/arch/s390/mm/init.c         |    5 +
 linux-1050/fs/proc/kcore.c             |    2 
 linux-2.6.10/include/asm-x86_64/page.h |    4 
 linux-2.6.11/drivers/char/mem.c        |    7 +
 linux-2.6.3/arch/ia64/mm/init.c        |    7 +
 linux-2.6.3/arch/ppc/mm/init.c         |    5 +
 linux-2.6.8/drivers/char/mem.c         |    1 
 linux-2.6.9/arch/i386/mm/init.c        |   19 ++++
 linux/arch/x86_64/mm/init.c            |   20 ++++
 linux/drivers/char/mem.c               |  140 ++++-----------------------------
 linux/include/asm-alpha/page.h         |    1 
 linux/include/asm-arm/page.h           |    2 
 linux/include/asm-arm26/page.h         |    2 
 linux/include/asm-cris/page.h          |    2 
 linux/include/asm-h8300/page.h         |    2 
 linux/include/asm-i386/page.h          |    4 
 linux/include/asm-ia64/page.h          |    2 
 linux/include/asm-m68k/page.h          |    2 
 linux/include/asm-m68knommu/page.h     |    2 
 linux/include/asm-mips/page.h          |    2 
 linux/include/asm-parisc/page.h        |    2 
 linux/include/asm-ppc/page.h           |    2 
 linux/include/asm-ppc64/page.h         |    2 
 linux/include/asm-s390/page.h          |    2 
 linux/include/asm-sh/page.h            |    2 
 linux/include/asm-sh64/page.h          |    2 
 linux/include/asm-sparc/page.h         |    2 
 linux/include/asm-sparc64/page.h       |    2 
 linux/include/asm-um/page.h            |    1 
 linux/include/asm-v850/page.h          |    2 
 ppc64-2.5-pseries/arch/ppc64/mm/init.c |   12 ++
 31 files changed, 136 insertions(+), 126 deletions(-)

--- NEW FILE linux-2.6.11-devmem.patch ---
--- linux-2.6.9/arch/i386/mm/init.c~	2004-12-09 00:30:22.439979032 -0500
+++ linux-2.6.9/arch/i386/mm/init.c	2004-12-09 00:31:40.906050376 -0500
@@ -225,6 +225,25 @@ static inline int page_is_ram(unsigned l
 	return 0;
 }
 
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
+ * valid. The argument is a physical page number.
+ *
+ *
+ * On x86, access has to be given to the first megabyte of ram because that area
+ * contains bios code and data regions used by X and dosemu and similar apps.
+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+ * mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+   if (pagenr <= 256)
+       return 1;
+   if (!page_is_ram(pagenr))
+       return 1;
+   return 0;
+}
+
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
diff -purN linux-2.6.7/arch/x86_64/mm/init.c linux/arch/x86_64/mm/init.c
--- linux-2.6.7/arch/x86_64/mm/init.c	2004-07-30 11:41:27.000000000 +0200
+++ linux/arch/x86_64/mm/init.c	2004-07-30 11:54:25.299432577 +0200
@@ -396,6 +396,26 @@ static inline int page_is_ram (unsigned 
 	return 0;
 }
 
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
+ * valid. The argument is a physical page number.
+ *
+ *
+ * On x86-64, access has to be given to the first megabyte of ram because that area
+ * contains bios code and data regions used by X and dosemu and similar apps.
+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+ * mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+	if (pagenr <= 256)
+		return 1;
+	if (!page_is_ram(pagenr))
+		return 1;
+	return 0;
+}
+
+
 static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
 			 kcore_vsyscall;
 
diff -purN linux-2.6.7/drivers/char/mem.c linux/drivers/char/mem.c
--- linux-2.6.7/drivers/char/mem.c	2004-07-30 11:42:13.000000000 +0200
+++ linux/drivers/char/mem.c	2004-07-30 11:54:25.316430579 +0200
@@ -111,6 +111,19 @@ static inline int valid_phys_addr_range(
 }
 #endif
 
+static inline int range_is_allowed(unsigned long from, unsigned long to)
+{
+	unsigned long cursor;
+
+	cursor = from >> PAGE_SHIFT;
+	while ((cursor << PAGE_SHIFT) < to) {
+		if (!devmem_is_allowed(cursor))
+			return 0;
+		cursor++;
+	}
+	return 1;
+}
+
 /*
  * This funcion reads the *physical* memory. The f_pos points directly to the 
  * memory location. 
@@ -173,6 +173,8 @@ static ssize_t read_mem(struct file * fi
 		 */
 		ptr = xlate_dev_mem_ptr(p);
 
+		if (!range_is_allowed(p, p+count))
+			return -EPERM;
 		if (copy_to_user(buf, ptr, sz))
 			return -EFAULT;
 		buf += sz;
@@ -230,6 +232,8 @@ static ssize_t write_mem(struct file * f
 		 */
 		ptr = xlate_dev_mem_ptr(p);
 
+		if (!range_is_allowed(ptr, ptr+sz))
+			return -EPERM;
 		copied = copy_from_user(ptr, buf, sz);
 		if (copied) {
 			ssize_t ret;
@@ -358,128 +362,6 @@ static ssize_t read_kmem(struct file *fi
 }
 
 
-static inline ssize_t
-do_write_kmem(void *p, unsigned long realp, const char __user * buf,
-	      size_t count, loff_t *ppos)
-{
-	ssize_t written, sz;
-	unsigned long copied;
-
-	written = 0;
-#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
-	/* we don't have page 0 mapped on sparc and m68k.. */
-	if (realp < PAGE_SIZE) {
-		unsigned long sz = PAGE_SIZE - realp;
-		if (sz > count)
-			sz = count;
-		/* Hmm. Do something? */
-		buf += sz;
-		p += sz;
-		realp += sz;
-		count -= sz;
-		written += sz;
-	}
-#endif
-
-	while (count > 0) {
-		char *ptr;
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-realp & (PAGE_SIZE - 1))
-			sz = -realp & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
-
-		sz = min_t(unsigned long, sz, count);
-
-		/*
-		 * On ia64 if a page has been mapped somewhere as
-		 * uncached, then it must also be accessed uncached
-		 * by the kernel or data corruption may occur
-		 */
-		ptr = xlate_dev_kmem_ptr(p);
-
-		copied = copy_from_user(ptr, buf, sz);
-		if (copied) {
-			ssize_t ret;
-
-			ret = written + (sz - copied);
-			if (ret)
-				return ret;
-			return -EFAULT;
-		}
-		buf += sz;
-		p += sz;
-		realp += sz;
-		count -= sz;
-		written += sz;
-	}
-
-	*ppos += written;
-	return written;
-}
-
-
-/*
- * This function writes to the *virtual* memory as seen by the kernel.
- */
-static ssize_t write_kmem(struct file * file, const char __user * buf, 
-			  size_t count, loff_t *ppos)
-{
-	unsigned long p = *ppos;
-	ssize_t wrote = 0;
-	ssize_t virtr = 0;
-	ssize_t written;
-	char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
-
-	if (p < (unsigned long) high_memory) {
-
-		wrote = count;
-		if (count > (unsigned long) high_memory - p)
-			wrote = (unsigned long) high_memory - p;
-
-		written = do_write_kmem((void*)p, p, buf, wrote, ppos);
-		if (written != wrote)
-			return written;
-		wrote = written;
-		p += wrote;
-		buf += wrote;
-		count -= wrote;
-	}
-
-	if (count > 0) {
-		kbuf = (char *)__get_free_page(GFP_KERNEL);
-		if (!kbuf)
-			return wrote ? wrote : -ENOMEM;
-		while (count > 0) {
-			int len = count;
-
-			if (len > PAGE_SIZE)
-				len = PAGE_SIZE;
-			if (len) {
-				written = copy_from_user(kbuf, buf, len);
-				if (written) {
-					ssize_t ret;
-
-					free_page((unsigned long)kbuf);
-					ret = wrote + virtr + (len - written);
-					return ret ? ret : -EFAULT;
-				}
-			}
-			len = vwrite(kbuf, (char *)p, len);
-			count -= len;
-			buf += len;
-			virtr += len;
-			p += len;
-		}
-		free_page((unsigned long)kbuf);
-	}
-
- 	*ppos = p;
- 	return virtr + wrote;
-}
-
 #if defined(CONFIG_ISA) || !defined(__mc68000__)
 static ssize_t read_port(struct file * file, char __user * buf,
 			 size_t count, loff_t *ppos)
@@ -594,7 +559,6 @@ static struct file_operations mem_fops =
 static struct file_operations kmem_fops = {
 	.llseek		= memory_lseek,
 	.read		= read_kmem,
-	.write		= write_kmem,
 	.mmap		= mmap_kmem,
 	.open		= open_kmem,
 };
diff -purN linux-2.6.7/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- linux-2.6.7/include/asm-alpha/page.h	2004-06-16 07:19:44.000000000 +0200
+++ linux/include/asm-alpha/page.h	2004-07-30 11:54:25.334428463 +0200
@@ -106,6 +106,7 @@ extern __inline__ int get_order(unsigned
 #define VM_DATA_DEFAULT_FLAGS		(VM_READ | VM_WRITE | VM_EXEC | \
 					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
 #endif /* __KERNEL__ */
 
 #endif /* _ALPHA_PAGE_H */
diff -purN linux-2.6.7/include/asm-arm/page.h linux/include/asm-arm/page.h
--- linux-2.6.7/include/asm-arm/page.h	2004-06-16 07:19:01.000000000 +0200
+++ linux/include/asm-arm/page.h	2004-07-30 11:54:25.351426465 +0200
@@ -196,6 +196,8 @@ static inline int get_order(unsigned lon
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif
diff -purN linux-2.6.7/include/asm-arm26/page.h linux/include/asm-arm26/page.h
--- linux-2.6.7/include/asm-arm26/page.h	2004-06-16 07:19:42.000000000 +0200
+++ linux/include/asm-arm26/page.h	2004-07-30 11:54:25.372423996 +0200
@@ -110,6 +110,8 @@ static inline int get_order(unsigned lon
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif
diff -purN linux-2.6.7/include/asm-cris/page.h linux/include/asm-cris/page.h
--- linux-2.6.7/include/asm-cris/page.h	2004-06-16 07:19:09.000000000 +0200
+++ linux/include/asm-cris/page.h	2004-07-30 11:54:25.385422468 +0200
@@ -96,6 +96,8 @@ static inline int get_order(unsigned lon
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _CRIS_PAGE_H */
diff -purN linux-2.6.7/include/asm-h8300/page.h linux/include/asm-h8300/page.h
--- linux-2.6.7/include/asm-h8300/page.h	2004-06-16 07:19:52.000000000 +0200
+++ linux/include/asm-h8300/page.h	2004-07-30 11:54:25.398420940 +0200
@@ -96,6 +96,8 @@ extern unsigned long memory_end;
 
 #endif /* __ASSEMBLY__ */
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _H8300_PAGE_H */
diff -purN linux-2.6.7/include/asm-i386/page.h linux/include/asm-i386/page.h
--- linux-2.6.7/include/asm-i386/page.h	2004-07-30 11:42:33.000000000 +0200
+++ linux/include/asm-i386/page.h	2004-07-30 11:54:25.649391435 +0200
@@ -128,6 +128,8 @@ static __inline__ int get_order(unsigned
 	return order;
 }
 
+extern int devmem_is_allowed(unsigned long pagenr);
+
 #endif /* __ASSEMBLY__ */
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
@@ -151,6 +153,8 @@ static __inline__ int get_order(unsigned
 	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
 		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+
+
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
diff -purN linux-2.6.7/include/asm-ia64/page.h linux/include/asm-ia64/page.h
--- linux-2.6.7/include/asm-ia64/page.h	2004-07-30 11:42:32.000000000 +0200
+++ linux/include/asm-ia64/page.h	2004-07-30 11:54:25.427417531 +0200
@@ -187,4 +187,6 @@ get_order (unsigned long size)
 					 (((current->personality & READ_IMPLIES_EXEC) != 0)	\
 					  ? VM_EXEC : 0))
 
+#define devmem_is_allowed(x) 1
+
 #endif /* _ASM_IA64_PAGE_H */
diff -purN linux-2.6.7/include/asm-m68k/page.h linux/include/asm-m68k/page.h
--- linux-2.6.7/include/asm-m68k/page.h	2004-07-30 11:42:15.000000000 +0200
+++ linux/include/asm-m68k/page.h	2004-07-30 11:54:25.450414827 +0200
@@ -190,6 +190,8 @@ static inline void *__va(unsigned long x
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _M68K_PAGE_H */
diff -purN linux-2.6.7/include/asm-m68knommu/page.h linux/include/asm-m68knommu/page.h
--- linux-2.6.7/include/asm-m68knommu/page.h	2004-06-16 07:19:22.000000000 +0200
+++ linux/include/asm-m68knommu/page.h	2004-07-30 11:54:25.463413299 +0200
@@ -96,6 +96,8 @@ extern unsigned long memory_end;
 
 #endif /* __ASSEMBLY__ */
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _M68KNOMMU_PAGE_H */
diff -purN linux-2.6.7/include/asm-mips/page.h linux/include/asm-mips/page.h
--- linux-2.6.7/include/asm-mips/page.h	2004-07-30 11:42:15.000000000 +0200
+++ linux/include/asm-mips/page.h	2004-07-30 11:54:25.486410595 +0200
@@ -137,4 +137,6 @@ static __inline__ int get_order(unsigned
 #define WANT_PAGE_VIRTUAL
 #endif
 
+#define devmem_is_allowed(x) 1
+
 #endif /* _ASM_PAGE_H */
diff -purN linux-2.6.7/include/asm-parisc/page.h linux/include/asm-parisc/page.h
--- linux-2.6.7/include/asm-parisc/page.h	2004-06-16 07:19:01.000000000 +0200
+++ linux/include/asm-parisc/page.h	2004-07-30 11:54:25.500408950 +0200
@@ -157,6 +157,8 @@ extern int npmem_ranges;
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _PARISC_PAGE_H */
diff -purN linux-2.6.7/include/asm-ppc/page.h linux/include/asm-ppc/page.h
--- linux-2.6.7/include/asm-ppc/page.h	2004-06-16 07:19:02.000000000 +0200
+++ linux/include/asm-ppc/page.h	2004-07-30 11:54:25.515407187 +0200
@@ -163,5 +163,7 @@ extern __inline__ int get_order(unsigned
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 #endif /* _PPC_PAGE_H */
diff -purN linux-2.6.7/include/asm-ppc64/page.h linux/include/asm-ppc64/page.h
--- linux-2.6.7/include/asm-ppc64/page.h	2004-06-16 07:18:47.000000000 +0200
+++ linux/include/asm-ppc64/page.h	2004-07-30 11:54:25.530405423 +0200
@@ -245,5 +245,7 @@ extern int page_is_ram(unsigned long phy
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 #endif /* _PPC64_PAGE_H */
diff -purN linux-2.6.7/include/asm-s390/page.h linux/include/asm-s390/page.h
--- linux-2.6.7/include/asm-s390/page.h	2004-06-16 07:18:59.000000000 +0200
+++ linux/include/asm-s390/page.h	2004-07-30 11:54:25.543403895 +0200
@@ -181,6 +181,8 @@ typedef struct { unsigned long pgd; } pg
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _S390_PAGE_H */
diff -purN linux-2.6.7/include/asm-sh/page.h linux/include/asm-sh/page.h
--- linux-2.6.7/include/asm-sh/page.h	2004-06-16 07:20:03.000000000 +0200
+++ linux/include/asm-sh/page.h	2004-07-30 11:54:25.559402014 +0200
@@ -133,6 +133,8 @@ static __inline__ int get_order(unsigned
 
 #endif
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_PAGE_H */
diff -purN linux-2.6.7/include/asm-sh64/page.h linux/include/asm-sh64/page.h
--- linux-2.6.7/include/asm-sh64/page.h	2004-07-30 11:42:15.000000000 +0200
+++ linux/include/asm-sh64/page.h	2004-07-30 11:54:25.579399663 +0200
@@ -132,6 +132,8 @@ extern __inline__ int get_order(unsigned
 
 #endif
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH64_PAGE_H */
diff -purN linux-2.6.7/include/asm-sparc/page.h linux/include/asm-sparc/page.h
--- linux-2.6.7/include/asm-sparc/page.h	2004-06-16 07:19:02.000000000 +0200
+++ linux/include/asm-sparc/page.h	2004-07-30 11:54:25.591398253 +0200
@@ -176,6 +176,8 @@ extern unsigned long pfn_base;
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _SPARC_PAGE_H */
diff -purN linux-2.6.7/include/asm-sparc64/page.h linux/include/asm-sparc64/page.h
--- linux-2.6.7/include/asm-sparc64/page.h	2004-07-30 11:42:15.000000000 +0200
+++ linux/include/asm-sparc64/page.h	2004-07-30 11:54:25.603396842 +0200
@@ -165,6 +165,8 @@ static __inline__ int get_order(unsigned
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* !(__KERNEL__) */
 
 #endif /* !(_SPARC64_PAGE_H) */
diff -purN linux-2.6.7/include/asm-um/page.h linux/include/asm-um/page.h
--- linux-2.6.7/include/asm-um/page.h	2004-06-16 07:19:36.000000000 +0200
+++ linux/include/asm-um/page.h	2004-07-30 11:54:25.620394844 +0200
@@ -44,5 +44,6 @@ extern struct page *page_mem_map(struct 
 
 extern struct page *arch_validate(struct page *page, int mask, int order);
 #define HAVE_ARCH_VALIDATE
+#define devmem_is_allowed(x) 1
 
 #endif
diff -purN linux-2.6.7/include/asm-v850/page.h linux/include/asm-v850/page.h
--- linux-2.6.7/include/asm-v850/page.h	2004-06-16 07:19:36.000000000 +0200
+++ linux/include/asm-v850/page.h	2004-07-30 11:54:25.630393668 +0200
@@ -141,6 +141,8 @@ extern __inline__ int get_order (unsigne
 #define __va(x)		     ((void *)__phys_to_virt ((unsigned long)(x)))
 
 
+#define devmem_is_allowed(x) 1
+
 #endif /* KERNEL */
 
 #endif /* __V850_PAGE_H__ */
diff -purN linux-2.6.7/include/asm-x86_64/page.h linux/include/asm-x86_64/page.h
--- linux-2.6.10/include/asm-x86_64/page.h~	2005-01-06 22:47:53.000000000 -0500
+++ linux-2.6.10/include/asm-x86_64/page.h	2005-01-06 22:48:27.000000000 -0500
@@ -138,6 +137,10 @@ extern int devmem_is_allowed(unsigned lo
 
 #define __HAVE_ARCH_GATE_AREA 1	
 
+#ifndef __ASSEMBLY__
+extern int devmem_is_allowed(unsigned long pagenr);
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif /* _X86_64_PAGE_H */

librtas accesses these pages through /dev/mem, so mark
them reserved and it gets permitted.

diff -urN linux-2.5/arch/ppc64/mm/init.c ppc64-2.5-pseries/arch/ppc64/mm/init.c
--- linux-2.5/arch/ppc64/mm/init.c	2004-09-24 15:23:06.000000000 +1000
+++ ppc64-2.5-pseries/arch/ppc64/mm/init.c	2004-10-12 15:41:27.000000000 +1000
@@ -719,6 +719,18 @@
 	totalram_pages += free_all_bootmem();
 #endif
 
+#ifdef CONFIG_PPC_PSERIES
+	/* Mark the RTAS pages as PG_reserved so userspace can mmap them */
+	if (rtas_rmo_buf) {
+		unsigned long pfn, start_pfn, end_pfn;
+
+		start_pfn = rtas_rmo_buf >> PAGE_SHIFT;
+		end_pfn = (rtas_rmo_buf + RTAS_RMOBUF_MAX) >>  PAGE_SHIFT;
+		for (pfn = start_pfn; pfn < end_pfn; pfn++)
+			SetPageReserved(pfn_to_page(pfn));
+	}
+#endif
+
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
 			page = pgdat->node_mem_map + i;


diff -urNp linux-1030/arch/s390/mm/init.c linux-1050/arch/s390/mm/init.c
--- linux-1030/arch/s390/mm/init.c
+++ linux-1050/arch/s390/mm/init.c
@@ -236,6 +236,11 @@ void __init paging_init(void)
 }
 #endif /* CONFIG_ARCH_S390X */
 
+int page_is_ram (unsigned long pagenr)
+{
+	return pagenr < max_mapnr;
+}
+
 void __init mem_init(void)
 {
 	unsigned long codesize, reservedpages, datasize, initsize;
--- linux-2.6.11/drivers/char/mem.c~	2005-03-18 14:25:26.000000000 -0500
+++ linux-2.6.11/drivers/char/mem.c	2005-03-18 14:25:45.000000000 -0500
@@ -287,6 +287,8 @@ static ssize_t read_kmem(struct file *fi
 	ssize_t read, virtr, sz;
 	char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
 
+	return -EPERM;
+
 	read = 0;
 	virtr = 0;
 	if (p < (unsigned long) high_memory) {
diff -urNp linux-1030/fs/proc/kcore.c linux-1050/fs/proc/kcore.c
--- linux-1030/fs/proc/kcore.c
+++ linux-1050/fs/proc/kcore.c
@@ -24,7 +24,7 @@
 
 static int open_kcore(struct inode * inode, struct file * filp)
 {
-	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+	return -EPERM;
 }
 
 static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
--- linux-2.6.3/arch/ppc/mm/init.c~	2004-03-09 13:41:17.699613784 +0100
+++ linux-2.6.3/arch/ppc/mm/init.c	2004-03-09 13:41:17.699613784 +0100
@@ -632,3 +632,8 @@
 	}
 #endif
 }
+
+int page_is_ram (unsigned long pagenr)
+{
+       return 1;
+}
--- linux-2.6.3/arch/ia64/mm/init.c.bak	Mon Mar  8 11:06:25 2004
+++ linux-2.6.3/arch/ia64/mm/init.c	Mon Mar  8 11:06:59 2004
@@ -218,6 +218,13 @@ free_initrd_mem (unsigned long start, un
 	}
 }
 
+int page_is_ram(unsigned long pagenr)
+{
+      //FIXME: implement w/efi walk
+      printk("page is ram is called!!!!!\n");	
+      return 1;
+}
+
 /*
  * This is like put_dirty_page() but installs a clean page in the kernel's page table.
  */
--- linux-2.6.8/drivers/char/mem.c~	2004-09-07 10:13:44.106301796 +0200
+++ linux-2.6.8/drivers/char/mem.c	2004-09-07 10:13:44.106301796 +0200
@@ -658,7 +658,6 @@
 	struct file_operations	*fops;
 } devlist[] = { /* list of minor devices */
 	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
-	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
 	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
 #if defined(CONFIG_ISA) || !defined(__mc68000__)
 	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
--- linux-2.6.11/drivers/char/mem.c~	2005-03-04 01:00:47.000000000 -0500
+++ linux-2.6.11/drivers/char/mem.c	2005-03-04 01:02:54.000000000 -0500
@@ -117,8 +117,11 @@ static inline int range_is_allowed(unsig
 	
 	cursor = from >> PAGE_SHIFT;
 	while ((cursor << PAGE_SHIFT) < to) {
-		if (!devmem_is_allowed(cursor))
+		if (!devmem_is_allowed(cursor)) {
+			printk ("Program %s tried to read /dev/mem between %lx->%lx."
+					"We stopped at %lx\n", current->comm, from, to, cursor);
 			return 0;
+		}
 		cursor++;
 	}
 	return 1;

linux-2.6.11-execshield.patch:
 arch/i386/kernel/asm-offsets.c       |    1 
 arch/i386/kernel/entry.S             |    8 +-
 arch/i386/kernel/process.c           |   59 +++++++++++++++++
 arch/i386/kernel/signal.c            |    4 -
 arch/i386/kernel/smp.c               |    3 
 arch/i386/kernel/sysenter.c          |   55 +++++++++++++++-
 arch/i386/kernel/traps.c             |   48 +++++++++++++-
 arch/i386/kernel/vsyscall-sysenter.S |    6 -
 arch/i386/kernel/vsyscall.lds.S      |    4 -
 arch/i386/mm/init.c                  |    6 +
 arch/i386/mm/mmap.c                  |    6 +
 arch/ia64/ia32/binfmt_elf32.c        |    2 
 arch/x86_64/ia32/ia32_binfmt.c       |    2 
 arch/x86_64/mm/Makefile              |    2 
 arch/x86_64/mm/mmap.c                |   95 +++++++++++++++++++++++++++
 drivers/char/random.c                |    7 +-
 fs/binfmt_elf.c                      |  120 ++++++++++++++++++++++++++++-------
 fs/proc/array.c                      |    8 +-
 fs/proc/base.c                       |    4 -
 fs/proc/task_mmu.c                   |   25 +++++--
 include/asm-i386/desc.h              |   14 ++++
 include/asm-i386/elf.h               |   42 ++++++++----
 include/asm-i386/mmu.h               |    6 +
 include/asm-i386/pgalloc.h           |    1 
 include/asm-i386/processor.h         |    8 ++
 include/asm-i386/thread_info.h       |    1 
 include/asm-ia64/pgalloc.h           |    4 +
 include/asm-ppc/pgalloc.h            |    5 +
 include/asm-ppc64/pgalloc.h          |    5 +
 include/asm-s390/pgalloc.h           |    4 +
 include/asm-sparc/pgalloc.h          |    4 +
 include/asm-sparc64/pgalloc.h        |    4 +
 include/asm-x86_64/pgalloc.h         |    7 ++
 include/asm-x86_64/processor.h       |    9 ++
 include/linux/mm.h                   |    9 ++
 include/linux/resource.h             |    5 +
 include/linux/sched.h                |    9 ++
 include/linux/sysctl.h               |    3 
 kernel/signal.c                      |   38 +++++++++++
 kernel/sysctl.c                      |   39 +++++++++++
 mm/fremap.c                          |   10 +-
 mm/mmap.c                            |  107 ++++++++++++++++++++++++++++---
 mm/mprotect.c                        |    5 +
 mm/mremap.c                          |    4 -
 44 files changed, 728 insertions(+), 80 deletions(-)

--- NEW FILE linux-2.6.11-execshield.patch ---
--- linux/fs/binfmt_elf.c.orig
+++ linux/fs/binfmt_elf.c
@@ -47,7 +47,7 @@
 
 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
 static int load_elf_library(struct file*);
-static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
+static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long);
 extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
 
 #ifndef elf_addr_t
@@ -285,20 +285,59 @@ create_elf_tables(struct linux_binprm *b
 #ifndef elf_map
 
 static unsigned long elf_map(struct file *filep, unsigned long addr,
-			struct elf_phdr *eppnt, int prot, int type)
+			     struct elf_phdr *eppnt, int prot, int type,
+			     unsigned long total_size)
 {
 	unsigned long map_addr;
+	unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
+	unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
+
+	addr = ELF_PAGESTART(addr);
+	size = ELF_PAGEALIGN(size);
 
 	down_write(&current->mm->mmap_sem);
-	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
-			   eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
-			   eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
+
+	/*
+	 * total_size is the size of the ELF (interpreter) image.
+	 * The _first_ mmap needs to know the full size, otherwise
+	 * randomization might put this image into an overlapping
+	 * position with the ELF binary image. (since size < total_size)
+	 * So we first map the 'big' image - and unmap the remainder at
+	 * the end. (which unmap is needed for ELF images with holes.)
+	 */
+	if (total_size) {
+		total_size = ELF_PAGEALIGN(total_size);
+		map_addr = do_mmap(filep, addr, total_size, prot, type, off);
+		if (!BAD_ADDR(map_addr))
+			do_munmap(current->mm, map_addr+size, total_size-size);
+	} else
+		map_addr = do_mmap(filep, addr, size, prot, type, off);
+		
 	up_write(&current->mm->mmap_sem);
-	return(map_addr);
+
+	return map_addr;
 }
 
 #endif /* !elf_map */
 
+static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
+{
+	int i, first_idx = -1, last_idx = -1;
+
+	for (i = 0; i < nr; i++)
+		if (cmds[i].p_type == PT_LOAD) {
+			last_idx = i;
+			if (first_idx == -1)
+				first_idx = i;
+		}
+
+	if (first_idx == -1)
+		return 0;
+
+	return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
+				ELF_PAGESTART(cmds[first_idx].p_vaddr);
+}
+
 /* This is much more generalized than the library routine read function,
    so we keep this separate.  Technically the library read function
    is only provided so that we can read a.out libraries that have
@@ -306,7 +345,8 @@ static unsigned long elf_map(struct file
 
 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
 				     struct file * interpreter,
-				     unsigned long *interp_load_addr)
+				     unsigned long *interp_load_addr,
+				     unsigned long no_base)
 {
 	struct elf_phdr *elf_phdata;
 	struct elf_phdr *eppnt;
@@ -314,6 +354,7 @@ static unsigned long load_elf_interp(str
 	int load_addr_set = 0;
 	unsigned long last_bss = 0, elf_bss = 0;
 	unsigned long error = ~0UL;
+	unsigned long total_size;
 	int retval, i, size;
 
 	/* First of all, some simple consistency checks */
@@ -352,6 +393,10 @@ static unsigned long load_elf_interp(str
 		goto out_close;
 	}
 
+	total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
+	if (!total_size)
+		goto out_close;
+
 	eppnt = elf_phdata;
 	for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
 	  if (eppnt->p_type == PT_LOAD) {
@@ -366,8 +411,11 @@ static unsigned long load_elf_interp(str
 	    vaddr = eppnt->p_vaddr;
 	    if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
 	    	elf_type |= MAP_FIXED;
+	    else if (no_base && interp_elf_ex->e_type == ET_DYN)
+		load_addr = -vaddr;
 
-	    map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
+	    map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type, total_size);
+	    total_size = 0;
 	    error = map_addr;
 	    if (BAD_ADDR(map_addr))
 	    	goto out_close;
@@ -527,7 +575,7 @@ static int load_elf_binary(struct linux_
 	unsigned long reloc_func_desc = 0;
 	char passed_fileno[6];
 	struct files_struct *files;
-	int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT;
+	int have_pt_gnu_stack, executable_stack;
 	unsigned long def_flags = 0;
 	struct {
 		struct elfhdr elf_ex;
@@ -683,6 +731,8 @@ static int load_elf_binary(struct linux_
 	}
 
 	elf_ppnt = elf_phdata;
+	executable_stack = EXSTACK_DEFAULT;
+
 	for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
 		if (elf_ppnt->p_type == PT_GNU_STACK) {
 			if (elf_ppnt->p_flags & PF_X)
@@ -693,6 +743,11 @@ static int load_elf_binary(struct linux_
 		}
 	have_pt_gnu_stack = (i < loc->elf_ex.e_phnum);
 
+	if (current->personality == PER_LINUX && exec_shield == 2) {
+		executable_stack = EXSTACK_DISABLE_X;
+		current->flags |= PF_RANDOMIZE;
+	}
+
 	/* Some simple consistency checks for the interpreter */
 	if (elf_interpreter) {
 		interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
@@ -746,6 +801,15 @@ static int load_elf_binary(struct linux_
 	if (retval)
 		goto out_free_dentry;
 
+#ifdef __i386__
+	/*
+	 * Turn off the CS limit completely if exec-shield disabled or
+	 * NX active:
+	 */
+	if (!exec_shield || executable_stack != EXSTACK_DISABLE_X || nx_enabled)
+		arch_add_exec_range(current->mm, -1);
+#endif
+
 	/* Discard our unneeded old files struct */
 	if (files) {
 		steal_locks(files);
@@ -764,7 +828,8 @@ static int load_elf_binary(struct linux_
 	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
 	   may depend on the personality.  */
 	SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
-	if (elf_read_implies_exec(loc->elf_ex, executable_stack))
+	if (exec_shield != 2 &&
+			elf_read_implies_exec(loc->elf_ex, executable_stack))
 		current->personality |= READ_IMPLIES_EXEC;
 
 	if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
@@ -792,10 +857,10 @@ static int load_elf_binary(struct linux_
 
 	current->mm->start_stack = bprm->p;
 
+
 	/* Now we do a little grungy work by mmaping the ELF image into
-	   the correct location in memory.  At this point, we assume that
-	   the image should be loaded at fixed address, not at a variable
-	   address. */
+	   the correct location in memory.
+	 */
 
 	for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
 		int elf_prot = 0, elf_flags;
@@ -839,16 +904,16 @@ static int load_elf_binary(struct linux_
 		elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
 
 		vaddr = elf_ppnt->p_vaddr;
-		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
+		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set)
 			elf_flags |= MAP_FIXED;
-		} else if (loc->elf_ex.e_type == ET_DYN) {
-			/* Try and get dynamic programs out of the way of the default mmap
-			   base, as well as whatever program they might try to exec.  This
-			   is because the brk will follow the loader, and is not movable.  */
+		else if (loc->elf_ex.e_type == ET_DYN)
+#ifdef __i386__
+			load_bias = 0;
+#else
 			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-		}
+#endif
 
-		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
+		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags, 0);
 		if (BAD_ADDR(error)) {
 			send_sig(SIGKILL, current, 0);
 			goto out_free_dentry;
@@ -925,7 +990,8 @@ static int load_elf_binary(struct linux_
 		else
 			elf_entry = load_elf_interp(&loc->interp_elf_ex,
 						    interpreter,
-						    &interp_load_addr);
+						    &interp_load_addr,
+						    load_bias);
 		if (BAD_ADDR(elf_entry)) {
 			printk(KERN_ERR "Unable to load interpreter %.128s\n",
 				elf_interpreter);
@@ -949,6 +1015,14 @@ static int load_elf_binary(struct linux_
 
 	set_binfmt(&elf_format);
 
+	/*
+	 * Map the vsyscall trampoline. This address is then passed via
+	 * AT_SYSINFO.
+	 */
+#ifdef __HAVE_ARCH_VSYSCALL
+	map_vsyscall();
+#endif
+
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
 	create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT),
@@ -962,6 +1036,10 @@ static int load_elf_binary(struct linux_
 	current->mm->end_data = end_data;
 	current->mm->start_stack = bprm->p;
 
+#ifdef __HAVE_ARCH_RANDOMIZE_BRK
+	if (current->flags & PF_RANDOMIZE)
+		randomize_brk(elf_brk);
+#endif
 	if (current->personality & MMAP_PAGE_ZERO) {
 		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
 		   and some applications "depend" upon this behavior.
--- linux/fs/proc/base.c.orig
+++ linux/fs/proc/base.c
@@ -142,7 +142,7 @@ static struct pid_entry tgid_base_stuff[
 	E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
 	E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
 	E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
+	E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUSR),
 	E(PROC_TGID_MEM,       "mem",     S_IFREG|S_IRUSR|S_IWUSR),
 #ifdef CONFIG_SECCOMP
 	E(PROC_TGID_SECCOMP,   "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
@@ -178,7 +178,7 @@ static struct pid_entry tid_base_stuff[]
 	E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
 	E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
 	E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
+	E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUSR),
 	E(PROC_TID_MEM,        "mem",     S_IFREG|S_IRUSR|S_IWUSR),
 #ifdef CONFIG_SECCOMP
 	E(PROC_TID_SECCOMP,    "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
--- linux/fs/proc/array.c.orig
+++ linux/fs/proc/array.c
@@ -385,8 +385,12 @@ static int do_task_stat(struct task_stru
 	ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
 	read_unlock(&tasklist_lock);
 
-	if (!whole || num_threads<2)
-		wchan = get_wchan(task);
+	if (!whole || num_threads<2) {
+		wchan = 0;
+		if (current->uid == task->uid || current->euid == task->uid ||
+				capable(CAP_SYS_NICE))
+			wchan = get_wchan(task);
+	}
 	if (!whole) {
 		min_flt = task->min_flt;
 		maj_flt = task->maj_flt;
--- linux/fs/proc/task_mmu.c.orig
+++ linux/fs/proc/task_mmu.c
@@ -21,13 +21,23 @@ char *task_mem(struct mm_struct *mm, cha
 		"VmStk:\t%8lu kB\n"
 		"VmExe:\t%8lu kB\n"
 		"VmLib:\t%8lu kB\n"
-		"VmPTE:\t%8lu kB\n",
+		"VmPTE:\t%8lu kB\n"
+		"StaBrk:\t%08lx kB\n"
+		"Brk:\t%08lx kB\n"
+		"StaStk:\t%08lx kB\n"
+		,
 		(mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
 		mm->locked_vm << (PAGE_SHIFT-10),
 		mm->rss << (PAGE_SHIFT-10),
 		data << (PAGE_SHIFT-10),
 		mm->stack_vm << (PAGE_SHIFT-10), text, lib,
-		(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
+		(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
+		mm->start_brk, mm->brk, mm->start_stack);
+#if __i386__
+	if (!nx_enabled)
+		buffer += sprintf(buffer,
+				"ExecLim:\t%08lx\n", mm->context.exec_limit);
+#endif
 	return buffer;
 }
 
@@ -107,7 +117,13 @@ static int show_map(struct seq_file *m, 
 			map->vm_end,
 			flags & VM_READ ? 'r' : '-',
 			flags & VM_WRITE ? 'w' : '-',
-			flags & VM_EXEC ? 'x' : '-',
+			(flags & VM_EXEC
+#ifdef __i386__
+				|| (!nx_enabled &&
+				(map->vm_start < task->mm->context.exec_limit))
+#endif
+			)
+				? 'x' : '-',
 			flags & VM_MAYSHARE ? 's' : 'p',
 			map->vm_pgoff << PAGE_SHIFT,
 			MAJOR(dev), MINOR(dev), ino, &len);
@@ -121,8 +137,7 @@ static int show_map(struct seq_file *m, 
 		seq_path(m, file->f_vfsmnt, file->f_dentry, "");
 	} else {
 		if (mm) {
-			if (map->vm_start <= mm->start_brk &&
-						map->vm_end >= mm->brk) {
+			if (map->vm_end == mm->brk) {
 				pad_len_spaces(m, len);
 				seq_puts(m, "[heap]");
 			} else {
--- linux/mm/mprotect.c.orig
+++ linux/mm/mprotect.c
@@ -22,6 +22,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
@@ -105,7 +106,7 @@ mprotect_fixup(struct vm_area_struct *vm
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long oldflags = vma->vm_flags;
 	long nrpages = (end - start) >> PAGE_SHIFT;
-	unsigned long charged = 0;
+	unsigned long charged = 0, old_end = vma->vm_end;
 	pgprot_t newprot;
 	pgoff_t pgoff;
 	int error;
@@ -166,6 +167,8 @@ success:
 	 */
 	vma->vm_flags = newflags;
 	vma->vm_page_prot = newprot;
+	if (oldflags & VM_EXEC)
+		arch_remove_exec_range(current->mm, old_end);
 	change_protection(vma, start, end, newprot);
 	__vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
 	__vm_stat_account(mm, newflags, vma->vm_file, nrpages);
--- linux/mm/mremap.c.orig
+++ linux/mm/mremap.c
@@ -398,8 +398,8 @@ unsigned long do_mremap(unsigned long ad
 			if (vma->vm_flags & VM_MAYSHARE)
 				map_flags |= MAP_SHARED;
 
-			new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
-						vma->vm_pgoff, map_flags);
+			new_addr = get_unmapped_area_prot(vma->vm_file, 0, new_len, 
+				vma->vm_pgoff, map_flags, vma->vm_flags & VM_EXEC);
 			ret = new_addr;
 			if (new_addr & ~PAGE_MASK)
 				goto out;
--- linux/mm/fremap.c.orig
+++ linux/mm/fremap.c
@@ -85,10 +85,12 @@ int install_page(struct mm_struct *mm, s
 	 * caller about it.
 	 */
 	err = -EINVAL;
-	inode = vma->vm_file->f_mapping->host;
-	size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	if (!page->mapping || page->index >= size)
-		goto err_unlock;
+	if (vma->vm_file) {
+		inode = vma->vm_file->f_mapping->host;
+		size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+		if (!page->mapping || page->index >= size)
+			goto err_unlock;
+	}
 
 	zap_pte(mm, vma, addr, pte);
 
--- linux/mm/mmap.c.orig
+++ linux/mm/mmap.c
@@ -24,6 +24,7 @@
 #include <linux/mount.h>
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
+#include <linux/random.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -334,6 +335,8 @@ static inline void
 __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
 		struct vm_area_struct *prev, struct rb_node *rb_parent)
 {
+	if (vma->vm_flags & VM_EXEC)
+		arch_add_exec_range(mm, vma->vm_end);
 	if (prev) {
 		vma->vm_next = prev->vm_next;
 		prev->vm_next = vma;
@@ -438,6 +441,8 @@ __vma_unlink(struct mm_struct *mm, struc
 	rb_erase(&vma->vm_rb, &mm->mm_rb);
 	if (mm->mmap_cache == vma)
 		mm->mmap_cache = prev;
+	if (vma->vm_flags & VM_EXEC)
+		arch_remove_exec_range(mm, vma->vm_end);
 }
 
 /*
@@ -743,6 +748,8 @@ struct vm_area_struct *vma_merge(struct 
 		} else					/* cases 2, 5, 7 */
 			vma_adjust(prev, prev->vm_start,
 				end, prev->vm_pgoff, NULL);
+		if (prev->vm_flags & VM_EXEC)
+			arch_add_exec_range(mm, prev->vm_end);
 		return prev;
 	}
 
@@ -914,7 +921,7 @@ unsigned long do_mmap_pgoff(struct file 
 	/* Obtain the address to map to. we verify (or select) it and ensure
 	 * that it represents a valid section of the address space.
 	 */
-	addr = get_unmapped_area(file, addr, len, pgoff, flags);
+	addr = get_unmapped_area_prot(file, addr, len, pgoff, flags, prot & PROT_EXEC);
 	if (addr & ~PAGE_MASK)
 		return addr;
 
@@ -1293,9 +1300,10 @@ void arch_unmap_area_topdown(struct vm_a
 		area->vm_mm->free_area_cache = area->vm_mm->mmap_base;
 }
 
+
 unsigned long
-get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
-		unsigned long pgoff, unsigned long flags)
+get_unmapped_area_prot(struct file *file, unsigned long addr, unsigned long len,
+		unsigned long pgoff, unsigned long flags, int exec)
 {
 	if (flags & MAP_FIXED) {
 		unsigned long ret;
@@ -1327,10 +1335,80 @@ get_unmapped_area(struct file *file, uns
 		return file->f_op->get_unmapped_area(file, addr, len,
 						pgoff, flags);
 
-	return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
+	if (exec && current->mm->get_unmapped_exec_area)
+		return current->mm->get_unmapped_exec_area(file, addr, len, pgoff, flags);
+	else
+		return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
+}
+
+EXPORT_SYMBOL(get_unmapped_area_prot);
+
+
+#define SHLIB_BASE             0x00111000
+
+unsigned long arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
+		unsigned long len0, unsigned long pgoff, unsigned long flags)
+{
+	unsigned long addr = addr0, len = len0;
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long tmp;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+		
+	if (!addr && !(flags & MAP_FIXED))
+		addr = randomize_range(SHLIB_BASE, 0x01000000, len);
+
+	if (addr) {
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start)) {
+			return addr;
+		}
+	}
+
+	addr = SHLIB_BASE;
+
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr) {
+			return -ENOMEM;
+		}
+		if (!vma || addr + len <= vma->vm_start) {
+			/*
+			 * Must not let a PROT_EXEC mapping get into the
+			 * brk area:
+			 */
+			if (addr + len > mm->brk)
+				goto failed;
+			
+			/*
+			 * Up until the brk area we randomize addresses
+			 * as much as possible:
+			 */
+			if (addr >= 0x01000000) {
+				tmp = randomize_range(0x01000000, mm->brk, len);
+				vma = find_vma(mm, tmp);
+				if (TASK_SIZE - len >= tmp &&
+				    (!vma || tmp + len <= vma->vm_start))
+					return tmp;
+			}
+			/*
+			 * Ok, randomization didnt work out - return
+			 * the result of the linear search:
+			 */
+			return addr;
+		}
+		addr = vma->vm_end;
+	}
+	
+failed:
+	return current->mm->get_unmapped_area(filp, addr0, len0, pgoff, flags);
 }
 
-EXPORT_SYMBOL(get_unmapped_area);
+
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
@@ -1405,6 +1483,14 @@ out:
 	return prev ? prev->vm_next : vma;
 }
 
+static int over_stack_limit(unsigned long sz)
+{
+	if (sz < EXEC_STACK_BIAS)
+		return 0;
+	return (sz - EXEC_STACK_BIAS) >
+			current->signal->rlim[RLIMIT_STACK].rlim_cur;
+}
+
 /*
  * Verify that the stack growth is acceptable and
  * update accounting. This is shared with both the
@@ -1420,7 +1506,7 @@ static int acct_stack_growth(struct vm_a
 		return -ENOMEM;
 
 	/* Stack limit test */
-	if (size > rlim[RLIMIT_STACK].rlim_cur)
+	if (over_stack_limit(size))
 		return -ENOMEM;
 
 	/* mlock limit tests */
@@ -1760,10 +1846,14 @@ int split_vma(struct mm_struct * mm, str
 	if (new->vm_ops && new->vm_ops->open)
 		new->vm_ops->open(new);
 
-	if (new_below)
+	if (new_below) {
+		unsigned long old_end = vma->vm_end;
+
 		vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
 			((addr - new->vm_start) >> PAGE_SHIFT), new);
-	else
+		if (vma->vm_flags & VM_EXEC)
+			arch_remove_exec_range(mm, old_end);
+	} else
 		vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
 
 	return 0;
@@ -1981,6 +2071,7 @@ void exit_mmap(struct mm_struct *mm)
 	mm->rss = 0;
 	mm->total_vm = 0;
 	mm->locked_vm = 0;
+	arch_flush_exec_range(mm);
 
 	spin_unlock(&mm->page_table_lock);
 
--- linux/kernel/signal.c.orig
+++ linux/kernel/signal.c
@@ -1193,6 +1193,37 @@ kill_proc_info(int sig, struct siginfo *
 	return error;
 }
 
+int print_fatal_signals = 0;
+
+static void print_fatal_signal(struct pt_regs *regs, int signr)
+{
+	printk("%s/%d: potentially unexpected fatal signal %d.\n",
+		current->comm, current->pid, signr);
+		
+#ifdef __i386__
+	printk("code at %08lx: ", regs->eip);
+	{
+		int i;
+		for (i = 0; i < 16; i++) {
+			unsigned char insn;
+
+			__get_user(insn, (unsigned char *)(regs->eip + i));
+			printk("%02x ", insn);
+		}
+	}
+#endif	
+	printk("\n");
+	show_regs(regs);
+}
+
+static int __init setup_print_fatal_signals(char *str)
+{
+	get_option (&str, &print_fatal_signals);
+
+	return 1;
+}
+
+__setup("print-fatal-signals=", setup_print_fatal_signals);
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1844,6 +1875,11 @@ relock:
 		if (!signr)
 			break; /* will return 0 */
 
+		if ((signr == SIGSEGV) && print_fatal_signals) {
+			spin_unlock_irq(&current->sighand->siglock);
+			print_fatal_signal(regs, signr);
+			spin_lock_irq(&current->sighand->siglock);
+		}
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
 			ptrace_signal_deliver(regs, cookie);
 
@@ -1939,6 +1975,8 @@ relock:
 		 * Anything else is fatal, maybe with a core dump.
 		 */
 		current->flags |= PF_SIGNALED;
+		if (print_fatal_signals)
+			print_fatal_signal(regs, signr);
 		if (sig_kernel_coredump(signr)) {
 			/*
 			 * If it was able to dump core, this kills all
--- linux/kernel/sysctl.c.orig
+++ linux/kernel/sysctl.c
@@ -72,6 +72,19 @@ extern int proc_unknown_nmi_panic(ctl_ta
 				  void __user *, size_t *, loff_t *);
 #endif
 
+extern unsigned int vdso_enabled;
+
+int exec_shield = 1;
+
+static int __init setup_exec_shield(char *str)
+{
+        get_option (&str, &exec_shield);
+
+        return 1;
+}
+
+__setup("exec-shield=", setup_exec_shield);
+
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
@@ -275,6 +288,32 @@ static ctl_table kern_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 	{
+		.ctl_name	= KERN_EXEC_SHIELD,
+		.procname	= "exec-shield",
+		.data		= &exec_shield,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= KERN_PRINT_FATAL,
+		.procname	= "print-fatal-signals",
+		.data		= &print_fatal_signals,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#if __i386__
+	{
+		.ctl_name	= KERN_VDSO,
+		.procname	= "vdso",
+		.data		= &vdso_enabled,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#endif
+	{
 		.ctl_name	= KERN_CORE_USES_PID,
 		.procname	= "core_uses_pid",
 		.data		= &core_uses_pid,
--- linux/arch/x86_64/mm/mmap.c.orig
+++ linux/arch/x86_64/mm/mmap.c
@@ -0,0 +1,95 @@
+/*
+ *  linux/arch/x86-64/mm/mmap.c
+ *
+ *  flexible mmap layout support
+ *
+ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * Started by Ingo Molnar <mingo at elte.hu>
+ */
+
+#include <linux/personality.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+
+/*
+ * Top of mmap area (just below the process stack).
+ *
+ * Leave an at least ~128 MB hole.
+ */
+#define MIN_GAP (128*1024*1024)
+#define MAX_GAP (TASK_SIZE/6*5)
+
+static inline unsigned long mmap_base(void)
+{
+	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+
+	if (gap < MIN_GAP)
+		gap = MIN_GAP;
+	else if (gap > MAX_GAP)
+		gap = MAX_GAP;
+
+	return TASK_SIZE - (gap & PAGE_MASK);
+}
+
+static inline int mmap_is_legacy(void)
+{
+	/*
+	 * Force standard allocation for 64 bit programs.
+	 */
+	if (!test_thread_flag(TIF_IA32))
+		return 1;
+		
+	if (current->personality & ADDR_COMPAT_LAYOUT) 
+		return 1;
+	
+	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+		return 1;
+		
+	return sysctl_legacy_va_layout;
+}
+
+/*
+ * This function, called very early during the creation of a new
+ * process VM image, sets up which VM layout function to use:
+ */
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+	/*
+	 * Fall back to the standard layout if the personality
+	 * bit is set, or if the expected stack growth is unlimited:
+	 */
+	if (mmap_is_legacy()) {
+		mm->mmap_base = TASK_UNMAPPED_BASE;
+		mm->get_unmapped_area = arch_get_unmapped_area;
+		mm->unmap_area = arch_unmap_area;
+	} else {
+		mm->mmap_base = mmap_base();
+		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		mm->unmap_area = arch_unmap_area_topdown;
+	}
+}
+
+unsigned long arch_align_stack(unsigned long sp)
+{
+	if (current->flags & PF_RANDOMIZE)
+		sp -= get_random_int() % 8192;
+	return sp & ~0xf;
+}
+
--- linux/arch/x86_64/mm/Makefile.orig
+++ linux/arch/x86_64/mm/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the linux x86_64-specific parts of the memory manager.
 #
 
-obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
+obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o mmap.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_DISCONTIGMEM) += numa.o
 obj-$(CONFIG_K8_NUMA) += k8topology.o
--- linux/arch/x86_64/ia32/ia32_binfmt.c.orig
+++ linux/arch/x86_64/ia32/ia32_binfmt.c
@@ -395,7 +395,7 @@ int setup_arg_pages(struct linux_binprm 
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
 {
 	unsigned long map_addr;
 	struct task_struct *me = current; 
--- linux/arch/ia64/ia32/binfmt_elf32.c.orig
+++ linux/arch/ia64/ia32/binfmt_elf32.c
@@ -272,7 +272,7 @@ elf32_set_personality (void)
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
 {
 	unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
 
--- linux/arch/i386/mm/mmap.c.orig
+++ linux/arch/i386/mm/mmap.c
@@ -62,15 +62,17 @@ void arch_pick_mmap_layout(struct mm_str
 	 * Fall back to the standard layout if the personality
 	 * bit is set, or if the expected stack growth is unlimited:
 	 */
-	if (sysctl_legacy_va_layout ||
+	if ((exec_shield != 2) && (sysctl_legacy_va_layout ||
 			(current->personality & ADDR_COMPAT_LAYOUT) ||
-			current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
+			current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = arch_get_unmapped_area;
 		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base(mm);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		if (!(current->personality & READ_IMPLIES_EXEC))
+			mm->get_unmapped_exec_area = arch_get_unmapped_exec_area;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
--- linux/arch/i386/mm/init.c.orig
+++ linux/arch/i386/mm/init.c
@@ -400,7 +400,7 @@ u64 __supported_pte_mask = ~_PAGE_NX;
  * Control non executable mappings.
  *
  * on      Enable
- * off     Disable
+ * off     Disable (disables exec-shield too)
  */
 void __init noexec_setup(const char *str)
 {
@@ -410,6 +410,7 @@ void __init noexec_setup(const char *str
 	} else if (!strncmp(str,"off",3)) {
 		disable_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
+		exec_shield = 0;
 	}
 }
 
@@ -474,7 +475,10 @@ void __init paging_init(void)
 	set_nx();
 	if (nx_enabled)
 		printk("NX (Execute Disable) protection: active\n");
+	else
 #endif
+	if (exec_shield)
+		printk("Using x86 segment limits to approximate NX protection\n");
 
 	pagetable_init();
 
--- linux/arch/i386/kernel/vsyscall.lds.S.orig
+++ linux/arch/i386/kernel/vsyscall.lds.S
@@ -7,7 +7,7 @@
 
 SECTIONS
 {
-  . = VSYSCALL_BASE + SIZEOF_HEADERS;
+  . = SIZEOF_HEADERS;
 
   .hash           : { *(.hash) }		:text
   .dynsym         : { *(.dynsym) }
@@ -20,7 +20,7 @@ SECTIONS
      For the layouts to match, we need to skip more than enough
      space for the dynamic symbol table et al.  If this amount
      is insufficient, ld -shared will barf.  Just increase it here.  */
-  . = VSYSCALL_BASE + 0x400;
+  . = 0x400;
 
   .text           : { *(.text) }		:text =0x90909090
 
--- linux/arch/i386/kernel/asm-offsets.c.orig
+++ linux/arch/i386/kernel/asm-offsets.c
@@ -53,6 +53,7 @@ void foo(void)
 	OFFSET(TI_preempt_count, thread_info, preempt_count);
 	OFFSET(TI_addr_limit, thread_info, addr_limit);
 	OFFSET(TI_restart_block, thread_info, restart_block);
+	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
 	BLANK();
 
 	OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
--- linux/arch/i386/kernel/signal.c.orig
+++ linux/arch/i386/kernel/signal.c
@@ -380,7 +380,7 @@ static void setup_frame(int sig, struct 
 			goto give_sigsegv;
 	}
 
-	restorer = &__kernel_sigreturn;
+	restorer = current->mm->context.vdso + (long)&__kernel_sigreturn;
 	if (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 
@@ -475,7 +475,7 @@ static void setup_rt_frame(int sig, stru
 		goto give_sigsegv;
 
 	/* Set up to return from userspace.  */
-	restorer = &__kernel_rt_sigreturn;
+	restorer = current->mm->context.vdso + (long)&__kernel_rt_sigreturn;
 	if (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 	err |= __put_user(restorer, &frame->pretcode);
--- linux/arch/i386/kernel/entry.S.orig
+++ linux/arch/i386/kernel/entry.S
@@ -201,8 +201,12 @@ sysenter_past_esp:
 	pushl %ebp
 	pushfl
 	pushl $(__USER_CS)
-	pushl $SYSENTER_RETURN
-
+	/*
+	 * Push current_thread_info()->sysenter_return to the stack.
+	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
+	 * pushed above, and the word being pushed now:
+	 */
+	pushl (TI_sysenter_return-THREAD_SIZE+4*4)(%esp)
 /*
  * Load the potential sixth argument from user stack.
  * Careful about security.
--- linux/arch/i386/kernel/process.c.orig
+++ linux/arch/i386/kernel/process.c
@@ -582,6 +582,8 @@ struct task_struct fastcall * __switch_t
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
 	__unlazy_fpu(prev_p);
+	if (next_p->mm)
+		load_user_cs_desc(cpu, next_p->mm);
 
 	/*
 	 * Reload esp0, LDT and the page table pointer:
@@ -835,3 +837,60 @@ unsigned long arch_align_stack(unsigned 
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
+{
+	if (limit > mm->context.exec_limit) {
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
+{
+	struct vm_area_struct *vma;
+	unsigned long limit = PAGE_SIZE;
+
+	if (old_end == mm->context.exec_limit) {
+		for (vma = mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_flush_exec_range(struct mm_struct *mm)
+{
+	mm->context.exec_limit = 0;
+	set_user_cs(&mm->context.user_cs, 0);
+}
+
+/*
+ * Generate random brk address between 128MB and 196MB. (if the layout
+ * allows it.)
+ */
+void randomize_brk(unsigned long old_brk)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = 0x08000000;
+	if (current->mm->brk >= range_start)
+		range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = new_brk;
+}
+
--- linux/arch/i386/kernel/traps.c.orig
+++ linux/arch/i386/kernel/traps.c
@@ -452,6 +452,10 @@ DO_ERROR(11, SIGBUS,  "segment not prese
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
 
+/*
+ * the original non-exec stack patch was written by
+ * Solar Designer <solar at openwall.com>. Thanks!
+ */
 fastcall void do_general_protection(struct pt_regs * regs, long error_code)
 {
 	int cpu = get_cpu();
@@ -482,7 +486,6 @@ fastcall void do_general_protection(stru
 		put_cpu();
 		return;
 	}
-	put_cpu();
 
 	if (regs->eflags & VM_MASK)
 		goto gp_in_vm86;
@@ -490,17 +493,60 @@ fastcall void do_general_protection(stru
 	if (!(regs->xcs & 3))
 		goto gp_in_kernel;
 
+	/*
+	 * lazy-check for CS validity on exec-shield binaries:
+	 */
+	if (current->mm) {
+		struct desc_struct *desc1, *desc2;
+		struct vm_area_struct *vma;
+		unsigned long limit = PAGE_SIZE;
+		
+		spin_lock(&current->mm->page_table_lock);
+		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+		spin_unlock(&current->mm->page_table_lock);
+
+		current->mm->context.exec_limit = limit;
+		set_user_cs(&current->mm->context.user_cs, limit);
+
+		desc1 = &current->mm->context.user_cs;
+		desc2 = per_cpu(cpu_gdt_table, cpu) + GDT_ENTRY_DEFAULT_USER_CS;
+
+		/*
+		 * The CS was not in sync - reload it and retry the
+		 * instruction. If the instruction still faults then
+		 * we wont hit this branch next time around.
+		 */
+		if (desc1->a != desc2->a || desc1->b != desc2->b) {
+			if (print_fatal_signals >= 2) {
+				printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+				printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
+			}
+			load_user_cs_desc(cpu, current->mm);
+			put_cpu();
+			return;
+		}
+	}
+	put_cpu();
+	if (print_fatal_signals) {
+		printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+		printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
+	}
+
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
 	force_sig(SIGSEGV, current);
 	return;
 
 gp_in_vm86:
+	put_cpu();
 	local_irq_enable();
 	handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
 	return;
 
 gp_in_kernel:
+	put_cpu();
 	if (!fixup_exception(regs)) {
 		if (notify_die(DIE_GPF, "general protection fault", regs,
 				error_code, 13, SIGSEGV) == NOTIFY_STOP)
--- linux/arch/i386/kernel/smp.c.orig
+++ linux/arch/i386/kernel/smp.c
@@ -22,6 +22,7 @@
 
 #include <asm/mtrr.h>
 #include <asm/tlbflush.h>
+#include <asm/desc.h>
 #include <mach_apic.h>
 
 /*
@@ -313,6 +314,8 @@ fastcall void smp_invalidate_interrupt(s
 	unsigned long cpu;
 
 	cpu = get_cpu();
+	if (current->active_mm)
+		load_user_cs_desc(cpu, current->active_mm);
 
 	if (!cpu_isset(cpu, flush_cpumask))
 		goto out;
--- linux/arch/i386/kernel/vsyscall-sysenter.S.orig
+++ linux/arch/i386/kernel/vsyscall-sysenter.S
@@ -24,11 +24,11 @@ __kernel_vsyscall:
 	/* 7: align return point with nop's to make disassembly easier */
 	.space 7,0x90
 
-	/* 14: System call restart point is here! (SYSENTER_RETURN - 2) */
+	/* 14: System call restart point is here! (SYSENTER_RETURN_OFFSET-2) */
 	jmp .Lenter_kernel
 	/* 16: System call normal return point is here! */
-	.globl SYSENTER_RETURN	/* Symbol used by entry.S.  */
-SYSENTER_RETURN:
+	.globl SYSENTER_RETURN_OFFSET	/* Symbol used by sysenter.c  */
+SYSENTER_RETURN_OFFSET:
 	pop %ebp
 .Lpop_ebp:
 	pop %edx
--- linux/arch/i386/kernel/sysenter.c.orig
+++ linux/arch/i386/kernel/sysenter.c
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/elf.h>
+#include <linux/mman.h>
 
 #include <asm/cpufeature.h>
 #include <asm/msr.h>
@@ -41,11 +42,20 @@ void enable_sep_cpu(void *info)
 extern const char vsyscall_int80_start, vsyscall_int80_end;
 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
 
+struct page *sysenter_page;
+
 static int __init sysenter_setup(void)
 {
 	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
 
-	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
+	/*
+	 * We keep this page mapped readonly, even though the executable
+	 * portion is randomized into a userspace vma - so that we dont
+	 * have to fix up the data within the VDSO page every time we
+	 * exec().
+	 */
+	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_KERNEL_RO);
+	sysenter_page = virt_to_page(page);
 
 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
 		memcpy(page,
@@ -63,3 +73,46 @@ static int __init sysenter_setup(void)
 }
 
 __initcall(sysenter_setup);
+
+extern void SYSENTER_RETURN_OFFSET;
+
+unsigned int vdso_enabled = 0;
+
+void map_vsyscall(void)
+{
+	struct thread_info *ti = current_thread_info();
+	struct vm_area_struct *vma;
+	unsigned long addr;
+
+	if (unlikely(!vdso_enabled)) {
+		current->mm->context.vdso = NULL;
+		return;
+	}
+
+	/*
+	 * Map the vDSO (it will be randomized):
+	 */
+	down_write(&current->mm->mmap_sem);
+	addr = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
+	current->mm->context.vdso = (void *)addr;
+	ti->sysenter_return = (void *)addr + (long)&SYSENTER_RETURN_OFFSET;
+	if (addr != -1) {
+		vma = find_vma(current->mm, addr);
+		if (vma) {
+			pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+			get_page(sysenter_page);
+			install_page(current->mm, vma, addr,
+					sysenter_page, vma->vm_page_prot);
+			
+		}
+	}
+	up_write(&current->mm->mmap_sem);
+}
+
+static int __init vdso_setup(char *str)
+{
+        vdso_enabled = simple_strtoul(str, NULL, 0);
+        return 1;
+}
+__setup("vdso=", vdso_setup);
+
--- linux/drivers/char/random.c.orig
+++ linux/drivers/char/random.c
@@ -1600,13 +1600,18 @@ EXPORT_SYMBOL(secure_tcpv6_port_ephemera
  */
 unsigned int get_random_int(void)
 {
+	unsigned int val = 0;
+
+#ifdef CONFIG_X86_HAS_TSC
+	rdtscl(val);
+#endif
 	/*
 	 * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
 	 * every second, from the entropy pool (and thus creates a limited
 	 * drain on it), and uses halfMD4Transform within the second. We
 	 * also mix it with jiffies and the PID:
 	 */
-	return secure_ip_id(current->pid + jiffies);
+	return secure_ip_id(current->pid + jiffies + (int)val);
 }
 
 /*
--- linux/include/asm-ia64/pgalloc.h.orig
+++ linux/include/asm-ia64/pgalloc.h
@@ -23,6 +23,10 @@
 #include <asm/mmu_context.h>
 #include <asm/processor.h>
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 /*
  * Very stupidly, we used to get new pgd's and pmd's, init their contents
  * to point to the NULL versions of the next level page table, later on
--- linux/include/asm-sparc/pgalloc.h.orig
+++ linux/include/asm-sparc/pgalloc.h
@@ -66,4 +66,8 @@ BTFIXUPDEF_CALL(void, pte_free, struct p
 #define pte_free(pte)		BTFIXUP_CALL(pte_free)(pte)
 #define __pte_free_tlb(tlb, pte)	pte_free(pte)
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 #endif /* _SPARC_PGALLOC_H */
--- linux/include/asm-s390/pgalloc.h.orig
+++ linux/include/asm-s390/pgalloc.h
@@ -19,6 +19,10 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 
+#define arch_add_exec_range(mm, limit) do { ; } while (0)
+#define arch_flush_exec_range(mm)      do { ; } while (0)
+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
+
 #define check_pgt_cache()	do {} while (0)
 
 extern void diag10(unsigned long addr);
--- linux/include/asm-ppc/pgalloc.h.orig
+++ linux/include/asm-ppc/pgalloc.h
@@ -40,5 +40,10 @@ extern void pte_free(struct page *pte);
 
 #define check_pgt_cache()	do { } while (0)
 
+#define arch_add_exec_range(mm, limit)         do { ; } while (0)
+#define arch_flush_exec_range(mm)              do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)      do { ; } while (0)
+
+
 #endif /* _PPC_PGALLOC_H */
 #endif /* __KERNEL__ */
--- linux/include/linux/resource.h.orig
+++ linux/include/linux/resource.h
@@ -52,8 +52,11 @@ struct rlimit {
 /*
  * Limit the stack by to some sane default: root can always
  * increase this limit if needed..  8MB seems reasonable.
+ *
+ * (2MB more to cover randomization effects.)
  */
-#define _STK_LIM	(8*1024*1024)
+#define _STK_LIM	(10*1024*1024)
+#define EXEC_STACK_BIAS	(2*1024*1024)
 
 /*
  * GPG wants 32kB of mlocked memory, to make sure pass phrases
--- linux/include/linux/sysctl.h.orig
+++ linux/include/linux/sysctl.h
@@ -84,6 +84,9 @@ enum
 
 	KERN_CAP_BSET=14,	/* int: capability bounding set */
 	KERN_PANIC=15,		/* int: panic timeout */
+	KERN_EXEC_SHIELD=1000,	/* int: exec-shield enabled (0/1/2) */
+	KERN_PRINT_FATAL=1001,	/* int: print fatal signals (0/1/2) */
+	KERN_VDSO=1002,		/* int: VDSO enabled (0/1) */
 	KERN_REALROOTDEV=16,	/* real root device to mount after initrd */
 
 	KERN_SPARC_REBOOT=21,	/* reboot command on Sparc */
--- linux/include/linux/sched.h.orig
+++ linux/include/linux/sched.h
@@ -36,6 +36,8 @@
 #include <linux/seccomp.h>
 
 struct exec_domain;
+extern int exec_shield;
+extern int print_fatal_signals;
 
 /*
  * cloning flags:
@@ -197,6 +199,10 @@ extern int sysctl_max_map_count;
 extern unsigned long
 arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
 		       unsigned long, unsigned long);
+
+extern unsigned long
+arch_get_unmapped_exec_area(struct file *, unsigned long, unsigned long,
+		       unsigned long, unsigned long);
 extern unsigned long
 arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
@@ -212,6 +218,9 @@ struct mm_struct {
 	unsigned long (*get_unmapped_area) (struct file *filp,
 				unsigned long addr, unsigned long len,
 				unsigned long pgoff, unsigned long flags);
+	unsigned long (*get_unmapped_exec_area) (struct file *filp,
+				unsigned long addr, unsigned long len,
+				unsigned long pgoff, unsigned long flags);
 	void (*unmap_area) (struct vm_area_struct *area);
 	unsigned long mmap_base;		/* base of mmap area */
 	unsigned long free_area_cache;		/* first hole */
--- linux/include/linux/mm.h.orig
+++ linux/include/linux/mm.h
@@ -728,7 +728,14 @@ extern struct vm_area_struct *copy_vma(s
 	unsigned long addr, unsigned long len, pgoff_t pgoff);
 extern void exit_mmap(struct mm_struct *);
 
-extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+extern unsigned long get_unmapped_area_prot(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, int);
+
+
+static inline unsigned long get_unmapped_area(struct file * file, unsigned long addr, 
+		unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0);	
+}
 
 extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 	unsigned long len, unsigned long prot,
--- linux/include/asm-i386/mmu.h.orig
+++ linux/include/asm-i386/mmu.h
@@ -7,11 +7,17 @@
  * we put the segment information here.
  *
  * cpu_vm_mask is used to optimize ldt flushing.
+ *
+ * exec_limit is used to track the range PROT_EXEC
+ * mappings span.
  */
 typedef struct { 
 	int size;
 	struct semaphore sem;
 	void *ldt;
+	struct desc_struct user_cs;
+	unsigned long exec_limit;
+	void *vdso;
 } mm_context_t;
 
 #endif
--- linux/include/asm-i386/processor.h.orig
+++ linux/include/asm-i386/processor.h
@@ -303,7 +303,10 @@ extern int bootloader_type;
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
+#define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE/3)
+
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
@@ -485,6 +488,9 @@ static inline void load_esp0(struct tss_
 	regs->xcs = __USER_CS;					\
 	regs->eip = new_eip;					\
 	regs->esp = new_esp;					\
+	preempt_disable();					\
+	load_user_cs_desc(smp_processor_id(), current->mm);	\
+	preempt_enable();					\
 } while (0)
 
 /* Forward declaration, a strange C thing */
--- linux/include/asm-i386/desc.h.orig
+++ linux/include/asm-i386/desc.h
@@ -135,6 +135,20 @@ static inline unsigned long get_desc_bas
 	return base;
 }
 
+static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
+{
+	limit = (limit - 1) / PAGE_SIZE;
+	desc->a = limit & 0xffff;
+	desc->b = (limit & 0xf0000) | 0x00c0fb00;
+}
+
+#define load_user_cs_desc(cpu, mm) \
+    	per_cpu(cpu_gdt_table, (cpu))[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs
+
+extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_flush_exec_range(struct mm_struct *mm);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
--- linux/include/asm-i386/thread_info.h.orig
+++ linux/include/asm-i386/thread_info.h
@@ -38,6 +38,7 @@ struct thread_info {
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
 						*/
+	void			*sysenter_return;
 	struct restart_block    restart_block;
 
 	unsigned long           previous_esp;   /* ESP of the previous stack in case
--- linux/include/asm-i386/pgalloc.h.orig
+++ linux/include/asm-i386/pgalloc.h
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <asm/processor.h>
 #include <asm/fixmap.h>
+#include <asm/desc.h>
 #include <linux/threads.h>
 #include <linux/mm.h>		/* for struct page */
 
--- linux/include/asm-i386/elf.h.orig
+++ linux/include/asm-i386/elf.h
@@ -9,6 +9,7 @@
 #include <asm/user.h>
 #include <asm/processor.h>
 #include <asm/system.h>		/* for savesegment */
+#include <asm/desc.h>
 
 #include <linux/utsname.h>
 
@@ -133,15 +134,22 @@ extern int dump_task_extended_fpu (struc
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
 
-#define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
-#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
-#define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
 extern void __kernel_vsyscall;
+#define VSYSCALL_BASE	((unsigned long)current->mm->context.vdso)
+#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
+#define VSYSCALL_OFFSET	((unsigned long) &__kernel_vsyscall)
+#define VSYSCALL_ENTRY	(VSYSCALL_BASE + VSYSCALL_OFFSET)
 
-#define ARCH_DLINFO						\
-do {								\
-		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
-		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);	\
+/* kernel-internal fixmap address: */
+#define __VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
+#define __VSYSCALL_EHDR	((const struct elfhdr *) __VSYSCALL_BASE)
+
+#define ARCH_DLINFO							\
+do {									\
+	if (VSYSCALL_BASE) {						\
+		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);		\
+		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);		\
+	}								\
 } while (0)
 
 /*
@@ -152,15 +160,15 @@ do {								\
  * Dumping its extra ELF program headers includes all the other information
  * a debugger needs to easily find how the vsyscall DSO was being used.
  */
-#define ELF_CORE_EXTRA_PHDRS		(VSYSCALL_EHDR->e_phnum)
+#define ELF_CORE_EXTRA_PHDRS		(__VSYSCALL_EHDR->e_phnum)
 #define ELF_CORE_WRITE_EXTRA_PHDRS					      \
 do {									      \
 	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+		(const struct elf_phdr *) (__VSYSCALL_BASE		      \
+					   + __VSYSCALL_EHDR->e_phoff);	      \
 	int i;								      \
 	Elf32_Off ofs = 0;						      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+	for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {		      \
 		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
 		if (phdr.p_type == PT_LOAD) {				      \
 			BUG_ON(ofs != 0);				      \
@@ -178,10 +186,10 @@ do {									      \
 #define ELF_CORE_WRITE_EXTRA_DATA					      \
 do {									      \
 	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+		(const struct elf_phdr *) (__VSYSCALL_BASE		      \
+					   + __VSYSCALL_EHDR->e_phoff);	      \
 	int i;								      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+	for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {		      \
 		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
 			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
 				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
@@ -190,4 +198,10 @@ do {									      \
 
 #endif
 
+#define __HAVE_ARCH_RANDOMIZE_BRK
+extern void randomize_brk(unsigned long old_brk);
+
+#define __HAVE_ARCH_VSYSCALL
+extern void map_vsyscall(void);
+
 #endif
--- linux/include/asm-ppc64/pgalloc.h.orig
+++ linux/include/asm-ppc64/pgalloc.h
@@ -11,6 +11,11 @@
 
 extern kmem_cache_t *zero_cache;
 
+/* Dummy functions since we don't support execshield on ppc */
+#define arch_add_exec_range(mm, limit) do { ; } while (0)
+#define arch_flush_exec_range(mm)      do { ; } while (0)
+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
+
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
--- linux/include/asm-sparc64/pgalloc.h.orig
+++ linux/include/asm-sparc64/pgalloc.h
@@ -250,4 +250,8 @@ static inline void pte_free(struct page 
 #define pgd_free(pgd)		free_pgd_fast(pgd)
 #define pgd_alloc(mm)		get_pgd_fast()
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 #endif /* _SPARC64_PGALLOC_H */
--- linux/include/asm-x86_64/processor.h.orig
+++ linux/include/asm-x86_64/processor.h
@@ -163,6 +163,15 @@ static inline void clear_in_cr4 (unsigne
  */
 #define TASK_SIZE	(0x800000000000UL)
 
+#define TASK_SIZE_64	(0x800000000000)
+
+#define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE_64)
+
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
+
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
+  
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
--- linux/include/asm-x86_64/pgalloc.h.orig
+++ linux/include/asm-x86_64/pgalloc.h
@@ -7,6 +7,13 @@
 #include <linux/threads.h>
 #include <linux/mm.h>
 
+#define arch_add_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+#define arch_flush_exec_range(mm) \
+		do { (void)(mm); } while (0)
+#define arch_remove_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+
 #define pmd_populate_kernel(mm, pmd, pte) \
 		set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
 #define pud_populate(mm, pud, pmd) \


--- NEW FILE patch-2.6.12-rc1.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBCOksMyGugalF9Dw4RApIAAJ9yZHzcN79RAToabN1syo0Wn5z12ACdECmK
5brFFzOQr1IATJ95r8HgnXU=
=vOkd
-----END PGP SIGNATURE-----




More information about the fedora-cvs-commits mailing list