From: Dave Chinner <david@fromorbit.com>
To: Dwight Engen <dwight.engen@oracle.com>
Cc: Serge Hallyn <serge.hallyn@ubuntu.com>,
"Eric W. Biederman" <ebiederm@gmail.com>,
xfs@oss.sgi.com
Subject: Re: [PATCH] userns: Convert xfs to use kuid/kgid where appropriate
Date: Mon, 24 Jun 2013 10:33:16 +1000 [thread overview]
Message-ID: <20130624003316.GH29376@dastard> (raw)
In-Reply-To: <20130621111420.5592707e@oracle.com>
On Fri, Jun 21, 2013 at 11:14:20AM -0400, Dwight Engen wrote:
> On Fri, 21 Jun 2013 08:03:11 +1000
> Dave Chinner <david@fromorbit.com> wrote:
>
> > On Thu, Jun 20, 2013 at 09:54:10AM -0400, Dwight Engen wrote:
> > > On Thu, 20 Jun 2013 10:13:41 +1000
> > > Dave Chinner <david@fromorbit.com> wrote:
> > >
> > > > On Wed, Jun 19, 2013 at 11:09:48AM -0400, Dwight Engen wrote:
> > > > > Use uint32 from init_user_ns for xfs internal uid/gid
> > > > > representation in acl, xfs_icdinode. Conversion of kuid/gid is
> > > > > done at the vfs boundary, other user visible xfs specific
> > > > > interfaces (bulkstat, eofblocks filter) expect uint32
> > > > > init_user_ns uid/gid values.
> > > >
> > > > It's minimal, but I'm not sure it's complete. I'll comment on that
> > > > in response to Eric's comments...
> > ...
> > > > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> > > > > index 7f7be5f..8049976 100644
> > > > > --- a/fs/xfs/xfs_inode.c
> > > > > +++ b/fs/xfs/xfs_inode.c
> > > > > @@ -1268,8 +1268,8 @@ xfs_ialloc(
> > > > > ip->i_d.di_onlink = 0;
> > > > > ip->i_d.di_nlink = nlink;
> > > > > ASSERT(ip->i_d.di_nlink == nlink);
> > > > > - ip->i_d.di_uid = current_fsuid();
> > > > > - ip->i_d.di_gid = current_fsgid();
> > > > > + ip->i_d.di_uid = from_kuid(&init_user_ns,
> > > > > current_fsuid());
> > > > > + ip->i_d.di_gid = from_kgid(&init_user_ns,
> > > > > current_fsgid());
> > > >
> > > > Why all new inodes be created in the init_user_ns? Shouldn't this
> > > > be current_user_ns()?
> > >
> > > current_fsuid() is the kuid_t from whatever userns current is in,
> >
> > Yes.
> >
> > > which we are converting to a flat uint32 since i_d is the on disk
> > > inode.
>
> I was incorrect here. current_fsuid() is the kuid_t from the
> perspective of init_user_ns, so the value won't be different, just the
> type.
I guess I'm not the only that is easily confused by this convoluted,
badly documented namespace conversion crap either....
> > So, init_user_ns is actually the target namespace of the conversion,
> > not the namespace we are converting *from*?
> >
> > <sigh>
> >
> > I *knew* this was going to happen when I first saw this code:
> >
> > http://www.spinics.net/lists/netdev/msg209217.html
> >
> > "For those of us that have to look at it once every few months,
> > following the same conventions as all the other code in the kernel
> > (i.e. kqid_to_id()) tells me everything I need to know without
> > having to go through the process of looking up the unusual
> > from_kqid() function and then from_kuid() to find out what it is
> > actually doing...."
> >
> > Here I am, several months later and trying to work out what the damn
> > conversion from_kgid() and make_kuid() are supposed to be doing and
> > trying to work out if it is correct or not...
> >
> > > This field is then used in xfs_setup_inode() to populate
> > > VFS_I(ip)->i_uid.
> >
> > But that then uses make_kuid(&init_user_ns, ip->i_d.di_uid) which
> > according to the documentation creates a kuid in the init_user_ns,
> > not in the current user namespace.
>
> Right, inside the kernel uids are all interpreted within
> init_user_ns context and are only converted to a different value if the
> caller is in some other userns at the kernel/user boundary (ie.
> cp_compat_stat()). Maybe it is more clear to say that init_user_ns is
> the "flat 32bit uid space" and thus has a mapping for every uid. So
> the value in init_user_ns will actually be equal to the di_uid value.
If that's the case, then why the hell do filesystems need to know
*anything* about namespaces and conversions? It shoul dbe
*completely* hidden from filesystem code with simple wrappers rather
than open coding init_user_ns conversions everywhere....
Indeed, for updating or getting the uid/gid from the struct inode
there are these helpers:
i_uid_read/i_uid_write
i_gid_read/i_uid_write
but there's nothing generic for the filesystems to use that just
take a kuid_t/kgid_t and return a raw value or vice versa. Nice.
> > So if we then do uid_eq(current_fsuid(), VFS_I(ip)->i_uid) on the
> > newly created and initialised inode they are different, yes? If they
> > are different, then this code is not correct....
>
> No they should equal because xfs_setup_inode() maps it back, see below.
>
> > > Most other filesystems would use inode_init_owner(),
> > > but xfs does not (I assume because it wants to handle SGID itself
> > > based on XFS_INHERIT_GID and irix_sgid_inherit).
> >
> > No, XFS doesn't use inode_init_owner() because we are initialising
> > the on disk XFS inode here, not the VFS struct inode...
>
> Right, but I was referring to xfs_setup_inode() which is setting up the
> VFS inode. It is called in both the from disk and new inode paths, and
> sets the VFS inode uid based on the value in the disk inode.
So perhaps your comment was in the wrong place? ;)
> I was
> trying to show that in the new inode path the VFS inode uid is being
> initialized the same as on other filesystems (ie from current_fsuid()),
> but with an extra step just because of "conversion" to and back from
> init_user_ns. The call sequence in xfs:
>
> xfs_ialloc():
> current_fsuid() -> from_kuid() -> di_uid
ip->i_d.di_uid = xfs_kuid_to_disk(current_fsuid());
> xfs_setup_inode():
> di_uid -> make_kuid() -> inode.i_uid == current_fsuid()
inode->i_uid = xfs_kuid_from_disk(ip->i_d.di_uid);
> Sorry, I think my first explanation wasn't clear, hopefully this is.
Well, it's taken me another hour of battling through the
undocumented crap that is this namespace code starting from
setuid(), but I understand the conversions being done now. I dislike
the implementation even more now, and I'm still wondering what the
hell we are supposed to do with bulkstat, filehandles and stuff like
xfs_fsr, backups, etc...
> > So, to prevent me from wondering what it is doing in another 6
> > months time, can you add a set of helper functions that are named:
> >
> > xfs_kuid_to_disk()
> > xfs_kuid_from_disk()
> > xfs_kgid_to_disk()
> > xfs_kgid_from_disk()
> >
> > and document why we are using the namespaces that are being used,
> > and then use them where we convert to/from the different inode
> > structures?
>
> Sure I can take a shot at that, and I'm guessing you would prefer to use
>
> inode->i_uid = xfs_kuid_from_disk(ip->i_d.di_uid);
>
> over
>
> i_uid_write(inode, ip->i_d.di_uid);
Yes, because i_uid_write() is not a generic helper function, and we
convert to/from disk format in many places where we aren't actually
reading/writing the struct inode. i.e. I don't see any reason at all
for having the variable init_user_ns anywhere in the XFS code
except than in those wrapper functions....
> > FWIW, what happens when ip->i_d.di_gid doesn't have a mapping in the
> > current namespace, and make_kuid/make_kgid return
> > INVALID_UID/INVALID_GID? Is this is going to happen, and if it does
> > what do we need to do about it? That will need to be added to the
> > comments, too.
>
> I don't think it will happen here because init_user_ns has a mapping
> for all values. Where it can happen is when there is a conversion to
> some subset userns, that doesn't have a mapping for the value.
Yup, understood.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2013-06-24 0:33 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-19 15:09 [PATCH] userns: Convert xfs to use kuid/kgid where appropriate Dwight Engen
2013-06-19 20:35 ` Eric W. Biederman
2013-06-20 1:41 ` Dave Chinner
2013-06-20 13:54 ` Dwight Engen
2013-06-20 21:10 ` Dave Chinner
2013-06-20 0:13 ` Dave Chinner
2013-06-20 13:54 ` Dwight Engen
2013-06-20 15:27 ` Brian Foster
2013-06-20 17:39 ` Dwight Engen
2013-06-20 19:12 ` Brian Foster
2013-06-20 22:12 ` Dave Chinner
2013-06-20 22:45 ` Eric W. Biederman
2013-06-20 23:35 ` Dave Chinner
2013-06-20 22:03 ` Dave Chinner
2013-06-21 15:14 ` Dwight Engen
2013-06-24 0:33 ` Dave Chinner [this message]
2013-06-24 13:10 ` [PATCH v2 RFC] " Dwight Engen
2013-06-25 16:46 ` Brian Foster
2013-06-25 20:08 ` Dwight Engen
2013-06-25 21:04 ` Brian Foster
2013-06-26 2:09 ` Dave Chinner
2013-06-26 21:30 ` Dwight Engen
2013-06-26 22:44 ` Dave Chinner
2013-06-27 13:02 ` Serge Hallyn
2013-06-28 1:54 ` Dave Chinner
2013-06-28 15:25 ` Serge Hallyn
2013-06-28 16:16 ` Dwight Engen
2013-06-27 20:57 ` Ben Myers
2013-06-28 1:46 ` Dave Chinner
2013-06-28 15:15 ` Serge Hallyn
2013-06-28 14:23 ` Dwight Engen
2013-06-28 15:11 ` [PATCH v3 0/6] " Dwight Engen
2013-06-28 15:11 ` [PATCH 1/6] create wrappers for converting kuid_t to/from uid_t Dwight Engen
2013-06-28 15:11 ` [PATCH 2/6] convert kuid_t to/from uid_t in ACLs Dwight Engen
2013-06-28 15:11 ` [PATCH 3/6] ioctl: check for capabilities in the current user namespace Dwight Engen
2013-06-28 15:11 ` [PATCH 4/6] convert kuid_t to/from uid_t for xfs internal structures Dwight Engen
2013-06-28 15:11 ` [PATCH 5/6] create internal eofblocks structure with kuid_t types Dwight Engen
2013-06-28 18:09 ` Brian Foster
2013-06-28 15:11 ` [PATCH 6/6] ioctl eofblocks: require non-privileged users to specify uid/gid match Dwight Engen
2013-06-28 18:50 ` Brian Foster
2013-06-28 20:28 ` Dwight Engen
2013-06-28 21:39 ` Brian Foster
2013-06-28 23:22 ` Dwight Engen
2013-07-01 12:21 ` Brian Foster
2013-07-06 4:44 ` [PATCH 1/1] export inode_capable Serge Hallyn
2013-07-08 13:09 ` [PATCH v2 RFC] userns: Convert xfs to use kuid/kgid where appropriate Serge Hallyn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130624003316.GH29376@dastard \
--to=david@fromorbit.com \
--cc=dwight.engen@oracle.com \
--cc=ebiederm@gmail.com \
--cc=serge.hallyn@ubuntu.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.