From d860afaebd1e04839047d247fa5d1cfcdeaeefb6 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 26 Oct 2023 02:57:36 +0000 Subject: [PATCH] f2fs-tools: ensure that unused xattr space is zeroized Make fsck.f2fs zeroize the unused xattr space, i.e. the space after the end of the zero-terminated xattr list, if it isn't already zeroized. This is important because the kernel currently does not explicitly zero-terminate the list when writing xattrs. So, the kernel relies on the unused space containing zeroes. Also, add a missing free() to fix a memory leak. Signed-off-by: Eric Biggers Signed-off-by: Jaegeuk Kim --- fsck/fsck.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index 07fa1893..f1a55db2 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -834,6 +834,17 @@ void fsck_reada_all_direct_node_blocks(struct f2fs_sb_info *sbi, } } +static bool is_zeroed(const u8 *p, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) { + if (p[i]) + return false; + } + return true; +} + int chk_extended_attributes(struct f2fs_sb_info *sbi, u32 nid, struct f2fs_node *inode) { @@ -841,6 +852,7 @@ int chk_extended_attributes(struct f2fs_sb_info *sbi, u32 nid, void *last_base_addr; struct f2fs_xattr_entry *ent; __u32 xattr_size = XATTR_SIZE(&inode->i); + bool need_fix = false; if (xattr_size == 0) return 0; @@ -856,18 +868,24 @@ int chk_extended_attributes(struct f2fs_sb_info *sbi, u32 nid, ASSERT_MSG("[0x%x] last xattr entry (offset: %lx) " "crosses the boundary", nid, (long int)((void *)ent - xattr)); - if (c.fix_on) { - memset(ent, 0, - (char *)last_base_addr - (char *)ent); - write_all_xattrs(sbi, inode, xattr_size, xattr); - FIX_MSG("[0x%x] nullify wrong xattr entries", - nid); - return 1; - } + need_fix = true; break; } } - + if (!need_fix && + !is_zeroed((u8 *)ent, (u8 *)last_base_addr - (u8 *)ent)) { + ASSERT_MSG("[0x%x] nonzero bytes in xattr space after " + "end of list", nid); + need_fix = true; + } + if (need_fix && c.fix_on) { + memset(ent, 0, (u8 *)last_base_addr - (u8 *)ent); + write_all_xattrs(sbi, inode, xattr_size, xattr); + FIX_MSG("[0x%x] nullify wrong xattr entries", nid); + free(xattr); + return 1; + } + free(xattr); return 0; }