diff options
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 | ||