- 论坛徽章:
- 0
|
do_execve为了把参数传递给新的程序,分三次调用copy_strings把filename,环境变量和命令行变量按地址从高到低的次序依次放入栈中。举个例子,如果运行"ls -l /usr"在shell中,那么filename就是"/bin/ls", 命令行参数总共三个,分别是"/bin/ls", "-l"和"/usr"。可是既然命令行参数中已经有filename了,为什么还要在单独先把filename放入栈中呢
下面的图从ULK3中拷贝下来,按照do_execve的实现似乎在Environment settings和栈底的NULL之间还有filename
int do_execve(char * filename,
char __user *__user *argv,
char __user *__user *envp,
struct pt_regs * regs)
{
struct linux_binprm *bprm;
struct file *file;
int retval;
int i;
retval = -ENOMEM;
bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
if (!bprm)
goto out_ret;
memset(bprm, 0, sizeof(*bprm));
file = open_exec(filename);
retval = PTR_ERR(file);
if (IS_ERR(file))
goto out_kfree;
sched_exec();
bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
bprm->file = file;
bprm->filename = filename;
bprm->interp = filename;
bprm->mm = mm_alloc();
retval = -ENOMEM;
if (!bprm->mm)
goto out_file;
retval = init_new_context(current, bprm->mm);
if (retval < 0)
goto out_mm;
bprm->argc = count(argv, bprm->p / sizeof(void *));
if ((retval = bprm->argc) < 0)
goto out_mm;
bprm->envc = count(envp, bprm->p / sizeof(void *));
if ((retval = bprm->envc) < 0)
goto out_mm;
retval = security_bprm_alloc(bprm);
if (retval)
goto out;
retval = prepare_binprm(bprm);
if (retval < 0)
goto out;
retval = copy_strings_kernel(1, &bprm->filename, bprm);
if (retval < 0)
goto out;
bprm->exec = bprm->p;
retval = copy_strings(bprm->envc, envp, bprm);
if (retval < 0)
goto out;
retval = copy_strings(bprm->argc, argv, bprm);
if (retval < 0)
goto out;
retval = search_binary_handler(bprm,regs);
if (retval >= 0) {
free_arg_pages(bprm);
/* execve success */
security_bprm_free(bprm);
acct_update_integrals();
update_mem_hiwater();
kfree(bprm);
return retval;
}
out:
/* Something went wrong, return the inode and free the argument pages*/
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
struct page * page = bprm->page;
if (page)
__free_page(page);
}
if (bprm->security)
security_bprm_free(bprm);
out_mm:
if (bprm->mm)
mmdrop(bprm->mm);
out_file:
if (bprm->file) {
allow_write_access(bprm->file);
fput(bprm->file);
}
out_kfree:
kfree(bprm);
out_ret:
return retval;
}
|
|