fix(core/caesar): remove count limit in confirm_properties
What changed, and why it matters
This commit fixes a bug in the Trezor hardware wallet's Caesar UI layout where long lists of key-value properties (for example, transaction details shown on the device screen) could either crash debug builds or be silently cut off in production builds. The fix replaces a fixed-size container with a lazy, unbounded one, so all properties are rendered and none are dropped. There is no direct evidence in the commit that this was exploited or treated as a security vulnerability by the vendor.
Treat as a routine robustness fix. Users should update to a firmware build containing this commit if they rely on the Caesar layout and review screens with many properties. No immediate incident response is indicated by the supplied materials.
Security signals we found
Silent truncation of user-visible confirmation data in production builds
Panic/crash in debug builds on oversized property lists
UI consistency fix aligning Caesar layout with other layouts
No changelog entry marked by [no changelog]
Evidence from the diff
The confirm_properties function in the Caesar layout previously parsed all key-value properties into a ParagraphVecLong with a hard capacity of 36 paragraphs (18 key-value pairs). When more items were supplied, debug builds panicked and production builds silently truncated the list. The patch removes the eager parse_properties helper and instead uses the existing lazy PropsList paragraph source, which other layouts already use. PROP_INNER_SPACING is reduced to 2 px to match the spacing previously hardcoded in add_paragraphs, preserving visual output. The change is purely a robustness/rendering fix; no cryptographic or authorization logic is modified.
Changed components
core/embed/rust/src/ui/layout_caesar/ui_firmware.rscore/embed/rust/src/ui/layout_caesar/theme/mod.rsTrezor firmware Caesar UI layoutconfirm_properties screenInspect captured patch +5 / −19
diff --git a/core/embed/rust/src/ui/layout_caesar/theme/mod.rs b/core/embed/rust/src/ui/layout_caesar/theme/mod.rs
index bf72d1ae..ce0e45b2 100644
--- a/core/embed/rust/src/ui/layout_caesar/theme/mod.rs
+++ b/core/embed/rust/src/ui/layout_caesar/theme/mod.rs
@@ -97,7 +97,9 @@ include_icon!(ICON_WARNING, "layout_caesar/res/warning.toif"); // 11*12
include_icon!(ICON_WARN_TITLE, "layout_caesar/res/bld_header_warn.toif");
// props settings
-pub const PROP_INNER_SPACING: i16 = PARAGRAPH_BOTTOM_SPACE;
+// Smaller than the default paragraph spacing so that 4 lines
+// (2 key:value pairs) fit on the same screen
+pub const PROP_INNER_SPACING: i16 = 2;
pub const PROPS_SPACING: i16 = PARAGRAPH_BOTTOM_SPACE;
pub const PROPS_KEY_FONT: TextStyle = TEXT_BOLD;
pub const PROPS_VALUE_FONT: TextStyle = TEXT_MONO;
diff --git a/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs b/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs
index cf296ca4..bd6e5af2 100644
--- a/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs
+++ b/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs
@@ -22,7 +22,7 @@ use crate::{
geometry,
layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
- util::{ConfirmValueParams, RecoveryType},
+ util::{ConfirmValueParams, PropsList, RecoveryType},
},
notification::Notification,
ui_firmware::{
@@ -439,7 +439,7 @@ impl FirmwareUI for UICaesar {
verb: Option<TString<'static>>,
external_menu: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
- let paragraphs = parse_properties(items)?;
+ let paragraphs = PropsList::new(items)?;
let button_text = verb.unwrap_or(if hold {
TR::buttons__hold_to_confirm.into()
@@ -1567,19 +1567,3 @@ fn add_paragraphs<'a>(
paragraphs.add(Paragraph::new(style, value));
}
}
-
-fn parse_properties(items: Obj) -> Result<ParagraphVecLong<'static>, Error> {
- let mut paragraphs = ParagraphVecLong::new();
-
- for para in IterBuf::new().try_iterate(items)? {
- let [key, value, is_data]: [Obj; 3] = util::iter_into_array(para)?;
- add_paragraphs(
- &mut paragraphs,
- key.try_into_option()?,
- value.try_into_option()?,
- is_data.try_into()?,
- );
- }
-
- Ok(paragraphs)
-}
Why this scored 51/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.