acl: conver higher-level helpers to rely on mnt_idmap
authorChristian Brauner <brauner@kernel.org>
Fri, 28 Oct 2022 07:56:20 +0000 (09:56 +0200)
committerChristian Brauner (Microsoft) <brauner@kernel.org>
Mon, 31 Oct 2022 16:48:12 +0000 (17:48 +0100)
Convert an initial portion to rely on struct mnt_idmap by converting the
high level xattr helpers.

Reviewed-by: Seth Forshee (DigitalOcean) <sforshee@kernel.org>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
fs/internal.h
fs/posix_acl.c
fs/xattr.c
io_uring/xattr.c

index 0c8812f..a803cc3 100644 (file)
@@ -227,28 +227,28 @@ struct xattr_ctx {
 };
 
 
-ssize_t do_getxattr(struct user_namespace *mnt_userns,
+ssize_t do_getxattr(struct mnt_idmap *idmap,
                    struct dentry *d,
                    struct xattr_ctx *ctx);
 
 int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
-int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
                struct xattr_ctx *ctx);
 int may_write_xattr(struct user_namespace *mnt_userns, struct inode *inode);
 
 #ifdef CONFIG_FS_POSIX_ACL
-int do_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+int do_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
               const char *acl_name, const void *kvalue, size_t size);
-ssize_t do_get_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+ssize_t do_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
                   const char *acl_name, void *kvalue, size_t size);
 #else
-static inline int do_set_acl(struct user_namespace *mnt_userns,
+static inline int do_set_acl(struct mnt_idmap *idmap,
                             struct dentry *dentry, const char *acl_name,
                             const void *kvalue, size_t size)
 {
        return -EOPNOTSUPP;
 }
-static inline ssize_t do_get_acl(struct user_namespace *mnt_userns,
+static inline ssize_t do_get_acl(struct mnt_idmap *idmap,
                                 struct dentry *dentry, const char *acl_name,
                                 void *kvalue, size_t size)
 {
index 989bbf2..7260b59 100644 (file)
@@ -871,7 +871,7 @@ EXPORT_SYMBOL (posix_acl_to_xattr);
 
 /**
  * vfs_posix_acl_to_xattr - convert from kernel to userspace representation
- * @mnt_userns: user namespace of the mount
+ * @idmap: idmap of the mount
  * @inode: inode the posix acls are set on
  * @acl: the posix acls as represented by the vfs
  * @buffer: the buffer into which to convert @acl
@@ -884,7 +884,7 @@ EXPORT_SYMBOL (posix_acl_to_xattr);
  * Return: On success, the size of the stored uapi posix acls, on error a
  * negative errno.
  */
-static ssize_t vfs_posix_acl_to_xattr(struct user_namespace *mnt_userns,
+static ssize_t vfs_posix_acl_to_xattr(struct mnt_idmap *idmap,
                                      struct inode *inode,
                                      const struct posix_acl *acl, void *buffer,
                                      size_t size)
@@ -893,6 +893,7 @@ static ssize_t vfs_posix_acl_to_xattr(struct user_namespace *mnt_userns,
        struct posix_acl_xattr_header *ext_acl = buffer;
        struct posix_acl_xattr_entry *ext_entry;
        struct user_namespace *fs_userns, *caller_userns;
+       struct user_namespace *mnt_userns;
        ssize_t real_size, n;
        vfsuid_t vfsuid;
        vfsgid_t vfsgid;
@@ -908,6 +909,7 @@ static ssize_t vfs_posix_acl_to_xattr(struct user_namespace *mnt_userns,
 
        fs_userns = i_user_ns(inode);
        caller_userns = current_user_ns();
+       mnt_userns = mnt_idmap_owner(idmap);
        for (n=0; n < acl->a_count; n++, ext_entry++) {
                const struct posix_acl_entry *acl_e = &acl->a_entries[n];
                ext_entry->e_tag  = cpu_to_le16(acl_e->e_tag);
@@ -1227,7 +1229,7 @@ out_inode_unlock:
 }
 EXPORT_SYMBOL_GPL(vfs_remove_acl);
 
-int do_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+int do_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
               const char *acl_name, const void *kvalue, size_t size)
 {
        int error;
@@ -1243,22 +1245,22 @@ int do_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
                        return PTR_ERR(acl);
        }
 
-       error = vfs_set_acl(mnt_userns, dentry, acl_name, acl);
+       error = vfs_set_acl(mnt_idmap_owner(idmap), dentry, acl_name, acl);
        posix_acl_release(acl);
        return error;
 }
 
-ssize_t do_get_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+ssize_t do_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
                   const char *acl_name, void *kvalue, size_t size)
 {
        ssize_t error;
        struct posix_acl *acl;
 
-       acl = vfs_get_acl(mnt_userns, dentry, acl_name);
+       acl = vfs_get_acl(mnt_idmap_owner(idmap), dentry, acl_name);
        if (IS_ERR(acl))
                return PTR_ERR(acl);
 
-       error = vfs_posix_acl_to_xattr(mnt_userns, d_inode(dentry),
+       error = vfs_posix_acl_to_xattr(idmap, d_inode(dentry),
                                       acl, kvalue, size);
        posix_acl_release(acl);
        return error;
index df3af9f..3641a0c 100644 (file)
@@ -597,19 +597,19 @@ int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
        return error;
 }
 
-int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
                struct xattr_ctx *ctx)
 {
        if (is_posix_acl_xattr(ctx->kname->name))
-               return do_set_acl(mnt_userns, dentry, ctx->kname->name,
+               return do_set_acl(idmap, dentry, ctx->kname->name,
                                  ctx->kvalue, ctx->size);
 
-       return vfs_setxattr(mnt_userns, dentry, ctx->kname->name,
+       return vfs_setxattr(mnt_idmap_owner(idmap), dentry, ctx->kname->name,
                        ctx->kvalue, ctx->size, ctx->flags);
 }
 
 static long
-setxattr(struct user_namespace *mnt_userns, struct dentry *d,
+setxattr(struct mnt_idmap *idmap, struct dentry *d,
        const char __user *name, const void __user *value, size_t size,
        int flags)
 {
@@ -627,7 +627,7 @@ setxattr(struct user_namespace *mnt_userns, struct dentry *d,
        if (error)
                return error;
 
-       error = do_setxattr(mnt_userns, d, &ctx);
+       error = do_setxattr(idmap, d, &ctx);
 
        kvfree(ctx.kvalue);
        return error;
@@ -646,7 +646,7 @@ retry:
                return error;
        error = mnt_want_write(path.mnt);
        if (!error) {
-               error = setxattr(mnt_user_ns(path.mnt), path.dentry, name,
+               error = setxattr(mnt_idmap(path.mnt), path.dentry, name,
                                 value, size, flags);
                mnt_drop_write(path.mnt);
        }
@@ -683,7 +683,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
        audit_file(f.file);
        error = mnt_want_write_file(f.file);
        if (!error) {
-               error = setxattr(file_mnt_user_ns(f.file),
+               error = setxattr(file_mnt_idmap(f.file),
                                 f.file->f_path.dentry, name,
                                 value, size, flags);
                mnt_drop_write_file(f.file);
@@ -696,7 +696,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
  * Extended attribute GET operations
  */
 ssize_t
-do_getxattr(struct user_namespace *mnt_userns, struct dentry *d,
+do_getxattr(struct mnt_idmap *idmap, struct dentry *d,
        struct xattr_ctx *ctx)
 {
        ssize_t error;
@@ -711,9 +711,10 @@ do_getxattr(struct user_namespace *mnt_userns, struct dentry *d,
        }
 
        if (is_posix_acl_xattr(ctx->kname->name))
-               error = do_get_acl(mnt_userns, d, kname, ctx->kvalue, ctx->size);
+               error = do_get_acl(idmap, d, kname, ctx->kvalue, ctx->size);
        else
-               error = vfs_getxattr(mnt_userns, d, kname, ctx->kvalue, ctx->size);
+               error = vfs_getxattr(mnt_idmap_owner(idmap), d, kname,
+                                    ctx->kvalue, ctx->size);
        if (error > 0) {
                if (ctx->size && copy_to_user(ctx->value, ctx->kvalue, error))
                        error = -EFAULT;
@@ -727,7 +728,7 @@ do_getxattr(struct user_namespace *mnt_userns, struct dentry *d,
 }
 
 static ssize_t
-getxattr(struct user_namespace *mnt_userns, struct dentry *d,
+getxattr(struct mnt_idmap *idmap, struct dentry *d,
         const char __user *name, void __user *value, size_t size)
 {
        ssize_t error;
@@ -746,7 +747,7 @@ getxattr(struct user_namespace *mnt_userns, struct dentry *d,
        if (error < 0)
                return error;
 
-       error =  do_getxattr(mnt_userns, d, &ctx);
+       error =  do_getxattr(idmap, d, &ctx);
 
        kvfree(ctx.kvalue);
        return error;
@@ -762,7 +763,7 @@ retry:
        error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
        if (error)
                return error;
-       error = getxattr(mnt_user_ns(path.mnt), path.dentry, name, value, size);
+       error = getxattr(mnt_idmap(path.mnt), path.dentry, name, value, size);
        path_put(&path);
        if (retry_estale(error, lookup_flags)) {
                lookup_flags |= LOOKUP_REVAL;
@@ -792,7 +793,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
        if (!f.file)
                return error;
        audit_file(f.file);
-       error = getxattr(file_mnt_user_ns(f.file), f.file->f_path.dentry,
+       error = getxattr(file_mnt_idmap(f.file), f.file->f_path.dentry,
                         name, value, size);
        fdput(f);
        return error;
@@ -877,7 +878,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
  * Extended attribute REMOVE operations
  */
 static long
-removexattr(struct user_namespace *mnt_userns, struct dentry *d,
+removexattr(struct mnt_idmap *idmap, struct dentry *d,
            const char __user *name)
 {
        int error;
@@ -890,9 +891,9 @@ removexattr(struct user_namespace *mnt_userns, struct dentry *d,
                return error;
 
        if (is_posix_acl_xattr(kname))
-               return vfs_remove_acl(mnt_userns, d, kname);
+               return vfs_remove_acl(mnt_idmap_owner(idmap), d, kname);
 
-       return vfs_removexattr(mnt_userns, d, kname);
+       return vfs_removexattr(mnt_idmap_owner(idmap), d, kname);
 }
 
 static int path_removexattr(const char __user *pathname,
@@ -906,7 +907,7 @@ retry:
                return error;
        error = mnt_want_write(path.mnt);
        if (!error) {
-               error = removexattr(mnt_user_ns(path.mnt), path.dentry, name);
+               error = removexattr(mnt_idmap(path.mnt), path.dentry, name);
                mnt_drop_write(path.mnt);
        }
        path_put(&path);
@@ -939,7 +940,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
        audit_file(f.file);
        error = mnt_want_write_file(f.file);
        if (!error) {
-               error = removexattr(file_mnt_user_ns(f.file),
+               error = removexattr(file_mnt_idmap(f.file),
                                    f.file->f_path.dentry, name);
                mnt_drop_write_file(f.file);
        }
index 99df641..6201a9f 100644 (file)
@@ -112,7 +112,7 @@ int io_fgetxattr(struct io_kiocb *req, unsigned int issue_flags)
        if (issue_flags & IO_URING_F_NONBLOCK)
                return -EAGAIN;
 
-       ret = do_getxattr(mnt_user_ns(req->file->f_path.mnt),
+       ret = do_getxattr(mnt_idmap(req->file->f_path.mnt),
                        req->file->f_path.dentry,
                        &ix->ctx);
 
@@ -133,9 +133,7 @@ int io_getxattr(struct io_kiocb *req, unsigned int issue_flags)
 retry:
        ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL);
        if (!ret) {
-               ret = do_getxattr(mnt_user_ns(path.mnt),
-                               path.dentry,
-                               &ix->ctx);
+               ret = do_getxattr(mnt_idmap(path.mnt), path.dentry, &ix->ctx);
 
                path_put(&path);
                if (retry_estale(ret, lookup_flags)) {
@@ -213,7 +211,7 @@ static int __io_setxattr(struct io_kiocb *req, unsigned int issue_flags,
 
        ret = mnt_want_write(path->mnt);
        if (!ret) {
-               ret = do_setxattr(mnt_user_ns(path->mnt), path->dentry, &ix->ctx);
+               ret = do_setxattr(mnt_idmap(path->mnt), path->dentry, &ix->ctx);
                mnt_drop_write(path->mnt);
        }