summaryrefslogtreecommitdiff
path: root/fs/ubifs/dir.c
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2023-11-20 14:13:45 +0300
committerRichard Weinberger <richard@nod.at>2024-01-05 19:03:41 +0300
commitc07a4dab243a99589bdfd5ec364b5cb1db6b70f3 (patch)
treef019df6d7addebcc1dd02d068d7ff88c1f9acf86 /fs/ubifs/dir.c
parent2ba5b48938d752d09d65d1a01c8ff0d2228c5ab5 (diff)
downloadlinux-c07a4dab243a99589bdfd5ec364b5cb1db6b70f3.tar.xz
ubifs: Check @c->dirty_[n|p]n_cnt and @c->nroot state under @c->lp_mutex
The checking of @c->nroot->flags and @c->dirty_[n|p]n_cnt in function nothing_to_commit() is not atomic, which could be raced with modifying of lpt, for example: P1 P2 P3 run_gc ubifs_garbage_collect do_commit ubifs_return_leb ubifs_lpt_lookup_dirty dirty_cow_nnode do_commit nothing_to_commit if (test_bit(DIRTY_CNODE, &c->nroot->flags) // false test_and_set_bit(DIRTY_CNODE, &nnode->flags) c->dirty_nn_cnt += 1 ubifs_assert(c, c->dirty_nn_cnt == 0) // false ! Fetch a reproducer in Link: UBIFS error (ubi0:0 pid 2747): ubifs_assert_failed UBIFS assert failed: c->dirty_pn_cnt == 0, in fs/ubifs/commit.c Call Trace: ubifs_ro_mode+0x58/0x70 [ubifs] ubifs_assert_failed+0x6a/0x90 [ubifs] do_commit+0x5b7/0x930 [ubifs] ubifs_run_commit+0xc6/0x1a0 [ubifs] ubifs_sync_fs+0xd8/0x110 [ubifs] sync_filesystem+0xb4/0x120 do_syscall_64+0x6f/0x140 Fix it by checking @c->dirty_[n|p]n_cnt and @c->nroot state with @c->lp_mutex locked. Fixes: 944fdef52ca9 ("UBIFS: do not start the commit if there is nothing to commit") Link: https://bugzilla.kernel.org/show_bug.cgi?id=218162 Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs/dir.c')
0 files changed, 0 insertions, 0 deletions