Skip to content

Commit 08ce2fe

Browse files
szymonwilczekaalexandrovich
authored andcommitted
ntfs3: fix circular locking dependency in run_unpack_ex
Syzbot reported a circular locking dependency between wnd->rw_lock (sbi->used.bitmap) and ni->file.run_lock. The deadlock scenario: 1. ntfs_extend_mft() takes ni->file.run_lock then wnd->rw_lock. 2. run_unpack_ex() takes wnd->rw_lock then tries to acquire ni->file.run_lock inside ntfs_refresh_zone(). This creates an AB-BA deadlock. Fix this by using down_read_trylock() instead of down_read() when acquiring run_lock in run_unpack_ex(). If the lock is contended, skip ntfs_refresh_zone() - the MFT zone will be refreshed on the next MFT operation. This breaks the circular dependency since we never block waiting for run_lock while holding wnd->rw_lock. Reported-by: syzbot+d27edf9f96ae85939222@syzkaller.appspotmail.com Tested-by: syzbot+d27edf9f96ae85939222@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=d27edf9f96ae85939222 Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
1 parent 099ef9a commit 08ce2fe

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

fs/ntfs3/run.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,11 +1131,14 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
11311131
struct rw_semaphore *lock =
11321132
is_mounted(sbi) ? &sbi->mft.ni->file.run_lock :
11331133
NULL;
1134-
if (lock)
1135-
down_read(lock);
1136-
ntfs_refresh_zone(sbi);
1137-
if (lock)
1138-
up_read(lock);
1134+
if (lock) {
1135+
if (down_read_trylock(lock)) {
1136+
ntfs_refresh_zone(sbi);
1137+
up_read(lock);
1138+
}
1139+
} else {
1140+
ntfs_refresh_zone(sbi);
1141+
}
11391142
}
11401143
up_write(&wnd->rw_lock);
11411144
if (err)

0 commit comments

Comments
 (0)