---
id: RUSTSEC-2026-0411
title: >-
  Out-of-bounds read in `Log2Cache::nlog2n()`, `nlog2n_difference()` and
  `plog2p()`
summary: >-
  Out-of-bounds read in `Log2Cache::nlog2n()`, `nlog2n_difference()` and
  `plog2p()`
severity: none
vendor: dahl-salso
product: dahl-salso
ecosystem: rust
affected:
  - 'dahl-salso >= 0.0.0-0, < 0.7.0'
patched:
  - dahl-salso 0.7.0
published: '2026-10-22'
updated: '2026-10-26'
sourceUpdated: '2026-10-26T14:00:05.091904359Z'
source: OSV
sourceUrl: 'https://osv.dev/vulnerability/RUSTSEC-2026-0411'
references:
  - url: 'https://crates.io/crates/dahl-salso'
  - url: 'https://rustsec.org/advisories/RUSTSEC-2026-0411.html'
  - url: 'https://github.com/dbdahl/rust-dahl-salso/issues/2'
tags:
  - osv
  - rust
ingestedAt: '2026-10-27T16:20:12.121Z'
---

## Overview

`Log2Cache::new(n)` fills its three tables with entries for `0..=n`, but the
three accessor methods index those tables with `get_unchecked` on a value the
caller supplies. Nothing bounds the argument and nothing documents a bound, so
any value above the `n` the cache was built with reads past the end of the
vector. `CountType` is `u32`, so the read can land up to `u32::MAX` elements
away, and `plog2p()` returns the value it read, disclosing whatever lies there.

For example, `Log2Cache::new(4)` builds tables holding 5 entries (indices
0,1,2,3,4). Then `cache.nlog2n(60000)` reads index 60000, far outside the
allocation. Under AddressSanitizer this faults with `SEGV`; Miri reports it as
undefined behavior at `src/log2cache.rs:42`.

`nlog2n_difference()` is off by one further: in the affected versions `new(n)`
pushes `n` entries into that table rather than `n + 1`, so even
`nlog2n_difference(n)` is out of bounds.

This can be triggered through safe public APIs — `Log2Cache::new()` and any of
`nlog2n()`, `nlog2n_difference()` and `plog2p()` — with no `unsafe` required
from the caller.

## Affected packages

- `dahl-salso >= 0.0.0-0, < 0.7.0`

## Remediation

Upgrade to a patched release:

- `dahl-salso 0.7.0`
