From: Seth Forshee <seth.forshee-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
To: "Eric W. Biederman"
<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
Alexander Viro
<viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org>,
Greg Kroah-Hartman
<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Serge Hallyn
<serge.hallyn-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>,
Seth Forshee
<seth.forshee-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
Miklos Szeredi <mszeredi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
linux-security-module-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-raid-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
Austin S Hemmelgarn
<ahferroin7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
selinux-+05T5uksL2qpZYMLLGbcSA@public.gmane.org,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Pavel Tikhomirov
<ptikhomirov-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org>
Subject: [PATCH v3 14/21] fs: Allow superblock owner to change ownership of inodes with unmappable ids
Date: Fri, 22 Apr 2016 10:38:31 -0500 [thread overview]
Message-ID: <1461339521-123191-15-git-send-email-seth.forshee@canonical.com> (raw)
In-Reply-To: <1461339521-123191-1-git-send-email-seth.forshee-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
In a userns mount some on-disk inodes may have ids which do not
map into s_user_ns, in which case the in-kernel inodes are owned
by invalid users. The superblock owner should be able to change
attributes of these inodes but cannot. However it is unsafe to
grant the superblock owner privileged access to all inodes in the
superblock since proc, sysfs, etc. use DAC to protect files which
may not belong to s_user_ns. The problem is restricted to only
inodes where the owner or group is an invalid user.
We can work around this by allowing users with CAP_CHOWN in
s_user_ns to change an invalid owner or group id, so long as the
other id is either invalid or mappable in s_user_ns. After
changing ownership the user will be privileged towards the inode
and thus able to change other attributes.
As an precaution, checks for invalid ids are added to the proc
and kernfs setattr interfaces. These filesystems are not expected
to have inodes with invalid ids, but if it does happen any
setattr operations will return -EPERM.
Signed-off-by: Seth Forshee <seth.forshee-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
---
fs/attr.c | 47 +++++++++++++++++++++++++++++++++++++++--------
fs/kernfs/inode.c | 2 ++
fs/proc/base.c | 2 ++
fs/proc/generic.c | 3 +++
fs/proc/proc_sysctl.c | 2 ++
5 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/fs/attr.c b/fs/attr.c
index 3cfaaac4a18e..a8b0931654a5 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -16,6 +16,43 @@
#include <linux/evm.h>
#include <linux/ima.h>
+static bool chown_ok(const struct inode *inode, kuid_t uid)
+{
+ struct user_namespace *user_ns;
+
+ if (uid_eq(current_fsuid(), inode->i_uid) && uid_eq(uid, inode->i_uid))
+ return true;
+ if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+ return true;
+
+ user_ns = inode->i_sb->s_user_ns;
+ if (!uid_valid(inode->i_uid) &&
+ (!gid_valid(inode->i_gid) || kgid_has_mapping(user_ns, inode->i_gid)) &&
+ ns_capable(user_ns, CAP_CHOWN))
+ return true;
+
+ return false;
+}
+
+static bool chgrp_ok(const struct inode *inode, kgid_t gid)
+{
+ struct user_namespace *user_ns;
+
+ if (uid_eq(current_fsuid(), inode->i_uid) &&
+ (in_group_p(gid) || gid_eq(gid, inode->i_gid)))
+ return true;
+ if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+ return true;
+
+ user_ns = inode->i_sb->s_user_ns;
+ if (!gid_valid(inode->i_gid) &&
+ (!uid_valid(inode->i_uid) || kuid_has_mapping(user_ns, inode->i_uid)) &&
+ ns_capable(user_ns, CAP_CHOWN))
+ return true;
+
+ return false;
+}
+
/**
* inode_change_ok - check if attribute changes to an inode are allowed
* @inode: inode to check
@@ -58,17 +95,11 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
return 0;
/* Make sure a caller can chown. */
- if ((ia_valid & ATTR_UID) &&
- (!uid_eq(current_fsuid(), inode->i_uid) ||
- !uid_eq(attr->ia_uid, inode->i_uid)) &&
- !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+ if ((ia_valid & ATTR_UID) && !chown_ok(inode, attr->ia_uid))
return -EPERM;
/* Make sure caller can chgrp. */
- if ((ia_valid & ATTR_GID) &&
- (!uid_eq(current_fsuid(), inode->i_uid) ||
- (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
- !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+ if ((ia_valid & ATTR_GID) && !chgrp_ok(inode, attr->ia_gid))
return -EPERM;
/* Make sure a caller can chmod. */
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 16405ae88d2d..2e97a337ee5f 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -117,6 +117,8 @@ int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr)
if (!kn)
return -EINVAL;
+ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+ return -EPERM;
mutex_lock(&kernfs_mutex);
error = inode_change_ok(inode, iattr);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index b1755b23893e..648d623e2158 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -711,6 +711,8 @@ int proc_setattr(struct dentry *dentry, struct iattr *attr)
if (attr->ia_valid & ATTR_MODE)
return -EPERM;
+ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+ return -EPERM;
error = inode_change_ok(inode, attr);
if (error)
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index ff3ffc76a937..1461570c552c 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -105,6 +105,9 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
struct proc_dir_entry *de = PDE(inode);
int error;
+ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+ return -EPERM;
+
error = inode_change_ok(inode, iattr);
if (error)
return error;
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index fe5b6e6c4671..f5d575157194 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -752,6 +752,8 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
return -EPERM;
+ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+ return -EPERM;
error = inode_change_ok(inode, attr);
if (error)
--
1.9.1
------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
--
fuse-devel mailing list
To unsubscribe or subscribe, visit https://lists.sourceforge.net/lists/listinfo/fuse-devel
next prev parent reply other threads:[~2016-04-22 15:38 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-22 15:38 [PATCH v3 00/21] Support fuse mounts in user namespaces Seth Forshee
2016-04-22 15:38 ` [PATCH v3 01/21] fs: fix a posible leak of allocated superblock Seth Forshee
2016-04-22 15:38 ` [PATCH v3 04/21] block_dev: Support checking inode permissions in lookup_bdev() Seth Forshee
2016-04-22 15:38 ` [PATCH v3 13/21] fs: Update posix_acl support to handle user namespace mounts Seth Forshee
[not found] ` <1461339521-123191-1-git-send-email-seth.forshee-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
2016-04-22 15:38 ` [PATCH v3 02/21] fs: Remove check of s_user_ns for existing mounts in fs_fully_visible() Seth Forshee
2016-04-22 15:38 ` [PATCH v3 03/21] fs: Allow sysfs and cgroupfs to share super blocks between user namespaces Seth Forshee
2016-04-25 19:01 ` Serge E. Hallyn
2016-04-22 15:38 ` [PATCH v3 05/21] block_dev: Check permissions towards block device inode when mounting Seth Forshee
2016-04-22 15:38 ` [PATCH v3 06/21] fs: Treat foreign mounts as nosuid Seth Forshee
2016-04-22 15:38 ` [PATCH v3 07/21] selinux: Add support for unprivileged mounts from user namespaces Seth Forshee
2016-04-22 15:38 ` [PATCH v3 08/21] userns: Replace in_userns with current_in_userns Seth Forshee
2016-04-22 15:38 ` [PATCH v3 09/21] Smack: Handle labels consistently in untrusted mounts Seth Forshee
2016-04-22 15:38 ` [PATCH v3 10/21] fs: Check for invalid i_uid in may_follow_link() Seth Forshee
2016-04-22 15:38 ` [PATCH v3 11/21] cred: Reject inodes with invalid ids in set_create_file_as() Seth Forshee
2016-04-22 15:38 ` [PATCH v3 12/21] fs: Refuse uid/gid changes which don't map into s_user_ns Seth Forshee
2016-04-22 15:38 ` Seth Forshee [this message]
2016-04-25 20:30 ` [PATCH v3 14/21] fs: Allow superblock owner to change ownership of inodes with unmappable ids Serge E. Hallyn
2016-04-25 20:54 ` Seth Forshee
2016-04-22 15:38 ` [PATCH v3 15/21] fs: Don't remove suid for CAP_FSETID in s_user_ns Seth Forshee
2016-04-22 15:38 ` [PATCH v3 16/21] fs: Allow superblock owner to access do_remount_sb() Seth Forshee
2016-04-22 15:38 ` [PATCH v3 17/21] capabilities: Allow privileged user in s_user_ns to set security.* xattrs Seth Forshee
2016-04-22 15:38 ` [PATCH v3 18/21] fuse: Add support for pid namespaces Seth Forshee
2016-04-22 15:38 ` [PATCH v3 19/21] fuse: Support fuse filesystems outside of init_user_ns Seth Forshee
2016-04-22 15:38 ` [PATCH v3 20/21] fuse: Restrict allow_other to the superblock's namespace or a descendant Seth Forshee
2016-04-22 15:38 ` [PATCH v3 21/21] fuse: Allow user namespace mounts Seth Forshee
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=1461339521-123191-15-git-send-email-seth.forshee@canonical.com \
--to=seth.forshee-z7wlfzj8ewms+fvcfc7uqw@public.gmane.org \
--cc=ahferroin7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=dm-devel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
--cc=fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
--cc=linux-bcache-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-raid-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-security-module-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=mszeredi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=ptikhomirov-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org \
--cc=selinux-+05T5uksL2qpZYMLLGbcSA@public.gmane.org \
--cc=serge.hallyn-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org \
--cc=viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org \
/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).