MCUboot Shared Boot Data: Detect Partial Records and Failed Retries
Require a complete expected field set and a successful producer result before treating shared boot information as a complete report. A valid-looking prefix can survive a later append failure. In MCUboot v2.2.0’s default in-memory writer, blindly repeating the whole report can then encounter a duplicate entry rather than fill the missing fields.
This guide examines boot_save_shared_data() with the default boot_add_data_to_shared_area() implementation. It excludes custom writers, the Zephyr retention-backed replacement and measured-boot attestation. The proposed fixtures are unexecuted; no target memory, boot configuration or production records were changed.
1. Identify the producer and storage implementation
Pin the loader binary, relevant data-sharing configuration, selected writer implementation and consumer. A matching function name is not sufficient: the Zephyr replacement uses retention operations, so its write-failure and persistence behavior needs separate review.
The public header defines nonzero failure results and distinct shared-memory status values. Keep the raw result instead of translating every failure into “no boot information.” Partial information and no information require different diagnoses.
For the worked default implementation, record the shared-area capacity and lifetime. Do not assume that ordinary RAM survives a reset or that another component cannot modify it. Those are platform properties requiring evidence beyond this source review.

2. Model the sequence as multiple appends
The tagged implementation writes mode, signature type and recovery information, then configured slot, version and size entries. It stops after an error and sets saved_bootinfo only after the selected writes all succeed.
The default writer rejects an existing major/minor pair and checks capacity before appending. Successful earlier entries are not rolled back when a later entry fails. Retrying the report starts at mode again; if that entry already exists, duplicate rejection can stop the retry.
That is a source-derived behavior of this sequence, not a claim that its API offers transactions or resumable report completion. A caller must not infer either property from a zero result on an earlier individual append.
3. Define completeness for the exact configuration
Create an expected-entry inventory from the resolved build. Separate unconditional fields from configuration-dependent fields and per-image fields whose generation has prerequisites. An optional field absent by design is different from a required field lost after an error.
| Consumer observation | Classification | Allowed interpretation |
|---|---|---|
| Well-formed expected set and successful producer result | Complete for this contract | Use the reported fields within their documented meanings |
| Well-formed prefix, required later entries absent | Incomplete | Preserve available observations; do not invent the rest |
| Optional entry absent under known configuration | Not provided by design | Record applicability instead of failure |
| Malformed lengths or unknown format | Unusable or unsupported | Reject unsafe parsing; preserve a bounded diagnostic |
| Complete-looking bytes, producer status unavailable | Completeness evidence limited | Do not silently equate appearance with confirmed publication |
Never replace a missing signature-type field with a numeric default and report that default as observed policy. A missing value must retain an explicit availability state, including why it is absent when known.
4. Qualify failure and retry separately
Use a controlled memory-writer harness with synthetic field values. Choose capacities relative to the actual entry sizes so one fixture fits the first entry but cannot fit a later one. Preserve the area before and after each operation for comparison.
| Proposed fixture | Expected scoped observation |
|---|---|
| Sufficient capacity for the complete configured report | All selected entries present; report succeeds |
| Capacity permits mode but rejects a later entry | Earlier mode remains; report fails and later fields are absent |
| Repeat that incomplete report in the same writer lifetime | Existing mode can cause overwrite status before completion |
| Repeat after complete successful report | Saved-report guard returns success without rewriting the report |
| Use a fresh, correctly initialized writer lifetime | Evaluate independently; do not assume stale private state resets itself |
These are proposed checks, not executed results. A test harness must reset both the modeled storage and relevant producer state consistently between independent cases. Clearing bytes alone while leaving internal initialization flags set does not reproduce a fresh boot.
5. Decide what a retry is allowed to mean
If a product requires report recovery, specify whether it uses a new generation, an independently staged complete snapshot or another reviewed publication protocol. Do not patch a duplicate error into success without establishing which fields now belong to the report.
Any integration change needs its own lifetime, ownership and failure analysis. The simplest honest consumer may retain the partial report with an incomplete status and request better evidence later. Whether boot itself may continue is a separate product policy.
The loader wrapper logs and returns shared-data failures. Trace its actual callers and downstream configuration before stating a final device behavior. This article does not claim every error universally stops or permits boot.
Hypothetical misleading support display
A fictional collector receives mode information but no signature-type field after capacity exhaustion. Its display substitutes zero and labels the device “unsigned.” The producer did not report that conclusion; the consumer manufactured it from absence.
A corrected display shows the observed mode, marks the report incomplete and leaves signature policy unavailable. Repeating the original producer call is not assumed to repair the record because its first append can now be a duplicate.
6. Keep report integrity separate from trust proof
A complete shared report is still not remote attestation, proof of protected memory or confirmation that all current bytes were freshly authenticated. Record who produced it, which boot it belongs to and which component could modify it.
Close the qualification with the exact field inventory, writer identity, capacity cases, raw results, retry observations and consumer availability states. This yields useful boot evidence without upgrading partial data into a complete policy claim.