diff options
author | Eric Biggers <ebiggers@google.com> | 2023-10-26 02:57:36 +0000 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2023-10-25 20:06:26 -0700 |
commit | d860afaebd1e04839047d247fa5d1cfcdeaeefb6 (patch) | |
tree | f88612c54f3fcd18c9279184d61bee140bc5bdbf | |
parent | c9009e00d44dcaaab0cd25d3a15cdd673843f71f (diff) | |
download | f2fs-tools-d860afaebd1e04839047d247fa5d1cfcdeaeefb6.tar.gz |
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 <ebiggers@google.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fsck/fsck.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/fsck/fsck.c b/fsck/fsck.c index 07fa189..f1a55db 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; } |