linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Djalal Harouni <tixxdz@gmail.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
	Chris Mason <clm@fb.com>, <tytso@mit.edu>,
	Serge Hallyn <serge.hallyn@canonical.com>,
	Josh Triplett <josh@joshtriplett.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Andy Lutomirski <luto@kernel.org>,
	Seth Forshee <seth.forshee@canonical.com>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	Dongsu Park <dongsu@endocode.com>,
	David Herrmann <dh.herrmann@googlemail.com>,
	Miklos Szeredi <mszeredi@redhat.com>,
	Alban Crequy <alban.crequy@gmail.com>
Cc: Djalal Harouni <tixxdz@gmail.com>, Djalal Harouni <tixxdz@opendz.org>
Subject: [RFC v2 PATCH 5/8] VFS:userns: add helpers to shift UIDs and GIDs into on-disk view
Date: Wed,  4 May 2016 16:26:51 +0200	[thread overview]
Message-ID: <1462372014-3786-6-git-send-email-tixxdz@gmail.com> (raw)
In-Reply-To: <1462372014-3786-1-git-send-email-tixxdz@gmail.com>

Add helpers to allow the VFS to shift UIDs and GIDs into on-disk view
according to the user namespace of the containing mount namespace.
All decisions are taken by VFS. This is a preparation patch for the next
one where we convert kuid and kgid to be written into disk.

To allow the shift of UID and GID, filesystems when mounted must set
"vfs_shift_uids" and "vfs_shift_gids" options, otherwise no shift is
performed at all.

vfs_shift_kuid_to_disk() and vfs_shift_kgid_to_disk() take two
arugments, the inode that we are trying to update on-disk and the
corresponding kuid and kgid that should be used to update
inode->{i_uid|i_gid} values. To convert to on-disk value we perform:

1) First check if UID/GID shift is enabled on the inode which means
   the filesystem and current mount namespace.

2) If the passed kuid has a mapping in the user namespace of the
containing mount namespace, then get the correspondig uid_t value
otherwise we fallback to init_user_ns

3) Finally construct the kuid from the pair init_user_ns and uid_t
values, this will always reflects what should be put into
inode->{i_uid|i_gid} on the disk.

If a mount supports VFS UID/GID shifts shows up in a mount namespace
that allows UID/GID shifts, these helpers will handle the shift to
on-disk view and perform the translation accordingly.

Signed-off-by: Dongsu Park <dongsu@endocode.com>
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
---
 fs/namespace.c     | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h |  3 ++
 2 files changed, 96 insertions(+)

diff --git a/fs/namespace.c b/fs/namespace.c
index a8820fb..7df896b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1726,6 +1726,99 @@ kgid_t vfs_shift_i_gid_to_virtual(const struct inode *inode)
 	return i_gid;
 }
 
+/*
+ * Returns the on-disk UID view of the passed kuid that is supposed to be
+ * used to update the inode's uid.
+ * If UID shifts are enabled on the mount namespace and the filesystem,
+ * the VFS will return the on-disk view of the passed kuid. If no shift is
+ * performed, kuid is returned without any change.
+ */
+kuid_t vfs_shift_kuid_to_disk(const struct inode *inode, kuid_t kuid)
+{
+	uid_t uid;
+	struct mnt_namespace *ns;
+
+	if (!current->mm)
+		return kuid;
+
+	ns = current->nsproxy->mnt_ns;
+
+	/* Nothing to do */
+	if (!vfs_mount_shift_i_uid(ns, inode))
+		return kuid;
+
+	/*
+	 * If kuid has a mapping in the mountns get its uid_t otherwise get it
+	 * from init_user_ns
+	 */
+	if (kuid_has_mapping(ns->user_ns, kuid))
+		uid = from_kuid(ns->user_ns, kuid);
+	else
+		uid = from_kuid(&init_user_ns, kuid);
+
+	if (uid == (uid_t) -1)
+		return kuid;
+
+	/* Get the final kuid that will be used for on-disk writes */
+	return make_kuid(&init_user_ns, uid);
+}
+
+/*
+ * Returns the on-disk GID view of the passed kgid that is supposed to be
+ * used to update the inode's gid.
+ * If GID shifts are enabled on the mount namespace and the filesystem,
+ * the VFS will return the on-disk view of the passed kgid. If no shift is
+ * performed, kgid is returned without any change.
+ */
+kgid_t vfs_shift_kgid_to_disk(const struct inode *inode, kgid_t kgid)
+{
+	gid_t gid;
+	struct mnt_namespace *ns;
+
+	if (!current->mm)
+		return kgid;
+
+	ns = current->nsproxy->mnt_ns;
+
+	/* Nothing to do ? */
+	if (!vfs_mount_shift_i_gid(ns, inode))
+		return kgid;
+
+	/*
+	 * If kgid has a mapping in the mountns get its gid_t otherwise get it
+	 * from init_user_ns
+	 */
+	if (kgid_has_mapping(ns->user_ns, kgid))
+		gid = from_kgid(ns->user_ns, kgid);
+	else
+		gid = from_kgid(&init_user_ns, kgid);
+
+	if (gid == (gid_t) -1)
+		return kgid;
+
+	/* Get the final kgid that will be used for on-disk writes */
+	return make_kgid(&init_user_ns, gid);
+}
+
+/*
+ * Converts the passed kgid from on-disk view into the virtual one and returns it.
+ * It takes two arguments, the inode where the related kgid is supposed to be
+ * used, and the kgid.
+ */
+kgid_t vfs_kgid_disk_to_virtual(const struct inode *inode, kgid_t kgid)
+{
+	struct mnt_namespace *ns = current->nsproxy->mnt_ns;
+
+	/* shift kgid if necessary */
+	if (!vfs_mount_shift_i_gid(ns, inode))
+		return kgid;
+
+	if (!kgid_has_mapping(ns->user_ns, kgid))
+		return make_kgid(ns->user_ns, kgid.val);
+
+	return kgid;
+}
+
 static bool mnt_ns_loop(struct dentry *dentry)
 {
 	/* Could bind mounting the mount namespace inode cause a
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a9efc5a..e957474 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1573,6 +1573,9 @@ extern void inode_init_owner(struct inode *inode, const struct inode *dir,
  */
 extern kuid_t vfs_shift_i_uid_to_virtual(const struct inode *inode);
 extern kgid_t vfs_shift_i_gid_to_virtual(const struct inode *inode);
+extern kgid_t vfs_kgid_disk_to_virtual(const struct inode *inode, kgid_t kgid);
+extern kuid_t vfs_shift_kuid_to_disk(const struct inode *inode, kuid_t kuid);
+extern kgid_t vfs_shift_kgid_to_disk(const struct inode *inode, kgid_t kgid);
 
 /*
  * VFS FS_IOC_FIEMAP helper definitions.
-- 
2.5.5

  parent reply	other threads:[~2016-05-04 14:26 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-04 14:26 [RFC v2 PATCH 0/8] VFS:userns: support portable root filesystems Djalal Harouni
2016-05-04 14:26 ` [RFC v2 PATCH 1/8] VFS: add CLONE_MNTNS_SHIFT_UIDGID flag to allow mounts to shift their UIDs/GIDs Djalal Harouni
2016-05-04 14:26 ` [RFC v2 PATCH 2/8] VFS:uidshift: add flags and helpers to shift UIDs and GIDs to virtual view Djalal Harouni
2016-05-04 14:26 ` [RFC v2 PATCH 3/8] fs: Treat foreign mounts as nosuid Djalal Harouni
2016-05-04 23:19   ` Serge Hallyn
2016-05-05 13:05     ` Seth Forshee
2016-05-05 22:40       ` Djalal Harouni
2016-05-04 14:26 ` [RFC v2 PATCH 4/8] VFS:userns: shift UID/GID to virtual view during permission access Djalal Harouni
2016-05-04 14:26 ` Djalal Harouni [this message]
2016-05-04 14:26 ` [RFC v2 PATCH 6/8] VFS:userns: shift UID/GID to on-disk view before any write to disk Djalal Harouni
2016-05-04 14:26 ` [RFC v2 PATCH 7/8] ext4: add support for vfs_shift_uids and vfs_shift_gids mount options Djalal Harouni
2016-05-04 14:26 ` [RFC v2 PATCH 8/8] btrfs: " Djalal Harouni
2016-05-04 16:34 ` [RFC v2 PATCH 0/8] VFS:userns: support portable root filesystems Josh Triplett
2016-05-04 21:06 ` James Bottomley
2016-05-05  7:36   ` Djalal Harouni
2016-05-05 11:56     ` James Bottomley
2016-05-05 21:49       ` Djalal Harouni
2016-05-05 22:08         ` James Bottomley
2016-05-10 23:36           ` James Bottomley
2016-05-11  0:38             ` Al Viro
2016-05-11  0:53             ` Al Viro
2016-05-11  3:47               ` James Bottomley
2016-05-11 16:42             ` Djalal Harouni
2016-05-11 18:33               ` James Bottomley
2016-05-12 19:55                 ` Djalal Harouni
2016-05-12 22:24                   ` James Bottomley
2016-05-14  9:53                     ` Djalal Harouni
2016-05-14 13:46                       ` James Bottomley
2016-05-15  2:21                         ` Eric W. Biederman
2016-05-15 15:04                           ` James Bottomley
2016-05-16 14:12                           ` Seth Forshee
2016-05-16 16:42                             ` Eric W. Biederman
2016-05-16 18:25                               ` Seth Forshee
2016-05-16 19:13                           ` James Bottomley
2016-05-17 22:40                             ` Eric W. Biederman
2016-05-17 11:42                           ` Djalal Harouni
2016-05-17 15:42                         ` Djalal Harouni
2016-05-04 23:30 ` Serge Hallyn
2016-05-06 14:38   ` Djalal Harouni
2016-05-09 16:26     ` Serge Hallyn
2016-05-10 10:33       ` Djalal Harouni
2016-05-05  0:23 ` Dave Chinner
2016-05-05  1:44   ` Andy Lutomirski
2016-05-05  2:25     ` Dave Chinner
2016-05-05  3:29       ` Andy Lutomirski
2016-05-05 22:34     ` Djalal Harouni
2016-05-05 22:24   ` Djalal Harouni
2016-05-06  2:50     ` Dave Chinner
2016-05-12 19:47       ` Djalal Harouni

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=1462372014-3786-6-git-send-email-tixxdz@gmail.com \
    --to=tixxdz@gmail.com \
    --cc=alban.crequy@gmail.com \
    --cc=clm@fb.com \
    --cc=dh.herrmann@googlemail.com \
    --cc=dongsu@endocode.com \
    --cc=ebiederm@xmission.com \
    --cc=josh@joshtriplett.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mszeredi@redhat.com \
    --cc=serge.hallyn@canonical.com \
    --cc=seth.forshee@canonical.com \
    --cc=tixxdz@opendz.org \
    --cc=tytso@mit.edu \
    --cc=viro@zeniv.linux.org.uk \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).