CVE-2026-50185 Overview
CVE-2026-50185 affects the RustCrypto cmov crate, which provides constant-time conditional move CPU intrinsics used by cryptographic implementations. The aarch64 backend incorrectly assumes that high bits are zero-extended when loading register-sized values smaller than a full register. Attackers who control high bits of a Cmov selector, or the high bits of self or other in u16 and i16CmovEq implementations, can cause left.cmovz(&right, condition) to produce incorrect output. The flaw exists from version 0.1.1 through 0.5.3 and is fixed in 0.5.4. The underlying weakness maps to [CWE-758] (reliance on undefined, unspecified, or implementation-defined behavior).
Critical Impact
Incorrect conditional selection in a primitive marketed as constant-time can undermine the integrity of higher-level cryptographic operations built on top of the cmov crate on aarch64 targets.
Affected Products
- RustCrypto cmov crate versions 0.1.1 through 0.5.3
- Downstream Rust cryptographic libraries linking cmov on aarch64
- ARM64 Linux, macOS, and other aarch64 platforms consuming the affected crate
Discovery Timeline
- 2026-07-17 - CVE-2026-50185 published to NVD
- 2026-07-23 - Last updated in NVD database
Technical Details for CVE-2026-50185
Vulnerability Analysis
The cmov crate exposes conditional move primitives that must execute in constant time so that cryptographic code paths do not leak secrets through branching. The aarch64 implementation in cmov/src/backends/aarch64.rs compares the condition register against zero using cmp {0:w}, 0. This treats the full 32-bit w view of the input register as the operand. The implementation assumes that when a smaller value such as a u8 or u16 is loaded into the register, the high bits are zero-extended by the caller. That assumption is not guaranteed by the Rust ABI.
When the caller passes a wider register value where the high bits contain arbitrary data, the comparison against zero produces a non-zero result even though the low bits represent a logical zero selector. The csel instruction then selects the wrong operand. The same issue applies to the u16 and i16CmovEq implementations, where dirty bits [16..] of self or other desynchronize the equality check from the intended semantic value.
Root Cause
The root cause is an incorrect ABI assumption in inline assembly. Rust does not guarantee that integer arguments narrower than a register are zero-extended into the destination register. The affected macro read the full register width without first masking or narrowing the compare operand, violating [CWE-758].
Attack Vector
Exploitation requires local, low-privilege access with the ability to influence inputs consumed by a caller of cmov on aarch64. A malicious or malformed input that leaves non-zero high bits in the selector or operand registers can force cmovz to return the wrong branch. The impact is limited to integrity of the returned value; there is no direct confidentiality or availability effect.
// Security patch in cmov/src/backends/aarch64.rs
/// Conditional select
macro_rules! csel {
- ($cmp:expr, $csel:expr, $dst:expr, $src:expr, $condition:expr) => {
+ ($tst:expr, $csel:expr, $dst:expr, $src:expr, $condition:expr) => {
unsafe {
asm! {
- "cmp {0:w}, 0",
+ $tst,
$csel,
in(reg) $condition,
inlateout(reg) *$dst,
Source: RustCrypto/utils commit dba6c355. The patch replaces the hard-coded cmp {0:w}, 0 with a caller-supplied test instruction ($tst) that correctly narrows the operand to the intended width before comparison.
Detection Methods for CVE-2026-50185
Indicators of Compromise
- Presence of the cmov crate at versions 0.1.1 through 0.5.3 in Cargo.lock files on aarch64 build or runtime hosts.
- Cryptographic operations producing incorrect ciphertext, signatures, or key material on aarch64 while identical code paths succeed on x86_64.
- Unit test regressions in downstream crates that exercise Cmov and CmovEq with non-canonical high bits.
Detection Strategies
- Perform Software Composition Analysis (SCA) against Rust build artifacts and inventory any transitive dependency on cmov < 0.5.4.
- Run cargo audit against project lockfiles to surface GHSA-3rjw-m598-pq24.
- Add differential test vectors comparing aarch64 and x86_64 outputs of any cryptographic routine that depends on cmov.
Monitoring Recommendations
- Track new releases of RustCrypto utility crates in dependency scanning pipelines.
- Monitor CI/CD jobs targeting aarch64-unknown-linux-gnu and aarch64-apple-darwin for test failures in cryptographic modules.
- Alert on build reproducibility mismatches between architectures for the same crate versions.
How to Mitigate CVE-2026-50185
Immediate Actions Required
- Upgrade the cmov crate to version 0.5.4 or later in all Rust projects.
- Rebuild and redeploy any aarch64 binaries that statically linked a vulnerable version.
- Audit transitive dependencies to confirm no lockfile still resolves to cmov versions 0.1.1 through 0.5.3.
Patch Information
The fix is available in cmov-v0.5.4. The patch, published in commit dba6c355, replaces the fixed cmp {0:w}, 0 instruction with a parameterized test macro that emits the correct compare or test instruction for the operand width. Full details are documented in GHSA-3rjw-m598-pq24.
Workarounds
- If upgrading is not immediately possible, restrict deployment of affected code paths to non-aarch64 targets where the backend is not used.
- Manually zero-extend inputs to Cmov selectors and CmovEq operands before invocation, ensuring high bits are cleared.
- Pin builds to reviewed crate revisions using cargo update -p cmov --precise 0.5.4.
# Update the cmov crate in a Rust workspace
cargo update -p cmov --precise 0.5.4
cargo tree -i cmov
cargo audit
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

