Commit 83ca4c7e authored by Linus Torvalds's avatar Linus Torvalds

Allocate new mm_struct for execve() early, so that we have

access to it by the time we start copying arguments.

We don't actually use it at this point yet.
parent bbe302ee
...@@ -391,42 +391,31 @@ int kernel_read(struct file *file, unsigned long offset, ...@@ -391,42 +391,31 @@ int kernel_read(struct file *file, unsigned long offset,
return result; return result;
} }
static int exec_mmap(void) static int exec_mmap(struct mm_struct *mm)
{ {
struct mm_struct * mm, * old_mm; struct mm_struct * old_mm, *active_mm;
old_mm = current->mm; /* Add it to the list of mm's */
mm = mm_alloc(); spin_lock(&mmlist_lock);
if (mm) { list_add(&mm->mmlist, &init_mm.mmlist);
struct mm_struct *active_mm; mmlist_nr++;
spin_unlock(&mmlist_lock);
if (init_new_context(current, mm)) {
mmdrop(mm);
return -ENOMEM;
}
/* Add it to the list of mm's */ task_lock(current);
spin_lock(&mmlist_lock); old_mm = current->mm;
list_add(&mm->mmlist, &init_mm.mmlist); active_mm = current->active_mm;
mmlist_nr++; current->mm = mm;
spin_unlock(&mmlist_lock); current->active_mm = mm;
activate_mm(active_mm, mm);
task_lock(current); task_unlock(current);
active_mm = current->active_mm; mm_release();
current->mm = mm; if (old_mm) {
current->active_mm = mm; if (active_mm != old_mm) BUG();
activate_mm(active_mm, mm); mmput(old_mm);
task_unlock(current);
mm_release();
if (old_mm) {
if (active_mm != old_mm) BUG();
mmput(old_mm);
return 0;
}
mmdrop(active_mm);
return 0; return 0;
} }
return -ENOMEM; mmdrop(active_mm);
return 0;
} }
/* /*
...@@ -565,7 +554,7 @@ int flush_old_exec(struct linux_binprm * bprm) ...@@ -565,7 +554,7 @@ int flush_old_exec(struct linux_binprm * bprm)
/* /*
* Release all of the old mmap stuff * Release all of the old mmap stuff
*/ */
retval = exec_mmap(); retval = exec_mmap(bprm->mm);
if (retval) goto mmap_failed; if (retval) goto mmap_failed;
/* This is the point of no return */ /* This is the point of no return */
...@@ -896,17 +885,23 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs ...@@ -896,17 +885,23 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
bprm.sh_bang = 0; bprm.sh_bang = 0;
bprm.loader = 0; bprm.loader = 0;
bprm.exec = 0; bprm.exec = 0;
if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) {
allow_write_access(file);
fput(file);
return bprm.argc;
}
if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) { bprm.mm = mm_alloc();
allow_write_access(file); retval = -ENOMEM;
fput(file); if (!bprm.mm)
return bprm.envc; 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 = prepare_binprm(&bprm); retval = prepare_binprm(&bprm);
if (retval < 0) if (retval < 0)
...@@ -932,16 +927,20 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs ...@@ -932,16 +927,20 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
out: out:
/* Something went wrong, return the inode and free the argument pages*/ /* Something went wrong, return the inode and free the argument pages*/
allow_write_access(bprm.file);
if (bprm.file)
fput(bprm.file);
for (i = 0 ; i < MAX_ARG_PAGES ; i++) { for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
struct page * page = bprm.page[i]; struct page * page = bprm.page[i];
if (page) if (page)
__free_page(page); __free_page(page);
} }
out_mm:
mmdrop(bprm.mm);
out_file:
if (bprm.file) {
allow_write_access(bprm.file);
fput(bprm.file);
}
return retval; return retval;
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
struct linux_binprm{ struct linux_binprm{
char buf[BINPRM_BUF_SIZE]; char buf[BINPRM_BUF_SIZE];
struct page *page[MAX_ARG_PAGES]; struct page *page[MAX_ARG_PAGES];
struct mm_struct *mm;
unsigned long p; /* current top of mem */ unsigned long p; /* current top of mem */
int sh_bang; int sh_bang;
struct file * file; struct file * file;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment