---
id: RUSTSEC-2026-0408
aliases:
  - GHSA-924w-mwc9-86m8
title: 'Aliasing violations in splice, mutable iteration and cursors'
summary: 'Aliasing violations in splice, mutable iteration and cursors'
severity: none
vendor: skiplist
product: skiplist
ecosystem: rust
affected:
  - 'skiplist >= 0.0.0-0, < 1.3.0'
patched:
  - skiplist 1.3.0
published: '2026-10-24'
updated: '2026-10-26'
sourceUpdated: '2026-10-26T14:00:05.788796703Z'
source: OSV
sourceUrl: 'https://osv.dev/vulnerability/RUSTSEC-2026-0408'
references:
  - url: 'https://crates.io/crates/skiplist'
  - url: 'https://rustsec.org/advisories/RUSTSEC-2026-0408.html'
  - url: 'https://github.com/JP-Ellis/rust-skiplist/pull/407'
tags:
  - osv
  - rust
ingestedAt: '2026-10-27T16:20:12.119Z'
---

## Overview

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.

## Affected packages

- `skiplist >= 0.0.0-0, < 1.3.0`

## Remediation

Upgrade to a patched release:

- `skiplist 1.3.0`
