From: Suresh Siddha Sync x86_64 noexec behaviour with i386. And remove all the confusing noexec related boot parameters. Signed-off-by: Suresh Siddha Signed-off-by: Andrew Morton --- 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-01 20:16:18.609240184 -0700 +++ 25-akpm/arch/x86_64/ia32/ia32_binfmt.c 2004-10-01 20:16:18.621238360 -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 #include @@ -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-01 20:16:18.610240032 -0700 +++ 25-akpm/arch/x86_64/ia32/sys_ia32.c 2004-10-01 20:16:18.622238208 -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-01 20:16:18.612239728 -0700 +++ 25-akpm/arch/x86_64/kernel/setup64.c 2004-10-01 20:16:18.623238056 -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-01 20:16:18.613239576 -0700 +++ 25-akpm/Documentation/kernel-parameters.txt 2004-10-01 20:16:18.624237904 -0700 @@ -774,7 +774,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-01 20:16:18.614239424 -0700 +++ 25-akpm/Documentation/x86_64/boot-options.txt 2004-10-01 20:16:18.624237904 -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-01 20:16:18.616239120 -0700 +++ 25-akpm/include/asm-x86_64/elf.h 2004-10-01 20:16:18.625237752 -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-01 20:16:18.617238968 -0700 +++ 25-akpm/include/asm-x86_64/page.h 2004-10-01 20:16:18.625237752 -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__ _