提交 786534b9 编写于 作者: A Andreas Gruenbacher 提交者: Al Viro

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: NAndreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: NJames Morris <james.l.morris@oracle.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 aa7c5241
...@@ -230,7 +230,7 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) ...@@ -230,7 +230,7 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
if (!attrs) if (!attrs)
return -ENOMEM; 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) static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
......
...@@ -921,38 +921,59 @@ static bool xattr_is_trusted(const char *name) ...@@ -921,38 +921,59 @@ static bool xattr_is_trusted(const char *name)
return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); 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 * xattr LIST operation for in-memory/pseudo filesystems
*/ */
ssize_t simple_xattr_list(struct simple_xattrs *xattrs, char *buffer, ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
size_t size) char *buffer, size_t size)
{ {
bool trusted = capable(CAP_SYS_ADMIN); bool trusted = capable(CAP_SYS_ADMIN);
struct simple_xattr *xattr; 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); spin_lock(&xattrs->lock);
list_for_each_entry(xattr, &xattrs->head, list) { list_for_each_entry(xattr, &xattrs->head, list) {
size_t len;
/* skip "trusted." attributes for unprivileged callers */ /* skip "trusted." attributes for unprivileged callers */
if (!trusted && xattr_is_trusted(xattr->name)) if (!trusted && xattr_is_trusted(xattr->name))
continue; continue;
len = strlen(xattr->name) + 1; err = xattr_list_one(&buffer, &remaining_size, xattr->name);
used += len; if (err)
if (buffer) { return err;
if (size < used) {
used = -ERANGE;
break;
}
memcpy(buffer, xattr->name, len);
buffer += len;
}
} }
spin_unlock(&xattrs->lock); spin_unlock(&xattrs->lock);
return used; return size - remaining_size;
} }
/* /*
......
...@@ -104,7 +104,8 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name, ...@@ -104,7 +104,8 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
void *buffer, size_t size); void *buffer, size_t size);
int simple_xattr_set(struct simple_xattrs *xattrs, const char *name, int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
const void *value, size_t size, int flags); 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, void simple_xattr_list_add(struct simple_xattrs *xattrs,
struct simple_xattr *new_xattr); struct simple_xattr *new_xattr);
......
...@@ -2606,7 +2606,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = { ...@@ -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) static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size)
{ {
struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); 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 */ #endif /* CONFIG_TMPFS_XATTR */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册