aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-09 23:02:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-09 23:02:25 -0400
commit42859eea96ba6beabfb0369a1eeffa3c7d2bd9cb (patch)
treefa38aeda0d6e7a4c48a882b166b8643594a1ad50 /fs/exec.c
parentf59b51fe3d3092c08d7d554ecb40db24011b2ebc (diff)
parentf322220d6159455da2b5a8a596d802c8695fed30 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull generic execve() changes from Al Viro: "This introduces the generic kernel_thread() and kernel_execve() functions, and switches x86, arm, alpha, um and s390 over to them." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (26 commits) s390: convert to generic kernel_execve() s390: switch to generic kernel_thread() s390: fold kernel_thread_helper() into ret_from_fork() s390: fold execve_tail() into start_thread(), convert to generic sys_execve() um: switch to generic kernel_thread() x86, um/x86: switch to generic sys_execve and kernel_execve x86: split ret_from_fork alpha: introduce ret_from_kernel_execve(), switch to generic kernel_execve() alpha: switch to generic kernel_thread() alpha: switch to generic sys_execve() arm: get rid of execve wrapper, switch to generic execve() implementation arm: optimized current_pt_regs() arm: introduce ret_from_kernel_execve(), switch to generic kernel_execve() arm: split ret_from_fork, simplify kernel_thread() [based on patch by rmk] generic sys_execve() generic kernel_execve() new helper: current_pt_regs() preparation for generic kernel_thread() um: kill thread->forking um: let signal_delivered() do SIGTRAP on singlestepping into handler ...
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c61
1 files changed, 56 insertions, 5 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 4f2bebc276c5..ca434534ae9a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -59,7 +59,6 @@
59#include <asm/uaccess.h> 59#include <asm/uaccess.h>
60#include <asm/mmu_context.h> 60#include <asm/mmu_context.h>
61#include <asm/tlb.h> 61#include <asm/tlb.h>
62#include <asm/exec.h>
63 62
64#include <trace/events/task.h> 63#include <trace/events/task.h>
65#include "internal.h" 64#include "internal.h"
@@ -392,7 +391,7 @@ struct user_arg_ptr {
392 union { 391 union {
393 const char __user *const __user *native; 392 const char __user *const __user *native;
394#ifdef CONFIG_COMPAT 393#ifdef CONFIG_COMPAT
395 compat_uptr_t __user *compat; 394 const compat_uptr_t __user *compat;
396#endif 395#endif
397 } ptr; 396 } ptr;
398}; 397};
@@ -1574,9 +1573,9 @@ int do_execve(const char *filename,
1574} 1573}
1575 1574
1576#ifdef CONFIG_COMPAT 1575#ifdef CONFIG_COMPAT
1577int compat_do_execve(char *filename, 1576int compat_do_execve(const char *filename,
1578 compat_uptr_t __user *__argv, 1577 const compat_uptr_t __user *__argv,
1579 compat_uptr_t __user *__envp, 1578 const compat_uptr_t __user *__envp,
1580 struct pt_regs *regs) 1579 struct pt_regs *regs)
1581{ 1580{
1582 struct user_arg_ptr argv = { 1581 struct user_arg_ptr argv = {
@@ -1658,3 +1657,55 @@ int get_dumpable(struct mm_struct *mm)
1658{ 1657{
1659 return __get_dumpable(mm->flags); 1658 return __get_dumpable(mm->flags);
1660} 1659}
1660
1661#ifdef __ARCH_WANT_SYS_EXECVE
1662SYSCALL_DEFINE3(execve,
1663 const char __user *, filename,
1664 const char __user *const __user *, argv,
1665 const char __user *const __user *, envp)
1666{
1667 const char *path = getname(filename);
1668 int error = PTR_ERR(path);
1669 if (!IS_ERR(path)) {
1670 error = do_execve(path, argv, envp, current_pt_regs());
1671 putname(path);
1672 }
1673 return error;
1674}
1675#ifdef CONFIG_COMPAT
1676asmlinkage long compat_sys_execve(const char __user * filename,
1677 const compat_uptr_t __user * argv,
1678 const compat_uptr_t __user * envp)
1679{
1680 const char *path = getname(filename);
1681 int error = PTR_ERR(path);
1682 if (!IS_ERR(path)) {
1683 error = compat_do_execve(path, argv, envp, current_pt_regs());
1684 putname(path);
1685 }
1686 return error;
1687}
1688#endif
1689#endif
1690
1691#ifdef __ARCH_WANT_KERNEL_EXECVE
1692int kernel_execve(const char *filename,
1693 const char *const argv[],
1694 const char *const envp[])
1695{
1696 struct pt_regs *p = current_pt_regs();
1697 int ret;
1698
1699 ret = do_execve(filename,
1700 (const char __user *const __user *)argv,
1701 (const char __user *const __user *)envp, p);
1702 if (ret < 0)
1703 return ret;
1704
1705 /*
1706 * We were successful. We won't be returning to our caller, but
1707 * instead to user space by manipulating the kernel stack.
1708 */
1709 ret_from_kernel_execve(p);
1710}
1711#endif