lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 29 Apr 2019 20:52:07 +0900
From:   Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
To:     Dmitry Vyukov <dvyukov@...gle.com>,
        Andrew Morton <akpm@...ux-foundation.org>
Cc:     linux-kernel@...r.kernel.org,
        Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
Subject: [PATCH] kernel/hung_task.c: Replace trigger_all_cpu_backtrace() with task traversal.

Since trigger_all_cpu_backtrace() uses NMI interface, printk() from other
CPUs are called from interrupt context. Therefore, CONFIG_PRINTK_CALLER=y
needlessly separates printk() from khungtaskd kernel thread running on
current CPU and printk() from other threads running on other CPUs.

Also, it is completely a garbage that trigger_all_cpu_backtrace() reports
khungtaskd kernel thread running on current CPU, for the purpose of
calling trigger_all_cpu_backtrace() from khungtaskd is to report running
threads which might have caused other threads being blocked for so long.

Therefore, report threads (except khungtaskd kernel thread itself) which
are on the scheduler using task traversal approach. This allows syzbot to
include backtrace of running threads into its report files.

Signed-off-by: Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
---
 kernel/hung_task.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index f108a95..2fddd98 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -164,6 +164,23 @@ static bool rcu_lock_break(struct task_struct *g, struct task_struct *t)
 	return can_cont;
 }
 
+static void print_all_running_threads(void)
+{
+#ifdef CONFIG_SMP
+	struct task_struct *g;
+	struct task_struct *t;
+
+	rcu_read_lock();
+	for_each_process_thread(g, t) {
+		if (!t->on_cpu || t == current)
+			continue;
+		pr_err("INFO: Currently running\n");
+		sched_show_task(t);
+	}
+	rcu_read_unlock();
+#endif
+}
+
 /*
  * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for
  * a really long time (120 seconds). If that happens, print out
@@ -201,7 +218,7 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
 	if (hung_task_show_lock)
 		debug_show_all_locks();
 	if (hung_task_call_panic) {
-		trigger_all_cpu_backtrace();
+		print_all_running_threads();
 		panic("hung_task: blocked tasks");
 	}
 }
-- 
1.8.3.1

Powered by blists - more mailing lists