diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 23:02:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 23:02:25 -0400 |
commit | 42859eea96ba6beabfb0369a1eeffa3c7d2bd9cb (patch) | |
tree | fa38aeda0d6e7a4c48a882b166b8643594a1ad50 /fs/exec.c | |
parent | f59b51fe3d3092c08d7d554ecb40db24011b2ebc (diff) | |
parent | f322220d6159455da2b5a8a596d802c8695fed30 (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.c | 61 |
1 files changed, 56 insertions, 5 deletions
@@ -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 |
1577 | int compat_do_execve(char *filename, | 1576 | int 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 | ||
1662 | SYSCALL_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 | ||
1676 | asmlinkage 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 | ||
1692 | int 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 | ||