[PATCH v8 15/21] printk: sysrq: Clamp console loglevel to valid range

Chris Down posted 21 patches 4 days, 1 hour ago
Only 20 patches received!
[PATCH v8 15/21] printk: sysrq: Clamp console loglevel to valid range
Posted by Chris Down 4 days, 1 hour ago
The sysrq loglevel handler (keys 0-9) directly assigns the numeric key
value to console_loglevel without any validation. This creates an
inconsistency with other interfaces: the new kernel.console_loglevel
sysctl, the per-console sysfs loglevel interface, and the
SYSLOG_ACTION_CONSOLE_LEVEL syslog command all clamp or reject values
outside the valid range.

In particular, sysrq 0 sets console_loglevel to 0 (LOGLEVEL_EMERG),
which is problematic because:

1. LOGLEVEL_EMERG (0) is reserved for emergency messages that should
   always reach all consoles. Setting console_loglevel to 0 would mean
   only KERN_EMERG messages print, which is likely never intended.

2. The per-console loglevel infrastructure explicitly rejects level 0
   for this reason, creating an inconsistency where sysrq can set a
   value that other interfaces refuse.

3. CONSOLE_LOGLEVEL_MIN is defined as 1, indicating the minimum valid
   console loglevel, yet sysrq ignores this.

Similarly, sysrq 9 sets console_loglevel to 9, which is above
LOGLEVEL_DEBUG (7) and serves no useful purpose since no messages have
a level that high.

Use console_clamp_loglevel() to clamp the requested loglevel to the
valid range [1, 8]. This ensures consistent behaviour across all
loglevel-setting interfaces.

Signed-off-by: Chris Down <chris@chrisdown.name>
---
 drivers/tty/sysrq.c    | 2 +-
 include/linux/printk.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 1d5ae9997e79..e9d97ec28432 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -101,7 +101,7 @@ __setup("sysrq_always_enabled", sysrq_always_enabled_setup);
 
 static void sysrq_handle_loglevel(u8 key)
 {
-	u8 loglevel = key - '0';
+	u8 loglevel = console_clamp_loglevel(key - '0');
 
 	console_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
 	pr_info("Loglevel set to %u\n", loglevel);
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 0aa8cb8ddc09..5a8c4aca729f 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -65,6 +65,7 @@ static inline const char *printk_skip_headers(const char *buffer)
 int match_devname_and_update_preferred_console(const char *match,
 					       const char *name,
 					       const short idx);
+int console_clamp_loglevel(int level);
 
 extern int console_printk[];
 
-- 
2.51.2