]> Pileus Git - ~andy/linux/blobdiff - fs/exec.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
[~andy/linux] / fs / exec.c
index 4f2bebc276c52f3ca60b75fbff9eeea8ea21bbe5..ca434534ae9abd43ee320e308b22199fb2d53849 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -59,7 +59,6 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
-#include <asm/exec.h>
 
 #include <trace/events/task.h>
 #include "internal.h"
@@ -392,7 +391,7 @@ struct user_arg_ptr {
        union {
                const char __user *const __user *native;
 #ifdef CONFIG_COMPAT
-               compat_uptr_t __user *compat;
+               const compat_uptr_t __user *compat;
 #endif
        } ptr;
 };
@@ -1574,9 +1573,9 @@ int do_execve(const char *filename,
 }
 
 #ifdef CONFIG_COMPAT
-int compat_do_execve(char *filename,
-       compat_uptr_t __user *__argv,
-       compat_uptr_t __user *__envp,
+int compat_do_execve(const char *filename,
+       const compat_uptr_t __user *__argv,
+       const compat_uptr_t __user *__envp,
        struct pt_regs *regs)
 {
        struct user_arg_ptr argv = {
@@ -1658,3 +1657,55 @@ int get_dumpable(struct mm_struct *mm)
 {
        return __get_dumpable(mm->flags);
 }
+
+#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