diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/commoncap.c | 12 |
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) |