From: Suresh Siddha <suresh.b.siddha@intel.com>

Sync x86_64 noexec behaviour with i386.  And remove all the confusing
noexec related boot parameters.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/Documentation/kernel-parameters.txt   |    2 
 25-akpm/Documentation/x86_64/boot-options.txt |   16 ------
 25-akpm/arch/x86_64/ia32/ia32_binfmt.c        |   10 +---
 25-akpm/arch/x86_64/ia32/sys_ia32.c           |    8 ---
 25-akpm/arch/x86_64/kernel/setup64.c          |   61 +-------------------------
 25-akpm/include/asm-x86_64/elf.h              |    5 ++
 25-akpm/include/asm-x86_64/page.h             |   12 -----
 7 files changed, 17 insertions(+), 97 deletions(-)

diff -puN arch/x86_64/ia32/ia32_binfmt.c~no-exec-i386-and-x86_64-fixes arch/x86_64/ia32/ia32_binfmt.c
--- 25/arch/x86_64/ia32/ia32_binfmt.c~no-exec-i386-and-x86_64-fixes	2004-10-03 16:43:30.961624672 -0700
+++ 25-akpm/arch/x86_64/ia32/ia32_binfmt.c	2004-10-03 16:43:30.972623000 -0700
@@ -182,6 +182,7 @@ struct elf_prpsinfo
 #define user user32
 
 #define __ASM_X86_64_ELF_H 1
+#define elf_read_implies_exec(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
 //#include <asm/ia32.h>
 #include <linux/elf.h>
 
