RustSec logo

HistoryEditJSON (OSV)

RUSTSEC-2026-0220

Uint shift operations: incorrect overflow flags and truncated shift amounts

Reported
Issued
Package
ruint (crates.io)
Type
Vulnerability
Categories
Keywords
#shift #overflow #arithmetic #infinite-loop
References
Patched
  • >=1.20.0
Affected Functions
Version
ruint::Uint::checked_shl
  • <1.20.0
ruint::Uint::checked_shr
  • <1.20.0
ruint::Uint::overflowing_shl
  • <1.20.0
ruint::Uint::overflowing_shr
  • <1.20.0
ruint::Uint::saturating_shl
  • <1.20.0
ruint::Uint::saturating_shr
  • <1.20.0
ruint::Uint::wrapping_shl
  • <1.20.0
ruint::Uint::wrapping_shr
  • <1.20.0

Description

Uint::overflowing_shl/overflowing_shr returned false-negative overflow flags. overflowing_shl missed bits shifted above BITS but within the top limb (non-limb-aligned widths such as U160), and limbs wholly discarded by shifts >= 64; overflowing_shr missed wholly discarded low limbs. Shifted values were correct; only the flag was wrong.

The wrong flag propagates: checked_shl/checked_shr return Some instead of None, strict_* fail to panic, and saturating_* return a wrapped value instead of saturating. The incorrect checked_shl result causes to_base_be (and string formatting) to loop forever on no-alloc builds for non-limb-aligned widths — a denial of service if formatting is reachable from untrusted input.

Separately, wrapping_shl/wrapping_shr on 64/128/256-bit types truncated the shift amount modulo 2^32, so shifts >= 2^32 returned an incorrectly wrapped value instead of zero; on 32-bit targets the generic path also truncated 64-bit shift amounts.

Callers using checked or saturating shift semantics on untrusted shift amounts may compute incorrect results.

Advisory available under CC0-1.0 license.