Patch "printk: Reduce console_unblank() usage in unsafe scenarios" has been added to the 6.5-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    printk: Reduce console_unblank() usage in unsafe scenarios

to the 6.5-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     printk-reduce-console_unblank-usage-in-unsafe-scenar.patch
and it can be found in the queue-6.5 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 2c4830d767254f7e42841303c7c91dbea51f2da9
Author: John Ogness <john.ogness@xxxxxxxxxxxxx>
Date:   Mon Jul 17 21:52:02 2023 +0206

    printk: Reduce console_unblank() usage in unsafe scenarios
    
    [ Upstream commit 7b23a66db55ed0a55b020e913f0d6f6d52a1ad2c ]
    
    A semaphore is not NMI-safe, even when using down_trylock(). Both
    down_trylock() and up() are using internal spinlocks and up()
    might even call wake_up_process().
    
    In the panic() code path it gets even worse because the internal
    spinlocks of the semaphore may have been taken by a CPU that has
    been stopped.
    
    To reduce the risk of deadlocks caused by the console semaphore in
    the panic path, make the following changes:
    
    - First check if any consoles have implemented the unblank()
      callback. If not, then there is no reason to take the console
      semaphore anyway. (This check is also useful for the non-panic
      path since the locking/unlocking of the console lock can be
      quite expensive due to console printing.)
    
    - If the panic path is in NMI context, bail out without attempting
      to take the console semaphore or calling any unblank() callbacks.
      Bailing out is acceptable because console_unblank() would already
      bail out if the console semaphore is contended. The alternative of
      ignoring the console semaphore and calling the unblank() callbacks
      anyway is a bad idea because these callbacks are also not NMI-safe.
    
    If consoles with unblank() callbacks exist and console_unblank() is
    called from a non-NMI panic context, it will still attempt a
    down_trylock(). This could still result in a deadlock if one of the
    stopped CPUs is holding the semaphore internal spinlock. But this
    is a risk that the kernel has been (and continues to be) willing
    to take.
    
    Signed-off-by: John Ogness <john.ogness@xxxxxxxxxxxxx>
    Reviewed-by: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx>
    Reviewed-by: Petr Mladek <pmladek@xxxxxxxx>
    Signed-off-by: Petr Mladek <pmladek@xxxxxxxx>
    Link: https://lore.kernel.org/r/20230717194607.145135-3-john.ogness@xxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 357a4d18f6387..7d3f30eb35862 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3045,9 +3045,27 @@ EXPORT_SYMBOL(console_conditional_schedule);
 
 void console_unblank(void)
 {
+	bool found_unblank = false;
 	struct console *c;
 	int cookie;
 
+	/*
+	 * First check if there are any consoles implementing the unblank()
+	 * callback. If not, there is no reason to continue and take the
+	 * console lock, which in particular can be dangerous if
+	 * @oops_in_progress is set.
+	 */
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(c) {
+		if ((console_srcu_read_flags(c) & CON_ENABLED) && c->unblank) {
+			found_unblank = true;
+			break;
+		}
+	}
+	console_srcu_read_unlock(cookie);
+	if (!found_unblank)
+		return;
+
 	/*
 	 * Stop console printing because the unblank() callback may
 	 * assume the console is not within its write() callback.
@@ -3056,6 +3074,16 @@ void console_unblank(void)
 	 * In that case, attempt a trylock as best-effort.
 	 */
 	if (oops_in_progress) {
+		/* Semaphores are not NMI-safe. */
+		if (in_nmi())
+			return;
+
+		/*
+		 * Attempting to trylock the console lock can deadlock
+		 * if another CPU was stopped while modifying the
+		 * semaphore. "Hope and pray" that this is not the
+		 * current situation.
+		 */
 		if (down_trylock_console_sem() != 0)
 			return;
 	} else



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux