summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2021-03-16 12:56:57 +0100
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2021-03-19 20:47:25 +0100
commita95f4c88599176d9a88dc19c02fa8dd95003eebf (patch)
treeee6ba5f4465adea29ffeb070d72c7570e0070d17
parente3310c21a43c1e3c004c6b53ee9179420a1be375 (diff)
downloadu-boot-a95f4c88599176d9a88dc19c02fa8dd95003eebf.tar.gz
efi_loader: NULL dereference in EFI console
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@gmx.de>
-rw-r--r--lib/efi_loader/efi_console.c51
1 files 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.
@@ -300,6 +300,37 @@ out:
}
/**
+ * 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.
*
* By default the only mode available is 80x25. If the console has at least 50
@@ -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) {