- 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
-
- Affected Functions
- Version
skiplist::ordered_skip_list::OrderedSkipList::append
-
skiplist::ordered_skip_list::OrderedSkipList::lower_bound_mut
-
skiplist::ordered_skip_list::OrderedSkipList::split_off
-
skiplist::ordered_skip_list::OrderedSkipList::split_off_index
-
skiplist::ordered_skip_list::OrderedSkipList::upper_bound_mut
-
skiplist::skip_list::SkipList::append
-
skiplist::skip_list::SkipList::iter_mut
-
skiplist::skip_list::SkipList::range_mut
-
skiplist::skip_list::SkipList::split_off
-
skiplist::skip_map::SkipMap::append
-
skiplist::skip_map::SkipMap::iter_mut
-
skiplist::skip_map::SkipMap::range_mut
-
skiplist::skip_map::SkipMap::split_off
-
skiplist::skip_map::SkipMap::values_mut
-
skiplist::skip_set::SkipSet::append
-
skiplist::skip_set::SkipSet::lower_bound_mut
-
skiplist::skip_set::SkipSet::split_off
-
skiplist::skip_set::SkipSet::split_off_index
-
skiplist::skip_set::SkipSet::upper_bound_mut
-
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.
- 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.
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.
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.
- 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.