]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Properly check status code of console_key_read
authorJan Janssen <medhefgo@web.de>
Mon, 21 Feb 2022 11:52:30 +0000 (12:52 +0100)
committerJan Janssen <medhefgo@web.de>
Tue, 22 Feb 2022 15:34:52 +0000 (16:34 +0100)
In some cases there was a unlikely possibility that we would look
at an uninitialized key value.
Also, returning in case of unexpected input error cases should prevent
infinite looping.

src/boot/efi/boot.c

index b2f4f873c3d1e63a6912f8b1bfd0d3c0b6c5df24..f6706c68fcb4ef36c9020b67d41ad3943f8bfab3 100644 (file)
@@ -182,6 +182,9 @@ static BOOLEAN line_edit(
                         cursor_color = TEXT_ATTR_SWAP(cursor_color);
 
                         err = console_key_read(&key, 750 * 1000);
+                        if (!IN_SET(err, EFI_SUCCESS, EFI_TIMEOUT, EFI_NOT_READY))
+                                return FALSE;
+
                         print_at(cursor + 1, y_pos, COLOR_EDIT, print + cursor);
                 } while (EFI_ERROR(err));
 
@@ -436,8 +439,16 @@ static void ps_bool(const CHAR16 *fmt, BOOLEAN value) {
         Print(fmt, yes_no(value));
 }
 
-static void print_status(Config *config, CHAR16 *loaded_image_path) {
+static BOOLEAN ps_continue(void) {
         UINT64 key;
+        EFI_STATUS err;
+
+        Print(L"\n--- Press any key to continue, ESC or q to quit. ---\n\n");
+        err = console_key_read(&key, UINT64_MAX);
+        return !EFI_ERROR(err) && !IN_SET(key, KEYPRESS(0, SCAN_ESC, 0), KEYPRESS(0, 0, 'q'), KEYPRESS(0, 0, 'Q'));
+}
+
+static void print_status(Config *config, CHAR16 *loaded_image_path) {
         UINTN x_max, y_max;
         UINT32 screen_width = 0, screen_height = 0;
         SecureBootMode secure;
@@ -468,8 +479,8 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) {
           ps_bool(L"                   TPM: %s\n",      tpm_present());
             Print(L"          console mode: %d/%d (%lux%lu @%ux%u)\n", ST->ConOut->Mode->Mode, ST->ConOut->Mode->MaxMode - 1LL, x_max, y_max, screen_width, screen_height);
 
-        Print(L"\n--- Press any key to continue. ---\n\n");
-        console_key_read(&key, UINT64_MAX);
+        if (!ps_continue())
+                return;
 
         switch (config->timeout_sec_config) {
         case TIMEOUT_UNSET:
@@ -519,8 +530,8 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) {
         if (config->console_mode_efivar != CONSOLE_MODE_KEEP)
             Print(L"console-mode (EFI var): %ld\n", config->console_mode_efivar);
 
-        Print(L"\n--- Press any key to continue. ---\n\n");
-        console_key_read(&key, UINT64_MAX);
+        if (!ps_continue())
+                return;
 
         for (UINTN i = 0; i < config->entry_count; i++) {
                 ConfigEntry *entry = config->entries[i];
@@ -545,10 +556,8 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) {
                     Print(L"     next path: %s\\%s\n",  entry->path, entry->next_name);
                 }
 
-                Print(L"\n--- Press any key to continue, ESC or q to quit. ---\n\n");
-                console_key_read(&key, UINT64_MAX);
-                if (key == KEYPRESS(0, SCAN_ESC, 0) || key == KEYPRESS(0, 0, 'q') || key == KEYPRESS(0, 0, 'Q'))
-                        break;
+                if (!ps_continue())
+                        return;
         }
 }
 
@@ -734,7 +743,12 @@ static BOOLEAN menu_run(
                         beep(idx_highlight + 1);
 
                 err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : UINT64_MAX);
+                if (err == EFI_NOT_READY)
+                        /* No input device returned a key, try again. This
+                         * normally should not happen. */
+                        continue;
                 if (err == EFI_TIMEOUT) {
+                        assert(timeout_remain > 0);
                         timeout_remain--;
                         if (timeout_remain == 0) {
                                 exit = TRUE;
@@ -743,8 +757,13 @@ static BOOLEAN menu_run(
 
                         /* update status */
                         continue;
-                } else
-                        timeout_remain = 0;
+                }
+                if (EFI_ERROR(err)) {
+                        exit = TRUE;
+                        break;
+                }
+
+                timeout_remain = 0;
 
                 /* clear status after keystroke */
                 if (status) {