diff options
-rw-r--r-- | firmware/lib/vboot_ui.c | 65 | ||||
-rw-r--r-- | tests/vboot_api_kernel2_tests.c | 71 |
2 files changed, 35 insertions, 101 deletions
diff --git a/firmware/lib/vboot_ui.c b/firmware/lib/vboot_ui.c index a6688f70..700c29a1 100644 --- a/firmware/lib/vboot_ui.c +++ b/firmware/lib/vboot_ui.c @@ -27,16 +27,13 @@ #include "vboot_kernel.h" #include "vboot_ui_common.h" -/* Global variables */ -enum { - POWER_BUTTON_HELD_SINCE_BOOT = 0, - POWER_BUTTON_RELEASED, - POWER_BUTTON_PRESSED, /* must have been previously released */ -} power_button_state; - void vb2_init_ui(void) { - power_button_state = POWER_BUTTON_HELD_SINCE_BOOT; + /* + * Read and ignore the current power button state in + * case it was held down at boot. + */ + VbExIsShutdownRequested(); } static void VbAllowUsbBoot(struct vb2_context *ctx) @@ -59,22 +56,6 @@ static int VbWantShutdown(struct vb2_context *ctx, uint32_t key) struct vb2_shared_data *sd = vb2_get_sd(ctx); uint32_t shutdown_request = VbExIsShutdownRequested(); - /* - * Ignore power button push until after we have seen it released. - * This avoids shutting down immediately if the power button is still - * being held on startup. After we've recognized a valid power button - * push then don't report the event until after the button is released. - */ - if (shutdown_request & VB_SHUTDOWN_REQUEST_POWER_BUTTON) { - shutdown_request &= ~VB_SHUTDOWN_REQUEST_POWER_BUTTON; - if (power_button_state == POWER_BUTTON_RELEASED) - power_button_state = POWER_BUTTON_PRESSED; - } else { - if (power_button_state == POWER_BUTTON_PRESSED) - shutdown_request |= VB_SHUTDOWN_REQUEST_POWER_BUTTON; - power_button_state = POWER_BUTTON_RELEASED; - } - if (key == VB_BUTTON_POWER_SHORT_PRESS) shutdown_request |= VB_SHUTDOWN_REQUEST_POWER_BUTTON; @@ -114,8 +95,6 @@ int VbUserConfirms(struct vb2_context *ctx, uint32_t confirm_flags) VbSharedDataHeader *shared = sd->vbsd; uint32_t key; uint32_t key_flags; - uint32_t btn; - int phys_presence_button_was_pressed = 0; int shutdown_requested = 0; VB2_DEBUG("Entering(%x)\n", confirm_flags); @@ -123,7 +102,14 @@ int VbUserConfirms(struct vb2_context *ctx, uint32_t confirm_flags) /* Await further instructions */ do { key = VbExKeyboardReadWithFlags(&key_flags); - shutdown_requested = VbWantShutdown(ctx, key); + + /* Do not use untrusted keyboard input */ + if (confirm_flags & VB_CONFIRM_MUST_TRUST_KEYBOARD && + !(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)) + shutdown_requested = VbWantShutdown(ctx, 0); + else + shutdown_requested = VbWantShutdown(ctx, key); + switch (key) { case VB_KEY_ENTER: /* If we require a trusted keyboard for confirmation, @@ -154,21 +140,17 @@ int VbUserConfirms(struct vb2_context *ctx, uint32_t confirm_flags) break; default: /* If the physical presence button is physical, and is - * pressed, this is also a YES, but must wait for - * release. + * pressed, this is also a YES. + * + * HACK for sarien: do not wait for release + * https://issuetracker.google.com/129471321 */ - btn = VbExGetSwitches( - VB_SWITCH_FLAG_PHYS_PRESENCE_PRESSED); - if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL)) { - if (btn) { - VB2_DEBUG("Presence button pressed, " - "awaiting release\n"); - phys_presence_button_was_pressed = 1; - } else if (phys_presence_button_was_pressed) { - VB2_DEBUG("Presence button released " - "(1)\n"); - return 1; - } + if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL) && + (confirm_flags & VB_CONFIRM_MUST_TRUST_KEYBOARD) && + (shutdown_requested & + VB_SHUTDOWN_REQUEST_POWER_BUTTON)) { + VB2_DEBUG("Presence button pressed (1)\n"); + return 1; } VbCheckDisplayKey(ctx, key, NULL); } @@ -969,6 +951,7 @@ static VbError_t recovery_ui(struct vb2_context *ctx) VbError_t VbBootRecovery(struct vb2_context *ctx) { + vb2_init_ui(); VbError_t retval = recovery_ui(ctx); VbDisplayScreen(ctx, VB_SCREEN_BLANK, 0, NULL); return retval; diff --git a/tests/vboot_api_kernel2_tests.c b/tests/vboot_api_kernel2_tests.c index cb2471f4..8cf12916 100644 --- a/tests/vboot_api_kernel2_tests.c +++ b/tests/vboot_api_kernel2_tests.c @@ -131,7 +131,9 @@ uint32_t VbExIsShutdownRequested(void) uint32_t result = 0; if (mock_gpio_count >= ARRAY_SIZE(mock_gpio)) return 0; - if (mock_gpio[mock_gpio_count].gpio_flags & GPIO_SHUTDOWN) + /* Tread power button as presence */ + if (mock_gpio[mock_gpio_count].gpio_flags & + (GPIO_SHUTDOWN | GPIO_PRESENCE)) result |= VB_SHUTDOWN_REQUEST_POWER_BUTTON; if (mock_gpio[mock_gpio_count].gpio_flags & GPIO_LID_CLOSED) result |= VB_SHUTDOWN_REQUEST_LID_CLOSED; @@ -376,42 +378,26 @@ static void VbUserConfirmsTest(void) * B means both shutdown and presence gpio * * 1: ______ppp______ -> confirm - * 2: ______sss______ -> shutdown * 3: ___pppsss______ -> confirm - * 4: ___sssppp______ -> shutdown * 5: ___pppBBB______ -> confirm - * 6: ___pppBBBppp___ -> shutdown * 7: ___pppBBBsss___ -> confirm * 8: ___sssBBB______ -> confirm - * 9: ___sssBBBppp___ -> shutdown * 10: ___sssBBBsss___ -> confirm * 11: ______BBB______ -> confirm * 12: ______BBBsss___ -> confirm - * 13: ______BBBppp___ -> shutdown */ /* 1: presence means confirm */ VbUserConfirmsTestGpio(GPIO_PRESENCE, 0, 0, 1, "presence"); - /* 2: shutdown means shutdown */ - VbUserConfirmsTestGpio(GPIO_SHUTDOWN, 0, 0, 0, "shutdown"); - /* 3: presence then shutdown means confirm */ VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_SHUTDOWN, 0, 1, "presence then shutdown"); - /* 4: shutdown then presence means shutdown */ - VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE, 0, 0, - "shutdown then presence"); - /* 5: presence then shutdown+presence then none mean confirm */ VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN, 0, 1, "presence, both, none"); - /* 6: presence then shutdown+presence then presence means shutdown */ - VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN, - GPIO_PRESENCE, 0, "presence, both, presence"); - /* 7: presence then shutdown+presence then shutdown means confirm */ VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_SHUTDOWN, 1, "presence, both, shutdown"); @@ -420,10 +406,6 @@ static void VbUserConfirmsTest(void) VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN, 0, 1, "shutdown, both, none"); - /* 9: shutdown then shutdown+presence then presence means shutdown */ - VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN, - GPIO_PRESENCE, 0, "shutdown, both, presence"); - /* 10: shutdown then shutdown+presence then shutdown means confirm */ VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_SHUTDOWN, 1, "shutdown, both, shutdown"); @@ -436,10 +418,6 @@ static void VbUserConfirmsTest(void) VbUserConfirmsTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_SHUTDOWN, 0, 1, "both, shutdown"); - /* 13: shutdown+presence then presence means shutdown */ - VbUserConfirmsTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN, - GPIO_PRESENCE, 0, 0, "both, presence"); - ResetMocks(); mock_keypress[0] = VB_KEY_ENTER; mock_keypress[1] = 'y'; @@ -450,7 +428,7 @@ static void VbUserConfirmsTest(void) TEST_EQ(VbUserConfirms(&ctx, VB_CONFIRM_SPACE_MEANS_NO | VB_CONFIRM_MUST_TRUST_KEYBOARD), - 0, "Recovery button stuck"); + -1, "Recovery button stuck (shutdown)"); printf("...done.\n"); } @@ -1068,14 +1046,14 @@ static void VbBootRecTest(void) VBERROR_SHUTDOWN_REQUESTED, "Shutdown requested by keyboard"); - /* Ignore power button held on boot */ + /* Ignore first read of power button held on boot */ ResetMocks(); mock_gpio[0].gpio_flags = GPIO_SHUTDOWN; - mock_gpio[0].count = 10; + mock_gpio[0].count = 0; mock_gpio[1].gpio_flags = 0; - mock_gpio[1].count = 10; + mock_gpio[1].count = 0; mock_gpio[2].gpio_flags = GPIO_SHUTDOWN; - mock_gpio[2].count = 10; + mock_gpio[2].count = 0; mock_gpio[3].gpio_flags = 0; mock_gpio[3].count = 100; shared->flags = VBSD_BOOT_REC_SWITCH_ON; @@ -1083,11 +1061,11 @@ static void VbBootRecTest(void) vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE; TEST_EQ(VbBootRecovery(&ctx), VBERROR_SHUTDOWN_REQUESTED, - "Ignore power button held on boot"); + "Ignore first power button press on boot"); TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT, " insert screen"); - /* Shutdown should happen while we're sending the 2nd block of events */ - TEST_EQ(mock_gpio_count, 3, " ignore held button"); + /* The second power button read (in first block) will shutdown */ + TEST_EQ(mock_gpio_count, 3, " ignore first power button press"); /* Broken screen */ ResetMocks(); @@ -1259,45 +1237,27 @@ static void VbBootRecTest(void) * B means both shutdown and presence gpio * * 1: ______ppp______ -> confirm - * 2: ______sss______ -> shutdown * 3: ___pppsss______ -> confirm - * 4: ___sssppp______ -> shutdown * 5: ___pppBBB______ -> confirm - * 6: ___pppBBBppp___ -> shutdown * 7: ___pppBBBsss___ -> confirm * 8: ___sssBBB______ -> confirm - * 9: ___sssBBBppp___ -> shutdown * 10: ___sssBBBsss___ -> confirm * 11: ______BBB______ -> confirm * 12: ______BBBsss___ -> confirm - * 13: ______BBBppp___ -> shutdown */ /* 1: Ctrl+D then presence means enable */ VbBootRecTestGpio(GPIO_PRESENCE, 0, 0, 1, "Ctrl+D todev confirm via presence"); - /* 2: Ctrl+D then shutdown means shutdown */ - VbBootRecTestGpio(GPIO_SHUTDOWN, 0, 0, 0, - "Ctrl+D todev then shutdown"); - /* 3: Ctrl+D then presence then shutdown means confirm */ VbBootRecTestGpio(GPIO_PRESENCE, GPIO_SHUTDOWN, 0, 1, "Ctrl+D todev confirm via presence then shutdown"); - /* 4: Ctrl+D then 2+ instance shutdown then presence means shutdown */ - VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE, 0, 0, - "Ctrl+D todev then 2+ shutdown then presence"); - /* 5: Ctrl+D then presence then shutdown+presence then none */ VbBootRecTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN, 0, 1, "Ctrl+D todev confirm via presence, both, none"); - /* 6: Ctrl+D then presence then shutdown+presence then presence */ - VbBootRecTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN, - GPIO_PRESENCE, 0, - "Ctrl+D todev confirm via presence, both, presence"); - /* 7: Ctrl+D then presence then shutdown+presence then shutdown */ VbBootRecTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_SHUTDOWN, 1, @@ -1307,11 +1267,6 @@ static void VbBootRecTest(void) VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN, 0, 1, "Ctrl+D todev then 2+ shutdown, both, none"); - /* 9: Ctrl+D then shutdown then shutdown+presence then presence */ - VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN, - GPIO_PRESENCE, 0, - "Ctrl+D todev then 2+ shutdown, both, presence"); - /* 10: Ctrl+D then shutdown then shutdown+presence then shutdown */ VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_SHUTDOWN, 1, @@ -1325,10 +1280,6 @@ static void VbBootRecTest(void) VbBootRecTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_SHUTDOWN, 0, 1, "Ctrl+D todev confirm via both then shutdown"); - /* 13: Ctrl+D then shutdown+presence then presence */ - VbBootRecTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_PRESENCE, 0, 0, - "Ctrl+D todev confirm via both then presence"); - /* Handle TPM error in enabling dev mode */ ResetMocks(); shared->flags = VBSD_BOOT_REC_SWITCH_ON; |