Skip to content

Potential soundness issue in bitpacking 0.9.3 #70

Description

@varies-rust

Hello, and thank you for maintaining this crate.

I found a sanitizer/Miri failure reachable through public crate APIs using safe Rust code. I may be missing crate-specific preconditions, but the behavior looks worth checking because safe callers should not be able to trigger undefined behavior.

Summary

  • Crate: bitpacking
  • Version tested: 0.9.3
  • API paths with similar failures observed:
    • BitPacker1x::num_bits_sorted
    • BitPacker1x::num_bits_strictly_sorted
    • BitPacker4x::num_bits_sorted
    • BitPacker4x::num_bits_strictly_sorted

Observed diagnostics

Miri undefined behavior: error: Undefined Behavior: memory access failed: attempting to access 4 bytes, but got 0x4[noalloc] which is a dangling pointer (it has no provenance)

Reproduction

The snippets below are minimal readable reproducers. Each PoC also includes the source location most relevant to the reported failure.

PoC 1: test_bitpacking3::generated_test_3

Relevant source location:

  • src/bitpacker1x.rs:161: the safe wrapper calls UnsafeBitPackerImpl::num_bits_sorted.
  • src/macros_simple.rs:424-438: the unsafe implementation loads a full fixed block from decompressed.

Readable equivalent PoC:

use bitpacking::{BitPacker, BitPacker1x};

#[test]
fn poc() {
    let packer = BitPacker1x::new();
    let short_block: Vec<u32> = Vec::new();

    let _ = packer.num_bits_sorted(0, &short_block);
}

Observed diagnostic:

error: Undefined Behavior: memory access failed: attempting to access 4 bytes, but got 0x4[noalloc] which is a dangling pointer (it has no provenance)

Source review and suggested fix

Brief reasoning:

  • The public num_bits path already checks for the exact block length.
  • The sorted variants skip that check and still load a full block from the slice.
  • That makes the length precondition caller-visible through a safe API.

Suggested fix:

  • Validate the exact block length before calling the unsafe routine, or make the precondition explicit in an unsafe API.

Thanks again for taking a look.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions