lkml.org 
[lkml]   [2022]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 23/28] fs: fix acl translation
    Date
    From: Christian Brauner <brauner@kernel.org>

    commit 705191b03d507744c7e097f78d583621c14988ac upstream.

    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: bd303368b776 ("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.15+
    Cc: <regressions@lists.linux.dev>
    Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/posix_acl.c | 10 ++++++++++
    fs/xattr.c | 6 ++++--
    include/linux/posix_acl_xattr.h | 4 ++++
    3 files changed, 18 insertions(+), 2 deletions(-)

    --- a/fs/posix_acl.c
    +++ b/fs/posix_acl.c
    @@ -760,9 +760,14 @@ static void posix_acl_fix_xattr_userns(
    }

    void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
    + struct inode *inode,
    void *value, size_t size)
    {
    struct user_namespace *user_ns = current_user_ns();
    +
    + /* Leave ids untouched on non-idmapped mounts. */
    + if (no_idmapping(mnt_userns, i_user_ns(inode)))
    + mnt_userns = &init_user_ns;
    if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
    return;
    posix_acl_fix_xattr_userns(&init_user_ns, user_ns, mnt_userns, value,
    @@ -770,9 +775,14 @@ void posix_acl_fix_xattr_from_user(struc
    }

    void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
    + struct inode *inode,
    void *value, size_t size)
    {
    struct user_namespace *user_ns = current_user_ns();
    +
    + /* Leave ids untouched on non-idmapped mounts. */
    + if (no_idmapping(mnt_userns, i_user_ns(inode)))
    + mnt_userns = &init_user_ns;
    if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
    return;
    posix_acl_fix_xattr_userns(user_ns, &init_user_ns, mnt_userns, value,
    --- a/fs/xattr.c
    +++ b/fs/xattr.c
    @@ -569,7 +569,8 @@ setxattr(struct user_namespace *mnt_user
    }
    if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
    - posix_acl_fix_xattr_from_user(mnt_userns, kvalue, size);
    + posix_acl_fix_xattr_from_user(mnt_userns, d_inode(d),
    + kvalue, size);
    }

    error = vfs_setxattr(mnt_userns, d, kname, kvalue, size, flags);
    @@ -667,7 +668,8 @@ getxattr(struct user_namespace *mnt_user
    if (error > 0) {
    if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
    - posix_acl_fix_xattr_to_user(mnt_userns, kvalue, error);
    + posix_acl_fix_xattr_to_user(mnt_userns, d_inode(d),
    + kvalue, error);
    if (size && copy_to_user(value, kvalue, error))
    error = -EFAULT;
    } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
    --- a/include/linux/posix_acl_xattr.h
    +++ b/include/linux/posix_acl_xattr.h
    @@ -34,15 +34,19 @@ posix_acl_xattr_count(size_t size)

    #ifdef CONFIG_FS_POSIX_ACL
    void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
    + struct inode *inode,
    void *value, size_t size);
    void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
    + struct inode *inode,
    void *value, size_t size);
    #else
    static inline void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
    + struct inode *inode,
    void *value, size_t size)
    {
    }
    static inline void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
    + struct inode *inode,
    void *value, size_t size)
    {
    }

    \
     
     \ /
      Last update: 2022-06-30 16:12    [W:4.126 / U:0.280 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site