• Zhihao Cheng's avatar
    ubifs: Fix 'ui->dirty' race between do_tmpfile() and writeback work · 60eb3b9c
    Zhihao Cheng authored
    'ui->dirty' is not protected by 'ui_mutex' in function do_tmpfile() which
    may race with ubifs_write_inode[wb_workfn] to access/update 'ui->dirty',
    finally dirty space is released twice.
    
    	open(O_TMPFILE)                wb_workfn
    do_tmpfile
      ubifs_budget_space(ino_req = { .dirtied_ino = 1})
      d_tmpfile // mark inode(tmpfile) dirty
      ubifs_jnl_update // without holding tmpfile's ui_mutex
        mark_inode_clean(ui)
          if (ui->dirty)
            ubifs_release_dirty_inode_budget(ui)  // release first time
                                       ubifs_write_inode
    				     mutex_lock(&ui->ui_mutex)
                                         ubifs_release_dirty_inode_budget(ui)
    				     // release second time
    				     mutex_unlock(&ui->ui_mutex)
          ui->dirty = 0
    
    Run generic/476 can reproduce following message easily
    (See reproducer in [Link]):
    
      UBIFS error (ubi0:0 pid 2578): ubifs_assert_failed [ubifs]: UBIFS assert
      failed: c->bi.dd_growth >= 0, in fs/ubifs/budget.c:554
      UBIFS warning (ubi0:0 pid 2578): ubifs_ro_mode [ubifs]: switched to
      read-only mode, error -22
      Workqueue: writeback wb_workfn (flush-ubifs_0_0)
      Call Trace:
        ubifs_ro_mode+0x54/0x60 [ubifs]
        ubifs_assert_failed+0x4b/0x80 [ubifs]
        ubifs_release_budget+0x468/0x5a0 [ubifs]
        ubifs_release_dirty_inode_budget+0x53/0x80 [ubifs]
        ubifs_write_inode+0x121/0x1f0 [ubifs]
        ...
        wb_workfn+0x283/0x7b0
    
    Fix it by holding tmpfile ubifs inode lock during ubifs_jnl_update().
    Similar problem exists in whiteout renaming, but previous fix("ubifs:
    Rename whiteout atomically") has solved the problem.
    
    Fixes: 474b9370 ("ubifs: Implement O_TMPFILE")
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=214765Signed-off-by: default avatarZhihao Cheng <chengzhihao1@huawei.com>
    Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
    60eb3b9c
dir.c 43.7 KB