Re: [PATCH v15 3/9] namei: LOOKUP_NO_XDEV: block mountpoint crossing

From: Al Viro
Date: Thu Nov 14 2019 - 00:44:54 EST


On Thu, Nov 14, 2019 at 03:49:45PM +1100, Aleksa Sarai wrote:
> On 2019-11-13, Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote:
> > On Tue, Nov 05, 2019 at 08:05:47PM +1100, Aleksa Sarai wrote:
> >
> > > @@ -862,6 +870,8 @@ static int nd_jump_root(struct nameidata *nd)
> > > void nd_jump_link(struct path *path)
> > > {
> > > struct nameidata *nd = current->nameidata;
> > > +
> > > + nd->last_magiclink.same_mnt = (nd->path.mnt == path->mnt);
> > > path_put(&nd->path);
> > >
> > > nd->path = *path;
> > > @@ -1082,6 +1092,10 @@ const char *get_link(struct nameidata *nd)
> > > if (nd->flags & LOOKUP_MAGICLINK_JUMPED) {
> > > if (unlikely(nd->flags & LOOKUP_NO_MAGICLINKS))
> > > return ERR_PTR(-ELOOP);
> > > + if (unlikely(nd->flags & LOOKUP_NO_XDEV)) {
> > > + if (!nd->last_magiclink.same_mnt)
> > > + return ERR_PTR(-EXDEV);
> > > + }
> > > }
> >
> > Ugh... Wouldn't it be better to take that logics (some equivalent thereof)
> > into nd_jump_link()? Or just have nd_jump_link() return an error...
>
> This could be done, but the reason for stashing it away in
> last_magiclink is because of the future magic-link re-opening patches
> which can't be implemented like that without putting the open_flags
> inside nameidata (which was decided to be too ugly a while ago).
>
> My point being that I could implement it this way for this series, but
> I'd have to implement something like last_magiclink when I end up
> re-posting the magic-link stuff in a few weeks.
>
> Looking at all the nd_jump_link() users, the other option is to just
> disallow magic-link crossings entirely for LOOKUP_NO_XDEV. The only
> thing allowing them permits is to resolve file descriptors that are
> pointing to the same procfs mount -- and it's unclear to me how useful
> that really is (apparmorfs and nsfs will always give -EXDEV because
> aafs_mnt and nsfs_mnt are internal kernel vfsmounts).

I would rather keep the entire if (nd->flags & LOOKUP_MAGICLINK_JUMPED)
out of the get_link(). If you want to generate some error if
nd_jump_link() has been called, just do it right there. The fewer
pieces of state need to be carried around, the better...

And as for opening them... Why would you need full open_flags in there?
Details, please...