diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-30 13:38:55 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-30 22:20:51 -0400 |
commit | 38b983b3461e7d3c64a981e2338bb34605c46f30 (patch) | |
tree | fb7dc311ba4d175746fb693530cf63db9ddb8616 /fs/exec.c | |
parent | 282124d18626379a20b41d25e0c580f290cd09d4 (diff) |
generic sys_execve()
Selected by __ARCH_WANT_SYS_EXECVE in unistd.h. Requires
* working current_pt_regs()
* *NOT* doing a syscall-in-kernel kind of kernel_execve()
implementation. Using generic kernel_execve() is fine.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 38 |
1 files changed, 34 insertions, 4 deletions
@@ -401,7 +401,7 @@ struct user_arg_ptr { | |||
401 | union { | 401 | union { |
402 | const char __user *const __user *native; | 402 | const char __user *const __user *native; |
403 | #ifdef CONFIG_COMPAT | 403 | #ifdef CONFIG_COMPAT |
404 | compat_uptr_t __user *compat; | 404 | const compat_uptr_t __user *compat; |
405 | #endif | 405 | #endif |
406 | } ptr; | 406 | } ptr; |
407 | }; | 407 | }; |
@@ -1600,9 +1600,9 @@ int do_execve(const char *filename, | |||
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | #ifdef CONFIG_COMPAT | 1602 | #ifdef CONFIG_COMPAT |
1603 | int compat_do_execve(char *filename, | 1603 | int compat_do_execve(const char *filename, |
1604 | compat_uptr_t __user *__argv, | 1604 | const compat_uptr_t __user *__argv, |
1605 | compat_uptr_t __user *__envp, | 1605 | const compat_uptr_t __user *__envp, |
1606 | struct pt_regs *regs) | 1606 | struct pt_regs *regs) |
1607 | { | 1607 | { |
1608 | struct user_arg_ptr argv = { | 1608 | struct user_arg_ptr argv = { |
@@ -2319,6 +2319,36 @@ int dump_seek(struct file *file, loff_t off) | |||
2319 | } | 2319 | } |
2320 | EXPORT_SYMBOL(dump_seek); | 2320 | EXPORT_SYMBOL(dump_seek); |
2321 | 2321 | ||
2322 | #ifdef __ARCH_WANT_SYS_EXECVE | ||
2323 | SYSCALL_DEFINE3(execve, | ||
2324 | const char __user *, filename, | ||
2325 | const char __user *const __user *, argv, | ||
2326 | const char __user *const __user *, envp) | ||
2327 | { | ||
2328 | const char *path = getname(filename); | ||
2329 | int error = PTR_ERR(path); | ||
2330 | if (!IS_ERR(path)) { | ||
2331 | error = do_execve(path, argv, envp, current_pt_regs()); | ||
2332 | putname(path); | ||
2333 | } | ||
2334 | return error; | ||
2335 | } | ||
2336 | #ifdef CONFIG_COMPAT | ||
2337 | asmlinkage long compat_sys_execve(const char __user * filename, | ||
2338 | const compat_uptr_t __user * argv, | ||
2339 | const compat_uptr_t __user * envp) | ||
2340 | { | ||
2341 | const char *path = getname(filename); | ||
2342 | int error = PTR_ERR(path); | ||
2343 | if (!IS_ERR(path)) { | ||
2344 | error = compat_do_execve(path, argv, envp, current_pt_regs()); | ||
2345 | putname(path); | ||
2346 | } | ||
2347 | return error; | ||
2348 | } | ||
2349 | #endif | ||
2350 | #endif | ||
2351 | |||
2322 | #ifdef __ARCH_WANT_KERNEL_EXECVE | 2352 | #ifdef __ARCH_WANT_KERNEL_EXECVE |
2323 | int kernel_execve(const char *filename, | 2353 | int kernel_execve(const char *filename, |
2324 | const char *const argv[], | 2354 | const char *const argv[], |