Skip to content

Undefined behavior during decoding #75

Closed
@StarStarJ

Description

@StarStarJ

Tried to use this crate as an alternative to the zstd crate, to allow tests running with miri, but it crashed due to UB:

test test::my_test ... error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
   --> /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/ringbuffer.rs:462:30
    |
462 |             .write_unaligned(src.0.cast::<CopyType>().read_unaligned())
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE on thread `test::my_test`:
    = note: inside `ruzstd::decoding::ringbuffer::copy_bytes_overshooting` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/ringbuffer.rs:462:30: 462:71
    = note: inside `ruzstd::decoding::ringbuffer::RingBuffer::extend_from_within_unchecked` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/ringbuffer.rs:307:17: 307:62
    = note: inside `ruzstd::decoding::decodebuffer::DecodeBuffer::repeat_in_chunks` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/decodebuffer.rs:153:17: 154:72
    = note: inside `ruzstd::decoding::decodebuffer::DecodeBuffer::repeat` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/decodebuffer.rs:108:17: 108:71
    = note: inside `ruzstd::decoding::sequence_execution::execute_sequences` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/sequence_execution.rs:75:13: 77:65
    = note: inside `ruzstd::decoding::block_decoder::BlockDecoder::decompress_block::<&mut &mut &[u8]>` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/block_decoder.rs:448:13: 448:41
    = note: inside `ruzstd::decoding::block_decoder::BlockDecoder::decode_block_content::<&mut &mut &[u8]>` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/decoding/block_decoder.rs:354:17: 354:65
    = note: inside `ruzstd::frame_decoder::FrameDecoder::decode_blocks::<&mut &[u8]>` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/frame_decoder.rs:416:44: 417:94
    = note: inside `<ruzstd::streaming_decoder::StreamingDecoder<&[u8], ruzstd::frame_decoder::FrameDecoder> as std::io::Read>::read` at /home/me/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ruzstd-0.7.2/src/streaming_decoder.rs:116:19: 119:14
    = note: inside `std::io::default_read_to_end::small_probe_read::<ruzstd::streaming_decoder::StreamingDecoder<&[u8], ruzstd::frame_decoder::FrameDecoder>>` at /home/me/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:424:19: 424:37
    = note: inside `std::io::default_read_to_end::<ruzstd::streaming_decoder::StreamingDecoder<&[u8], ruzstd::frame_decoder::FrameDecoder>>` at /home/me/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:439:20: 439:44
    = note: inside `<ruzstd::streaming_decoder::StreamingDecoder<&[u8], ruzstd::frame_decoder::FrameDecoder> as std::io::Read>::read_to_end` at /home/me/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:876:9: 876:45

The invoking code is not really special:

let mut uncompressed_file = <Vec<u8>>::new();
#[cfg(feature = "pure_rust_zstd")]
{
    let mut decoder =
        ruzstd::StreamingDecoder::new(&file[offset..offset + size])?;
    decoder.read_to_end(&mut uncompressed_file)?;
}
#[cfg(not(feature = "pure_rust_zstd"))]
{
    let mut dec = zstd::Decoder::new(&file[offset..offset + size])?;
    dec.read_to_end(&mut uncompressed_file)?;
    dec.finish();
}

where offset might be an arbitrary offset within a bigger buffer

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions