Skip to content

Unbounded allocation in VecOf decode #567

@pbeza

Description

@pbeza

The VecOf<T> SCALE decoder in dstack/ra-tls/src/attestation/mod.rs reads a length prefix from untrusted input and pre-allocates a Vec of that size without any upper bound, enabling an attacker to trigger arbitrarily large memory allocations with a crafted payload.

Root Cause

The VecOf decoder reads a count value from untrusted input and allocates a vector of that size without any upper bound:

// codecs.rs:24-37
let count = u32::decode(input)?;
let mut items = Vec::with_capacity(count as usize);  // Unbounded allocation
for _ in 0..count {
    items.push(T::decode(input)?);
}

A malformed event log entry with a large count value can trigger allocation of gigabytes of memory.

Attack Path

  1. Attacker crafts a malformed CCEL (CC Event Log) entry with count = 0xFFFFFFFF
  2. Application parses the event log using the VecOf decoder
  3. Vec::with_capacity(4294967295) attempts to allocate ~4 GB
  4. Process crashes due to OOM or the system becomes unresponsive

Impact

Denial of service when parsing malformed event logs. The event log could be corrupted by a malicious host (the CCEL table is provided by the firmware/VMM) or by a compromised process inside the CVM.

Suggested Fix

Add a maximum count limit:

const MAX_VEC_COUNT: u32 = 65536;  // Reasonable upper bound

let count = u32::decode(input)?;
if count > MAX_VEC_COUNT {
    return Err(Error::CountTooLarge(count));
}
let mut items = Vec::with_capacity(count as usize);

Note: This issue was created automatically. The vulnerability report was generated by Claude and has not been verified by a human.

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