From 11736ccabbcc74cfb295faa87fc9813c5a463244 Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Sat, 26 Sep 2026 20:09:51 -0700 Subject: [PATCH] fix(menu): don't panic on very large timeouts The basic menu set a single timer for the whole timeout, and converting a timeout of more than about 1.8e12 seconds into 100ns timer units panics. The timeout can come from --menu-timeout or from LoaderConfigTimeout, which persists, so the panic would repeat on every boot. Limit a single timer to u32::MAX seconds. --- crates/boot/src/menu.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/boot/src/menu.rs b/crates/boot/src/menu.rs index e6ad5a8..abd8b84 100644 --- a/crates/boot/src/menu.rs +++ b/crates/boot/src/menu.rs @@ -19,6 +19,10 @@ pub mod basic; /// simple: A full-screen menu that selects entries with the arrow keys. pub mod simple; +/// The longest duration a single timer is set for. This is well within the range of +/// the 100ns units that timers are set in, and still over a century long. +const MAX_TIMER_DURATION: Duration = Duration::from_secs(u32::MAX as u64); + /// A boot menu that can be shown to select an entry to boot. pub trait BootMenu { /// Select an entry from `entries` to boot. If no entry is chosen before `timeout` passes, @@ -49,7 +53,9 @@ pub fn wait_for_key(input: &mut Input, timeout: Duration) -> Result { }; // Set a timer to trigger after the specified duration. - let trigger = TimerTrigger::Relative(timeout); + // The timer is limited to what the firmware can represent, as a longer timeout + // can't be converted into a timer trigger. + let trigger = TimerTrigger::Relative(timeout.min(MAX_TIMER_DURATION)); uefi::boot::set_timer(&timer_event, trigger).context("unable to set timeout timer")?; let events = vec![timer_event, key_event];