{"id":"RUSTSEC-2026-0220","aliases":[],"status":"published","title":"Uint shift operations: incorrect overflow flags and truncated shift amounts","description":"`Uint::overflowing_shl`/`overflowing_shr` returned false-negative overflow\nflags. `overflowing_shl` missed bits shifted above `BITS` but within the top\nlimb (non-limb-aligned widths such as `U160`), and limbs wholly discarded by\nshifts \u003e= 64; `overflowing_shr` missed wholly discarded low limbs. Shifted\nvalues were correct; only the flag was wrong.\n\nThe wrong flag propagates: `checked_shl`/`checked_shr` return `Some` instead\nof `None`, `strict_*` fail to panic, and `saturating_*` return a wrapped\nvalue instead of saturating. The incorrect `checked_shl` result causes\n`to_base_be` (and string formatting) to loop forever on no-alloc builds for\nnon-limb-aligned widths — a denial of service if formatting is reachable\nfrom untrusted input.\n\nSeparately, `wrapping_shl`/`wrapping_shr` on 64/128/256-bit types truncated\nthe shift amount modulo 2^32, so shifts \u003e= 2^32 returned an incorrectly\nwrapped value instead of zero; on 32-bit targets the generic path also\ntruncated 64-bit shift amounts.\n\nCallers using checked or saturating shift semantics on untrusted shift\namounts may compute incorrect results.","facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"published":"2026-07-08T12:00:00Z","modified":"2026-07-30T19:15:04Z","fixes":[{"ecosystem":"crates.io","package":"ruint","fixed_in":["1.20.0"],"sources":["osv"]}],"affected":[{"source":"osv","ecosystem":"crates.io","package":"ruint","ranges":[{"type":"SEMVER","events":[{"introduced":"0.0.0-0"},{"fixed":"1.20.0"}]}]}],"references":[{"url":"https://crates.io/crates/ruint","tags":["package"]},{"url":"https://rustsec.org/advisories/RUSTSEC-2026-0220.html","tags":["advisory"]},{"url":"https://github.com/alloy-rs/ruint/pull/603","tags":["web"]}],"sources":{"osv":[{"id":"RUSTSEC-2026-0220","title":"Uint shift operations: incorrect overflow flags and truncated shift amounts","description":"`Uint::overflowing_shl`/`overflowing_shr` returned false-negative overflow\nflags. `overflowing_shl` missed bits shifted above `BITS` but within the top\nlimb (non-limb-aligned widths such as `U160`), and limbs wholly discarded by\nshifts \u003e= 64; `overflowing_shr` missed wholly discarded low limbs. Shifted\nvalues were correct; only the flag was wrong.\n\nThe wrong flag propagates: `checked_shl`/`checked_shr` return `Some` instead\nof `None`, `strict_*` fail to panic, and `saturating_*` return a wrapped\nvalue instead of saturating. The incorrect `checked_shl` result causes\n`to_base_be` (and string formatting) to loop forever on no-alloc builds for\nnon-limb-aligned widths — a denial of service if formatting is reachable\nfrom untrusted input.\n\nSeparately, `wrapping_shl`/`wrapping_shr` on 64/128/256-bit types truncated\nthe shift amount modulo 2^32, so shifts \u003e= 2^32 returned an incorrectly\nwrapped value instead of zero; on 32-bit targets the generic path also\ntruncated 64-bit shift amounts.\n\nCallers using checked or saturating shift semantics on untrusted shift\namounts may compute incorrect results.","status":"published","published":"2026-07-08T12:00:00Z","modified":"2026-07-30T19:15:04.02591801Z","updated_at":"2026-11-02T15:53:40.430679Z"}]}}
