Commit af8e38c7 authored by Andrew Morton's avatar Andrew Morton Committed by Jens Axboe

[PATCH] xattr: listxattr fix

Patch from Andreas Gruenbacher <agruen@suse.de>

This patch fixes a bug in the ext2 and ext3 listxattr operation: Even if
an attribute is hidden from the user, the terminating NULL character was
included in the listxattr result. After the patch this doesn't happen
anymore.
parent 358bae5b
...@@ -421,26 +421,26 @@ static size_t ...@@ -421,26 +421,26 @@ static size_t
ext2_xattr_list_acl_access(char *list, struct inode *inode, ext2_xattr_list_acl_access(char *list, struct inode *inode,
const char *name, int name_len) const char *name, int name_len)
{ {
const size_t len = sizeof(XATTR_NAME_ACL_ACCESS)-1; const size_t size = sizeof(XATTR_NAME_ACL_ACCESS);
if (!test_opt(inode->i_sb, POSIX_ACL)) if (!test_opt(inode->i_sb, POSIX_ACL))
return 0; return 0;
if (list) if (list)
memcpy(list, XATTR_NAME_ACL_ACCESS, len); memcpy(list, XATTR_NAME_ACL_ACCESS, size);
return len; return size;
} }
static size_t static size_t
ext2_xattr_list_acl_default(char *list, struct inode *inode, ext2_xattr_list_acl_default(char *list, struct inode *inode,
const char *name, int name_len) const char *name, int name_len)
{ {
const size_t len = sizeof(XATTR_NAME_ACL_DEFAULT)-1; const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT);
if (!test_opt(inode->i_sb, POSIX_ACL)) if (!test_opt(inode->i_sb, POSIX_ACL))
return 0; return 0;
if (list) if (list)
memcpy(list, XATTR_NAME_ACL_DEFAULT, len); memcpy(list, XATTR_NAME_ACL_DEFAULT, size);
return len; return size;
} }
static int static int
......
...@@ -409,10 +409,9 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", ...@@ -409,10 +409,9 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
goto bad_block; goto bad_block;
handler = ext2_xattr_handler(entry->e_name_index); handler = ext2_xattr_handler(entry->e_name_index);
if (handler) { if (handler)
size += handler->list(NULL, inode, entry->e_name, size += handler->list(NULL, inode, entry->e_name,
entry->e_name_len) + 1; entry->e_name_len);
}
} }
if (ext2_xattr_cache_insert(bh)) if (ext2_xattr_cache_insert(bh))
...@@ -433,11 +432,9 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", ...@@ -433,11 +432,9 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
struct ext2_xattr_handler *handler; struct ext2_xattr_handler *handler;
handler = ext2_xattr_handler(entry->e_name_index); handler = ext2_xattr_handler(entry->e_name_index);
if (handler) { if (handler)
buf += handler->list(buf, inode, entry->e_name, buf += handler->list(buf, inode, entry->e_name,
entry->e_name_len); entry->e_name_len);
*buf++ = '\0';
}
} }
error = size; error = size;
......
...@@ -29,8 +29,9 @@ ext2_xattr_user_list(char *list, struct inode *inode, ...@@ -29,8 +29,9 @@ ext2_xattr_user_list(char *list, struct inode *inode,
if (list) { if (list) {
memcpy(list, XATTR_USER_PREFIX, prefix_len); memcpy(list, XATTR_USER_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len); memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
} }
return prefix_len + name_len; return prefix_len + name_len + 1;
} }
static int static int
......
...@@ -433,26 +433,26 @@ static size_t ...@@ -433,26 +433,26 @@ static size_t
ext3_xattr_list_acl_access(char *list, struct inode *inode, ext3_xattr_list_acl_access(char *list, struct inode *inode,
const char *name, int name_len) const char *name, int name_len)
{ {
const size_t len = sizeof(XATTR_NAME_ACL_ACCESS)-1; const size_t size = sizeof(XATTR_NAME_ACL_ACCESS);
if (!test_opt(inode->i_sb, POSIX_ACL)) if (!test_opt(inode->i_sb, POSIX_ACL))
return 0; return 0;
if (list) if (list)
memcpy(list, XATTR_NAME_ACL_ACCESS, len); memcpy(list, XATTR_NAME_ACL_ACCESS, size);
return len; return size;
} }
static size_t static size_t
ext3_xattr_list_acl_default(char *list, struct inode *inode, ext3_xattr_list_acl_default(char *list, struct inode *inode,
const char *name, int name_len) const char *name, int name_len)
{ {
const size_t len = sizeof(XATTR_NAME_ACL_DEFAULT)-1; const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT);
if (!test_opt(inode->i_sb, POSIX_ACL)) if (!test_opt(inode->i_sb, POSIX_ACL))
return 0; return 0;
if (list) if (list)
memcpy(list, XATTR_NAME_ACL_DEFAULT, len); memcpy(list, XATTR_NAME_ACL_DEFAULT, size);
return len; return size;
} }
static int static int
......
...@@ -402,10 +402,9 @@ bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", ...@@ -402,10 +402,9 @@ bad_block: ext3_error(inode->i_sb, "ext3_xattr_list",
goto bad_block; goto bad_block;
handler = ext3_xattr_handler(entry->e_name_index); handler = ext3_xattr_handler(entry->e_name_index);
if (handler) { if (handler)
size += handler->list(NULL, inode, entry->e_name, size += handler->list(NULL, inode, entry->e_name,
entry->e_name_len) + 1; entry->e_name_len);
}
} }
if (ext3_xattr_cache_insert(bh)) if (ext3_xattr_cache_insert(bh))
...@@ -426,11 +425,9 @@ bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", ...@@ -426,11 +425,9 @@ bad_block: ext3_error(inode->i_sb, "ext3_xattr_list",
struct ext3_xattr_handler *handler; struct ext3_xattr_handler *handler;
handler = ext3_xattr_handler(entry->e_name_index); handler = ext3_xattr_handler(entry->e_name_index);
if (handler) { if (handler)
buf += handler->list(buf, inode, entry->e_name, buf += handler->list(buf, inode, entry->e_name,
entry->e_name_len); entry->e_name_len);
*buf++ = '\0';
}
} }
error = size; error = size;
......
...@@ -31,8 +31,9 @@ ext3_xattr_user_list(char *list, struct inode *inode, ...@@ -31,8 +31,9 @@ ext3_xattr_user_list(char *list, struct inode *inode,
if (list) { if (list) {
memcpy(list, XATTR_USER_PREFIX, prefix_len); memcpy(list, XATTR_USER_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len); memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
} }
return prefix_len + name_len; return prefix_len + name_len + 1;
} }
static int static int
......
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