Commit 764a5c6b authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Al Viro

xattr handlers: Simplify list operation

Change the list operation to only return whether or not an attribute
should be listed.  Copying the attribute names into the buffer is moved
to the callers.

Since the result only depends on the dentry and not on the attribute
name, we do not pass the attribute name to list operations.
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 1046cb11
...@@ -292,16 +292,21 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", ...@@ -292,16 +292,21 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
const struct xattr_handler *handler = const struct xattr_handler *handler =
ext2_xattr_handler(entry->e_name_index); ext2_xattr_handler(entry->e_name_index);
if (handler) { if (handler && (!handler->list || handler->list(dentry))) {
size_t size = handler->list(handler, dentry, buffer, const char *prefix = handler->prefix ?: handler->name;
rest, entry->e_name, size_t prefix_len = strlen(prefix);
entry->e_name_len); size_t size = prefix_len + entry->e_name_len + 1;
if (buffer) { if (buffer) {
if (size > rest) { if (size > rest) {
error = -ERANGE; error = -ERANGE;
goto cleanup; goto cleanup;
} }
buffer += size; memcpy(buffer, prefix, prefix_len);
buffer += prefix_len;
memcpy(buffer, entry->e_name, entry->e_name_len);
buffer += entry->e_name_len;
*buffer++ = 0;
} }
rest -= size; rest -= size;
} }
......
...@@ -7,22 +7,6 @@ ...@@ -7,22 +7,6 @@
#include <linux/security.h> #include <linux/security.h>
#include "xattr.h" #include "xattr.h"
static size_t
ext2_xattr_security_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{
const int prefix_len = XATTR_SECURITY_PREFIX_LEN;
const size_t total_len = prefix_len + name_len + 1;
if (list && total_len <= list_size) {
memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
}
static int static int
ext2_xattr_security_get(const struct xattr_handler *handler, ext2_xattr_security_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
...@@ -67,7 +51,6 @@ ext2_init_security(struct inode *inode, struct inode *dir, ...@@ -67,7 +51,6 @@ ext2_init_security(struct inode *inode, struct inode *dir,
const struct xattr_handler ext2_xattr_security_handler = { const struct xattr_handler ext2_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ext2_xattr_security_list,
.get = ext2_xattr_security_get, .get = ext2_xattr_security_get,
.set = ext2_xattr_security_set, .set = ext2_xattr_security_set,
}; };
...@@ -8,23 +8,10 @@ ...@@ -8,23 +8,10 @@
#include "ext2.h" #include "ext2.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext2_xattr_trusted_list(const struct xattr_handler *handler, ext2_xattr_trusted_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; return capable(CAP_SYS_ADMIN);
const size_t total_len = prefix_len + name_len + 1;
if (!capable(CAP_SYS_ADMIN))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
......
...@@ -10,23 +10,10 @@ ...@@ -10,23 +10,10 @@
#include "ext2.h" #include "ext2.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext2_xattr_user_list(const struct xattr_handler *handler, ext2_xattr_user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t prefix_len = XATTR_USER_PREFIX_LEN; return test_opt(dentry->d_sb, XATTR_USER);
const size_t total_len = prefix_len + name_len + 1;
if (!test_opt(dentry->d_sb, XATTR_USER))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_USER_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
......
...@@ -404,19 +404,24 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, ...@@ -404,19 +404,24 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
const struct xattr_handler *handler = const struct xattr_handler *handler =
ext4_xattr_handler(entry->e_name_index); ext4_xattr_handler(entry->e_name_index);
if (handler) { if (handler && (!handler->list || handler->list(dentry))) {
size_t size = handler->list(handler, dentry, buffer, const char *prefix = handler->prefix ?: handler->name;
rest, entry->e_name, size_t prefix_len = strlen(prefix);
entry->e_name_len); size_t size = prefix_len + entry->e_name_len + 1;
if (buffer) { if (buffer) {
if (size > rest) if (size > rest)
return -ERANGE; return -ERANGE;
buffer += size; memcpy(buffer, prefix, prefix_len);
buffer += prefix_len;
memcpy(buffer, entry->e_name, entry->e_name_len);
buffer += entry->e_name_len;
*buffer++ = 0;
} }
rest -= size; rest -= size;
} }
} }
return buffer_size - rest; return buffer_size - rest; /* total size */
} }
static int static int
......
...@@ -11,23 +11,6 @@ ...@@ -11,23 +11,6 @@
#include "ext4.h" #include "ext4.h"
#include "xattr.h" #include "xattr.h"
static size_t
ext4_xattr_security_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{
const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1;
const size_t total_len = prefix_len + name_len + 1;
if (list && total_len <= list_size) {
memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
}
static int static int
ext4_xattr_security_get(const struct xattr_handler *handler, ext4_xattr_security_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
...@@ -75,7 +58,6 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, ...@@ -75,7 +58,6 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct xattr_handler ext4_xattr_security_handler = { const struct xattr_handler ext4_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ext4_xattr_security_list,
.get = ext4_xattr_security_get, .get = ext4_xattr_security_get,
.set = ext4_xattr_security_set, .set = ext4_xattr_security_set,
}; };
...@@ -12,23 +12,10 @@ ...@@ -12,23 +12,10 @@
#include "ext4.h" #include "ext4.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext4_xattr_trusted_list(const struct xattr_handler *handler, ext4_xattr_trusted_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; return capable(CAP_SYS_ADMIN);
const size_t total_len = prefix_len + name_len + 1;
if (!capable(CAP_SYS_ADMIN))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
......
...@@ -11,23 +11,10 @@ ...@@ -11,23 +11,10 @@
#include "ext4.h" #include "ext4.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext4_xattr_user_list(const struct xattr_handler *handler, ext4_xattr_user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t prefix_len = XATTR_USER_PREFIX_LEN; return test_opt(dentry->d_sb, XATTR_USER);
const size_t total_len = prefix_len + name_len + 1;
if (!test_opt(dentry->d_sb, XATTR_USER))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_USER_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
......
...@@ -25,40 +25,6 @@ ...@@ -25,40 +25,6 @@
#include "f2fs.h" #include "f2fs.h"
#include "xattr.h" #include "xattr.h"
static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t len)
{
struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
const char *prefix;
int total_len, prefix_len;
switch (handler->flags) {
case F2FS_XATTR_INDEX_USER:
if (!test_opt(sbi, XATTR_USER))
return -EOPNOTSUPP;
break;
case F2FS_XATTR_INDEX_TRUSTED:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
break;
case F2FS_XATTR_INDEX_SECURITY:
break;
default:
return -EINVAL;
}
prefix = xattr_prefix(handler);
prefix_len = strlen(prefix);
total_len = prefix_len + len + 1;
if (list && total_len <= list_size) {
memcpy(list, prefix, prefix_len);
memcpy(list + prefix_len, name, len);
list[prefix_len + len] = '\0';
}
return total_len;
}
static int f2fs_xattr_generic_get(const struct xattr_handler *handler, static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, void *buffer, struct dentry *dentry, const char *name, void *buffer,
size_t size) size_t size)
...@@ -107,17 +73,16 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler, ...@@ -107,17 +73,16 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
value, size, NULL, flags); value, size, NULL, flags);
} }
static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler, static bool f2fs_xattr_user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t len)
{ {
const char *xname = F2FS_SYSTEM_ADVISE_NAME; struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
size_t size;
size = strlen(xname) + 1; return test_opt(sbi, XATTR_USER);
if (list && size <= list_size) }
memcpy(list, xname, size);
return size; static bool f2fs_xattr_trusted_list(struct dentry *dentry)
{
return capable(CAP_SYS_ADMIN);
} }
static int f2fs_xattr_advise_get(const struct xattr_handler *handler, static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
...@@ -175,7 +140,7 @@ int f2fs_init_security(struct inode *inode, struct inode *dir, ...@@ -175,7 +140,7 @@ int f2fs_init_security(struct inode *inode, struct inode *dir,
const struct xattr_handler f2fs_xattr_user_handler = { const struct xattr_handler f2fs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX, .prefix = XATTR_USER_PREFIX,
.flags = F2FS_XATTR_INDEX_USER, .flags = F2FS_XATTR_INDEX_USER,
.list = f2fs_xattr_generic_list, .list = f2fs_xattr_user_list,
.get = f2fs_xattr_generic_get, .get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set, .set = f2fs_xattr_generic_set,
}; };
...@@ -183,7 +148,7 @@ const struct xattr_handler f2fs_xattr_user_handler = { ...@@ -183,7 +148,7 @@ const struct xattr_handler f2fs_xattr_user_handler = {
const struct xattr_handler f2fs_xattr_trusted_handler = { const struct xattr_handler f2fs_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX, .prefix = XATTR_TRUSTED_PREFIX,
.flags = F2FS_XATTR_INDEX_TRUSTED, .flags = F2FS_XATTR_INDEX_TRUSTED,
.list = f2fs_xattr_generic_list, .list = f2fs_xattr_trusted_list,
.get = f2fs_xattr_generic_get, .get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set, .set = f2fs_xattr_generic_set,
}; };
...@@ -191,7 +156,6 @@ const struct xattr_handler f2fs_xattr_trusted_handler = { ...@@ -191,7 +156,6 @@ const struct xattr_handler f2fs_xattr_trusted_handler = {
const struct xattr_handler f2fs_xattr_advise_handler = { const struct xattr_handler f2fs_xattr_advise_handler = {
.name = F2FS_SYSTEM_ADVISE_NAME, .name = F2FS_SYSTEM_ADVISE_NAME,
.flags = F2FS_XATTR_INDEX_ADVISE, .flags = F2FS_XATTR_INDEX_ADVISE,
.list = f2fs_xattr_advise_list,
.get = f2fs_xattr_advise_get, .get = f2fs_xattr_advise_get,
.set = f2fs_xattr_advise_set, .set = f2fs_xattr_advise_set,
}; };
...@@ -199,7 +163,6 @@ const struct xattr_handler f2fs_xattr_advise_handler = { ...@@ -199,7 +163,6 @@ const struct xattr_handler f2fs_xattr_advise_handler = {
const struct xattr_handler f2fs_xattr_security_handler = { const struct xattr_handler f2fs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.flags = F2FS_XATTR_INDEX_SECURITY, .flags = F2FS_XATTR_INDEX_SECURITY,
.list = f2fs_xattr_generic_list,
.get = f2fs_xattr_generic_get, .get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set, .set = f2fs_xattr_generic_set,
}; };
...@@ -447,20 +410,27 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -447,20 +410,27 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
list_for_each_xattr(entry, base_addr) { list_for_each_xattr(entry, base_addr) {
const struct xattr_handler *handler = const struct xattr_handler *handler =
f2fs_xattr_handler(entry->e_name_index); f2fs_xattr_handler(entry->e_name_index);
const char *prefix;
size_t prefix_len;
size_t size; size_t size;
if (!handler) if (!handler || (handler->list && !handler->list(dentry)))
continue; continue;
size = handler->list(handler, dentry, buffer, rest, prefix = handler->prefix ?: handler->name;
entry->e_name, entry->e_name_len); prefix_len = strlen(prefix);
if (buffer && size > rest) { size = prefix_len + entry->e_name_len + 1;
if (buffer) {
if (size > rest) {
error = -ERANGE; error = -ERANGE;
goto cleanup; goto cleanup;
} }
memcpy(buffer, prefix, prefix_len);
if (buffer) buffer += prefix_len;
buffer += size; memcpy(buffer, entry->e_name, entry->e_name_len);
buffer += entry->e_name_len;
*buffer++ = 0;
}
rest -= size; rest -= size;
} }
error = buffer_size - rest; error = buffer_size - rest;
......
...@@ -64,24 +64,8 @@ static int jffs2_security_setxattr(const struct xattr_handler *handler, ...@@ -64,24 +64,8 @@ static int jffs2_security_setxattr(const struct xattr_handler *handler,
name, buffer, size, flags); name, buffer, size, flags);
} }
static size_t jffs2_security_listxattr(const struct xattr_handler *handler,
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{
size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1;
if (list && retlen <= list_size) {
strcpy(list, XATTR_SECURITY_PREFIX);
strcpy(list + XATTR_SECURITY_PREFIX_LEN, name);
}
return retlen;
}
const struct xattr_handler jffs2_security_xattr_handler = { const struct xattr_handler jffs2_security_xattr_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = jffs2_security_listxattr,
.set = jffs2_security_setxattr, .set = jffs2_security_setxattr,
.get = jffs2_security_getxattr .get = jffs2_security_getxattr
}; };
...@@ -967,7 +967,8 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -967,7 +967,8 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct jffs2_xattr_ref *ref, **pref; struct jffs2_xattr_ref *ref, **pref;
struct jffs2_xattr_datum *xd; struct jffs2_xattr_datum *xd;
const struct xattr_handler *xhandle; const struct xattr_handler *xhandle;
ssize_t len, rc; const char *prefix;
ssize_t prefix_len, len, rc;
int retry = 0; int retry = 0;
rc = check_xattr_ref_inode(c, ic); rc = check_xattr_ref_inode(c, ic);
...@@ -998,18 +999,23 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -998,18 +999,23 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
} }
} }
xhandle = xprefix_to_handler(xd->xprefix); xhandle = xprefix_to_handler(xd->xprefix);
if (!xhandle) if (!xhandle || (xhandle->list && !xhandle->list(dentry)))
continue; continue;
prefix = xhandle->prefix ?: xhandle->name;
prefix_len = strlen(prefix);
rc = prefix_len + xd->name_len + 1;
if (buffer) { if (buffer) {
rc = xhandle->list(xhandle, dentry, buffer + len, if (rc > size - len) {
size - len, xd->xname, rc = -ERANGE;
xd->name_len);
} else {
rc = xhandle->list(xhandle, dentry, NULL, 0,
xd->xname, xd->name_len);
}
if (rc < 0)
goto out; goto out;
}
memcpy(buffer, prefix, prefix_len);
buffer += prefix_len;
memcpy(buffer, xd->xname, xd->name_len);
buffer += xd->name_len;
*buffer++ = 0;
}
len += rc; len += rc;
} }
rc = len; rc = len;
......
...@@ -32,22 +32,9 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler, ...@@ -32,22 +32,9 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
name, buffer, size, flags); name, buffer, size, flags);
} }
static size_t jffs2_trusted_listxattr(const struct xattr_handler *handler, static bool jffs2_trusted_listxattr(struct dentry *dentry)
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{ {
size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1; return capable(CAP_SYS_ADMIN);
if (!capable(CAP_SYS_ADMIN))
return 0;
if (list && retlen<=list_size) {
strcpy(list, XATTR_TRUSTED_PREFIX);
strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name);
}
return retlen;
} }
const struct xattr_handler jffs2_trusted_xattr_handler = { const struct xattr_handler jffs2_trusted_xattr_handler = {
......
...@@ -32,24 +32,8 @@ static int jffs2_user_setxattr(const struct xattr_handler *handler, ...@@ -32,24 +32,8 @@ static int jffs2_user_setxattr(const struct xattr_handler *handler,
name, buffer, size, flags); name, buffer, size, flags);
} }
static size_t jffs2_user_listxattr(const struct xattr_handler *handler,
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{
size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1;
if (list && retlen <= list_size) {
strcpy(list, XATTR_USER_PREFIX);
strcpy(list + XATTR_USER_PREFIX_LEN, name);
}
return retlen;
}
const struct xattr_handler jffs2_user_xattr_handler = { const struct xattr_handler jffs2_user_xattr_handler = {
.prefix = XATTR_USER_PREFIX, .prefix = XATTR_USER_PREFIX,
.list = jffs2_user_listxattr,
.set = jffs2_user_setxattr, .set = jffs2_user_setxattr,
.get = jffs2_user_getxattr .get = jffs2_user_getxattr
}; };
...@@ -6263,19 +6263,9 @@ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler, ...@@ -6263,19 +6263,9 @@ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); return nfs4_proc_get_acl(d_inode(dentry), buf, buflen);
} }
static size_t nfs4_xattr_list_nfs4_acl(const struct xattr_handler *handler, static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
struct dentry *dentry, char *list,
size_t list_len, const char *name,
size_t name_len)
{ {
size_t len = sizeof(XATTR_NAME_NFSV4_ACL); return nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)));
if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry))))
return 0;
if (list && len <= list_len)
memcpy(list, XATTR_NAME_NFSV4_ACL, len);
return len;
} }
#ifdef CONFIG_NFS_V4_SECURITY_LABEL #ifdef CONFIG_NFS_V4_SECURITY_LABEL
......
...@@ -823,21 +823,10 @@ posix_acl_xattr_set(const struct xattr_handler *handler, ...@@ -823,21 +823,10 @@ posix_acl_xattr_set(const struct xattr_handler *handler,
return ret; return ret;
} }
static size_t static bool
posix_acl_xattr_list(const struct xattr_handler *handler, posix_acl_xattr_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const char *xname = handler->name; return IS_POSIXACL(d_backing_inode(dentry));
size_t size;
if (!IS_POSIXACL(d_backing_inode(dentry)))
return 0;
size = strlen(xname) + 1;
if (list && size <= list_size)
memcpy(list, xname, size);
return size;
} }
const struct xattr_handler posix_acl_access_xattr_handler = { const struct xattr_handler posix_acl_access_xattr_handler = {
......
...@@ -840,19 +840,16 @@ static int listxattr_filler(struct dir_context *ctx, const char *name, ...@@ -840,19 +840,16 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr,
name); name);
if (!handler) /* Unsupported xattr name */ if (!handler /* Unsupported xattr name */ ||
(handler->list && !handler->list(b->dentry)))
return 0; return 0;
size = namelen + 1;
if (b->buf) { if (b->buf) {
size = handler->list(handler, b->dentry,
b->buf + b->pos, b->size, name,
namelen);
if (size > b->size) if (size > b->size)
return -ERANGE; return -ERANGE;
} else { memcpy(b->buf + b->pos, name, namelen);
size = handler->list(handler, b->dentry, b->buf[b->pos + namelen] = 0;
NULL, 0, name, namelen);
} }
b->pos += size; b->pos += size;
} }
return 0; return 0;
......
...@@ -34,21 +34,9 @@ security_set(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -34,21 +34,9 @@ security_set(const struct xattr_handler *handler, struct dentry *dentry,
return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
} }
static size_t security_list(const struct xattr_handler *handler, static bool security_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_len,
const char *name, size_t namelen)
{ {
const size_t len = namelen + 1; return !IS_PRIVATE(d_inode(dentry));
if (IS_PRIVATE(d_inode(dentry)))
return 0;
if (list && len <= list_len) {
memcpy(list, name, namelen);
list[namelen] = '\0';
}
return len;
} }
/* Initializes the security context for a new inode and returns the number /* Initializes the security context for a new inode and returns the number
......
...@@ -33,20 +33,9 @@ trusted_set(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -33,20 +33,9 @@ trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
} }
static size_t trusted_list(const struct xattr_handler *handler, static bool trusted_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t len = name_len + 1; return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry));
if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
return 0;
if (list && len <= list_size) {
memcpy(list, name, name_len);
list[name_len] = '\0';
}
return len;
} }
const struct xattr_handler reiserfs_xattr_trusted_handler = { const struct xattr_handler reiserfs_xattr_trusted_handler = {
......
...@@ -30,19 +30,9 @@ user_set(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -30,19 +30,9 @@ user_set(const struct xattr_handler *handler, struct dentry *dentry,
return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
} }
static size_t user_list(const struct xattr_handler *handler, static bool user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t len = name_len + 1; return reiserfs_xattrs_user(dentry->d_sb);
if (!reiserfs_xattrs_user(dentry->d_sb))
return 0;
if (list && len <= list_size) {
memcpy(list, name, name_len);
list[name_len] = '\0';
}
return len;
} }
const struct xattr_handler reiserfs_xattr_user_handler = { const struct xattr_handler reiserfs_xattr_user_handler = {
......
...@@ -58,7 +58,7 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer, ...@@ -58,7 +58,7 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
struct squashfs_xattr_entry entry; struct squashfs_xattr_entry entry;
struct squashfs_xattr_val val; struct squashfs_xattr_val val;
const struct xattr_handler *handler; const struct xattr_handler *handler;
int name_size, prefix_size = 0; int name_size;
err = squashfs_read_metadata(sb, &entry, &start, &offset, err = squashfs_read_metadata(sb, &entry, &start, &offset,
sizeof(entry)); sizeof(entry));
...@@ -67,15 +67,16 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer, ...@@ -67,15 +67,16 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
name_size = le16_to_cpu(entry.size); name_size = le16_to_cpu(entry.size);
handler = squashfs_xattr_handler(le16_to_cpu(entry.type)); handler = squashfs_xattr_handler(le16_to_cpu(entry.type));
if (handler) if (handler && (!handler->list || handler->list(d))) {
prefix_size = handler->list(handler, d, buffer, rest, const char *prefix = handler->prefix ?: handler->name;
NULL, name_size); size_t prefix_size = strlen(prefix);
if (prefix_size) {
if (buffer) { if (buffer) {
if (prefix_size + name_size + 1 > rest) { if (prefix_size + name_size + 1 > rest) {
err = -ERANGE; err = -ERANGE;
goto failed; goto failed;
} }
memcpy(buffer, prefix, prefix_size);
buffer += prefix_size; buffer += prefix_size;
} }
err = squashfs_read_metadata(sb, buffer, &start, err = squashfs_read_metadata(sb, buffer, &start,
...@@ -212,18 +213,6 @@ static int squashfs_xattr_get(struct inode *inode, int name_index, ...@@ -212,18 +213,6 @@ static int squashfs_xattr_get(struct inode *inode, int name_index,
} }
static size_t squashfs_xattr_handler_list(const struct xattr_handler *handler,
struct dentry *d, char *list,
size_t list_size, const char *name,
size_t name_len)
{
int len = strlen(handler->prefix);
if (list && len <= list_size)
memcpy(list, handler->prefix, len);
return len;
}
static int squashfs_xattr_handler_get(const struct xattr_handler *handler, static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
struct dentry *d, const char *name, struct dentry *d, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
...@@ -238,22 +227,15 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler, ...@@ -238,22 +227,15 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
static const struct xattr_handler squashfs_xattr_user_handler = { static const struct xattr_handler squashfs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX, .prefix = XATTR_USER_PREFIX,
.flags = SQUASHFS_XATTR_USER, .flags = SQUASHFS_XATTR_USER,
.list = squashfs_xattr_handler_list,
.get = squashfs_xattr_handler_get .get = squashfs_xattr_handler_get
}; };
/* /*
* Trusted namespace support * Trusted namespace support
*/ */
static size_t squashfs_trusted_xattr_handler_list(const struct xattr_handler *handler, static bool squashfs_trusted_xattr_handler_list(struct dentry *d)
struct dentry *d, char *list,
size_t list_size, const char *name,
size_t name_len)
{ {
if (!capable(CAP_SYS_ADMIN)) return capable(CAP_SYS_ADMIN);
return 0;
return squashfs_xattr_handler_list(handler, d, list, list_size, name,
name_len);
} }
static const struct xattr_handler squashfs_xattr_trusted_handler = { static const struct xattr_handler squashfs_xattr_trusted_handler = {
...@@ -269,7 +251,6 @@ static const struct xattr_handler squashfs_xattr_trusted_handler = { ...@@ -269,7 +251,6 @@ static const struct xattr_handler squashfs_xattr_trusted_handler = {
static const struct xattr_handler squashfs_xattr_security_handler = { static const struct xattr_handler squashfs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.flags = SQUASHFS_XATTR_SECURITY, .flags = SQUASHFS_XATTR_SECURITY,
.list = squashfs_xattr_handler_list,
.get = squashfs_xattr_handler_get .get = squashfs_xattr_handler_get
}; };
......
...@@ -723,23 +723,25 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -723,23 +723,25 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
if (!buffer) { if (!buffer) {
for_each_xattr_handler(handlers, handler) { for_each_xattr_handler(handlers, handler) {
if (!handler->list) if (!handler->name ||
(handler->list && !handler->list(dentry)))
continue; continue;
size += handler->list(handler, dentry, NULL, 0, size += strlen(handler->name) + 1;
NULL, 0);
} }
} else { } else {
char *buf = buffer; char *buf = buffer;
size_t len;
for_each_xattr_handler(handlers, handler) { for_each_xattr_handler(handlers, handler) {
if (!handler->list) if (!handler->name ||
(handler->list && !handler->list(dentry)))
continue; continue;
size = handler->list(handler, dentry, buf, buffer_size, len = strlen(handler->name);
NULL, 0); if (len + 1 > buffer_size)
if (size > buffer_size)
return -ERANGE; return -ERANGE;
buf += size; memcpy(buf, handler->name, len + 1);
buffer_size -= size; buf += len + 1;
buffer_size -= len + 1;
} }
size = buf - buffer; size = buf - buffer;
} }
......
...@@ -28,9 +28,7 @@ struct xattr_handler { ...@@ -28,9 +28,7 @@ struct xattr_handler {
const char *name; const char *name;
const char *prefix; const char *prefix;
int flags; /* fs private flags */ int flags; /* fs private flags */
size_t (*list)(const struct xattr_handler *, struct dentry *dentry, bool (*list)(struct dentry *dentry);
char *list, size_t list_size, const char *name,
size_t name_len);
int (*get)(const struct xattr_handler *, struct dentry *dentry, int (*get)(const struct xattr_handler *, struct dentry *dentry,
const char *name, void *buffer, size_t size); const char *name, void *buffer, size_t size);
int (*set)(const struct xattr_handler *, struct dentry *dentry, int (*set)(const struct xattr_handler *, struct dentry *dentry,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment