lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20161031121455.23280-1-paul.burton@imgtec.com>
Date:   Mon, 31 Oct 2016 12:14:55 +0000
From:   Paul Burton <paul.burton@...tec.com>
To:     Michael Ellerman <mpe@...erman.id.au>
CC:     Paul Burton <paul.burton@...tec.com>,
        Andreas Schwab <schwab@...ux-m68k.org>,
        Andrew Morton <akpm@...ux-foundation.org>,
        Borislav Petkov <bp@...e.de>,
        Larry Finger <Larry.Finger@...inger.net>,
        Petr Mladek <pmladek@...e.com>,
        Sergey Senozhatsky <sergey.senozhatsky@...il.com>,
        Tejun Heo <tj@...nel.org>, <linux-kernel@...r.kernel.org>,
        <linuxppc-dev@...ts.ozlabs.org>
Subject: [PATCH v2] console: use first console if stdout-path device doesn't appear

If a device tree specified a preferred device for kernel console output
via the stdout-path or linux,stdout-path chosen node properties there's
no guarantee that it will have specified a device for which we have a
driver. It may also be the case that we do have a driver but it doesn't
call of_console_check() to register as a preferred console (eg. offb
driver as used on powermac systems). In these cases try to ensure that
we provide some console output by enabling the first usable registered
console, which we keep track of with the of_fallback_console variable.

Tested in QEMU with a PowerPC pseries_defconfig kernel.

Signed-off-by: Paul Burton <paul.burton@...tec.com>
Fixes: 05fd007e4629 ("console: don't prefer first registered if DT specifies stdout-path")
Reported-by: Andreas Schwab <schwab@...ux-m68k.org>
Reported-by: Larry Finger <Larry.Finger@...inger.net>
Reported-by: Michael Ellerman <mpe@...erman.id.au>
Cc: Andreas Schwab <schwab@...ux-m68k.org>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: Borislav Petkov <bp@...e.de>
Cc: Larry Finger <Larry.Finger@...inger.net>
Cc: Michael Ellerman <mpe@...erman.id.au>
Cc: Petr Mladek <pmladek@...e.com>
Cc: Sergey Senozhatsky <sergey.senozhatsky@...il.com>
Cc: Tejun Heo <tj@...nel.org>
Cc: linux-kernel@...r.kernel.org
Cc: linuxppc-dev@...ts.ozlabs.org

---

Changes in v2:
- Split enable_console() out of register_console() & call in the fallback case.
- Track the console we would have enabled as of_fallback_console.

 kernel/printk/printk.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 5 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index de08fc9..b02c00a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -264,6 +264,13 @@ void console_set_by_of(void)
 # define of_specified_console false
 #endif
 
+/*
+ * The first usable console, which we'll fall back to using if the system
+ * uses a device tree which indicates a stdout-path device for which we
+ * have no driver, or for which our driver doesn't call of_console_check().
+ */
+static struct console *of_fallback_console;
+
 /* Flag: console code may call schedule() */
 static int console_may_schedule;
 
@@ -2598,6 +2605,8 @@ static int __init keep_bootcon_setup(char *str)
 
 early_param("keep_bootcon", keep_bootcon_setup);
 
+static void enable_console(struct console *newcon);
+
 /*
  * The console driver calls this routine during kernel initialization
  * to register the console printing procedure with printk() and to
@@ -2620,7 +2629,6 @@ early_param("keep_bootcon", keep_bootcon_setup);
 void register_console(struct console *newcon)
 {
 	int i;
-	unsigned long flags;
 	struct console *bcon = NULL;
 	struct console_cmdline *c;
 
@@ -2657,7 +2665,9 @@ void register_console(struct console *newcon)
 	 *	didn't select a console we take the first one
 	 *	that registers here.
 	 */
-	if (preferred_console < 0 && !of_specified_console) {
+	if (preferred_console < 0 && of_specified_console) {
+		of_fallback_console = of_fallback_console ?: newcon;
+	} else if (preferred_console < 0) {
 		if (newcon->index < 0)
 			newcon->index = 0;
 		if (newcon->setup == NULL ||
@@ -2705,8 +2715,18 @@ void register_console(struct console *newcon)
 		break;
 	}
 
-	if (!(newcon->flags & CON_ENABLED))
-		return;
+	if (newcon->flags & CON_ENABLED)
+		enable_console(newcon);
+}
+EXPORT_SYMBOL(register_console);
+
+static void enable_console(struct console *newcon)
+{
+	struct console *bcon = NULL;
+	unsigned long flags;
+
+	if (console_drivers && console_drivers->flags & CON_BOOT)
+		bcon = console_drivers;
 
 	/*
 	 * If we have a bootconsole, and are switching to a real console,
@@ -2777,7 +2797,6 @@ void register_console(struct console *newcon)
 				unregister_console(bcon);
 	}
 }
-EXPORT_SYMBOL(register_console);
 
 int unregister_console(struct console *console)
 {
@@ -2839,10 +2858,41 @@ EXPORT_SYMBOL(unregister_console);
  * intersects with the init section. Note that code exists elsewhere to get
  * rid of the boot console as soon as the proper console shows up, so there
  * won't be side-effects from postponing the removal.
+ *
+ * Additionally we may be using a device tree which specifies valid
+ * stdout-path referencing a device for which we don't have a driver, or for
+ * which we have a driver that doesn't register itself as preferred console
+ * using of_console_check(). In these cases we attempt here to enable the
+ * first usable registered console, which we assigned to of_fallback_console.
  */
 static int __init printk_late_init(void)
 {
 	struct console *con;
+	bool any_enabled = false;
+
+	for_each_console(con) {
+		if (!(con->flags & CON_ENABLED))
+			continue;
+
+		any_enabled = true;
+		break;
+	}
+
+	if (!any_enabled && of_fallback_console) {
+		if (of_fallback_console->index < 0)
+			of_fallback_console->index = 0;
+
+		if (!of_fallback_console->setup ||
+		    !of_fallback_console->setup(of_fallback_console, NULL)) {
+			of_fallback_console->flags |= CON_ENABLED;
+			if (of_fallback_console->device) {
+				of_fallback_console->flags |= CON_CONSDEV;
+				preferred_console = 0;
+			}
+		}
+
+		enable_console(of_fallback_console);
+	}
 
 	for_each_console(con) {
 		if (!keep_bootcon && con->flags & CON_BOOT) {
-- 
2.10.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