summaryrefslogtreecommitdiff
path: root/fs/exec.c
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2016-07-24 11:30:18 -0400
committerGreg Ungerer <gerg@linux-m68k.org>2016-07-25 16:51:49 +1000
commit7e7ec6a934349ef6983f06f7ac0da09cc8a42983 (patch)
treed6058da1f3716a7173362a28fd816d4c60fef790 /fs/exec.c
parentc995ee28d29d6f256c3a8a6c4e66469554374f25 (diff)
downloadlwn-7e7ec6a934349ef6983f06f7ac0da09cc8a42983.tar.gz
lwn-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.c33
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)