summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--security/commoncap.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index 26c1cb725dcb..78598be45f10 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -500,7 +500,8 @@ int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size)
__u32 magic, nsmagic;
struct inode *inode = d_backing_inode(dentry);
struct user_namespace *task_ns = current_user_ns(),
- *fs_ns = inode->i_sb->s_user_ns;
+ *fs_ns = inode->i_sb->s_user_ns,
+ *ancestor;
kuid_t rootid;
size_t newsize;
@@ -523,6 +524,15 @@ int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size)
if (nsrootid == -1)
return -EINVAL;
+ /*
+ * Do not allow allow adding a v3 filesystem capability xattr
+ * if the rootid field is ambiguous.
+ */
+ for (ancestor = task_ns->parent; ancestor; ancestor = ancestor->parent) {
+ if (from_kuid(ancestor, rootid) == 0)
+ return -EINVAL;
+ }
+
newsize = sizeof(struct vfs_ns_cap_data);
nscap = kmalloc(newsize, GFP_ATOMIC);
if (!nscap)