path: root/kernel/capability.c
diff options
authorAndy Lutomirski <>2014-06-10 19:45:42 (GMT)
committerGreg Kroah-Hartman <>2014-06-16 20:42:52 (GMT)
commit4f80c6c1825a91cecf3b3bd19c824e768d98fe48 (patch)
treecdb4e44336c2a34d559d3a609784d74a37c7301a /kernel/capability.c
parent853771148c5aa5998c423ed4dddd7605d4b4c949 (diff)
fs,userns: Change inode_capable to capable_wrt_inode_uidgid
commit 23adbe12ef7d3d4195e80800ab36b37bee28cd03 upstream. The kernel has no concept of capabilities with respect to inodes; inodes exist independently of namespaces. For example, inode_capable(inode, CAP_LINUX_IMMUTABLE) would be nonsense. This patch changes inode_capable to check for uid and gid mappings and renames it to capable_wrt_inode_uidgid, which should make it more obvious what it does. Fixes CVE-2014-4014. Cc: Theodore Ts'o <> Cc: Serge Hallyn <> Cc: "Eric W. Biederman" <> Cc: Dave Chinner <> Signed-off-by: Andy Lutomirski <> Signed-off-by: Linus Torvalds <> Signed-off-by: Greg Kroah-Hartman <>
Diffstat (limited to 'kernel/capability.c')
1 files changed, 7 insertions, 11 deletions
diff --git a/kernel/capability.c b/kernel/capability.c
index f6c2ce5..d52eecc 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -445,22 +445,18 @@ bool nsown_capable(int cap)
- * inode_capable - Check superior capability over inode
+ * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
* @inode: The inode in question
* @cap: The capability in question
- * Return true if the current task has the given superior capability
- * targeted at it's own user namespace and that the given inode is owned
- * by the current user namespace or a child namespace.
- *
- * Currently we check to see if an inode is owned by the current
- * user namespace by seeing if the inode's owner maps into the
- * current user namespace.
- *
+ * Return true if the current task has the given capability targeted at
+ * its own user namespace and that the given inode's uid and gid are
+ * mapped into the current user namespace.
-bool inode_capable(const struct inode *inode, int cap)
+bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
struct user_namespace *ns = current_user_ns();
- return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
+ return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
+ kgid_has_mapping(ns, inode->i_gid);