RustSec logo

History ⋅ Edit ⋅ JSON (OSV)

RUSTSEC-2026-0452

Out-of-bounds read when decoding internal keys shorter than 16 bytes

Reported
Issued
Package
surrealkv (crates.io)
Type
Vulnerability
Categories
Keywords
#out-of-bounds-read #sstable #undefined-behavior
Aliases
References
CVSS Score
7.9 HIGH
CVSS Details
Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality Impact
High
Integrity Impact
None
Availability Impact
Low
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:L
Patched
  • >=1.2.0

Description

InternalKeyRef::from_encoded is a safe constructor whose only length check is debug_assert!(encoded.len() >= 16), which is compiled out in release builds. Its accessors perform unchecked length arithmetic on the slice: user_key() slices &encoded[..len - 16], trailer()/seq_num() pass len - 16 and timestamp() passes len - 8 to read_u64_be, which computes buffer.as_ptr().add(offset) and performs an 8-byte load. For a short slice the subtraction underflows usize, the pointer wraps below the allocation and eight bytes before the buffer are read (undefined behavior; confirmed with AddressSanitizer as a heap-buffer-overflow). In debug builds the same call panics instead.

The same invariant is missing at the on-disk decode boundary: BlockIterator::seek_next_entry rebuilds the current key from block bytes with upper-bound checks only, and BlockIterator::key() wraps it in InternalKeyRef, which surrealdb's kv-surrealkv backend then reads through key_ref.timestamp(). A crafted or corrupted SSTable therefore reaches the same unchecked subtraction without any unsafe at the call site.

1.2.0 rejects internal keys shorter than their 8-byte trailer before any accessor computes an offset and makes the accessors bounds-checked (fix in commit ac642f9, surrealdb 4.0.0 ships surrealkv 1.2.0).

Advisory available under CC0-1.0 license.