• Jan Kara's avatar
    ext4: fix race when reusing xattr blocks · 65f8b800
    Jan Kara authored
    When ext4_xattr_block_set() decides to remove xattr block the following
    race can happen:
    
    CPU1                                    CPU2
    ext4_xattr_block_set()                  ext4_xattr_release_block()
      new_bh = ext4_xattr_block_cache_find()
    
                                              lock_buffer(bh);
                                              ref = le32_to_cpu(BHDR(bh)->h_refcount);
                                              if (ref == 1) {
                                                ...
                                                mb_cache_entry_delete();
                                                unlock_buffer(bh);
                                                ext4_free_blocks();
                                                  ...
                                                  ext4_forget(..., bh, ...);
                                                    jbd2_journal_revoke(..., bh);
    
      ext4_journal_get_write_access(..., new_bh, ...)
        do_get_write_access()
          jbd2_journal_cancel_revoke(..., new_bh);
    
    Later the code in ext4_xattr_block_set() finds out the block got freed
    and cancels reusal of the block but the revoke stays canceled and so in
    case of block reuse and journal replay the filesystem can get corrupted.
    If the race works out slightly differently, we can also hit assertions
    in the jbd2 code.
    
    Fix the problem by making sure that once matching mbcache entry is
    found, code dropping the last xattr block reference (or trying to modify
    xattr block in place) waits until the mbcache entry reference is
    dropped. This way code trying to reuse xattr block is protected from
    someone trying to drop the last reference to xattr block.
    Reported-and-tested-by: default avatarRitesh Harjani <ritesh.list@gmail.com>
    CC: stable@vger.kernel.org
    Fixes: 82939d79 ("ext4: convert to mbcache2")
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Link: https://lore.kernel.org/r/20220712105436.32204-5-jack@suse.czSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    65f8b800
xattr.c 81.8 KB