LruCache::pop() in lru was not panic-safe. If the Drop implementation of a stored key panics during pop(), self.detach() is never called, leaving dangling pointers in the internal doubly-linked list.
A subsequent cache operation that triggers eviction can then dereference these dangling pointers:
- The node is freed from the map, but remains linked in the LRU list due to the skipped detach() call
- When a new insertion causes eviction, the LRU traversal encounters the dangling pointer
- This results in a write to already-freed memory during the eviction process
Both types of undefined behavior can be invoked in safe Rust, but only if unwinding panics are enabled and std::panic::catch_unwind is used with key types that have potentially-panicking Drop implementations.
Fixed in lru 0.18.2 by detaching the node from the linked list before freeing it and dropping the key (lru-rs#238).
{
"license": "CC0-1.0"
}