On Mon, Jul 10, 2017 at 1:46 AM, Eric W. Biederman <ebiederm@xxxxxxxxxxxx> wrote: > > But you miss it. > > The "point of no return" is the call to de_thread. Or aguably anything in > flush_old_exec. Once anything in the current task is modified you can't > return an error. > > It very much does not have anything to do with brpm. It has > everything to do with current. Yes, but the thing that actually enforces this is the test of bprm->mm and the SIGSEGV in search_binary_handlers(). -Kees > > >> diff --git a/fs/exec.c b/fs/exec.c >> index 904199086490..7842ae661e34 100644 >> --- a/fs/exec.c >> +++ b/fs/exec.c >> @@ -1285,7 +1285,14 @@ int flush_old_exec(struct linux_binprm * bprm) >> if (retval) >> goto out; >> >> - bprm->mm = NULL; /* We're using it now */ >> + /* >> + * After clearing bprm->mm (to mark that current is using the >> + * prepared mm now), we are at the point of no return. If >> + * anything from here on returns an error, the check in >> + * search_binary_handler() will kill current (since the mm has >> + * been replaced). >> + */ >> + bprm->mm = NULL; >> >> set_fs(USER_DS); >> current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | > > Eric -- Kees Cook Pixel Security