Switch notify_change() to lookup fsids in the fsid mappings. If no fsid mappings are setup the behavior is unchanged, i.e. fsids are looked up in the id mappings. Filesystems that share a superblock in all user namespaces they are mounted in will retain their old semantics even with the introduction of fsid mappings. Signed-off-by: Christian Brauner <christian.brauner@xxxxxxxxxx> --- /* v2 */ unchanged /* v3 */ unchanged --- fs/attr.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index b4bbdbd4c8ca..b3fe9d9582d2 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -17,6 +17,8 @@ #include <linux/security.h> #include <linux/evm.h> #include <linux/ima.h> +#include <linux/fsuidgid.h> +#include <linux/fs.h> static bool chown_ok(const struct inode *inode, kuid_t uid) { @@ -310,12 +312,21 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de * Verify that uid/gid changes are valid in the target * namespace of the superblock. */ - if (ia_valid & ATTR_UID && - !kuid_has_mapping(inode->i_sb->s_user_ns, attr->ia_uid)) - return -EOVERFLOW; - if (ia_valid & ATTR_GID && - !kgid_has_mapping(inode->i_sb->s_user_ns, attr->ia_gid)) - return -EOVERFLOW; + if (is_userns_visible(inode->i_sb->s_iflags)) { + if (ia_valid & ATTR_UID && + !kuid_has_mapping(inode->i_sb->s_user_ns, attr->ia_uid)) + return -EOVERFLOW; + if (ia_valid & ATTR_GID && + !kgid_has_mapping(inode->i_sb->s_user_ns, attr->ia_gid)) + return -EOVERFLOW; + } else { + if (ia_valid & ATTR_UID && + !kfsuid_has_mapping(inode->i_sb->s_user_ns, attr->ia_uid)) + return -EOVERFLOW; + if (ia_valid & ATTR_GID && + !kfsgid_has_mapping(inode->i_sb->s_user_ns, attr->ia_gid)) + return -EOVERFLOW; + } /* Don't allow modifications of files with invalid uids or * gids unless those uids & gids are being made valid. -- 2.25.0