diff options
| author | Luke Hoersten <[email protected]> | 2026-07-28 17:18:43 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-07-28 17:18:43 -0500 |
| commit | 28a660e8bacac84523601f67547b2671058d9b20 (patch) | |
| tree | 10dd1c7f4c9cde9e9a06d028cea33e145e95a542 /src/state.rs | |
| parent | 07d4713f554b2ae2ccf4871f6be0590c129342b0 (diff) | |
Harden against untrusted input and reduce controller boilerplate
Security:
- Epoch conversions no longer panic on out-of-range values: a device may
report any u64 as its clock, so to_timestamp is fallible (rendered
labeled-raw), from_timestamp clamps a pre-epoch host clock to zero (a
Pi with no RTC reads 1970 early after boot), and delta arithmetic
saturates. Fixes crashes in inspect and status
- Identity Debug redacts the root CA private key so no stray {:?} leaks it
- fsync the temp file before rename, so a power loss cannot surface an
empty identity.json
- Document in the README that device attestation is not verified, the NTP
servers contacted, and the at-rest key
Cleanup:
- A MatterCtx extension trait replaces the repeated map_err/anyhow closure
at every rs-matter call site with .ctx("what")
- SyncOutcome::failed/skipped constructors collapse two large literals
- read_our_fabric_entry shares the fabric-filtered read across the label,
decommission, and inspect paths
36 unit tests, clippy clean.
Diffstat (limited to 'src/state.rs')
| -rw-r--r-- | src/state.rs | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/state.rs b/src/state.rs index 887ac21..8f30e2c 100644 --- a/src/state.rs +++ b/src/state.rs @@ -94,7 +94,12 @@ pub(crate) fn write_private(path: &Path, bytes: &[u8]) -> io::Result<()> { .mode(0o600) .open(path)?; file.write_all(bytes)?; - file.write_all(b"\n") + file.write_all(b"\n")?; + // Flush to disk before the caller renames over the real file: the + // atomicity claim is only true if the temp file's bytes are durable, + // otherwise a power loss can surface the rename with empty content and + // orphan the root CA key. A one-shot CLI does not care about the cost. + file.sync_all() } #[cfg(not(unix))] |
