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. fs/exec.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff -puN fs/exec.c~exec_mmap-is-the-point-of-no-return fs/exec.c --- 25/fs/exec.c~exec_mmap-is-the-point-of-no-return 2003-07-02 23:55:43.000000000 -0700 +++ 25-akpm/fs/exec.c 2003-07-03 00:37:36.000000000 -0700 @@ -758,12 +758,6 @@ int flush_old_exec(struct linux_binprm * 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. @@ -772,6 +766,13 @@ int flush_old_exec(struct linux_binprm * 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 */ _