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>
This commit is contained in:
parent
c995ee28d2
commit
7e7ec6a934
|
@ -67,8 +67,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *,
|
|||
struct elf_fdpic_params *);
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *,
|
||||
unsigned long *);
|
||||
static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *,
|
||||
struct file *,
|
||||
struct mm_struct *);
|
||||
|
@ -515,8 +513,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
|||
sp = mm->start_stack;
|
||||
|
||||
/* stack the program arguments and environment */
|
||||
if (elf_fdpic_transfer_args_to_stack(bprm, &sp) < 0)
|
||||
if (transfer_args_to_stack(bprm, &sp) < 0)
|
||||
return -EFAULT;
|
||||
sp &= ~15;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -709,39 +708,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* transfer the program arguments and environment from the holding pages onto
|
||||
* the stack
|
||||
*/
|
||||
#ifndef CONFIG_MMU
|
||||
static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm,
|
||||
unsigned long *_sp)
|
||||
{
|
||||
unsigned long index, stop, sp;
|
||||
char *src;
|
||||
int ret = 0;
|
||||
|
||||
stop = bprm->p >> PAGE_SHIFT;
|
||||
sp = *_sp;
|
||||
|
||||
for (index = MAX_ARG_PAGES - 1; index >= stop; index--) {
|
||||
src = kmap(bprm->page[index]);
|
||||
sp -= PAGE_SIZE;
|
||||
if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0)
|
||||
ret = -EFAULT;
|
||||
kunmap(bprm->page[index]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
*_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* load the appropriate binary image (executable or interpreter) into memory
|
||||
|
|
33
fs/exec.c
33
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)
|
||||
|
|
|
@ -113,6 +113,8 @@ extern int suid_dumpable;
|
|||
extern int setup_arg_pages(struct linux_binprm * bprm,
|
||||
unsigned long stack_top,
|
||||
int executable_stack);
|
||||
extern int transfer_args_to_stack(struct linux_binprm *bprm,
|
||||
unsigned long *sp_location);
|
||||
extern int bprm_change_interp(char *interp, struct linux_binprm *bprm);
|
||||
extern int copy_strings_kernel(int argc, const char *const *argv,
|
||||
struct linux_binprm *bprm);
|
||||
|
|
Loading…
Reference in New Issue