Skip to content

Commit 705191b

Browse files
braunertorvalds
authored andcommitted
fs: fix acl translation
Last cycle we extended the idmapped mounts infrastructure to support idmapped mounts of idmapped filesystems (No such filesystem yet exist.). Since then, the meaning of an idmapped mount is a mount whose idmapping is different from the filesystems idmapping. While doing that work we missed to adapt the acl translation helpers. They still assume that checking for the identity mapping is enough. But they need to use the no_idmapping() helper instead. Note, POSIX ACLs are always translated right at the userspace-kernel boundary using the caller's current idmapping and the initial idmapping. The order depends on whether we're coming from or going to userspace. The filesystem's idmapping doesn't matter at the border. Consequently, if a non-idmapped mount is passed we need to make sure to always pass the initial idmapping as the mount's idmapping and not the filesystem idmapping. Since it's irrelevant here it would yield invalid ids and prevent setting acls for filesystems that are mountable in a userns and support posix acls (tmpfs and fuse). I verified the regression reported in [1] and verified that this patch fixes it. A regression test will be added to xfstests in parallel. Link: https://bugzilla.kernel.org/show_bug.cgi?id=215849 [1] Fixes: bd30336 ("fs: support mapped mounts of mapped filesystems") Cc: Seth Forshee <sforshee@digitalocean.com> Cc: Christoph Hellwig <hch@lst.de> Cc: <stable@vger.kernel.org> # 5.17 Cc: <regressions@lists.linux.dev> Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent b2d229d commit 705191b

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

fs/posix_acl.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,19 +759,29 @@ static void posix_acl_fix_xattr_userns(
759759
}
760760

761761
void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
762+
struct inode *inode,
762763
void *value, size_t size)
763764
{
764765
struct user_namespace *user_ns = current_user_ns();
766+
767+
/* Leave ids untouched on non-idmapped mounts. */
768+
if (no_idmapping(mnt_userns, i_user_ns(inode)))
769+
mnt_userns = &init_user_ns;
765770
if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
766771
return;
767772
posix_acl_fix_xattr_userns(&init_user_ns, user_ns, mnt_userns, value,
768773
size, true);
769774
}
770775

771776
void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
777+
struct inode *inode,
772778
void *value, size_t size)
773779
{
774780
struct user_namespace *user_ns = current_user_ns();
781+
782+
/* Leave ids untouched on non-idmapped mounts. */
783+
if (no_idmapping(mnt_userns, i_user_ns(inode)))
784+
mnt_userns = &init_user_ns;
775785
if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
776786
return;
777787
posix_acl_fix_xattr_userns(user_ns, &init_user_ns, mnt_userns, value,

fs/xattr.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,8 @@ setxattr(struct user_namespace *mnt_userns, struct dentry *d,
569569
}
570570
if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
571571
(strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
572-
posix_acl_fix_xattr_from_user(mnt_userns, kvalue, size);
572+
posix_acl_fix_xattr_from_user(mnt_userns, d_inode(d),
573+
kvalue, size);
573574
}
574575

575576
error = vfs_setxattr(mnt_userns, d, kname, kvalue, size, flags);
@@ -667,7 +668,8 @@ getxattr(struct user_namespace *mnt_userns, struct dentry *d,
667668
if (error > 0) {
668669
if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
669670
(strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
670-
posix_acl_fix_xattr_to_user(mnt_userns, kvalue, error);
671+
posix_acl_fix_xattr_to_user(mnt_userns, d_inode(d),
672+
kvalue, error);
671673
if (size && copy_to_user(value, kvalue, error))
672674
error = -EFAULT;
673675
} else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {

include/linux/posix_acl_xattr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,19 @@ posix_acl_xattr_count(size_t size)
3434

3535
#ifdef CONFIG_FS_POSIX_ACL
3636
void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
37+
struct inode *inode,
3738
void *value, size_t size);
3839
void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
40+
struct inode *inode,
3941
void *value, size_t size);
4042
#else
4143
static inline void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
44+
struct inode *inode,
4245
void *value, size_t size)
4346
{
4447
}
4548
static inline void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
49+
struct inode *inode,
4650
void *value, size_t size)
4751
{
4852
}

0 commit comments

Comments
 (0)