@@ -360,11 +361,11 @@ int setup_arg_pages(struct linux_binprm 
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
 		mpnt->vm_end = IA32_STACK_TOP;
 		if (executable_stack == EXSTACK_ENABLE_X)
-			mpnt->vm_flags = vm_stack_flags32 |  VM_EXEC;
+			mpnt->vm_flags = VM_STACK_FLAGS |  VM_EXEC;
 		else if (executable_stack == EXSTACK_DISABLE_X)
-			mpnt->vm_flags = vm_stack_flags32 & ~VM_EXEC;
+			mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
 		else
-			mpnt->vm_flags = vm_stack_flags32;
+			mpnt->vm_flags = VM_STACK_FLAGS;
  		mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? 
  			PAGE_COPY_EXEC : PAGE_COPY;
 		insert_vm_struct(mm, mpnt);
@@ -390,9 +391,6 @@ elf32_map (struct file *filep, unsigned 
 	unsigned long map_addr;
 	struct task_struct *me = current; 
 
-	if (prot & PROT_READ) 
-		prot |= vm_force_exec32;
-
 	down_write(&me->mm->mmap_sem);
 	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
 			   eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, 
diff -puN arch/x86_64/ia32/sys_ia32.c~no-exec-i386-and-x86_64-fixes arch/x86_64/ia32/sys_ia32.c
--- 25/arch/x86_64/ia32/sys_ia32.c~no-exec-i386-and-x86_64-fixes	2004-10-03 16:43:30.962624520 -0700
+++ 25-akpm/arch/x86_64/ia32/sys_ia32.c	2004-10-03 16:43:30.974622696 -0700
@@ -218,9 +218,6 @@ sys32_mmap(struct mmap_arg_struct __user
 			return -EBADF;
 	}
 	
-	if (a.prot & PROT_READ) 
-		a.prot |= vm_force_exec32;
-
 	mm = current->mm; 
 	down_write(&mm->mmap_sem); 
 	retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT);
@@ -235,8 +232,6 @@ sys32_mmap(struct mmap_arg_struct __user
 asmlinkage long 
 sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
 {
-	if (prot & PROT_READ) 
-		prot |= vm_force_exec32;
 	return sys_mprotect(start,len,prot); 
 }
 
@@ -1044,9 +1039,6 @@ asmlinkage long sys32_mmap2(unsigned lon
 			return -EBADF;
 	}
 
-	if (prot & PROT_READ)
-		prot |= vm_force_exec32;
-
 	down_write(&mm->mmap_sem);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 	up_write(&mm->mmap_sem);
diff -puN arch/x86_64/kernel/setup64.c~no-exec-i386-and-x86_64-fixes arch/x86_64/kernel/setup64.c
--- 25/arch/x86_64/kernel/setup64.c~no-exec-i386-and-x86_64-fixes	2004-10-03 16:43:30.964624216 -0700
+++ 25-akpm/arch/x86_64/kernel/setup64.c	2004-10-03 16:43:30.974622696 -0700
@@ -43,80 +43,27 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
 
 unsigned long __supported_pte_mask = ~0UL;
 static int do_not_nx __initdata = 0;
-unsigned long vm_stack_flags = __VM_STACK_FLAGS; 
-unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; 
-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; 
 
 /* noexec=on|off
 Control non executable mappings for 64bit processes.
 
-on	Enable
+on	Enable(default)
 off	Disable
-noforce (default) Don't enable by default for heap/stack/data, 
-	but allow PROT_EXEC to be effective
-
 */ 
 static int __init nonx_setup(char *str)
 {
 	if (!strcmp(str, "on")) {
                 __supported_pte_mask |= _PAGE_NX; 
  		do_not_nx = 0; 
- 		vm_data_default_flags &= ~VM_EXEC; 
- 		vm_stack_flags &= ~VM_EXEC;  
-	} else if (!strcmp(str, "noforce") || !strcmp(str, "off")) {
-		do_not_nx = (str[0] == 'o');
-		if (do_not_nx)
-			__supported_pte_mask &= ~_PAGE_NX; 
-		vm_data_default_flags |= VM_EXEC; 
-		vm_stack_flags |= VM_EXEC;
+	} else if (!strcmp(str, "off")) {
+		do_not_nx = 1;
+		__supported_pte_mask &= ~_PAGE_NX;
         } 
         return 1;
 } 
 
 __setup("noexec=", nonx_setup); 
 
-/* noexec32=opt{,opt} 
-
-Control the no exec default for 32bit processes. Can be also overwritten
-per executable using ELF header flags (e.g. needed for the X server)
-Requires noexec=on or noexec=noforce to be effective.
-
-Valid options: 
-   all,on    Heap,stack,data is non executable. 	
-   off       (default) Heap,stack,data is executable
-   stack     Stack is non executable, heap/data is.
-   force     Don't imply PROT_EXEC for PROT_READ 
-   compat    (default) Imply PROT_EXEC for PROT_READ
-
-*/
- static int __init nonx32_setup(char *s)
- {
-	 while (*s) {
-		if (!strncmp(s, "all", 3) || !strncmp(s,"on",2)) {
-			vm_data_default_flags32 &= ~VM_EXEC; 
-			vm_stack_flags32 &= ~VM_EXEC;  
-		} else if (!strncmp(s, "off",3)) {
-			vm_data_default_flags32 |= VM_EXEC; 
-			vm_stack_flags32 |= VM_EXEC;  
-		} else if (!strncmp(s, "stack", 5)) {
-			vm_data_default_flags32 |= VM_EXEC; 
-			vm_stack_flags32 &= ~VM_EXEC;  		
-		} else if (!strncmp(s, "force",5)) {
-			vm_force_exec32 = 0; 
-		} else if (!strncmp(s, "compat",5)) {
-			vm_force_exec32 = PROT_EXEC;
-		} 
-		s += strcspn(s, ",");
-		if (*s == ',')
-			++s;
-	 }
-	 return 1;
-} 
-
-__setup("noexec32=", nonx32_setup); 
-
 /*
  * Great future plan:
  * Declare PDA itself and support (irqstack,tss,pml4) as per cpu data.
diff -puN Documentation/kernel-parameters.txt~no-exec-i386-and-x86_64-fixes Documentation/kernel-parameters.txt
--- 25/Documentation/kernel-parameters.txt~no-exec-i386-and-x86_64-fixes	2004-10-03 16:43:30.965624064 -0700
+++ 25-akpm/Documentation/kernel-parameters.txt	2004-10-03 16:43:30.976622392 -0700
@@ -771,7 +771,7 @@ running once the system is up.
 
 	noexec		[IA-64]
 
-	noexec		[i386]
+	noexec		[i386, x86_64]
 			noexec=on: enable non-executable mappings (default)
 			noexec=off: disable nn-executable mappings
 
diff -puN Documentation/x86_64/boot-options.txt~no-exec-i386-and-x86_64-fixes Documentation/x86_64/boot-options.txt
--- 25/Documentation/x86_64/boot-options.txt~no-exec-i386-and-x86_64-fixes	2004-10-03 16:43:30.966623912 -0700
+++ 25-akpm/Documentation/x86_64/boot-options.txt	2004-10-03 16:43:30.976622392 -0700
@@ -87,22 +87,8 @@ Non Executable Mappings
 
   noexec=on|off
 
-  on      Enable
+  on      Enable(default)
   off     Disable
-  noforce (default) Don't enable by default for heap/stack/data,
-          but allow PROT_EXEC to be effective
-
-  noexec32=opt{,opt}
-
-  Control the no exec default for 32bit processes.
-  Requires noexec=on or noexec=noforce to be effective.
-
-  Valid options:
-     all,on    Heap,stack,data is non executable.
-     off       (default) Heap,stack,data is executable
-     stack     Stack is non executable, heap/data is.
-     force     Don't imply PROT_EXEC for PROT_READ
-     compat    (default) Imply PROT_EXEC for PROT_READ
 
 SMP
 
diff -puN include/asm-x86_64/elf.h~no-exec-i386-and-x86_64-fixes include/asm-x86_64/elf.h
--- 25/include/asm-x86_64/elf.h~no-exec-i386-and-x86_64-fixes	2004-10-03 16:43:30.968623608 -0700
+++ 25-akpm/include/asm-x86_64/elf.h	2004-10-03 16:43:30.977622240 -0700
@@ -143,6 +143,11 @@ typedef struct user_i387_struct elf_fpre
 #ifdef __KERNEL__
 extern void set_personality_64bit(void);
 #define SET_PERSONALITY(ex, ibcs2) set_personality_64bit()
+/*
+ * An executable for which elf_read_implies_exec() returns TRUE will
+ * have the READ_IMPLIES_EXEC personality flag set automatically.
+ */
+#define elf_read_implies_exec(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
 	
 /*
  * An executable for which elf_read_implies_exec() returns TRUE will
diff -puN include/asm-x86_64/page.h~no-exec-i386-and-x86_64-fixes include/asm-x86_64/page.h
--- 25/include/asm-x86_64/page.h~no-exec-i386-and-x86_64-fixes	2004-10-03 16:43:30.969623456 -0700
+++ 25-akpm/include/asm-x86_64/page.h	2004-10-03 16:43:30.977622240 -0700
@@ -130,18 +130,10 @@ extern __inline__ int get_order(unsigned
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
-#define __VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
-				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#define __VM_STACK_FLAGS 	(VM_GROWSDOWN | VM_READ | VM_WRITE | VM_EXEC | \
-                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
 #define VM_DATA_DEFAULT_FLAGS \
-	(test_thread_flag(TIF_IA32) ? vm_data_default_flags32 : \
-	  vm_data_default_flags) 
+	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define VM_STACK_DEFAULT_FLAGS \
-	(test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags) 
-	
 #define CONFIG_ARCH_GATE_AREA 1	
 
 #ifndef __ASSEMBLY__
_