Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 786534b9 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Al Viro
Browse files

tmpfs: listxattr should include POSIX ACL xattrs



When a file on tmpfs has an ACL or a Default ACL, listxattr should include the
corresponding xattr name.

Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: default avatarJames Morris <james.l.morris@oracle.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent aa7c5241
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
	if (!attrs)
		return -ENOMEM;

	return simple_xattr_list(&attrs->xattrs, buf, size);
	return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size);
}

static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
+37 −16
Original line number Diff line number Diff line
@@ -921,38 +921,59 @@ static bool xattr_is_trusted(const char *name)
	return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
}

static int xattr_list_one(char **buffer, ssize_t *remaining_size,
			  const char *name)
{
	size_t len = strlen(name) + 1;
	if (*buffer) {
		if (*remaining_size < len)
			return -ERANGE;
		memcpy(*buffer, name, len);
		*buffer += len;
	}
	*remaining_size -= len;
	return 0;
}

/*
 * xattr LIST operation for in-memory/pseudo filesystems
 */
ssize_t simple_xattr_list(struct simple_xattrs *xattrs, char *buffer,
			  size_t size)
ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
			  char *buffer, size_t size)
{
	bool trusted = capable(CAP_SYS_ADMIN);
	struct simple_xattr *xattr;
	size_t used = 0;
	ssize_t remaining_size = size;
	int err;

#ifdef CONFIG_FS_POSIX_ACL
	if (inode->i_acl) {
		err = xattr_list_one(&buffer, &remaining_size,
				     XATTR_NAME_POSIX_ACL_ACCESS);
		if (err)
			return err;
	}
	if (inode->i_default_acl) {
		err = xattr_list_one(&buffer, &remaining_size,
				     XATTR_NAME_POSIX_ACL_DEFAULT);
		if (err)
			return err;
	}
#endif

	spin_lock(&xattrs->lock);
	list_for_each_entry(xattr, &xattrs->head, list) {
		size_t len;

		/* skip "trusted." attributes for unprivileged callers */
		if (!trusted && xattr_is_trusted(xattr->name))
			continue;

		len = strlen(xattr->name) + 1;
		used += len;
		if (buffer) {
			if (size < used) {
				used = -ERANGE;
				break;
			}
			memcpy(buffer, xattr->name, len);
			buffer += len;
		}
		err = xattr_list_one(&buffer, &remaining_size, xattr->name);
		if (err)
			return err;
	}
	spin_unlock(&xattrs->lock);

	return used;
	return size - remaining_size;
}

/*
+2 −1
Original line number Diff line number Diff line
@@ -104,7 +104,8 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
		     void *buffer, size_t size);
int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
		     const void *value, size_t size, int flags);
ssize_t simple_xattr_list(struct simple_xattrs *xattrs, char *buffer, size_t size);
ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, char *buffer,
			  size_t size);
void simple_xattr_list_add(struct simple_xattrs *xattrs,
			   struct simple_xattr *new_xattr);

+1 −1
Original line number Diff line number Diff line
@@ -2606,7 +2606,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
	struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
	return simple_xattr_list(&info->xattrs, buffer, size);
	return simple_xattr_list(d_inode(dentry), &info->xattrs, buffer, size);
}
#endif /* CONFIG_TMPFS_XATTR */