[PATCH resend v3 2/2] exec: Broadly lock nascent mm until setup_arg_pages()

Jann Horn jannh at google.com
Mon Nov 2 22:53:27 EST 2020


On Tue, Oct 20, 2020 at 9:15 PM Jason Gunthorpe <jgg at nvidia.com> wrote:
> On Sat, Oct 17, 2020 at 12:57:13AM +0200, Jann Horn wrote:
> > @@ -1545,6 +1532,18 @@ void setup_new_exec(struct linux_binprm * bprm)
> >       me->mm->task_size = TASK_SIZE;
> >       mutex_unlock(&me->signal->exec_update_mutex);
> >       mutex_unlock(&me->signal->cred_guard_mutex);
> > +
> > +     if (!IS_ENABLED(CONFIG_MMU)) {
> > +             /*
> > +              * On MMU, setup_arg_pages() wants to access bprm->vma after
> > +              * this point, so we can't drop the mmap lock yet.
> > +              * On !MMU, we have neither setup_arg_pages() nor bprm->vma,
> > +              * so we should drop the lock here.
> > +              */
> > +             mmap_write_unlock(bprm->mm);
> > +             mmput(bprm->mm);
> > +             bprm->mm = NULL;
> > +     }
>
> The only thing I dislike about this is how tricky the lock lifetime
> is, it all looks correct, but expecting the setup_arg_pages() or
> setup_new_exec() to unlock (depending!) is quite tricky.
>
> It feels like it would be clearer to have an explicit function to do
> this, like 'release_brp_mm()' indicating that current->mm is now the
> only way to get the mm and it must be locked.

That was a good suggestion; I tried to amend my patch as suggested,
and while trying to do that, noticed that under CONFIG_MMU,
binfmt_flat first does setup_new_exec(), then vm_mmap(), and then
later on setup_arg_pages()...

So your suggestion indeed helped make it clear that my patch was
wrong. Guess I'll have to go figure out how to rearrange the pieces in
binfmt_flat to make this work...



More information about the linux-um mailing list