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

John Ogness posted 1 patch 2 years, 6 months ago
kernel/printk/printk.c | 6 ++++++
1 file changed, 6 insertions(+)
[PATCH 5.10-rt] printk: ignore consoles without write() callback
Posted by John Ogness 2 years, 6 months ago
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/1831554214.546921.1676479103702.JavaMail.zimbra@hale.at
Reported-by: Michael Thalmeier <michael.thalmeier@hale.at>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index d2205872304d..64747c72fbea 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2267,6 +2267,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)) {
@@ -3566,6 +3570,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 = atomic64_read(&con->printk_seq);
 			if (printk_seq < seq)
 				diff += seq - printk_seq;
-- 
2.30.2
Re: [PATCH 5.10-rt] printk: ignore consoles without write() callback
Posted by Luis Claudio R. Goncalves 2 years, 6 months ago
On Fri, Feb 17, 2023 at 09:53:44AM +0106, John Ogness wrote:
> 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/1831554214.546921.1676479103702.JavaMail.zimbra@hale.at
> Reported-by: Michael Thalmeier <michael.thalmeier@hale.at>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Thank you! I will apply that to the next 5.10-rt build.

Luis

> ---
>  kernel/printk/printk.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index d2205872304d..64747c72fbea 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2267,6 +2267,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)) {
> @@ -3566,6 +3570,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 = atomic64_read(&con->printk_seq);
>  			if (printk_seq < seq)
>  				diff += seq - printk_seq;
> -- 
> 2.30.2
> 
---end quoted text---