linux-kernel.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 4/8] VFS:userns: shift UID/GID to virtual view during permission access
Date: Wed,  4 May 2016 16:26:50 +0200	[thread overview]
Message-ID: <1462372014-3786-5-git-send-email-tixxdz@gmail.com> (raw)
In-Reply-To: <1462372014-3786-1-git-send-email-tixxdz@gmail.com>

If both the mount namespace and the mount point support UID/GID shifts,
then before doing any permission check, translate inode->{i_uid|i_gid}
into the kernel virtual view, then use the result to do the permission
checks. If there is no support for UID/GID shifts, we fallback to
inode->{i_uid|i_gid} on-disk values.

The VFS will shift these values to the virtual view, the result
will be used to compare with current's fsuid and fsgid and to perform
classic or capable checks. Since inode->{i_uid|i_gid} will always
contain the on-disk values we do the virtual translation when an access
is needed.

This solves the problem of privileged userns or users inside containers
that want to access files, but the access fails since VFS uses their
global kuid/kgid.

Permission checks inside user_ns_X
----------------------------------

Without this Patch:
-------------------------------------------------------------------------
inode->uid on Disk | init_user_ns uid | user_ns_X uid           | Access
-------------------------------------------------------------------------
0                  | 1000000          | 0 (userns root)         | Denied
-------------------------------------------------------------------------
999                | 1000999          | 999                     | Denied
-------------------------------------------------------------------------
1000               | 1001000          | 1000                    | Denied
-------------------------------------------------------------------------
1000               | 1000000          | 0 (userns root CAPS)    | Denied
-------------------------------------------------------------------------
0                  | 1001000          | 1000                    | Denied
-------------------------------------------------------------------------

With this patch:
--------------------------------------------------------------------------
inode->uid on Disk | init_user_ns uid | user_ns_X uid           | Access
--------------------------------------------------------------------------
0                  | 1000000          | 0 (userns root)         | Granted
--------------------------------------------------------------------------
999                | 1000999          | 999                     | Granted
--------------------------------------------------------------------------
1000               | 1001000          | 1000                    | Granted
--------------------------------------------------------------------------
1000               | 1000000          | 0 (userns root CAPS)    | Granted
--------------------------------------------------------------------------
999                | 1000000          | 0 (userns root CAPS)    | Granted
--------------------------------------------------------------------------
0                  | 1001000          | 1000                    | Denied
--------------------------------------------------------------------------
0                  | 1000999          | 999                     | Denied
--------------------------------------------------------------------------
1000               | 1000999          | 999                     | Denied
--------------------------------------------------------------------------

* CAPS: means capabilities, the access was granted due to the capabilities
  of the caller inside user_ns_X and the shifted UID/GID of the inode are
  also mapped in that user_ns_X

Privileged root user namespaces with uid 0 inside the container will be
able to access inodes->i_uid == 0 on-disk if that inode is on a file
system that supports VFS UID/GID shifts and the caller is inside a mount
namespace that also supports the above.

Signed-off-by: Dongsu Park <dongsu@endocode.com>
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
---
 fs/inode.c          |  5 +++--
 fs/namei.c          |  6 ++++--
 kernel/capability.c | 14 ++++++++++++--
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/fs/inode.c b/fs/inode.c
index 69b8b52..07daf5f 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1961,12 +1961,13 @@ EXPORT_SYMBOL(inode_init_owner);
 bool inode_owner_or_capable(const struct inode *inode)
 {
 	struct user_namespace *ns;
+	kuid_t i_uid = vfs_shift_i_uid_to_virtual(inode);
 
-	if (uid_eq(current_fsuid(), inode->i_uid))
+	if (uid_eq(current_fsuid(), i_uid))
 		return true;
 
 	ns = current_user_ns();
-	if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid))
+	if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, i_uid))
 		return true;
 	return false;
 }
diff --git a/fs/namei.c b/fs/namei.c
index 1d9ca2d..f7ee498 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -289,8 +289,10 @@ static int check_acl(struct inode *inode, int mask)
 static int acl_permission_check(struct inode *inode, int mask)
 {
 	unsigned int mode = inode->i_mode;
+	kuid_t i_uid = vfs_shift_i_uid_to_virtual(inode);
+	kgid_t i_gid = vfs_shift_i_gid_to_virtual(inode);
 
-	if (likely(uid_eq(current_fsuid(), inode->i_uid)))
+	if (likely(uid_eq(current_fsuid(), i_uid)))
 		mode >>= 6;
 	else {
 		if (IS_POSIXACL(inode) && (mode & S_IRWXG)) {
@@ -299,7 +301,7 @@ static int acl_permission_check(struct inode *inode, int mask)
 				return error;
 		}
 
-		if (in_group_p(inode->i_gid))
+		if (in_group_p(i_gid))
 			mode >>= 3;
 	}
 
diff --git a/kernel/capability.c b/kernel/capability.c
index 45432b5..fdc8afb 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -441,9 +441,19 @@ EXPORT_SYMBOL(file_ns_capable);
  */
 bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
 {
+	kuid_t i_uid;
+	kgid_t i_gid;
 	struct user_namespace *ns = current_user_ns();
 
-	return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
-		kgid_has_mapping(ns, inode->i_gid);
+	/*
+	 * Check if inode's UID/GID are mean to be shifted into the current
+	 * mount namespace, if so we use the result to check if the shifted
+	 * UID/GID have a mapping in current's user namespace.
+	 */
+	i_uid = vfs_shift_i_uid_to_virtual(inode);
+	i_gid = vfs_shift_i_gid_to_virtual(inode);
+
+	return ns_capable(ns, cap) && kuid_has_mapping(ns, i_uid) &&
+		kgid_has_mapping(ns, i_gid);
 }
 EXPORT_SYMBOL(capable_wrt_inode_uidgid);
-- 
2.5.5

  parent reply	other threads:[~2016-05-04 14:29 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 ` Djalal Harouni [this message]
2016-05-04 14:26 ` [RFC v2 PATCH 5/8] VFS:userns: add helpers to shift UIDs and GIDs into on-disk view Djalal Harouni
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-5-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).