| From: John Ogness <john.ogness@linutronix.de> |
| Date: Sun, 17 Feb 2019 03:11:20 +0100 |
| Subject: [PATCH] printk: only allow kernel to emergency message |
| |
| Emergency messages exist as a mechanism for the kernel to |
| communicate critical information to users. It is not meant for |
| use by userspace. Only allow facility=0 messages to be |
| processed by the emergency message code. |
| |
| Signed-off-by: John Ogness <john.ogness@linutronix.de> |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| kernel/printk/printk.c | 17 +++++++++++------ |
| 1 file changed, 11 insertions(+), 6 deletions(-) |
| |
| --- a/kernel/printk/printk.c |
| +++ b/kernel/printk/printk.c |
| @@ -1754,7 +1754,8 @@ static void printk_write_history(struct |
| * The console_lock must be held. |
| */ |
| static void call_console_drivers(u64 seq, const char *ext_text, size_t ext_len, |
| - const char *text, size_t len, int level) |
| + const char *text, size_t len, int level, |
| + int facility) |
| { |
| struct console *con; |
| |
| @@ -1774,13 +1775,14 @@ static void call_console_drivers(u64 seq |
| con->wrote_history = 1; |
| con->printk_seq = seq - 1; |
| } |
| - if (con->write_atomic && level < emergency_console_loglevel) { |
| + if (con->write_atomic && level < emergency_console_loglevel && |
| + facility == 0) { |
| /* skip emergency messages, already printed */ |
| if (con->printk_seq < seq) |
| con->printk_seq = seq; |
| continue; |
| } |
| - if (con->flags & CON_BOOT) { |
| + if (con->flags & CON_BOOT && facility == 0) { |
| /* skip emergency messages, already printed */ |
| if (con->printk_seq < seq) |
| con->printk_seq = seq; |
| @@ -1951,7 +1953,10 @@ asmlinkage int vprintk_emit(int facility |
| * - text points to beginning of text |
| * - there is room before text for prefix |
| */ |
| - printk_emergency(rbuf, level & 7, ts_nsec, cpu, text, text_len); |
| + if (facility == 0) { |
| + /* only the kernel can create emergency messages */ |
| + printk_emergency(rbuf, level & 7, ts_nsec, cpu, text, text_len); |
| + } |
| |
| if ((lflags & LOG_CONT) || !(lflags & LOG_NEWLINE)) { |
| cont_add(ctx, cpu, caller_id, facility, level, lflags, text, text_len); |
| @@ -2716,8 +2721,8 @@ static int printk_kthread_func(void *dat |
| |
| console_lock(); |
| console_may_schedule = 0; |
| - call_console_drivers(master_seq, ext_text, |
| - ext_len, text, len, msg->level); |
| + call_console_drivers(master_seq, ext_text, ext_len, text, len, |
| + msg->level, msg->facility); |
| if (len > 0 || ext_len > 0) |
| printk_delay(msg->level); |
| console_unlock(); |