Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Szymon Wilczek and committed by
Konstantin Komarov
08ce2fee 099ef9ab

+8 -5
+8 -5
fs/ntfs3/run.c
··· 1131 1131 struct rw_semaphore *lock = 1132 1132 is_mounted(sbi) ? &sbi->mft.ni->file.run_lock : 1133 1133 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 + } 1139 1142 } 1140 1143 up_write(&wnd->rw_lock); 1141 1144 if (err)