diff options
| author | Andrew Morton <akpm@osdl.org> | 2003-07-04 19:37:46 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-07-04 19:37:46 -0700 |
| commit | 12c1bf07056e1cb01f1ae2f23846780e04cb65c7 (patch) | |
| tree | 2b7f384de28baf5eb2e84f8a836bdbd667edea24 /fs/exec.c | |
| parent | e34b0f533d3da5bdff2360c306e4255fed3cbebd (diff) | |
[PATCH] after exec_mmap(), exec cannot fail
If de_thread() fails in flush_old_exec() then we try to fail the execve().
That is a bad move, because exec_mmap() has already switched the current
process over to the new mm. The new process is not yet sufficiently set up
to handle the error and the kernel doublefaults and dies. exec_mmap() is the
point of no return.
Change flush_old_exec() to call de_thread() before running exec_mmap() so the
execing program sees the error. I added fault injection to both de_thread()
and exec_mmap() - everything now survives OK.
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c index 4f37deb79e00..3d9730f93e08 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -759,12 +759,6 @@ int flush_old_exec(struct linux_binprm * bprm) char * name; int i, ch, retval; - /* - * Release all of the old mmap stuff - */ - retval = exec_mmap(bprm->mm); - if (retval) - goto out; /* * Make sure we have a private signal table and that * we are unassociated from the previous thread group. @@ -773,6 +767,13 @@ int flush_old_exec(struct linux_binprm * bprm) if (retval) goto out; + /* + * Release all of the old mmap stuff + */ + retval = exec_mmap(bprm->mm); + if (retval) + goto out; + bprm->mm = NULL; /* We're using it now */ /* This is the point of no return */ |
