RustSec logo

History ⋅ Edit ⋅ JSON (OSV)

RUSTSEC-2026-0454

Data race and double free via unsound Send/Sync in reblessive

Reported
Issued
Package
surrealdb-core (crates.io)
Type
Vulnerability
Categories
Keywords
#data-race #double-free #send-sync
Aliases
References
CVSS Score
7.8 HIGH
CVSS Details
Attack Vector
Local
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality Impact
High
Integrity Impact
High
Availability Impact
High
CVSS Vector
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H
Patched
  • >=4.0.0

Description

dbs::Executor drives every SurrealQL statement through reblessive::tree::TreeStack. In reblessive 0.4.3 the runtime types unconditionally assert Send/Sync (unsafe impl Send/Sync for Stack, TreeStack and Runner), while the public entry points accept any future without a Send bound and store it type-erased in a bump allocator.

Two safe-code consequences follow. First, Runner::step_async/finish_async return driver futures tied to the stack borrow rather than to &mut self, so a driver future can be duplicated; because Stack is Sync those futures are Send, and polling two copies on different threads runs drive_top_task concurrently — racy Cell/UnsafeCell access, double pop_task()/pop_dealloc() (double drop / double free) and a non-atomic Option::take. Second, TreeStack: Send lets safe code move a driver whose type-erased future captures !Send state (Rc, RefCell) to another thread while the creating thread keeps an alias of that state.

No unsafe is needed at the call site. surrealdb-core's own query futures are Send only because of the unsound unsafe impl Send for TreeStack, while the captured &mut tree::Stk is deliberately !Send.

The unsound dependency was removed in 4.0.0 and the parser now uses plain recursion (commit 75407c4bcc).

Advisory available under CC0-1.0 license.