Skip to contentSkip to conversation

no exec: i386 and x86_64 fixes

PATCH In review Suresh Siddha 3 participants 4 messages Sep 24, 2004 – Oct 1, 2004

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 no exec: i386 and x86_64 fixes

Appended patch fixes

a) a bug in i386 which has to do with a typo
(change elf_read_implies_exec_binary to elf_read_implies_exec)

b) sync x86_64 noexec behaviour with i386. And remove all the confusing noexec related boot parameters.

Documentation/kernel-parameters.txt +1 -1
diff -Nru linux-2.6.9-rc2/Documentation/kernel-parameters.txt linux-nx/Documentation/kernel-parameters.txt
@@ -735,7 +735,7 @@
 
 	noexec		[IA-64]
 
-	noexec		[i386]
+	noexec		[i386, x86_64]
 			noexec=on: enable non-executable mappings (default)
 			noexec=off: disable nn-executable mappings
 
Documentation/x86_64/boot-options.txt +1 -15
diff -Nru linux-2.6.9-rc2/Documentation/x86_64/boot-options.txt linux-nx/Documentation/x86_64/boot-options.txt
@@ -87,22 +87,8 @@
 
   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
 
arch/x86_64/ia32/ia32_binfmt.c +4 -6
diff -Nru linux-2.6.9-rc2/arch/x86_64/ia32/ia32_binfmt.c linux-nx/arch/x86_64/ia32/ia32_binfmt.c
@@ -182,6 +182,7 @@
 #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 @@
 		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 @@
 	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, 
arch/x86_64/ia32/sys_ia32.c +0 -8
diff -Nru linux-2.6.9-rc2/arch/x86_64/ia32/sys_ia32.c linux-nx/arch/x86_64/ia32/sys_ia32.c
@@ -218,9 +218,6 @@
 			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 @@
 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 @@
 			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);
arch/x86_64/kernel/setup64.c +4 -57

84 lines not on this page · raw message

include/asm-i386/elf.h +1 -1
diff -Nru linux-2.6.9-rc2/include/asm-i386/elf.h linux-nx/include/asm-i386/elf.h
@@ -123,7 +123,7 @@
  * 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_binary(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
+#define elf_read_implies_exec(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
 
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
include/asm-x86_64/elf.h +5 -0
diff -Nru linux-2.6.9-rc2/include/asm-x86_64/elf.h linux-nx/include/asm-x86_64/elf.h
@@ -143,6 +143,11 @@
 #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))
 	
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
include/asm-x86_64/page.h +2 -10
diff -Nru linux-2.6.9-rc2/include/asm-x86_64/page.h linux-nx/include/asm-x86_64/page.h
@@ -130,18 +130,10 @@
 #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__
#1 lore raw
Quoted 7 lines · Suresh Siddha

Appended patch fixes

a) a bug in i386 which has to do with a typo
(change elf_read_implies_exec_binary to elf_read_implies_exec)

b) sync x86_64 noexec behaviour with i386. And remove all the confusing noexec related boot parameters.

Thanks, x86-64 part looks good.
-Andi

#2 lore raw

PATCH 1/1 no exec: sync x86_64 behaviour with i386

Quoted 1 line · Andi Kleen

Thanks, x86-64 part looks good.

Quoted 4 lines · Ingo Molnar
Quoted 1 line · Suresh Siddha

+#define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))

yeah, we noticed this a couple of days ago and the fix is in BK already (post 2.6.9-rc2 commit).

Here is a new patch with the already fixed i386 hunk removed. Andrew/Andi please apply.

thanks,
suresh
--

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

arch/x86_64/ia32/ia32_binfmt.c +4 -6
diff -Nru linux-2.6.9-rc3/arch/x86_64/ia32/ia32_binfmt.c linux-nx/arch/x86_64/ia32/ia32_binfmt.c
@@ -182,6 +182,7 @@
 #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 @@
 		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 @@
 	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, 
arch/x86_64/ia32/sys_ia32.c +0 -8
diff -Nru linux-2.6.9-rc3/arch/x86_64/ia32/sys_ia32.c linux-nx/arch/x86_64/ia32/sys_ia32.c
@@ -218,9 +218,6 @@
 			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 @@
 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 @@
 			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);
arch/x86_64/kernel/setup64.c +4 -57

84 lines not on this page · raw message

Documentation/kernel-parameters.txt +1 -1
diff -Nru linux-2.6.9-rc3/Documentation/kernel-parameters.txt linux-nx/Documentation/kernel-parameters.txt
@@ -746,7 +746,7 @@
 
 	noexec		[IA-64]
 
-	noexec		[i386]
+	noexec		[i386, x86_64]
 			noexec=on: enable non-executable mappings (default)
 			noexec=off: disable nn-executable mappings
 
Documentation/x86_64/boot-options.txt +1 -15
diff -Nru linux-2.6.9-rc3/Documentation/x86_64/boot-options.txt linux-nx/Documentation/x86_64/boot-options.txt
@@ -87,22 +87,8 @@
 
   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
 
include/asm-x86_64/elf.h +5 -0
diff -Nru linux-2.6.9-rc3/include/asm-x86_64/elf.h linux-nx/include/asm-x86_64/elf.h
@@ -143,6 +143,11 @@
 #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
include/asm-x86_64/page.h +2 -10
diff -Nru linux-2.6.9-rc3/include/asm-x86_64/page.h linux-nx/include/asm-x86_64/page.h
@@ -130,18 +130,10 @@
 #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__
#3 lore raw
In reply to Suresh Siddha

include/asm-i386/elf.h line 126

Quoted 5 lines · Suresh Siddha

* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically. */

include/asm-i386/elf.h +1 -1
-#define elf_read_implies_exec_binary(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
+#define elf_read_implies_exec(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))

yeah, we noticed this a couple of days ago and the fix is in BK already (post 2.6.9-rc2 commit).

Ingo