Skip to content

Commit f1e94f5

Browse files
committed
Transient override address, component_prep_image_update.
Fixes from review. Fix memory alias for RoT Hubris 'B' image's access to transient boot override setting. `component_update_prep_image` was using `bootstate` to determine active image. The `same_image` function is a more direct test and does not depend on `bootstate` being valid.
1 parent 0f07178 commit f1e94f5

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

chips/lpc55/memory.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ execute = false
103103

104104
[[override]]
105105
name = "b"
106-
address = 0x3003ffe0
106+
address = 0x2003ffe0
107107
size = 32
108108
read = true
109109
write = true

drv/lpc55-update-server/src/main.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -498,48 +498,53 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> {
498498
UpdateState::Finished | UpdateState::NoUpdate => (),
499499
}
500500

501-
let image = match (component, slot) {
501+
self.image = match (component, slot) {
502502
(RotComponent::Hubris, SlotId::A)
503503
| (RotComponent::Hubris, SlotId::B) => {
504-
let active = match bootstate()
505-
.map_err(|_| UpdateError::MissingHandoffData)?
506-
.active
507-
{
508-
stage0_handoff::RotSlot::A => SlotId::A,
509-
stage0_handoff::RotSlot::B => SlotId::B,
510-
};
511-
if active == slot {
504+
// Fail early on attempt to update the running image.
505+
if same_image(component, slot) {
512506
return Err(UpdateError::InvalidSlotIdForOperation.into());
513507
}
508+
514509
// Rollback protection will be implemented by refusing to set
515-
// boot preference to an image that has a lower EPOC vale in the
516-
// caboose.
517-
//
510+
// boot preference to an image that has a lower EPOC value in
511+
// its caboose.
518512
// Setting the boot preference before updating would sidestep that
519513
// protection. So, we will fail the prepare step if any
520514
// preference settings are selecting the update target image.
515+
//
516+
// After the update, the boot image selection will be based on:
517+
// - there being only one properly signed image, or
518+
// - transient boot selection (highest priority), or
519+
// - pending persistent selection (altering the persistent
520+
// selection)
521+
// - persistent preference if neither of the above was used.
522+
521523
let (persistent, pending_persistent, transient) =
522524
self.boot_preferences()?;
525+
526+
// The transient preference must not select the update target.
523527
if let Some(pref) = transient {
524-
if active != pref {
528+
if slot == pref {
525529
return Err(UpdateError::InvalidPreferredSlotId.into());
526530
}
527531
}
532+
// If there is a pending persistent preference, it must
533+
// not select the update target.
528534
if let Some(pref) = pending_persistent {
529-
if active != pref {
535+
if slot == pref {
530536
return Err(UpdateError::InvalidPreferredSlotId.into());
531537
}
532-
}
533-
if active != persistent {
538+
} else if slot == persistent {
539+
// If there is no pending persistent preference, then the
540+
// persistent preference must select the currently active image.
534541
return Err(UpdateError::InvalidPreferredSlotId.into());
535542
}
536543
Some((component, slot))
537544
}
538545
(RotComponent::Stage0, SlotId::B) => Some((component, slot)),
539546
_ => return Err(UpdateError::InvalidSlotIdForOperation.into()),
540547
};
541-
542-
self.image = image;
543548
self.state = UpdateState::InProgress;
544549
ringbuf_entry!(Trace::State(self.state));
545550
self.next_block = None;

0 commit comments

Comments
 (0)