diff options
author | Nicolas Pitre <nicolas.pitre@linaro.org> | 2016-07-24 17:30:18 +0200 |
---|---|---|
committer | Greg Ungerer <gerg@linux-m68k.org> | 2016-07-25 08:51:49 +0200 |
commit | 7e7ec6a934349ef6983f06f7ac0da09cc8a42983 (patch) | |
tree | d6058da1f3716a7173362a28fd816d4c60fef790 /fs/exec.c | |
parent | binfmt_flat: prevent kernel dammage from corrupted executable headers (diff) | |
download | linux-7e7ec6a934349ef6983f06f7ac0da09cc8a42983.tar.xz linux-7e7ec6a934349ef6983f06f7ac0da09cc8a42983.zip |
elf_fdpic_transfer_args_to_stack(): make it generic
This copying of arguments and environment is common to both NOMMU
binary formats we support. Let's make the elf_fdpic version available
to the flat format as well.
While at it, improve the code a bit not to copy below the actual
data area.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
Reviewed-by: Greg Ungerer <gerg@linux-m68k.org>
Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c index 887c1c955df8..ef0df2f09257 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -762,6 +762,39 @@ out_unlock: } EXPORT_SYMBOL(setup_arg_pages); +#else + +/* + * Transfer the program arguments and environment from the holding pages + * onto the stack. The provided stack pointer is adjusted accordingly. + */ +int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location) +{ + unsigned long index, stop, sp; + int ret = 0; + + stop = bprm->p >> PAGE_SHIFT; + sp = *sp_location; + + for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { + unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; + char *src = kmap(bprm->page[index]) + offset; + sp -= PAGE_SIZE - offset; + if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0) + ret = -EFAULT; + kunmap(bprm->page[index]); + if (ret) + goto out; + } + + *sp_location = sp; + +out: + return ret; +} +EXPORT_SYMBOL(transfer_args_to_stack); + #endif /* CONFIG_MMU */ static struct file *do_open_execat(int fd, struct filename *name, int flags) |