[5.15-rt] printk: ignore consoles without write() callback

Message ID 87zg9d99mp.fsf@jogness.linutronix.de
State New
Headers
Series [5.15-rt] printk: ignore consoles without write() callback |

Commit Message

John Ogness Feb. 16, 2023, 10:39 a.m. UTC
  The ttynull driver does not provide an implementation for the write()
callback. This leads to a NULL pointer dereference in the related
printing kthread, which assumes it can call that callback.

Do not create kthreads for consoles that do not implement the write()
callback. Also, for pr_flush(), ignore consoles that do not implement
write() or write_atomic() since there is no way those consoles can
flush their output.

Link: https://lore.kernel.org/lkml/878rgy37f5.fsf@jogness.linutronix.de
Fixes: 8782b1ef4125 ("printk: move console printing to kthreads")
Reported-by: Michael Thalmeier <michael.thalmeier@hale.at>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 This is only a problem for the PREEMPT_RT tree. Mainline does not have
 this problem.

 kernel/printk/printk.c | 6 ++++++
 1 file changed, 6 insertions(+)
  

Comments

Sebastian Andrzej Siewior Feb. 16, 2023, 4:54 p.m. UTC | #1
On 2023-02-16 11:45:58 [+0106], John Ogness wrote:
>  This is only a problem for the PREEMPT_RT tree. Mainline does not have
>  this problem.

Is this 5.15 and less or current dev RT and less?

Sebastian
  
John Ogness Feb. 17, 2023, 8:45 a.m. UTC | #2
On 2023-02-16, Sebastian Siewior <bigeasy@linutronix.de> wrote:
>>  This is only a problem for the PREEMPT_RT tree. Mainline does not have
>>  this problem.
>
> Is this 5.15 and less or current dev RT and less?

5.10-rt is also affected. The changes for 5.10-rt are the same, but the
patch does not apply as-is. I will reply with a patch for 5.10-rt.

5.4-rt is not affected.

John Ogness
  

Patch

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 7f27cfee283e..752afe88b5b4 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2343,6 +2343,10 @@  static int printk_kthread_func(void *data)
 /* Must be called within console_lock(). */
 static void start_printk_kthread(struct console *con)
 {
+	/* No need to start a printing thread if the console cannot print. */
+	if (!con->write)
+		return;
+
 	con->thread = kthread_run(printk_kthread_func, con,
 				  "pr/%s%d", con->name, con->index);
 	if (IS_ERR(con->thread)) {
@@ -3737,6 +3741,8 @@  bool pr_flush(int timeout_ms, bool reset_on_progress)
 		for_each_console(con) {
 			if (!(con->flags & CON_ENABLED))
 				continue;
+			if (!con->write && !con->write_atomic)
+				continue;
 			printk_seq = read_console_seq(con);
 			if (printk_seq < seq)
 				diff += seq - printk_seq;