diff options
| author | John Ogness <john.ogness@linutronix.de> | 2026-07-03 16:20:31 +0206 |
|---|---|---|
| committer | Petr Mladek <pmladek@suse.com> | 2026-07-09 13:33:17 +0200 |
| commit | 36630cafbeede0b64c370edb2f7b4094327ee1e0 (patch) | |
| tree | 8cff4ca2c3432856c8e57a02c242b88de04246ef /kernel/printk | |
| parent | 3a341cb3a2c2879732bc9cf006caa6a087b82241 (diff) | |
| download | lwn-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.c | 11 |
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; |
