From: Stephen Rothwell Date: Mon, 8 Oct 2012 02:45:44 +0000 (+1100) Subject: Merge remote-tracking branch 'signal/for-next' X-Git-Tag: next-20121008~3 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=b9b4f6ade6346645158449f166367735c92b3ac8;p=karo-tx-linux.git Merge remote-tracking branch 'signal/for-next' Conflicts: arch/alpha/Kconfig arch/arm/Kconfig arch/arm/include/asm/thread_info.h arch/avr32/include/asm/Kbuild arch/c6x/Kconfig arch/cris/include/asm/Kbuild arch/frv/include/asm/Kbuild arch/h8300/include/asm/Kbuild arch/ia64/include/asm/Kbuild arch/m32r/include/asm/Kbuild arch/m68k/Kconfig arch/microblaze/include/asm/Kbuild arch/mn10300/Kconfig arch/mn10300/include/asm/Kbuild arch/powerpc/Kconfig arch/s390/Kconfig arch/um/kernel/exec.c arch/x86/Kconfig arch/x86/kernel/process_32.c arch/x86/kernel/signal.c arch/xtensa/include/asm/Kbuild fs/exec.c --- b9b4f6ade6346645158449f166367735c92b3ac8 diff --cc arch/alpha/Kconfig index 7e3710c0cce5,7da91246e279..6ac8f6e512f6 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@@ -20,8 -20,7 +20,9 @@@ config ALPH select GENERIC_CMOS_UPDATE select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA + select GENERIC_KERNEL_THREAD help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --cc arch/arm/Kconfig index 6434a3ca79e5,a949eec22861..e85f2b635bc3 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@@ -50,8 -49,7 +50,9 @@@ config AR select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN + select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND + select MODULES_USE_ELF_REL + select GENERIC_KERNEL_THREAD help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --cc arch/arm/include/asm/thread_info.h index f71cdab18b87,b2d6b412172d..8477b4c1d39f --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@@ -150,8 -148,6 +150,7 @@@ extern int vfp_restore_user_hwstate(str #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 +#define TIF_SYSCALL_TRACEPOINT 10 - #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 20 @@@ -163,8 -159,6 +162,7 @@@ #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) +#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) - #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) diff --cc arch/avr32/include/asm/Kbuild index e3ba7bca06fa,aa47fff70760..be0433ee5a8e --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@@ -1,5 -1,4 +1,6 @@@ include include/asm-generic/Kbuild.asm +generic-y += clkdev.h + generic-y += exec.h + header-y += cachectl.h diff --cc arch/c6x/Kconfig index f6a3648f5ec3,45268b50c0c8..20ef56e467b3 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@@ -17,7 -17,7 +17,8 @@@ config C6 select OF select OF_EARLY_FLATTREE select GENERIC_CLOCKEVENTS + select MODULES_USE_ELF_RELA + select GENERIC_KERNEL_THREAD config MMU def_bool n diff --cc arch/c6x/include/asm/unistd.h index ed2259043eec,3c131d5888c1..4ff747d12dad --- a/arch/c6x/include/asm/unistd.h +++ b/arch/c6x/include/asm/unistd.h @@@ -13,7 -13,12 +13,10 @@@ * NON INFRINGEMENT. See the GNU General Public License for * more details. */ -#if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL) -#define _ASM_C6X_UNISTD_H + #define __ARCH_WANT_KERNEL_EXECVE + #define __ARCH_WANT_SYS_EXECVE + /* Use the standard ABI for syscalls. */ #include diff --cc arch/cris/include/asm/Kbuild index 6900bbf903c5,b68ad4bfa088..a0f88f2b2425 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@@ -8,5 -8,4 +8,6 @@@ header-y += etraxgpio. header-y += rs485.h header-y += sync_serial.h +generic-y += module.h +generic-y += clkdev.h + generic-y += exec.h diff --cc arch/frv/include/asm/Kbuild index 13cd044aabdf,32c16468cf5e..557eba73997c --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@@ -2,4 -2,4 +2,6 @@@ include include/asm-generic/Kbuild.as header-y += registers.h header-y += termios.h ++ +generic-y += clkdev.h + generic-y += exec.h diff --cc arch/h8300/include/asm/Kbuild index 98477e928788,3a2af1a2974f..1e8326951f4b --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild @@@ -1,4 -1,2 +1,5 @@@ include include/asm-generic/Kbuild.asm + +generic-y += module.h +generic-y += clkdev.h + generic-y += exec.h diff --cc arch/ia64/include/asm/Kbuild index d756d59034b8,98efd48d7da4..72a50b2b4857 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@@ -1,1 -1,16 +1,2 @@@ -include include/asm-generic/Kbuild.asm - -header-y += break.h -header-y += cmpxchg.h -header-y += fpu.h -header-y += gcc_intrin.h -header-y += ia64regs.h -header-y += intel_intrin.h -header-y += intrinsics.h -header-y += perfmon.h -header-y += perfmon_default_smpl.h -header-y += ptrace_offsets.h -header-y += rse.h -header-y += ucontext.h -header-y += ustack.h +generic-y += clkdev.h + generic-y += exec.h diff --cc arch/m32r/include/asm/Kbuild index 98477e928788,708340339b05..1e8326951f4b --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@@ -1,4 -1,3 +1,5 @@@ include include/asm-generic/Kbuild.asm +generic-y += module.h +generic-y += clkdev.h + generic-y += exec.h diff --cc arch/m68k/Kconfig index 0df07cee3faf,ccda007ba40f..b4126a7dfddc --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@@ -13,9 -13,7 +13,10 @@@ config M68 select FPU if MMU select ARCH_WANT_IPC_PARSE_VERSION select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_REL + select MODULES_USE_ELF_RELA + select GENERIC_KERNEL_THREAD config RWSEM_GENERIC_SPINLOCK bool diff --cc arch/microblaze/include/asm/Kbuild index 48510f6cec8f,5a0e72bf998d..8653072d7e9f --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@@ -1,4 -1,4 +1,5 @@@ include include/asm-generic/Kbuild.asm header-y += elf.h +generic-y += clkdev.h + generic-y += exec.h diff --cc arch/mn10300/Kconfig index aa03f2e13385,ddbdc33471a8..549b9e50182e --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@@ -8,7 -8,7 +8,8 @@@ config MN1030 select HAVE_ARCH_KGDB select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER select GENERIC_CLOCKEVENTS + select MODULES_USE_ELF_RELA + select GENERIC_KERNEL_THREAD config AM33_2 def_bool n diff --cc arch/mn10300/include/asm/Kbuild index 0d20f5526dd8,708340339b05..fccd81eddff1 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@@ -1,3 -1,3 +1,4 @@@ include include/asm-generic/Kbuild.asm +generic-y += clkdev.h + generic-y += exec.h diff --cc arch/parisc/include/asm/Kbuild index 0587f62e5b76,818d65165678..458371a1565a --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@@ -1,5 -1,5 +1,6 @@@ include include/asm-generic/Kbuild.asm header-y += pdc.h +generic-y += clkdev.h generic-y += word-at-a-time.h + generic-y += exec.h diff --cc arch/powerpc/Kconfig index 8d8a7c6a7066,6e5a0979c085..088fc76ce9f0 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@@ -139,8 -139,7 +139,9 @@@ config PP select GENERIC_CLOCKEVENTS select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA + select GENERIC_KERNEL_THREAD config EARLY_PRINTK bool diff --cc arch/powerpc/include/asm/unistd.h index c683fa350add,26a6825909b6..2533752af30f --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@@ -419,8 -419,9 +419,10 @@@ #define __ARCH_WANT_COMPAT_SYS_TIME #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_NEWFSTATAT +#define __ARCH_WANT_COMPAT_SYS_SENDFILE #endif + #define __ARCH_WANT_SYS_EXECVE + #define __ARCH_WANT_KERNEL_EXECVE /* * "Conditional" syscalls diff --cc arch/powerpc/kernel/sys_ppc32.c index abd1112da54f,a1ae73a0f352..9c2ed90ece8f --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@@ -143,41 -143,50 +143,19 @@@ long compat_sys_ipc(u32 call, u32 first * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */ -asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) +asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd, + compat_off_t __user *offset, u32 count) { - mm_segment_t old_fs = get_fs(); - int ret; - off_t of; - off_t __user *up; - - if (offset && get_user(of, offset)) - return -EFAULT; - - /* The __user pointer cast is valid because of the set_fs() */ - set_fs(KERNEL_DS); - up = offset ? (off_t __user *) &of : NULL; - ret = sys_sendfile((int)out_fd, (int)in_fd, up, count); - set_fs(old_fs); - - if (offset && put_user(of, offset)) - return -EFAULT; - - return ret; + return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count); } -asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) +asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd, + compat_loff_t __user *offset, u32 count) { - mm_segment_t old_fs = get_fs(); - int ret; - loff_t lof; - loff_t __user *up; - - if (offset && get_user(lof, offset)) - return -EFAULT; - - /* The __user pointer cast is valid because of the set_fs() */ - set_fs(KERNEL_DS); - up = offset ? (loff_t __user *) &lof : NULL; - ret = sys_sendfile64(out_fd, in_fd, up, count); - set_fs(old_fs); - - if (offset && put_user(lof, offset)) - return -EFAULT; - - return ret; + return sys_sendfile((int)out_fd, (int)in_fd, + (off_t __user *)offset, count); } - long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - struct pt_regs *regs) - { - int error; - char * filename; - - filename = getname((char __user *) a0); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - flush_fp_to_thread(current); - flush_altivec_to_thread(current); - - error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs); - - putname(filename); - - out: - return error; - } - /* Note: it is necessary to treat option as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) diff --cc arch/s390/Kconfig index de7ce84eae56,57442393bac7..35eaaaa62d3f --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@@ -132,8 -125,7 +132,9 @@@ config S39 select GENERIC_CLOCKEVENTS select KTIME_SCALAR if 32BIT select HAVE_ARCH_SECCOMP_FILTER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA + select GENERIC_KERNEL_THREAD config SCHED_OMIT_FRAME_POINTER def_bool y diff --cc arch/s390/include/asm/processor.h index 56831dfa9198,da6f5baeee5c..94e749c90230 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@@ -142,15 -133,8 +145,14 @@@ struct task_struct struct mm_struct; struct seq_file; +#ifdef CONFIG_64BIT +extern void show_cacheinfo(struct seq_file *m); +#else +static inline void show_cacheinfo(struct seq_file *m) { } +#endif + /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); - extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); /* * Return saved PC of a blocked thread. diff --cc arch/s390/kernel/process.c index 5024be27df44,bab088de4569..cd31ad457a9b --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@@ -169,15 -146,25 +149,30 @@@ int copy_thread(unsigned long clone_fla /* fake return stack for resume(), don't go back to schedule */ frame->sf.gprs[9] = (unsigned long) frame; - /* Save access registers to new thread structure. */ - save_access_regs(&p->thread.acrs[0]); + /* Store access registers to kernel stack of new process. */ + if (unlikely(!regs)) { + /* kernel thread */ + memset(&frame->childregs, 0, sizeof(struct pt_regs)); + frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | + PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; + frame->childregs.psw.addr = PSW_ADDR_AMODE | + (unsigned long) kernel_thread_starter; + frame->childregs.gprs[9] = new_stackp; /* function */ + frame->childregs.gprs[10] = arg; + frame->childregs.gprs[11] = (unsigned long) do_exit; + frame->childregs.orig_gpr2 = -1; + + return 0; + } + frame->childregs = *regs; + frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ + frame->childregs.gprs[15] = new_stackp; + /* Don't copy runtime instrumentation info */ + p->thread.ri_cb = NULL; + p->thread.ri_signum = 0; + frame->childregs.psw.mask &= ~PSW_MASK_RI; + #ifndef CONFIG_64BIT /* * save fprs to current->thread.fp_regs to merge them with diff --cc arch/sparc/include/asm/Kbuild index 100aa10fd78f,cf1e85782703..164e6f24671c --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@@ -17,8 -17,8 +17,9 @@@ header-y += uctx. header-y += utrap.h header-y += watchdog.h +generic-y += clkdev.h generic-y += div64.h + generic-y += exec.h generic-y += local64.h generic-y += irq_regs.h generic-y += local.h diff --cc arch/x86/Kconfig index 3ba3813932ba,d93eb9d1bb97..8fc92d61a786 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@@ -102,14 -97,10 +102,15 @@@ config X8 select KTIME_SCALAR if X86_32 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select MODULES_USE_ELF_REL if X86_32 + select MODULES_USE_ELF_RELA if X86_64 + select HAVE_RCU_USER_QS if X86_64 + select HAVE_IRQ_TIME_ACCOUNTING + select GENERIC_KERNEL_THREAD config INSTRUCTION_DECODER - def_bool (KPROBES || PERF_EVENTS || UPROBES) + def_bool y + depends on KPROBES || PERF_EVENTS || UPROBES config OUTPUT_FORMAT string diff --cc arch/x86/kernel/process_32.c index b9ff83c7135b,25e7e9390d26..44e0bff38e72 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@@ -190,6 -207,16 +207,12 @@@ start_thread(struct pt_regs *regs, unsi regs->cs = __USER_CS; regs->ip = new_ip; regs->sp = new_sp; + regs->flags = X86_EFLAGS_IF; - /* - * Free the old FP and other extended state - */ - free_thread_xstate(current); + /* + * force it to the iret return path by making it look as if there was + * some work pending. + */ + set_thread_flag(TIF_NOTIFY_RESUME); } EXPORT_SYMBOL_GPL(start_thread); diff --cc arch/x86/kernel/signal.c index b33144c8b309,c648fc529872..29ad351804e9 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@@ -839,12 -800,6 +839,8 @@@ do_notify_resume(struct pt_regs *regs, } if (thread_info_flags & _TIF_USER_RETURN_NOTIFY) fire_user_return_notifiers(); + - #ifdef CONFIG_X86_32 - clear_thread_flag(TIF_IRET); - #endif /* CONFIG_X86_32 */ - + rcu_user_enter(); } void signal_fault(struct pt_regs *regs, void __user *frame, char *where) diff --cc arch/xtensa/include/asm/Kbuild index 0d20f5526dd8,708340339b05..fccd81eddff1 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@@ -1,3 -1,3 +1,4 @@@ include include/asm-generic/Kbuild.asm +generic-y += clkdev.h + generic-y += exec.h diff --cc fs/binfmt_elf.c index 28a64e769527,2ab91905b2e2..5ce922db010d --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@@ -36,15 -35,7 +36,14 @@@ #include #include #include - #include +#ifndef user_long_t +#define user_long_t long +#endif +#ifndef user_siginfo_t +#define user_siginfo_t siginfo_t +#endif + 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 *, diff --cc fs/exec.c index 9824473a7ec1,50a1270da95b..b91051215ce7 --- a/fs/exec.c +++ b/fs/exec.c @@@ -1646,3 -2031,342 +1645,55 @@@ int get_dumpable(struct mm_struct *mm { return __get_dumpable(mm->flags); } + -static void wait_for_dump_helpers(struct file *file) -{ - struct pipe_inode_info *pipe; - - pipe = file->f_path.dentry->d_inode->i_pipe; - - pipe_lock(pipe); - pipe->readers++; - pipe->writers--; - - while ((pipe->readers > 1) && (!signal_pending(current))) { - wake_up_interruptible_sync(&pipe->wait); - kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); - pipe_wait(pipe); - } - - pipe->readers--; - pipe->writers++; - pipe_unlock(pipe); - -} - - -/* - * umh_pipe_setup - * helper function to customize the process used - * to collect the core in userspace. Specifically - * it sets up a pipe and installs it as fd 0 (stdin) - * for the process. Returns 0 on success, or - * PTR_ERR on failure. - * Note that it also sets the core limit to 1. This - * is a special value that we use to trap recursive - * core dumps - */ -static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) -{ - struct file *files[2]; - struct fdtable *fdt; - struct coredump_params *cp = (struct coredump_params *)info->data; - struct files_struct *cf = current->files; - int err = create_pipe_files(files, 0); - if (err) - return err; - - cp->file = files[1]; - - sys_close(0); - fd_install(0, files[0]); - spin_lock(&cf->file_lock); - fdt = files_fdtable(cf); - __set_open_fd(0, fdt); - __clear_close_on_exec(0, fdt); - spin_unlock(&cf->file_lock); - - /* and disallow core files too */ - current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; - - return 0; -} - -void do_coredump(long signr, int exit_code, struct pt_regs *regs) -{ - struct core_state core_state; - struct core_name cn; - struct mm_struct *mm = current->mm; - struct linux_binfmt * binfmt; - const struct cred *old_cred; - struct cred *cred; - int retval = 0; - int flag = 0; - int ispipe; - bool need_nonrelative = false; - static atomic_t core_dump_count = ATOMIC_INIT(0); - struct coredump_params cprm = { - .signr = signr, - .regs = regs, - .limit = rlimit(RLIMIT_CORE), - /* - * We must use the same mm->flags while dumping core to avoid - * inconsistency of bit flags, since this flag is not protected - * by any locks. - */ - .mm_flags = mm->flags, - }; - - audit_core_dumps(signr); - - binfmt = mm->binfmt; - if (!binfmt || !binfmt->core_dump) - goto fail; - if (!__get_dumpable(cprm.mm_flags)) - goto fail; - - cred = prepare_creds(); - if (!cred) - goto fail; - /* - * We cannot trust fsuid as being the "true" uid of the process - * nor do we know its entire history. We only know it was tainted - * so we dump it as root in mode 2, and only into a controlled - * environment (pipe handler or fully qualified path). - */ - if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) { - /* Setuid core dump mode */ - flag = O_EXCL; /* Stop rewrite attacks */ - cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ - need_nonrelative = true; - } - - retval = coredump_wait(exit_code, &core_state); - if (retval < 0) - goto fail_creds; - - old_cred = override_creds(cred); - - /* - * Clear any false indication of pending signals that might - * be seen by the filesystem code called to write the core file. - */ - clear_thread_flag(TIF_SIGPENDING); - - ispipe = format_corename(&cn, signr); - - if (ispipe) { - int dump_count; - char **helper_argv; - - if (ispipe < 0) { - printk(KERN_WARNING "format_corename failed\n"); - printk(KERN_WARNING "Aborting core\n"); - goto fail_corename; - } - - if (cprm.limit == 1) { - /* See umh_pipe_setup() which sets RLIMIT_CORE = 1. - * - * Normally core limits are irrelevant to pipes, since - * we're not writing to the file system, but we use - * cprm.limit of 1 here as a speacial value, this is a - * consistent way to catch recursive crashes. - * We can still crash if the core_pattern binary sets - * RLIM_CORE = !1, but it runs as root, and can do - * lots of stupid things. - * - * Note that we use task_tgid_vnr here to grab the pid - * of the process group leader. That way we get the - * right pid if a thread in a multi-threaded - * core_pattern process dies. - */ - printk(KERN_WARNING - "Process %d(%s) has RLIMIT_CORE set to 1\n", - task_tgid_vnr(current), current->comm); - printk(KERN_WARNING "Aborting core\n"); - goto fail_unlock; - } - cprm.limit = RLIM_INFINITY; - - dump_count = atomic_inc_return(&core_dump_count); - if (core_pipe_limit && (core_pipe_limit < dump_count)) { - printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", - task_tgid_vnr(current), current->comm); - printk(KERN_WARNING "Skipping core dump\n"); - goto fail_dropcount; - } - - helper_argv = argv_split(GFP_KERNEL, cn.corename+1, NULL); - if (!helper_argv) { - printk(KERN_WARNING "%s failed to allocate memory\n", - __func__); - goto fail_dropcount; - } - - retval = call_usermodehelper_fns(helper_argv[0], helper_argv, - NULL, UMH_WAIT_EXEC, umh_pipe_setup, - NULL, &cprm); - argv_free(helper_argv); - if (retval) { - printk(KERN_INFO "Core dump to %s pipe failed\n", - cn.corename); - goto close_fail; - } - } else { - struct inode *inode; - - if (cprm.limit < binfmt->min_coredump) - goto fail_unlock; - - if (need_nonrelative && cn.corename[0] != '/') { - printk(KERN_WARNING "Pid %d(%s) can only dump core "\ - "to fully qualified path!\n", - task_tgid_vnr(current), current->comm); - printk(KERN_WARNING "Skipping core dump\n"); - goto fail_unlock; - } - - cprm.file = filp_open(cn.corename, - O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, - 0600); - if (IS_ERR(cprm.file)) - goto fail_unlock; - - inode = cprm.file->f_path.dentry->d_inode; - if (inode->i_nlink > 1) - goto close_fail; - if (d_unhashed(cprm.file->f_path.dentry)) - goto close_fail; - /* - * AK: actually i see no reason to not allow this for named - * pipes etc, but keep the previous behaviour for now. - */ - if (!S_ISREG(inode->i_mode)) - goto close_fail; - /* - * Dont allow local users get cute and trick others to coredump - * into their pre-created files. - */ - if (!uid_eq(inode->i_uid, current_fsuid())) - goto close_fail; - if (!cprm.file->f_op || !cprm.file->f_op->write) - goto close_fail; - if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file)) - goto close_fail; - } - - retval = binfmt->core_dump(&cprm); - if (retval) - current->signal->group_exit_code |= 0x80; - - if (ispipe && core_pipe_limit) - wait_for_dump_helpers(cprm.file); -close_fail: - if (cprm.file) - filp_close(cprm.file, NULL); -fail_dropcount: - if (ispipe) - atomic_dec(&core_dump_count); -fail_unlock: - kfree(cn.corename); -fail_corename: - coredump_finish(mm); - revert_creds(old_cred); -fail_creds: - put_cred(cred); -fail: - return; -} - -/* - * Core dumping helper functions. These are the only things you should - * do on a core-file: use only these functions to write out all the - * necessary info. - */ -int dump_write(struct file *file, const void *addr, int nr) -{ - return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr; -} -EXPORT_SYMBOL(dump_write); - -int dump_seek(struct file *file, loff_t off) -{ - int ret = 1; - - if (file->f_op->llseek && file->f_op->llseek != no_llseek) { - if (file->f_op->llseek(file, off, SEEK_CUR) < 0) - return 0; - } else { - char *buf = (char *)get_zeroed_page(GFP_KERNEL); - - if (!buf) - return 0; - while (off > 0) { - unsigned long n = off; - - if (n > PAGE_SIZE) - n = PAGE_SIZE; - if (!dump_write(file, buf, n)) { - ret = 0; - break; - } - off -= n; - } - free_page((unsigned long)buf); - } - return ret; -} -EXPORT_SYMBOL(dump_seek); - + #ifdef __ARCH_WANT_SYS_EXECVE + SYSCALL_DEFINE3(execve, + const char __user *, filename, + const char __user *const __user *, argv, + const char __user *const __user *, envp) + { + const char *path = getname(filename); + int error = PTR_ERR(path); + if (!IS_ERR(path)) { + error = do_execve(path, argv, envp, current_pt_regs()); + putname(path); + } + return error; + } + #ifdef CONFIG_COMPAT + asmlinkage long compat_sys_execve(const char __user * filename, + const compat_uptr_t __user * argv, + const compat_uptr_t __user * envp) + { + const char *path = getname(filename); + int error = PTR_ERR(path); + if (!IS_ERR(path)) { + error = compat_do_execve(path, argv, envp, current_pt_regs()); + putname(path); + } + return error; + } + #endif + #endif + + #ifdef __ARCH_WANT_KERNEL_EXECVE + int kernel_execve(const char *filename, + const char *const argv[], + const char *const envp[]) + { + struct pt_regs *p = current_pt_regs(); + int ret; + + ret = do_execve(filename, + (const char __user *const __user *)argv, + (const char __user *const __user *)envp, p); + if (ret < 0) + return ret; + + /* + * We were successful. We won't be returning to our caller, but + * instead to user space by manipulating the kernel stack. + */ + ret_from_kernel_execve(p); + } + #endif