summaryrefslogtreecommitdiff
path: root/kernel/printk
diff options
context:
space:
mode:
authorJohn Ogness <john.ogness@linutronix.de>2026-07-03 16:20:31 +0206
committerPetr Mladek <pmladek@suse.com>2026-07-09 13:33:17 +0200
commit36630cafbeede0b64c370edb2f7b4094327ee1e0 (patch)
tree8cff4ca2c3432856c8e57a02c242b88de04246ef /kernel/printk
parent3a341cb3a2c2879732bc9cf006caa6a087b82241 (diff)
downloadlwn-36630cafbeede0b64c370edb2f7b4094327ee1e0.tar.gz
lwn-36630cafbeede0b64c370edb2f7b4094327ee1e0.zip
printk: Fix possible console use-after-free
When emitting a record via legacy printing, it is possible that a handover to another legacy printing context occurs. When a context has performed a handover, the console SRCU read lock is released and the pointer to the console struct might now be invalid. Therefore, after calling nbcon_legacy_emit_next_record() or console_emit_next_record(), it is necessary to check if a handover occurred _before_ further @con usage. Sashiko pointed out that console_flush_one_record() was not doing this. In console_flush_one_record(), after emitting a record, move the further usage of @con after the handover check. Fixes: c158834b223f ("printk: nbcon: Use nbcon consoles in console_flush_all()") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/lkml/20260630170903.099D61F000E9@smtp.kernel.org Signed-off-by: John Ogness <john.ogness@linutronix.de> Reviewed-by: Petr Mladek <pmladek@suse.com> Link: https://patch.msgid.link/20260703141521.202813-1-john.ogness@linutronix.de Signed-off-by: Petr Mladek <pmladek@suse.com>
Diffstat (limited to 'kernel/printk')
-rw-r--r--kernel/printk/printk.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 2fe9a963c823..6d363e42e2a0 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3264,10 +3264,8 @@ static bool console_flush_one_record(bool do_cond_resched, u64 *next_seq, bool *
if (flags & CON_NBCON) {
progress = nbcon_legacy_emit_next_record(con, handover, cookie,
!do_cond_resched);
- printk_seq = nbcon_seq_read(con);
} else {
progress = console_emit_next_record(con, handover, cookie);
- printk_seq = con->seq;
}
/*
@@ -3277,6 +3275,15 @@ static bool console_flush_one_record(bool do_cond_resched, u64 *next_seq, bool *
if (*handover)
goto fail;
+ /*
+ * @con can be used here now that it is certain that this
+ * context is still holding the SRCU read lock.
+ */
+ if (flags & CON_NBCON)
+ printk_seq = nbcon_seq_read(con);
+ else
+ printk_seq = con->seq;
+
/* Track the next of the highest seq flushed. */
if (printk_seq > *next_seq)
*next_seq = printk_seq;