RustSec logo

History ⋅ Edit ⋅ JSON (OSV)

RUSTSEC-2026-0408

Aliasing violations in splice, mutable iteration and cursors

Reported
Issued
Package
skiplist (crates.io)
Type
INFO Unsound
Categories
Keywords
#aliasing #stacked-borrows #tree-borrows #miri
Aliases
References
CVSS Score
2.1 LOW
CVSS Details
Attack Complexity
Low
Attack Requirements
Present
Attack Vector
Local
Privileges Required
None
Availability Impact to the Subsequent System
None
Confidentiality Impact to the Subsequent System
None
Integrity Impact to the Subsequent System
None
User Interaction
None
Availability Impact to the Vulnerable System
Low
Confidentiality Impact to the Vulnerable System
Low
Integrity Impact to the Vulnerable System
Low
CVSS Vector
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
Patched
  • >=1.3.0
Affected Functions
Version
skiplist::ordered_skip_list::OrderedSkipList::append
  • <1.3.0
skiplist::ordered_skip_list::OrderedSkipList::lower_bound_mut
  • >=1.2.0, <1.3.0
skiplist::ordered_skip_list::OrderedSkipList::split_off
  • <1.3.0
skiplist::ordered_skip_list::OrderedSkipList::split_off_index
  • <1.3.0
skiplist::ordered_skip_list::OrderedSkipList::upper_bound_mut
  • >=1.2.0, <1.3.0
skiplist::skip_list::SkipList::append
  • <1.3.0
skiplist::skip_list::SkipList::iter_mut
  • <1.3.0
skiplist::skip_list::SkipList::range_mut
  • <1.3.0
skiplist::skip_list::SkipList::split_off
  • <1.3.0
skiplist::skip_map::SkipMap::append
  • <1.3.0
skiplist::skip_map::SkipMap::iter_mut
  • <1.3.0
skiplist::skip_map::SkipMap::range_mut
  • <1.3.0
skiplist::skip_map::SkipMap::split_off
  • <1.3.0
skiplist::skip_map::SkipMap::values_mut
  • <1.3.0
skiplist::skip_set::SkipSet::append
  • <1.3.0
skiplist::skip_set::SkipSet::lower_bound_mut
  • >=1.2.0, <1.3.0
skiplist::skip_set::SkipSet::split_off
  • <1.3.0
skiplist::skip_set::SkipSet::split_off_index
  • <1.3.0
skiplist::skip_set::SkipSet::upper_bound_mut
  • >=1.2.0, <1.3.0

Description

Four code paths create a pointer whose permission is later revoked, then write through it. Miri reports each as undefined behaviour under both the Tree Borrows and Stacked Borrows aliasing models (CWE-758). All four are reachable from safe code with standard Ord types.

  1. Splice back-pointer. split_off, split_off_index and append stored the first spliced node's prev pointer from a reference to the head, then wrote through that same reference, invalidating the stored pointer. A later pop_first or pop_front writes through it. This affects all four collections.
  2. SkipMap::range_mut back pointer. With an Included or Excluded upper bound, the back pointer came from a shared reference. next_back hands out &mut V through it, and writing to that value is undefined behaviour.
  3. IterMut::next_back reads a yielded node. In SkipList and SkipMap, next_back read the predecessor node even after the front end had yielded it as &mut. The read freezes the caller's reference, and the caller's next write through it is undefined behaviour. This affects iter_mut, values_mut and range_mut used from both ends.
  4. Cursor list pointer. lower_bound_mut and upper_bound_mut on OrderedSkipList and SkipSet (cursor feature) took the cursor's list pointer, then searched through &self. A comparator with interior-mutable state, such as a Cell call counter, wrote to the list's memory through that shared borrow and invalidated the cursor's pointer. The comparator can be a fully consistent order. SkipMap cursors are not affected.

No miscompilation has been observed in an optimised build. A future compiler may still optimise on the violated aliasing assumptions.

The flaws were corrected in 1.3.0. Each fix derives the pointer used for mutation from the collection's long-lived allocation pointers, and each has a Miri regression test.

Advisory available under CC0-1.0 license.