Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e7ec6a9 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Greg Ungerer
Browse files

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: default avatarNicolas Pitre <nico@linaro.org>
Reviewed-by: default avatarGreg Ungerer <gerg@linux-m68k.org>
Signed-off-by: default avatarGreg Ungerer <gerg@linux-m68k.org>
parent c995ee28
Loading
Loading
Loading
Loading
+2 −36
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -762,6 +762,39 @@ int setup_arg_pages(struct linux_binprm *bprm,
}
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)
+2 −0
Original line number Diff line number Diff line
@@ -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);