Patch from Andreas Gruenbacher 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. fs/ext2/acl.c | 12 ++++++------ fs/ext2/xattr.c | 9 +++------ fs/ext2/xattr_user.c | 3 ++- fs/ext3/acl.c | 12 ++++++------ fs/ext3/xattr.c | 9 +++------ fs/ext3/xattr_user.c | 3 ++- 6 files changed, 22 insertions(+), 26 deletions(-) diff -puN fs/ext2/acl.c~ext2_ext3_listxattr-bug fs/ext2/acl.c --- 25/fs/ext2/acl.c~ext2_ext3_listxattr-bug Tue Feb 11 12:17:41 2003 +++ 25-akpm/fs/ext2/acl.c Tue Feb 11 12:17:41 2003 @@ -421,26 +421,26 @@ static size_t ext2_xattr_list_acl_access(char *list, struct inode *inode, 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)) return 0; if (list) - memcpy(list, XATTR_NAME_ACL_ACCESS, len); - return len; + memcpy(list, XATTR_NAME_ACL_ACCESS, size); + return size; } static size_t ext2_xattr_list_acl_default(char *list, struct inode *inode, 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)) return 0; if (list) - memcpy(list, XATTR_NAME_ACL_DEFAULT, len); - return len; + memcpy(list, XATTR_NAME_ACL_DEFAULT, size); + return size; } static int diff -puN fs/ext2/xattr.c~ext2_ext3_listxattr-bug fs/ext2/xattr.c --- 25/fs/ext2/xattr.c~ext2_ext3_listxattr-bug Tue Feb 11 12:17:41 2003 +++ 25-akpm/fs/ext2/xattr.c Tue Feb 11 12:17:41 2003 @@ -409,10 +409,9 @@ bad_block: ext2_error(inode->i_sb, "ext2 goto bad_block; handler = ext2_xattr_handler(entry->e_name_index); - if (handler) { + if (handler) size += handler->list(NULL, inode, entry->e_name, - entry->e_name_len) + 1; - } + entry->e_name_len); } if (ext2_xattr_cache_insert(bh)) @@ -433,11 +432,9 @@ bad_block: ext2_error(inode->i_sb, "ext2 struct ext2_xattr_handler *handler; handler = ext2_xattr_handler(entry->e_name_index); - if (handler) { + if (handler) buf += handler->list(buf, inode, entry->e_name, entry->e_name_len); - *buf++ = '\0'; - } } error = size; diff -puN fs/ext2/xattr_user.c~ext2_ext3_listxattr-bug fs/ext2/xattr_user.c --- 25/fs/ext2/xattr_user.c~ext2_ext3_listxattr-bug Tue Feb 11 12:17:41 2003 +++ 25-akpm/fs/ext2/xattr_user.c Tue Feb 11 12:17:41 2003 @@ -29,8 +29,9 @@ ext2_xattr_user_list(char *list, struct if (list) { memcpy(list, XATTR_USER_PREFIX, prefix_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 diff -puN fs/ext3/acl.c~ext2_ext3_listxattr-bug fs/ext3/acl.c --- 25/fs/ext3/acl.c~ext2_ext3_listxattr-bug Tue Feb 11 12:17:41 2003 +++ 25-akpm/fs/ext3/acl.c Tue Feb 11 12:17:41 2003 @@ -433,26 +433,26 @@ static size_t ext3_xattr_list_acl_access(char *list, struct inode *inode, 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)) return 0; if (list) - memcpy(list, XATTR_NAME_ACL_ACCESS, len); - return len; + memcpy(list, XATTR_NAME_ACL_ACCESS, size); + return size; } static size_t ext3_xattr_list_acl_default(char *list, struct inode *inode, 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)) return 0; if (list) - memcpy(list, XATTR_NAME_ACL_DEFAULT, len); - return len; + memcpy(list, XATTR_NAME_ACL_DEFAULT, size); + return size; } static int diff -puN fs/ext3/xattr.c~ext2_ext3_listxattr-bug fs/ext3/xattr.c --- 25/fs/ext3/xattr.c~ext2_ext3_listxattr-bug Tue Feb 11 12:17:41 2003 +++ 25-akpm/fs/ext3/xattr.c Tue Feb 11 12:17:41 2003 @@ -402,10 +402,9 @@ bad_block: ext3_error(inode->i_sb, "ext3 goto bad_block; handler = ext3_xattr_handler(entry->e_name_index); - if (handler) { + if (handler) size += handler->list(NULL, inode, entry->e_name, - entry->e_name_len) + 1; - } + entry->e_name_len); } if (ext3_xattr_cache_insert(bh)) @@ -426,11 +425,9 @@ bad_block: ext3_error(inode->i_sb, "ext3 struct ext3_xattr_handler *handler; handler = ext3_xattr_handler(entry->e_name_index); - if (handler) { + if (handler) buf += handler->list(buf, inode, entry->e_name, entry->e_name_len); - *buf++ = '\0'; - } } error = size; diff -puN fs/ext3/xattr_user.c~ext2_ext3_listxattr-bug fs/ext3/xattr_user.c --- 25/fs/ext3/xattr_user.c~ext2_ext3_listxattr-bug Tue Feb 11 12:17:41 2003 +++ 25-akpm/fs/ext3/xattr_user.c Tue Feb 11 12:17:41 2003 @@ -31,8 +31,9 @@ ext3_xattr_user_list(char *list, struct if (list) { memcpy(list, XATTR_USER_PREFIX, prefix_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 _