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:
committed by
Greg Ungerer
parent
c995ee28d2
commit
7e7ec6a934
@@ -67,8 +67,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *,
|
|||||||
struct elf_fdpic_params *);
|
struct elf_fdpic_params *);
|
||||||
|
|
||||||
#ifndef CONFIG_MMU
|
#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 *,
|
static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *,
|
||||||
struct file *,
|
struct file *,
|
||||||
struct mm_struct *);
|
struct mm_struct *);
|
||||||
@@ -515,8 +513,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
|||||||
sp = mm->start_stack;
|
sp = mm->start_stack;
|
||||||
|
|
||||||
/* stack the program arguments and environment */
|
/* 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;
|
return -EFAULT;
|
||||||
|
sp &= ~15;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -709,39 +708,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
|||||||
return 0;
|
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
|
* 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);
|
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 */
|
#endif /* CONFIG_MMU */
|
||||||
|
|
||||||
static struct file *do_open_execat(int fd, struct filename *name, int flags)
|
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,
|
extern int setup_arg_pages(struct linux_binprm * bprm,
|
||||||
unsigned long stack_top,
|
unsigned long stack_top,
|
||||||
int executable_stack);
|
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 bprm_change_interp(char *interp, struct linux_binprm *bprm);
|
||||||
extern int copy_strings_kernel(int argc, const char *const *argv,
|
extern int copy_strings_kernel(int argc, const char *const *argv,
|
||||||
struct linux_binprm *bprm);
|
struct linux_binprm *bprm);
|
||||||
|
|||||||
Reference in New Issue
Block a user