From: Eric Biggers <ebigg...@google.com>

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 <ebigg...@google.com>
---
 fsck/fsck.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 72daa71..51e46e4 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -827,54 +827,72 @@ void fsck_reada_all_direct_node_blocks(struct 
f2fs_sb_info *sbi,
 {
        int i;
 
        for (i = 0; i < NIDS_PER_BLOCK; i++) {
                u32 nid = le32_to_cpu(node_blk->in.nid[i]);
 
                fsck_reada_node_block(sbi, nid);
        }
 }
 
+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)
 {
        void *xattr;
        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;
 
        xattr = read_all_xattrs(sbi, inode, false);
        ASSERT(xattr);
 
        last_base_addr = (void *)xattr + xattr_size;
 
        list_for_each_xattr(ent, xattr) {
                if ((void *)(ent) + sizeof(__u32) > last_base_addr ||
                        (void *)XATTR_NEXT_ENTRY(ent) > last_base_addr) {
                        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;
 }
 
 /* start with valid nid and blkaddr */
 void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
                enum FILE_TYPE ftype, struct f2fs_node *node_blk,
                u32 *blk_cnt, struct f2fs_compr_blk_cnt *cbc,
                struct node_info *ni, struct child_info *child_d)
 {
        struct f2fs_fsck *fsck = F2FS_FSCK(sbi);

base-commit: 104b6b83206a9919d4b10f310981cc99fbbc8ed1
-- 
2.42.0.820.g83a721a137-goog



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to