Native fixes following the independent reviews
The three identified native issues are patched. At test time production still
ran a10323d; the deployment update below records the subsequent 92bd475
rollout and its separate build/Nitro evidence.
Implementation
- Concurrent hardware-AES VM construction now uses a per-call volatile probe. Optimized ARM disassembly still contains the AES instruction. No global constructor mutex is required.
- VM destruction explicitly clears the register file, program, configuration, memory registers, temporary hash and scratchpad. JIT code allocations are made writable, cleared in full, then unmapped. Interpreter state and explicit BLAKE2b temporaries are cleared. Compiler bookkeeping is cleared as described in the patch notes.
- Page-permission system-call failures abort before code proceeds. This preserves the existing void C API and prevents a C++ exception from crossing Rust's C ABI. The availability cost is process termination, potentially interrupting other work. It does not return a hash after a failed protection transition.
The upstream algorithm identifiers and hash outputs remain unchanged. Original upstream checksums are retained separately; the Rust build verifies 166 patched source/header entries. These are local hardening changes, so the source is no longer described as unmodified upstream.
Validation
- ARM ThreadSanitizer: seven concurrent workers, 100 VM creations each, no constructor serialization; exit 0 and no sanitizer report.
- ARM ASan/UBSan: light and full-memory modes each matched 16 secure-JIT and interpreted hashes. VM register/program/tempHash storage was zero at the destruction boundary and no longer reconstructed the final hash.
- Negative control: the same destruction-boundary test linked against the
preserved unpatched library failed with
register remanence after destructor. - Linux x86-64: light and full-memory tests each passed 16 differential hashes, confirmed both scratchpads and the entire JIT mapping were zero immediately before release, and injected five permission failures. All five produced SIGABRT rather than returning normally or returning a hash.
- Upstream native suite under ARM ASan/UBSan: 104 tests passed; three incompatible configuration tests skipped.
- Rust timelock suite: three passed and the resource-heavy full-memory vector skipped by default; that vector was run explicitly and passed separately.
- Enclave epoch admission, expiry and key-lifetime tests: three passed.
- The standalone test driver completed a fresh Linux build and both memory modes.
The test driver creates a fresh build and retains
commands and logs. The native regression uses
Linux linker wrappers only in the test executable. Local raw evidence is under
.local/native-fixes-20260910/; Linux work used the existing Hetzner solver host
in an isolated test directory. No additional AWS compute was started.
This is not a proof of erasure of arbitrary compiler/register/kernel copies, side-channel resistance, or a seven-day wall-clock lower bound. The RISC-V and Windows paths were edited consistently but were not executed in these tests. ASan/UBSan instrument C/C++ code, not dynamically emitted machine instructions. The subsequent rollout has separate build evidence, a new PCR pin and real Nitro checks. These regression tests do not establish a new full-duration calibration.
Deployment update: these native fixes are included in production source
92bd47508d7ad48442c98148f6b4e09c6169ab5e, launched non-debug on Graviton5
on 2026-09-10. Its short-work Nitro diagnostic passed authenticated Mullvad
HTTPS forwarding and exact offline record recovery. Full-duration warm-up is
pending. See deployment evidence.