fix(core/rust): adjust menu item limits to prevent overflow errors
What changed, and why it matters
This commit fixes a capacity mismatch in the Trezor hardware wallet's on-screen menus. A global limit allowed up to 6 menu entries, but the internal storage for two menu layouts only held 5. When a 6-item menu was built, the code would panic (crash) instead of showing the menu. The patch raises both storage capacities to 6 and adds compile-time checks so the bug cannot silently recur if the global limit is changed again. The crash is a denial-of-service issue for the device UI, not a direct theft-of-funds vulnerability.
Treat as a low-severity hardening fix. Verify that all other layout variants using MAX_MENU_ITEMS have capacities at least as large, and consider replacing unwrap! pushes with fallible push handling so menus exceeding capacity are rejected gracefully rather than panicking.
Security signals we found
Bounded vector capacity mismatch with global menu item limit
Runtime panic (unwrap!) on menu item overflow
Compile-time const assertion added to prevent regression
UI denial-of-service via malformed/large menu construction
No evidence of memory corruption or code execution
Evidence from the diff
The change increases MAX_MENU_ITEMS from 5 to 6 and aligns the bounded Vec capacities in the Delizia and Eckhart layout vertical menus (VerticalMenuItems and ShortMenuVec) to at least 6. It also introduces const assertions (assert!(VERTICAL_MENU_ITEMS >= MAX_MENU_ITEMS) and assert!(SHORT_MENU_ITEMS >= MAX_MENU_ITEMS)) so that future increases to MAX_MENU_ITEMS trigger a compile error rather than a runtime panic. The affected push paths use unwrap! / MenuItems::push, which panic on overflow. The patch is defensive and prevents a device UI panic when a menu reaches the new 6-item limit.
Changed components
core/embed/rust/src/ui/layout_delizia/component/vertical_menu.rscore/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rscore/embed/rust/src/ui/ui_firmware.rsInspect captured patch +17 / −3
### core/embed/rust/src/ui/layout_delizia/component/vertical_menu.rs
@@ -314,7 +314,15 @@ impl crate::trace::Trace for VerticalMenu {
}
}
-pub type VerticalMenuItems = Vec<VerticalMenuItem, 6>;
+pub const VERTICAL_MENU_ITEMS: usize = 6;
+
+/// `select_menu()` builds these out of a list already bounded by
+/// `MAX_MENU_ITEMS`, pushing with `unwrap!`, which panics on overflow rather
+/// than returning an error. Keep the capacity at or above that bound so raising
+/// `MAX_MENU_ITEMS` alone cannot turn a rejected menu into a fatal error.
+const _: () = assert!(VERTICAL_MENU_ITEMS >= crate::ui::ui_firmware::MAX_MENU_ITEMS);
+
+pub type VerticalMenuItems = Vec<VerticalMenuItem, VERTICAL_MENU_ITEMS>;
pub enum VerticalMenuItem {
Item(TString<'static>),
### core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs
@@ -15,7 +15,13 @@ use crate::ui::util::animation_disabled;
/// Presently, VerticalMenu holds only fixed number of buttons.
pub const LONG_MENU_ITEMS: usize = 100;
pub const MEDIUM_MENU_ITEMS: usize = 10;
-pub const SHORT_MENU_ITEMS: usize = 5;
+pub const SHORT_MENU_ITEMS: usize = 6;
+
+/// `select_menu()` builds a `ShortMenuVec` out of a list already bounded by
+/// `MAX_MENU_ITEMS`, and `MenuItems::push` panics on overflow rather than
+/// returning an error. Keep the capacity at or above that bound so raising
+/// `MAX_MENU_ITEMS` alone cannot turn a rejected menu into a fatal error.
+const _: () = assert!(SHORT_MENU_ITEMS >= crate::ui::ui_firmware::MAX_MENU_ITEMS);
pub type LongMenuGc = GcBox<Vec<Button, LONG_MENU_ITEMS>>;
pub type ShortMenuVec = Vec<Button, SHORT_MENU_ITEMS>;
### core/embed/rust/src/ui/ui_firmware.rs
@@ -15,7 +15,7 @@ use crate::ui::notification::Notification;
pub const MAX_CHECKLIST_ITEMS: usize = 3;
pub const MAX_WORD_QUIZ_ITEMS: usize = 3;
pub const MAX_GROUP_SHARE_LINES: usize = 4;
-pub const MAX_MENU_ITEMS: usize = 5;
+pub const MAX_MENU_ITEMS: usize = 6;
pub const MAX_PAIRED_DEVICES: usize = 8; // Maximum number of paired devices in the device menu
Why this scored 42/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.