• Jan Kara's avatar
    jbd2: fix use after free in jbd2_log_do_checkpoint() · ccd3c437
    Jan Kara authored
    The code cleaning transaction's lists of checkpoint buffers has a bug
    where it increases bh refcount only after releasing
    journal->j_list_lock. Thus the following race is possible:
    
    CPU0					CPU1
    jbd2_log_do_checkpoint()
    					jbd2_journal_try_to_free_buffers()
    					  __journal_try_to_free_buffer(bh)
      ...
      while (transaction->t_checkpoint_io_list)
      ...
        if (buffer_locked(bh)) {
    
    <-- IO completes now, buffer gets unlocked -->
    
          spin_unlock(&journal->j_list_lock);
    					    spin_lock(&journal->j_list_lock);
    					    __jbd2_journal_remove_checkpoint(jh);
    					    spin_unlock(&journal->j_list_lock);
    					  try_to_free_buffers(page);
          get_bh(bh) <-- accesses freed bh
    
    Fix the problem by grabbing bh reference before unlocking
    journal->j_list_lock.
    
    Fixes: dc6e8d66 ("jbd2: don't call get_bh() before calling __jbd2_journal_remove_checkpoint()")
    Fixes: be1158cc ("jbd2: fold __process_buffer() into jbd2_log_do_checkpoint()")
    Reported-by: syzbot+7f4a27091759e2fe7453@syzkaller.appspotmail.com
    CC: stable@vger.kernel.org
    Reviewed-by: default avatarLukas Czerner <lczerner@redhat.com>
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Signed-off-by: Theodore Ts'o's avatarTheodore Ts'o <tytso@mit.edu>
    ccd3c437
Name
Last commit
Last update
..
Kconfig Loading commit data...
Makefile Loading commit data...
checkpoint.c Loading commit data...
commit.c Loading commit data...
journal.c Loading commit data...
recovery.c Loading commit data...
revoke.c Loading commit data...
transaction.c Loading commit data...