^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008 Christoph Hellwig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Portions Copyright (C) 2000-2008 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_da_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_attr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_acl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_da_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/posix_acl_xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct inode *inode, const char *name, void *value, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct xfs_da_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .dp = XFS_I(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .attr_filter = handler->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .name = name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .namelen = strlen(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .value = value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .valuelen = size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) error = xfs_attr_get(&args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return args.valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct inode *inode, const char *name, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct xfs_da_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .dp = XFS_I(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .attr_filter = handler->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .attr_flags = flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .name = name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .namelen = strlen(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .value = (void *)value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .valuelen = size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) error = xfs_attr_set(&args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (!error && (handler->flags & XFS_ATTR_ROOT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) xfs_forget_acl(inode, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static const struct xattr_handler xfs_xattr_user_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .prefix = XATTR_USER_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .flags = 0, /* no flags implies user namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .get = xfs_xattr_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .set = xfs_xattr_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static const struct xattr_handler xfs_xattr_trusted_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .prefix = XATTR_TRUSTED_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .flags = XFS_ATTR_ROOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .get = xfs_xattr_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .set = xfs_xattr_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static const struct xattr_handler xfs_xattr_security_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .prefix = XATTR_SECURITY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .flags = XFS_ATTR_SECURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .get = xfs_xattr_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .set = xfs_xattr_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const struct xattr_handler *xfs_xattr_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) &xfs_xattr_user_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) &xfs_xattr_trusted_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) &xfs_xattr_security_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #ifdef CONFIG_XFS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) &posix_acl_access_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) &posix_acl_default_xattr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) __xfs_xattr_put_listent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct xfs_attr_list_context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) char *prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int prefix_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int namelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) char *offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int arraytop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (context->count < 0 || context->seen_enough)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!context->buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto compute_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) arraytop = context->count + prefix_len + namelen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (arraytop > context->firstu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) context->count = -1; /* insufficient space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) context->seen_enough = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) offset = context->buffer + context->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) strncpy(offset, prefix, prefix_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) offset += prefix_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) strncpy(offset, (char *)name, namelen); /* real name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) offset += namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *offset = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) compute_size:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) context->count += prefix_len + namelen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) xfs_xattr_put_listent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct xfs_attr_list_context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int valuelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) char *prefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int prefix_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ASSERT(context->count >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (flags & XFS_ATTR_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #ifdef CONFIG_XFS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (namelen == SGI_ACL_FILE_SIZE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) strncmp(name, SGI_ACL_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) SGI_ACL_FILE_SIZE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) __xfs_xattr_put_listent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) context, XATTR_SYSTEM_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) XATTR_SYSTEM_PREFIX_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) XATTR_POSIX_ACL_ACCESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) strlen(XATTR_POSIX_ACL_ACCESS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } else if (namelen == SGI_ACL_DEFAULT_SIZE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) strncmp(name, SGI_ACL_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) SGI_ACL_DEFAULT_SIZE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) __xfs_xattr_put_listent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) context, XATTR_SYSTEM_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) XATTR_SYSTEM_PREFIX_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) XATTR_POSIX_ACL_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) strlen(XATTR_POSIX_ACL_DEFAULT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * Only show root namespace entries if we are actually allowed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * see them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) prefix = XATTR_TRUSTED_PREFIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) prefix_len = XATTR_TRUSTED_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } else if (flags & XFS_ATTR_SECURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) prefix = XATTR_SECURITY_PREFIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) prefix_len = XATTR_SECURITY_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) prefix = XATTR_USER_PREFIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) prefix_len = XATTR_USER_PREFIX_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) __xfs_xattr_put_listent(context, prefix, prefix_len, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) xfs_vn_listxattr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) char *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct xfs_attr_list_context context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * First read the regular on-disk attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) memset(&context, 0, sizeof(context));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) context.dp = XFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) context.resynch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) context.buffer = size ? data : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) context.bufsize = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) context.firstu = context.bufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) context.put_listent = xfs_xattr_put_listent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) error = xfs_attr_list(&context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (context.count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return context.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }