Message ID | 20210121131959.646623-3-christian.brauner@ubuntu.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | idmapped mounts | expand |
On Thu, Jan 21, 2021 at 02:19:21PM +0100, Christian Brauner wrote: > Add simple helpers to make it easy to map kuids into and from idmapped > mounts. We provide simple wrappers that filesystems can use to e.g. > initialize inodes similar to i_{uid,gid}_read() and i_{uid,gid}_write(). > Accessing an inode through an idmapped mount maps the i_uid and i_gid of > the inode to the mount's user namespace. If the fsids are used to > initialize inodes they are unmapped according to the mount's user > namespace. Passing the initial user namespace to these helpers makes > them a nop and so any non-idmapped paths will not be impacted. > > Link: https://lore.kernel.org/r/20210112220124.837960-9-christian.brauner@ubuntu.com > Cc: David Howells <dhowells@redhat.com> > Cc: Al Viro <viro@zeniv.linux.org.uk> > Cc: linux-fsdevel@vger.kernel.org > Reviewed-by: Christoph Hellwig <hch@lst.de> > Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com> > --- > /* v2 */ > - Christoph Hellwig <hch@lst.de>: > - Get rid of the ifdefs and the config option that hid idmapped mounts. > > /* v3 */ > unchanged > > /* v4 */ > - Serge Hallyn <serge@hallyn.com>: > - Use "mnt_userns" to refer to a vfsmount's userns everywhere to make > terminology consistent. > > /* v5 */ > unchanged > base-commit: 7c53f6b671f4aba70ff15e1b05148b10d58c2837 > > /* v6 */ > unchanged > base-commit: 19c329f6808995b142b3966301f217c831e7cf31 > --- > include/linux/fs.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 47 insertions(+) > > diff --git a/include/linux/fs.h b/include/linux/fs.h > index fd0b80e6361d..3165998e2294 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -40,6 +40,7 @@ > #include <linux/build_bug.h> > #include <linux/stddef.h> > #include <linux/mount.h> > +#include <linux/cred.h> > > #include <asm/byteorder.h> > #include <uapi/linux/fs.h> > @@ -1573,6 +1574,52 @@ static inline void i_gid_write(struct inode *inode, gid_t gid) > inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid); > } > > +static inline kuid_t kuid_into_mnt(struct user_namespace *mnt_userns, > + kuid_t kuid) > +{ > + return make_kuid(mnt_userns, __kuid_val(kuid)); > +} > + Hi Christian, I am having little trouble w.r.t function names and trying to figure out whether they are mapping id down or up. For example, kuid_into_mnt() ultimately calls map_id_down(). That is, id visible inside user namespace is mapped to host (if observer is in init_user_ns, IIUC). But fsuid_into_mnt() ultimately calls map_id_up(). That's take a kuid and map it into the user_namespace. So both the helpers end with into_mnt() but one maps id down and other maps id up. I found this confusing and was wondering how should I visualize it. So thought of asking you. Is this intentional or can naming be improved so that *_into_mnt() means one thing (Either map_id_up() or map_id_down()). And vice-a-versa for *_from_mnt(). Thanks Vivek > +static inline kgid_t kgid_into_mnt(struct user_namespace *mnt_userns, > + kgid_t kgid) > +{ > + return make_kgid(mnt_userns, __kgid_val(kgid)); > +} > + > +static inline kuid_t i_uid_into_mnt(struct user_namespace *mnt_userns, > + const struct inode *inode) > +{ > + return kuid_into_mnt(mnt_userns, inode->i_uid); > +} > + > +static inline kgid_t i_gid_into_mnt(struct user_namespace *mnt_userns, > + const struct inode *inode) > +{ > + return kgid_into_mnt(mnt_userns, inode->i_gid); > +} > + > +static inline kuid_t kuid_from_mnt(struct user_namespace *mnt_userns, > + kuid_t kuid) > +{ > + return KUIDT_INIT(from_kuid(mnt_userns, kuid)); > +} > + > +static inline kgid_t kgid_from_mnt(struct user_namespace *mnt_userns, > + kgid_t kgid) > +{ > + return KGIDT_INIT(from_kgid(mnt_userns, kgid)); > +} > + > +static inline kuid_t fsuid_into_mnt(struct user_namespace *mnt_userns) > +{ > + return kuid_from_mnt(mnt_userns, current_fsuid()); > +} > + > +static inline kgid_t fsgid_into_mnt(struct user_namespace *mnt_userns) > +{ > + return kgid_from_mnt(mnt_userns, current_fsgid()); > +} > + > extern struct timespec64 current_time(struct inode *inode); > > /* > -- > 2.30.0 >
diff --git a/include/linux/fs.h b/include/linux/fs.h index fd0b80e6361d..3165998e2294 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -40,6 +40,7 @@ #include <linux/build_bug.h> #include <linux/stddef.h> #include <linux/mount.h> +#include <linux/cred.h> #include <asm/byteorder.h> #include <uapi/linux/fs.h> @@ -1573,6 +1574,52 @@ static inline void i_gid_write(struct inode *inode, gid_t gid) inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid); } +static inline kuid_t kuid_into_mnt(struct user_namespace *mnt_userns, + kuid_t kuid) +{ + return make_kuid(mnt_userns, __kuid_val(kuid)); +} + +static inline kgid_t kgid_into_mnt(struct user_namespace *mnt_userns, + kgid_t kgid) +{ + return make_kgid(mnt_userns, __kgid_val(kgid)); +} + +static inline kuid_t i_uid_into_mnt(struct user_namespace *mnt_userns, + const struct inode *inode) +{ + return kuid_into_mnt(mnt_userns, inode->i_uid); +} + +static inline kgid_t i_gid_into_mnt(struct user_namespace *mnt_userns, + const struct inode *inode) +{ + return kgid_into_mnt(mnt_userns, inode->i_gid); +} + +static inline kuid_t kuid_from_mnt(struct user_namespace *mnt_userns, + kuid_t kuid) +{ + return KUIDT_INIT(from_kuid(mnt_userns, kuid)); +} + +static inline kgid_t kgid_from_mnt(struct user_namespace *mnt_userns, + kgid_t kgid) +{ + return KGIDT_INIT(from_kgid(mnt_userns, kgid)); +} + +static inline kuid_t fsuid_into_mnt(struct user_namespace *mnt_userns) +{ + return kuid_from_mnt(mnt_userns, current_fsuid()); +} + +static inline kgid_t fsgid_into_mnt(struct user_namespace *mnt_userns) +{ + return kgid_from_mnt(mnt_userns, current_fsgid()); +} + extern struct timespec64 current_time(struct inode *inode); /*