Commit 48716031 authored by Suresh B. Siddha's avatar Suresh B. Siddha Committed by Linus Torvalds

[PATCH] no exec: i386 and x86_64 cleanups

Sync x86_64 noexec behaviour with i386.  And remove all the confusing
noexec related boot parameters.
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 18e1a8cb
...@@ -769,7 +769,7 @@ running once the system is up. ...@@ -769,7 +769,7 @@ running once the system is up.
noexec [IA-64] noexec [IA-64]
noexec [i386] noexec [i386, x86_64]
noexec=on: enable non-executable mappings (default) noexec=on: enable non-executable mappings (default)
noexec=off: disable nn-executable mappings noexec=off: disable nn-executable mappings
......
...@@ -87,22 +87,8 @@ Non Executable Mappings ...@@ -87,22 +87,8 @@ Non Executable Mappings
noexec=on|off noexec=on|off
on Enable on Enable(default)
off Disable 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 SMP
......
...@@ -182,6 +182,7 @@ struct elf_prpsinfo ...@@ -182,6 +182,7 @@ struct elf_prpsinfo
#define user user32 #define user user32
#define __ASM_X86_64_ELF_H 1 #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 <asm/ia32.h>
#include <linux/elf.h> #include <linux/elf.h>
...@@ -360,11 +361,11 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) ...@@ -360,11 +361,11 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p; mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
mpnt->vm_end = IA32_STACK_TOP; mpnt->vm_end = IA32_STACK_TOP;
if (executable_stack == EXSTACK_ENABLE_X) 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) else if (executable_stack == EXSTACK_DISABLE_X)
mpnt->vm_flags = vm_stack_flags32 & ~VM_EXEC; mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
else else
mpnt->vm_flags = vm_stack_flags32; mpnt->vm_flags = VM_STACK_FLAGS;
mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ?
PAGE_COPY_EXEC : PAGE_COPY; PAGE_COPY_EXEC : PAGE_COPY;
insert_vm_struct(mm, mpnt); insert_vm_struct(mm, mpnt);
...@@ -390,9 +391,6 @@ elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p ...@@ -390,9 +391,6 @@ elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p
unsigned long map_addr; unsigned long map_addr;
struct task_struct *me = current; struct task_struct *me = current;
if (prot & PROT_READ)
prot |= vm_force_exec32;
down_write(&me->mm->mmap_sem); down_write(&me->mm->mmap_sem);
map_addr = do_mmap(filep, ELF_PAGESTART(addr), map_addr = do_mmap(filep, ELF_PAGESTART(addr),
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot,
......
...@@ -218,9 +218,6 @@ sys32_mmap(struct mmap_arg_struct __user *arg) ...@@ -218,9 +218,6 @@ sys32_mmap(struct mmap_arg_struct __user *arg)
return -EBADF; return -EBADF;
} }
if (a.prot & PROT_READ)
a.prot |= vm_force_exec32;
mm = current->mm; mm = current->mm;
down_write(&mm->mmap_sem); down_write(&mm->mmap_sem);
retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT); 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 *arg) ...@@ -235,8 +232,6 @@ sys32_mmap(struct mmap_arg_struct __user *arg)
asmlinkage long asmlinkage long
sys32_mprotect(unsigned long start, size_t len, unsigned long prot) 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); return sys_mprotect(start,len,prot);
} }
...@@ -1044,9 +1039,6 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, ...@@ -1044,9 +1039,6 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
return -EBADF; return -EBADF;
} }
if (prot & PROT_READ)
prot |= vm_force_exec32;
down_write(&mm->mmap_sem); down_write(&mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&mm->mmap_sem); up_write(&mm->mmap_sem);
......
...@@ -43,80 +43,27 @@ char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); ...@@ -43,80 +43,27 @@ char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
unsigned long __supported_pte_mask = ~0UL; unsigned long __supported_pte_mask = ~0UL;
static int do_not_nx __initdata = 0; 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 /* noexec=on|off
Control non executable mappings for 64bit processes. Control non executable mappings for 64bit processes.
on Enable on Enable(default)
off Disable 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) static int __init nonx_setup(char *str)
{ {
if (!strcmp(str, "on")) { if (!strcmp(str, "on")) {
__supported_pte_mask |= _PAGE_NX; __supported_pte_mask |= _PAGE_NX;
do_not_nx = 0; do_not_nx = 0;
vm_data_default_flags &= ~VM_EXEC; } else if (!strcmp(str, "off")) {
vm_stack_flags &= ~VM_EXEC; do_not_nx = 1;
} else if (!strcmp(str, "noforce") || !strcmp(str, "off")) { __supported_pte_mask &= ~_PAGE_NX;
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;
} }
return 1; return 1;
} }
__setup("noexec=", nonx_setup); __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: * Great future plan:
* Declare PDA itself and support (irqstack,tss,pml4) as per cpu data. * Declare PDA itself and support (irqstack,tss,pml4) as per cpu data.
......
...@@ -143,6 +143,11 @@ typedef struct user_i387_struct elf_fpregset_t; ...@@ -143,6 +143,11 @@ typedef struct user_i387_struct elf_fpregset_t;
#ifdef __KERNEL__ #ifdef __KERNEL__
extern void set_personality_64bit(void); extern void set_personality_64bit(void);
#define SET_PERSONALITY(ex, ibcs2) set_personality_64bit() #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 * An executable for which elf_read_implies_exec() returns TRUE will
......
...@@ -130,18 +130,10 @@ extern __inline__ int get_order(unsigned long size) ...@@ -130,18 +130,10 @@ extern __inline__ int get_order(unsigned long size)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define pfn_to_kaddr(pfn) __va((pfn) << 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 \ #define VM_DATA_DEFAULT_FLAGS \
(test_thread_flag(TIF_IA32) ? vm_data_default_flags32 : \ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
vm_data_default_flags) 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 #define CONFIG_ARCH_GATE_AREA 1
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment