]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
new helper: import_xattr_name()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 26 Sep 2024 18:11:52 +0000 (14:11 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 6 Nov 2024 17:59:39 +0000 (12:59 -0500)
common logics for marshalling xattr names.

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/internal.h
fs/xattr.c
io_uring/xattr.c

index 81c7a085355c963316cc42a422882738182fbe9c..b9f5ac4d39fc70fcda67291438cf44993cd5a54f 100644 (file)
@@ -288,6 +288,9 @@ ssize_t do_getxattr(struct mnt_idmap *idmap,
 int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx);
 int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
                struct kernel_xattr_ctx *ctx);
+
+int import_xattr_name(struct xattr_name *kname, const char __user *name);
+
 int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode);
 
 #ifdef CONFIG_FS_POSIX_ACL
index 1214ae7e71db63028b28cc9eabb00b0f86efea6a..d8f7c766f28a4b1ac1b2264ce0ae932282383525 100644 (file)
@@ -586,6 +586,17 @@ retry_deleg:
 }
 EXPORT_SYMBOL_GPL(vfs_removexattr);
 
+int import_xattr_name(struct xattr_name *kname, const char __user *name)
+{
+       int error = strncpy_from_user(kname->name, name,
+                                       sizeof(kname->name));
+       if (error == 0 || error == sizeof(kname->name))
+               return -ERANGE;
+       if (error < 0)
+               return error;
+       return 0;
+}
+
 /*
  * Extended attribute SET operations
  */
@@ -597,14 +608,10 @@ int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx)
        if (ctx->flags & ~(XATTR_CREATE|XATTR_REPLACE))
                return -EINVAL;
 
-       error = strncpy_from_user(ctx->kname->name, name,
-                               sizeof(ctx->kname->name));
-       if (error == 0 || error == sizeof(ctx->kname->name))
-               return  -ERANGE;
-       if (error < 0)
+       error = import_xattr_name(ctx->kname, name);
+       if (error)
                return error;
 
-       error = 0;
        if (ctx->size) {
                if (ctx->size > XATTR_SIZE_MAX)
                        return -E2BIG;
@@ -763,10 +770,8 @@ getxattr(struct mnt_idmap *idmap, struct dentry *d,
                .flags    = 0,
        };
 
-       error = strncpy_from_user(kname.name, name, sizeof(kname.name));
-       if (error == 0 || error == sizeof(kname.name))
-               error = -ERANGE;
-       if (error < 0)
+       error = import_xattr_name(&kname, name);
+       if (error)
                return error;
 
        error =  do_getxattr(idmap, d, &ctx);
@@ -906,12 +911,10 @@ static int path_removexattr(const char __user *pathname,
 {
        struct path path;
        int error;
-       char kname[XATTR_NAME_MAX + 1];
+       struct xattr_name kname;
 
-       error = strncpy_from_user(kname, name, sizeof(kname));
-       if (error == 0 || error == sizeof(kname))
-               error = -ERANGE;
-       if (error < 0)
+       error = import_xattr_name(&kname, name);
+       if (error)
                return error;
 retry:
        error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
@@ -919,7 +922,7 @@ retry:
                return error;
        error = mnt_want_write(path.mnt);
        if (!error) {
-               error = removexattr(mnt_idmap(path.mnt), path.dentry, kname);
+               error = removexattr(mnt_idmap(path.mnt), path.dentry, kname.name);
                mnt_drop_write(path.mnt);
        }
        path_put(&path);
@@ -945,23 +948,21 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
 SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
 {
        CLASS(fd, f)(fd);
-       char kname[XATTR_NAME_MAX + 1];
+       struct xattr_name kname;
        int error;
 
        if (fd_empty(f))
                return -EBADF;
        audit_file(fd_file(f));
 
-       error = strncpy_from_user(kname, name, sizeof(kname));
-       if (error == 0 || error == sizeof(kname))
-               error = -ERANGE;
-       if (error < 0)
+       error = import_xattr_name(&kname, name);
+       if (error)
                return error;
 
        error = mnt_want_write_file(fd_file(f));
        if (!error) {
                error = removexattr(file_mnt_idmap(fd_file(f)),
-                                   fd_file(f)->f_path.dentry, kname);
+                                   fd_file(f)->f_path.dentry, kname.name);
                mnt_drop_write_file(fd_file(f));
        }
        return error;
index f440121c398446ca5b88be5b062387eef96958d7..0b3b871eaa65b3c6f5864d0914841be4ad95400f 100644 (file)
@@ -62,11 +62,8 @@ static int __io_getxattr_prep(struct io_kiocb *req,
        if (!ix->ctx.kname)
                return -ENOMEM;
 
-       ret = strncpy_from_user(ix->ctx.kname->name, name,
-                               sizeof(ix->ctx.kname->name));
-       if (!ret || ret == sizeof(ix->ctx.kname->name))
-               ret = -ERANGE;
-       if (ret < 0) {
+       ret = import_xattr_name(ix->ctx.kname, name);
+       if (ret) {
                kfree(ix->ctx.kname);
                return ret;
        }