Skip to content

index out of bounds in storage/src/mmr/mem.rs:130 #1844

@dnkolegov-ar

Description

@dnkolegov-ar

config.pinned_nodes[i] may not have i element

index out of bounds: the len is 0 but the index is 0

Fuzz test

```rust
#![no_main]
use libfuzzer_sys::fuzz_target;
use arbitrary::Arbitrary;
use commonware_storage::mmr::{mem::{Config, Mmr}, Position, Location};
use commonware_cryptography::Sha256;

#[derive(Arbitrary, Debug)]
struct FuzzInput {
    pruned_to_pos: u64,
    nodes: Vec<[u8; 32]>,
    pinned_nodes: Vec<[u8; 32]>,
    call_leaves: bool,
    call_range_proof: bool,
}

fuzz_target!(|data: &[u8]| {
    let Ok(input) = FuzzInput::arbitrary(&mut arbitrary::Unstructured::new(data)) else {
        return;
    };

    let nodes: Vec<_> = input.nodes
        .into_iter()
        .map(|bytes| <Sha256 as commonware_cryptography::Hasher>::Digest::from(bytes))
        .collect();

    let pinned_nodes: Vec<_> = input.pinned_nodes
        .into_iter()
        .map(|bytes| <Sha256 as commonware_cryptography::Hasher>::Digest::from(bytes))
        .collect();

    let config = Config::<Sha256> {
        nodes,
        pruned_to_pos: Position::new(input.pruned_to_pos),
        pinned_nodes,
        pool: None,
    };

    let mmr = Mmr::init(config);

    if input.pruned_to_pos == u64::MAX || input.pruned_to_pos == u64::MAX - 1 {
        return;
    }

    if input.call_leaves {
        let _ = mmr.leaves();
    }

    if input.call_range_proof {
        let leaves = mmr.leaves();
        let leaves_u64: u64 = leaves.into();
        if leaves_u64 > 0 {
            let _ = mmr.range_proof(Location::new(0)..leaves);
        }
    }
});

Metadata

Metadata

Type

No type

Projects

Status

Ready for Review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions