- Reported
-
- Issued
-
- Package
-
skiplist
(crates.io)
- Type
-
Vulnerability
- Categories
-
- Keywords
-
#memory-safety
#use-after-free
#double-free
#panic-safety
- Aliases
-
- References
-
- Patched
-
- Affected Functions
- Version
skiplist::ordered_skip_list::OrderedSkipList::clear
-
skiplist::ordered_skip_list::OrderedSkipList::dedup_by
-
skiplist::ordered_skip_list::OrderedSkipList::retain
-
skiplist::skip_list::SkipList::clear
-
skiplist::skip_list::SkipList::dedup_by
-
skiplist::skip_list::SkipList::retain
-
skiplist::skip_list::SkipList::retain_mut
-
skiplist::skip_map::SkipMap::clear
-
skiplist::skip_map::SkipMap::retain
-
Description
SkipList::clear drops the node chain and only then resets tail and len.
The drop runs each element's Drop, and T carries no bounds excluding a
panicking one. If it unwinds, tail still points at the freed node while len
stays non-zero.
back(), back_mut(), last_key_value() and last() dereference tail
through unsafe, so reading the container after the unwind is a use-after-free
(CWE-416). Drop for SkipList calls Box::from_raw on self.head, which
clear already destroyed, so dropping the container is a double free
(CWE-415).
retain, retain_mut and dedup_by reach the same state through
Node::filter_rebuild, which frees nodes and runs a user predicate before the
caller commits tail and len. There the head links are left partially
rewired, so traversal can also reach freed nodes.
Mitigation
Update to 1.1.1.
Advisory available under CC0-1.0
license.