[PATCH] efi_loader: NULL dereference in EFI console

Heinrich Schuchardt xypron.glpk at gmx.de
Tue Mar 16 17:56:36 CET 2021


Even if CONFIG_DM_VIDEO=y and stdout="vidconsole" a video device may not be
available. Check the return values of the relevant functions.

If no video output device is available, assume that the serial console is
in use.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 lib/efi_loader/efi_console.c | 51 +++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index c4003554c2..6040f3a99a 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -254,7 +254,7 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
 }

 /**
- * query_console_serial() - query console size
+ * query_console_serial() - query serial console size
  *
  * When using a serial console or the net console we can only devise the
  * terminal size by querying the terminal using ECMA-48 control sequences.
@@ -299,6 +299,37 @@ out:
 	return ret;
 }

+/**
+ * query_vidconsole() - query video console size
+ *
+ *
+ * @rows:	pointer to return number of rows
+ * @cols:	pointer to return number of columns
+ * Returns:	0 on success
+ */
+static int __maybe_unused query_vidconsole(int *rows, int *cols)
+{
+	const char *stdout_name = env_get("stdout");
+	struct stdio_dev *stdout_dev;
+	struct udevice *dev;
+	struct vidconsole_priv *priv;
+
+	if (!stdout_name || strncmp(stdout_name, "vidconsole", 10))
+		return -ENODEV;
+	stdout_dev = stdio_get_by_name("vidconsole");
+	if (!stdout_dev)
+		return -ENODEV;
+	dev = stdout_dev->priv;
+	if (!dev)
+		return -ENODEV;
+	priv = dev_get_uclass_priv(dev);
+	if (!priv)
+		return -ENODEV;
+	*rows = priv->rows;
+	*cols = priv->cols;
+	return 0;
+}
+
 /**
  * query_console_size() - update the mode table.
  *
@@ -308,21 +339,15 @@ out:
  */
 static void query_console_size(void)
 {
-	const char *stdout_name = env_get("stdout");
 	int rows = 25, cols = 80;
+	int ret = -ENODEV;

-	if (stdout_name && !strncmp(stdout_name, "vidconsole", 10) &&
-	    IS_ENABLED(CONFIG_DM_VIDEO)) {
-		struct stdio_dev *stdout_dev =
-			stdio_get_by_name("vidconsole");
-		struct udevice *dev = stdout_dev->priv;
-		struct vidconsole_priv *priv =
-			dev_get_uclass_priv(dev);
-		rows = priv->rows;
-		cols = priv->cols;
-	} else if (query_console_serial(&rows, &cols)) {
+	if IS_ENABLED(CONFIG_DM_VIDEO)
+		ret = query_vidconsole(&rows, &cols);
+	if (ret)
+		ret = query_console_serial(&rows, &cols);
+	if (ret)
 		return;
-	}

 	/* Test if we can have Mode 1 */
 	if (cols >= 80 && rows >= 50) {
--
2.30.2



More information about the U-Boot mailing list