From 98e9cb5711c68223f0e4d5201b9a6add255ec550 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 2 Dec 2015 14:44:36 +0100 Subject: vfs: Distinguish between full xattr names and proper prefixes Add an additional "name" field to struct xattr_handler. When the name is set, the handler matches attributes with exactly that name. When the prefix is set instead, the handler matches attributes with the given prefix and with a non-empty suffix. This patch should avoid bugs like the one fixed in commit c361016a in the future. Signed-off-by: Andreas Gruenbacher Reviewed-by: James Morris Signed-off-by: Al Viro --- fs/squashfs/xattr.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'fs/squashfs') diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c index 6a4cc344085c..2f0ccbaa2d92 100644 --- a/fs/squashfs/xattr.c +++ b/fs/squashfs/xattr.c @@ -228,9 +228,6 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler, struct dentry *d, const char *name, void *buffer, size_t size) { - if (name[0] == '\0') - return -EINVAL; - return squashfs_xattr_get(d_inode(d), handler->flags, name, buffer, size); } -- cgit v1.2.3 From 764a5c6b1fa4306dd7573c1d80914254909cd036 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 2 Dec 2015 14:44:43 +0100 Subject: 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: Andreas Gruenbacher Signed-off-by: Al Viro --- fs/squashfs/xattr.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) (limited to 'fs/squashfs') diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c index 2f0ccbaa2d92..1e9de96288d8 100644 --- a/fs/squashfs/xattr.c +++ b/fs/squashfs/xattr.c @@ -58,7 +58,7 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer, struct squashfs_xattr_entry entry; struct squashfs_xattr_val val; const struct xattr_handler *handler; - int name_size, prefix_size = 0; + int name_size; err = squashfs_read_metadata(sb, &entry, &start, &offset, sizeof(entry)); @@ -67,15 +67,16 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer, name_size = le16_to_cpu(entry.size); handler = squashfs_xattr_handler(le16_to_cpu(entry.type)); - if (handler) - prefix_size = handler->list(handler, d, buffer, rest, - NULL, name_size); - if (prefix_size) { + if (handler && (!handler->list || handler->list(d))) { + const char *prefix = handler->prefix ?: handler->name; + size_t prefix_size = strlen(prefix); + if (buffer) { if (prefix_size + name_size + 1 > rest) { err = -ERANGE; goto failed; } + memcpy(buffer, prefix, prefix_size); buffer += prefix_size; } err = squashfs_read_metadata(sb, buffer, &start, @@ -212,18 +213,6 @@ failed: } -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, struct dentry *d, const char *name, void *buffer, size_t size) @@ -238,22 +227,15 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler, static const struct xattr_handler squashfs_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .flags = SQUASHFS_XATTR_USER, - .list = squashfs_xattr_handler_list, .get = squashfs_xattr_handler_get }; /* * Trusted namespace support */ -static size_t squashfs_trusted_xattr_handler_list(const struct xattr_handler *handler, - struct dentry *d, char *list, - size_t list_size, const char *name, - size_t name_len) +static bool squashfs_trusted_xattr_handler_list(struct dentry *d) { - if (!capable(CAP_SYS_ADMIN)) - return 0; - return squashfs_xattr_handler_list(handler, d, list, list_size, name, - name_len); + return capable(CAP_SYS_ADMIN); } 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 = { .prefix = XATTR_SECURITY_PREFIX, .flags = SQUASHFS_XATTR_SECURITY, - .list = squashfs_xattr_handler_list, .get = squashfs_xattr_handler_get }; -- cgit v1.2.3