summaryrefslogtreecommitdiff
path: root/fs/xattr.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2024-09-26 14:11:52 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2024-11-06 12:59:39 -0500
commita10c4c5e01bdab617eaf3aaac9a96c22ddefa97e (patch)
tree1aeed61667a9430a3a93262e4ebb62e09454621e /fs/xattr.c
parent537c76629d7855ce11400eaad0137a062bfc15f6 (diff)
new helper: import_xattr_name()
common logics for marshalling xattr names. Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c45
1 files changed, 23 insertions, 22 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index 1214ae7e71db..d8f7c766f28a 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -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;