^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) File: fs/xattr.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Extended attribute handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/evm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/fsnotify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/posix_acl_xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) strcmp_prefix(const char *a, const char *a_prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) while (*a_prefix && *a == *a_prefix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) a++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) a_prefix++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return *a_prefix ? NULL : a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * In order to implement different sets of xattr operations for each xattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * prefix, a filesystem should create a null-terminated array of struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * xattr_handler (one for each prefix) and hang a pointer to it off of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * s_xattr field of the superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define for_each_xattr_handler(handlers, handler) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (handlers) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) for ((handler) = *(handlers)++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) (handler) != NULL; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) (handler) = *(handlers)++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Find the xattr_handler with the matching prefix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static const struct xattr_handler *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) xattr_resolve_name(struct inode *inode, const char **name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) const struct xattr_handler **handlers = inode->i_sb->s_xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const struct xattr_handler *handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (!(inode->i_opflags & IOP_XATTR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (unlikely(is_bad_inode(inode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return ERR_PTR(-EOPNOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) for_each_xattr_handler(handlers, handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const char *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) n = strcmp_prefix(*name, xattr_prefix(handler));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (!handler->prefix ^ !*n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *name = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return ERR_PTR(-EOPNOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Check permissions for extended attribute access. This is a bit complicated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * because different namespaces have very different rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) xattr_permission(struct inode *inode, const char *name, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * We can never set or remove an extended attribute on a read-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * filesystem or on an immutable / append-only inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (mask & MAY_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Updating an xattr will likely cause i_uid and i_gid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * to be writen back improperly if their true value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * unknown to the vfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (HAS_UNMAPPED_ID(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * No restriction for security.* and system.* from the VFS. Decision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * on these is left to the underlying filesystem / security module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * The trusted.* namespace can only be accessed by privileged users.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * In the user.* namespace, only regular files and directories can have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * extended attributes. For sticky directories, only the owner and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * privileged users can write attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) (mask & MAY_WRITE) && !inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return inode_permission(inode, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Look for any handler that deals with the specified namespace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) xattr_supported_namespace(struct inode *inode, const char *prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) const struct xattr_handler **handlers = inode->i_sb->s_xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const struct xattr_handler *handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) size_t preflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!(inode->i_opflags & IOP_XATTR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (unlikely(is_bad_inode(inode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) preflen = strlen(prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) for_each_xattr_handler(handlers, handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!strncmp(xattr_prefix(handler), prefix, preflen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) EXPORT_SYMBOL(xattr_supported_namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) const void *value, size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) const struct xattr_handler *handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) handler = xattr_resolve_name(inode, &name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (IS_ERR(handler))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return PTR_ERR(handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (!handler->set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) value = ""; /* empty EA, do not remove */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return handler->set(handler, dentry, inode, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) EXPORT_SYMBOL(__vfs_setxattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * __vfs_setxattr_noperm - perform setxattr operation without performing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * permission checks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * @dentry - object to perform setxattr on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * @name - xattr name to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * @value - value to set @name to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * @size - size of @value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * @flags - flags to pass into filesystem operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * returns the result of the internal setxattr or setsecurity operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * This function requires the caller to lock the inode's i_mutex before it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * is executed. It also assumes that the caller will make the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * permission checks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) const void *value, size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct inode *inode = dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int error = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int issec = !strncmp(name, XATTR_SECURITY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) XATTR_SECURITY_PREFIX_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (issec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) inode->i_flags &= ~S_NOSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (inode->i_opflags & IOP_XATTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) error = __vfs_setxattr(dentry, inode, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) fsnotify_xattr(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) security_inode_post_setxattr(dentry, name, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (unlikely(is_bad_inode(inode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (error == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) error = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (issec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) error = security_inode_setsecurity(inode, suffix, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) fsnotify_xattr(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * __vfs_setxattr_locked - set an extended attribute while holding the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @dentry: object to perform setxattr on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @name: xattr name to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * @value: value to set @name to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @size: size of @value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @flags: flags to pass into filesystem operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @delegated_inode: on return, will contain an inode pointer that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * a delegation was broken on, NULL if none.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) __vfs_setxattr_locked(struct dentry *dentry, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) const void *value, size_t size, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct inode **delegated_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct inode *inode = dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) error = xattr_permission(inode, name, MAY_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) error = security_inode_setxattr(dentry, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) error = try_break_deleg(inode, delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) EXPORT_SYMBOL_GPL(__vfs_setxattr_locked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct inode *inode = dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct inode *delegated_inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) retry_deleg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) error = __vfs_setxattr_locked(dentry, name, value, size, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) &delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (delegated_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) error = break_deleg_wait(&delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) goto retry_deleg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) EXPORT_SYMBOL_NS_GPL(vfs_setxattr, ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) xattr_getsecurity(struct inode *inode, const char *name, void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) void *buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!value || !size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) len = security_inode_getsecurity(inode, name, &buffer, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto out_noalloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) len = security_inode_getsecurity(inode, name, &buffer, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (size < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) len = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) memcpy(value, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) out_noalloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Allocate memory, if not already allocated, or re-allocate correct size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * before retrieving the extended attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * Returns the result of alloc, if failed, or the getxattr operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) size_t xattr_size, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) const struct xattr_handler *handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct inode *inode = dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) char *value = *xattr_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) error = xattr_permission(inode, name, MAY_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) handler = xattr_resolve_name(inode, &name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (IS_ERR(handler))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return PTR_ERR(handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (!handler->get)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) error = handler->get(handler, dentry, inode, name, NULL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (!value || (error > xattr_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) value = krealloc(*xattr_value, error + 1, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) memset(value, 0, error + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) error = handler->get(handler, dentry, inode, name, value, error, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *xattr_value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) void *value, size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) const struct xattr_handler *handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (flags & XATTR_NOSECURITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) goto nolsm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) error = xattr_permission(inode, name, MAY_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) error = security_inode_getxattr(dentry, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!strncmp(name, XATTR_SECURITY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) XATTR_SECURITY_PREFIX_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int ret = xattr_getsecurity(inode, suffix, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * Only overwrite the return value if a security module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * is actually active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (ret == -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) goto nolsm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) nolsm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) handler = xattr_resolve_name(inode, &name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (IS_ERR(handler))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return PTR_ERR(handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!handler->get)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return handler->get(handler, dentry, inode, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) EXPORT_SYMBOL(__vfs_getxattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return __vfs_getxattr(dentry, dentry->d_inode, name, value, size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) EXPORT_SYMBOL_NS_GPL(vfs_getxattr, ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) vfs_listxattr(struct dentry *dentry, char *list, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ssize_t error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) error = security_inode_listxattr(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) error = inode->i_op->listxattr(dentry, list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) error = security_inode_listsecurity(inode, list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (size && error > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) error = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) EXPORT_SYMBOL_NS_GPL(vfs_listxattr, ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) __vfs_removexattr(struct dentry *dentry, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) const struct xattr_handler *handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) handler = xattr_resolve_name(inode, &name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (IS_ERR(handler))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return PTR_ERR(handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!handler->set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return handler->set(handler, dentry, inode, name, NULL, 0, XATTR_REPLACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) EXPORT_SYMBOL(__vfs_removexattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * __vfs_removexattr_locked - set an extended attribute while holding the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * @dentry: object to perform setxattr on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * @name: name of xattr to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * @delegated_inode: on return, will contain an inode pointer that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * a delegation was broken on, NULL if none.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) __vfs_removexattr_locked(struct dentry *dentry, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct inode **delegated_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct inode *inode = dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) error = xattr_permission(inode, name, MAY_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) error = security_inode_removexattr(dentry, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) error = try_break_deleg(inode, delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) error = __vfs_removexattr(dentry, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) fsnotify_xattr(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) evm_inode_post_removexattr(dentry, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) EXPORT_SYMBOL_GPL(__vfs_removexattr_locked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) vfs_removexattr(struct dentry *dentry, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct inode *inode = dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct inode *delegated_inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) retry_deleg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) error = __vfs_removexattr_locked(dentry, name, &delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (delegated_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) error = break_deleg_wait(&delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) goto retry_deleg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) EXPORT_SYMBOL_GPL(vfs_removexattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * Extended attribute SET operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) setxattr(struct dentry *d, const char __user *name, const void __user *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) void *kvalue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) char kname[XATTR_NAME_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) error = strncpy_from_user(kname, name, sizeof(kname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (error == 0 || error == sizeof(kname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) error = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (size > XATTR_SIZE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) kvalue = kvmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (!kvalue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (copy_from_user(kvalue, value, size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) posix_acl_fix_xattr_from_user(kvalue, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) else if (strcmp(kname, XATTR_NAME_CAPS) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) error = cap_convert_nscap(d, &kvalue, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) size = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) error = vfs_setxattr(d, kname, kvalue, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) kvfree(kvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static int path_setxattr(const char __user *pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) const char __user *name, const void __user *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) size_t size, int flags, unsigned int lookup_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) error = mnt_want_write(path.mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) error = setxattr(path.dentry, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) mnt_drop_write(path.mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) path_put(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (retry_estale(error, lookup_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) lookup_flags |= LOOKUP_REVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) const char __user *, name, const void __user *, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) size_t, size, int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) const char __user *, name, const void __user *, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) size_t, size, int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return path_setxattr(pathname, name, value, size, flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) const void __user *,value, size_t, size, int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct fd f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) int error = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) audit_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) error = mnt_want_write_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) error = setxattr(f.file->f_path.dentry, name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) mnt_drop_write_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * Extended attribute GET operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) getxattr(struct dentry *d, const char __user *name, void __user *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ssize_t error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) void *kvalue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) char kname[XATTR_NAME_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) error = strncpy_from_user(kname, name, sizeof(kname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (error == 0 || error == sizeof(kname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) error = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (size > XATTR_SIZE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) size = XATTR_SIZE_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) kvalue = kvzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (!kvalue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) error = vfs_getxattr(d, kname, kvalue, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (error > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) posix_acl_fix_xattr_to_user(kvalue, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (size && copy_to_user(value, kvalue, error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* The file system tried to returned a value bigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) than XATTR_SIZE_MAX bytes. Not possible. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) error = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) kvfree(kvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static ssize_t path_getxattr(const char __user *pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) const char __user *name, void __user *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) size_t size, unsigned int lookup_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ssize_t error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) error = getxattr(path.dentry, name, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) path_put(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (retry_estale(error, lookup_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) lookup_flags |= LOOKUP_REVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) const char __user *, name, void __user *, value, size_t, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) const char __user *, name, void __user *, value, size_t, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return path_getxattr(pathname, name, value, size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) void __user *, value, size_t, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct fd f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ssize_t error = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) audit_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) error = getxattr(f.file->f_path.dentry, name, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * Extended attribute LIST operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) listxattr(struct dentry *d, char __user *list, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ssize_t error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) char *klist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (size > XATTR_LIST_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) size = XATTR_LIST_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) klist = kvmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (!klist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) error = vfs_listxattr(d, klist, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (error > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (size && copy_to_user(list, klist, error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) } else if (error == -ERANGE && size >= XATTR_LIST_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* The file system tried to returned a list bigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) than XATTR_LIST_MAX bytes. Not possible. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) error = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) kvfree(klist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static ssize_t path_listxattr(const char __user *pathname, char __user *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) size_t size, unsigned int lookup_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ssize_t error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) error = listxattr(path.dentry, list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) path_put(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (retry_estale(error, lookup_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) lookup_flags |= LOOKUP_REVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) size_t, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return path_listxattr(pathname, list, size, LOOKUP_FOLLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) size_t, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return path_listxattr(pathname, list, size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct fd f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ssize_t error = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) audit_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) error = listxattr(f.file->f_path.dentry, list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * Extended attribute REMOVE operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) removexattr(struct dentry *d, const char __user *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) char kname[XATTR_NAME_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) error = strncpy_from_user(kname, name, sizeof(kname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (error == 0 || error == sizeof(kname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) error = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return vfs_removexattr(d, kname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static int path_removexattr(const char __user *pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) const char __user *name, unsigned int lookup_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) error = mnt_want_write(path.mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) error = removexattr(path.dentry, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) mnt_drop_write(path.mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) path_put(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (retry_estale(error, lookup_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) lookup_flags |= LOOKUP_REVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) const char __user *, name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return path_removexattr(pathname, name, LOOKUP_FOLLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) const char __user *, name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return path_removexattr(pathname, name, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct fd f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) int error = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) audit_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) error = mnt_want_write_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) error = removexattr(f.file->f_path.dentry, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) mnt_drop_write_file(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * Combine the results of the list() operation from every xattr_handler in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) unsigned int size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) for_each_xattr_handler(handlers, handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (!handler->name ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) (handler->list && !handler->list(dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) size += strlen(handler->name) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) char *buf = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) for_each_xattr_handler(handlers, handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (!handler->name ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) (handler->list && !handler->list(dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) len = strlen(handler->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (len + 1 > buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) memcpy(buf, handler->name, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) buf += len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) buffer_size -= len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) size = buf - buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) EXPORT_SYMBOL(generic_listxattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * xattr_full_name - Compute full attribute name from suffix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * @handler: handler of the xattr_handler operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * @name: name passed to the xattr_handler operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * The get and set xattr handler operations are called with the remainder of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * the attribute name after skipping the handler's prefix: for example, "foo"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * is passed to the get operation of a handler with prefix "user." to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * attribute "user.foo". The full name is still "there" in the name though.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * Note: the list xattr handler operation when called from the vfs is passed a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * NULL name; some file systems use this operation internally, with varying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * semantics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) const char *xattr_full_name(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) size_t prefix_len = strlen(xattr_prefix(handler));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return name - prefix_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) EXPORT_SYMBOL(xattr_full_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * Allocate new xattr and copy in the value; but leave the name to callers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct simple_xattr *simple_xattr_alloc(const void *value, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct simple_xattr *new_xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* wrap around? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) len = sizeof(*new_xattr) + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (len < sizeof(*new_xattr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) new_xattr = kvmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!new_xattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) new_xattr->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) memcpy(new_xattr->value, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return new_xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * xattr GET operation for in-memory/pseudo filesystems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) void *buffer, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct simple_xattr *xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) spin_lock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) list_for_each_entry(xattr, &xattrs->head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (strcmp(name, xattr->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = xattr->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (size < xattr->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) memcpy(buffer, xattr->value, xattr->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) spin_unlock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * simple_xattr_set - xattr SET operation for in-memory/pseudo filesystems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * @xattrs: target simple_xattr list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * @name: name of the extended attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * @value: value of the xattr. If %NULL, will remove the attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * @size: size of the new xattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * @flags: %XATTR_{CREATE|REPLACE}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * @removed_size: returns size of the removed xattr, -1 if none removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * %XATTR_CREATE is set, the xattr shouldn't exist already; otherwise fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * with -EEXIST. If %XATTR_REPLACE is set, the xattr should exist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * otherwise, fails with -ENODATA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * Returns 0 on success, -errno on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) const void *value, size_t size, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ssize_t *removed_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct simple_xattr *xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct simple_xattr *new_xattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (removed_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) *removed_size = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* value == NULL means remove */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) new_xattr = simple_xattr_alloc(value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (!new_xattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) new_xattr->name = kstrdup(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (!new_xattr->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) kvfree(new_xattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) spin_lock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) list_for_each_entry(xattr, &xattrs->head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (!strcmp(name, xattr->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (flags & XATTR_CREATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) xattr = new_xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) err = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) } else if (new_xattr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) list_replace(&xattr->list, &new_xattr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (removed_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) *removed_size = xattr->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) list_del(&xattr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (removed_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) *removed_size = xattr->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (flags & XATTR_REPLACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) xattr = new_xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) err = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) list_add(&new_xattr->list, &xattrs->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) xattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) spin_unlock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (xattr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) kfree(xattr->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) kvfree(xattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static bool xattr_is_trusted(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static int xattr_list_one(char **buffer, ssize_t *remaining_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) size_t len = strlen(name) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (*buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (*remaining_size < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) memcpy(*buffer, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *buffer += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) *remaining_size -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * xattr LIST operation for in-memory/pseudo filesystems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) char *buffer, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) bool trusted = capable(CAP_SYS_ADMIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) struct simple_xattr *xattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) ssize_t remaining_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) #ifdef CONFIG_FS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (IS_POSIXACL(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (inode->i_acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) err = xattr_list_one(&buffer, &remaining_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) XATTR_NAME_POSIX_ACL_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (inode->i_default_acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) err = xattr_list_one(&buffer, &remaining_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) XATTR_NAME_POSIX_ACL_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) spin_lock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) list_for_each_entry(xattr, &xattrs->head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) /* skip "trusted." attributes for unprivileged callers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (!trusted && xattr_is_trusted(xattr->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) err = xattr_list_one(&buffer, &remaining_size, xattr->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) spin_unlock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return err ? err : size - remaining_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * Adds an extended attribute to the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) void simple_xattr_list_add(struct simple_xattrs *xattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct simple_xattr *new_xattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) spin_lock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) list_add(&new_xattr->list, &xattrs->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) spin_unlock(&xattrs->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }