What changed, and why it matters
This commit fixes a low-level memory-safety issue in the SHA-256 code that runs on ARM 64-bit processors (aarch64). The code was asking the CPU to load four 32-bit numbers starting from a pointer that only pointed to a single 32-bit number. Rust's strict memory rules (flagged by the Miri checker) consider this undefined behavior, even though real hardware often tolerates it. The fix uses a pointer to the whole array instead, so the load is clearly valid.
Apply the patch. It is a small, clearly correct fix that removes Miri-reported undefined behavior. No immediate incident response is warranted unless additional evidence emerges that the UB was exploitable in practice.
Security signals we found
Undefined behavior flagged by Miri in unsafe Rust code
Incorrect reference-to-pointer conversion for SIMD load width
Memory-safety fix in cryptographic hash implementation
Evidence from the diff
In hashes/src/sha256/crypto/arm_sha2.rs, two vld1q_u32 NEON intrinsics were passed &INIT[0] and &INIT[4], references to individual u32 elements. vld1q_u32 performs a 128-bit load of four contiguous u32 values, so creating a reference to one u32 and then loading four is undefined behavior under Rust’s aliasing/reference rules and was reported as UB by Miri. The patch replaces those references with INIT.as_ptr() and INIT.as_ptr().add(4), which are raw pointers to the array data and correctly authorize a four-element load. This is a defensive correctness fix; there is no evidence in the commit of an exploitable security vulnerability or of miscompilation causing real-world harm.
Changed components
hashes/src/sha256/crypto/arm_sha2.rsaarch64 SHA-256 NEON implementation (sha256d_64_2way)Inspect captured patch +2 / −2
diff --git a/hashes/src/sha256/crypto/arm_sha2.rs b/hashes/src/sha256/crypto/arm_sha2.rs
index ba64ed69..3314d57d 100644
--- a/hashes/src/sha256/crypto/arm_sha2.rs
+++ b/hashes/src/sha256/crypto/arm_sha2.rs
@@ -533,10 +533,10 @@ pub(super) unsafe fn sha256d_64_2way(output: &mut [[u8; 32]; 2], input: &[[u8; 6
state1_b = vsha256h2q_u32(state1_b, tmp2_b, tmp0_b);
// Transform 1: Update state
- tmp = vld1q_u32(&INIT[0]);
+ tmp = vld1q_u32(INIT.as_ptr());
state0_a = vaddq_u32(state0_a, tmp);
state0_b = vaddq_u32(state0_b, tmp);
- tmp = vld1q_u32(&INIT[4]);
+ tmp = vld1q_u32(INIT.as_ptr().add(4));
state1_a = vaddq_u32(state1_a, tmp);
state1_b = vaddq_u32(state1_b, tmp);
Why this scored 36/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.