[PATCH] locking/lockdep: Add config option to allow lockdep splat upon ioctl(FIFREEZE) request

From: Tetsuo Handa
Date: Thu Jun 14 2018 - 03:14:55 EST


syzbot is hitting hung task problems at __sb_start_write() [1]. While hung
tasks at __sb_start_write() suggest that filesystem was frozen, syzbot is
not doing ioctl(FIFREEZE) requests. Therefore, the root cause of hung tasks
is currently unknown. If there are other paths to freeze filesystem and
return to userspace without thawing, syzbot needs to avoid testing such
paths. Therefore, this patch adds a kernel config option which allows
lockdep to splat if syzbot found such paths.

[1] https://syzkaller.appspot.com/bug?id=287aa8708bc940d0ca1645223c53dd4c2d203be6

Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Will Deacon <will.deacon@xxxxxxx>
Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx>
---
fs/super.c | 4 ++++
lib/Kconfig.debug | 13 +++++++++++++
2 files changed, 17 insertions(+)

diff --git a/fs/super.c b/fs/super.c
index 50728d9..eb51268 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1428,10 +1428,12 @@ static void sb_wait_write(struct super_block *sb, int level)
*/
static void lockdep_sb_freeze_release(struct super_block *sb)
{
+#ifndef CONFIG_LOCKDEP_REPORT_FSFREEZE_FROM_USERSPACE
int level;

for (level = SB_FREEZE_LEVELS - 1; level >= 0; level--)
percpu_rwsem_release(sb->s_writers.rw_sem + level, 0, _THIS_IP_);
+#endif
}

/*
@@ -1439,10 +1441,12 @@ static void lockdep_sb_freeze_release(struct super_block *sb)
*/
static void lockdep_sb_freeze_acquire(struct super_block *sb)
{
+#ifndef CONFIG_LOCKDEP_REPORT_FSFREEZE_FROM_USERSPACE
int level;

for (level = 0; level < SB_FREEZE_LEVELS; ++level)
percpu_rwsem_acquire(sb->s_writers.rw_sem + level, 0, _THIS_IP_);
+#endif
}

static void sb_freeze_unlock(struct super_block *sb)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index d543c65..e119d19 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1170,6 +1170,19 @@ config DEBUG_LOCK_ALLOC
spin_lock_init()/mutex_init()/etc., or whether there is any lock
held during task exit.

+config LOCKDEP_REPORT_FSFREEZE_FROM_USERSPACE
+ bool "Allow lockdep splat upon ioctl(FIFREEZE) request"
+ depends on PROVE_LOCKING
+ default n
+ help
+ Freezing filesystems and not thawing shortly will kill the system with
+ hung tasks. Since ioctl(FIFREEZE) request returns to userspace with
+ locks held, in order to suppress lockdep splat messages, information
+ of held locks is cleared without actually releasing locks held. But
+ doing so might hide possible deadlock bugs. Thus, this option allows
+ lockdep splat if ioctl(FIFREEZE) is requested, in order to help
+ finding possible deadlock bugs.
+
config LOCKDEP
bool
depends on DEBUG_KERNEL && LOCK_DEBUGGING_SUPPORT
--
1.8.3.1