Skip to content

fix(edgebreaker): validate num_encoded_symbols against remaining bit budget (fixes #1169) - #1223

Open
jdymitarai wants to merge 1 commit into
google:mainfrom
jdymitarai:fix-edgebreaker-dos-uncontrolled-alloc
Open

fix(edgebreaker): validate num_encoded_symbols against remaining bit budget (fixes #1169)#1223
jdymitarai wants to merge 1 commit into
google:mainfrom
jdymitarai:fix-edgebreaker-dos-uncontrolled-alloc

Conversation

@jdymitarai

Copy link
Copy Markdown

Summary of Changes

Fixes #1169 (CWE-789: Uncontrolled Memory Allocation in MeshEdgebreakerDecoderImpl::DecodeConnectivity() allowing DoS with tiny input).

Problem

MeshEdgebreakerDecoderImpl::DecodeConnectivity() reads num_encoded_symbols and num_faces from untrusted input and proceeds to allocate substantial internal structures:

  • processed_corner_ids_.reserve(num_faces);
  • processed_connectivity_corners_.reserve(num_faces);
  • corner_table_->Reset(num_faces, ...);

While num_faces is checked against max_encoded_faces (num_encoded_symbols * 4 / 3), num_encoded_symbols was never validated against the remaining size of the input buffer. As demonstrated in #1169, a crafted 61-byte input claiming an astronomical symbol count triggers multi-gigabyte allocations and immediate out-of-memory crashes / DoS in applications and WebAssembly decoders.

Fix

Because each Edgebreaker symbol requires at least 1 bit in the remaining bitstream (e.g. TOPOLOGY_C is 1 bit, others 3 bits, or at least 1 bit under prediction/entropy decoding), validate that num_encoded_symbols does not exceed remaining_size() * 8. If it does, DecodeConnectivity() immediately returns false before any memory allocation occurs.

Test

Added MeshEdgebreakerEncodingTest.RejectExcessiveSymbols with the reproducer payload from #1169 to ensure malformed buffers with excessive symbol counts are safely rejected.

…budget (fixes google#1169)

In MeshEdgebreakerDecoderImpl::DecodeConnectivity(), num_encoded_symbols is read
from untrusted input. Prior to this commit, num_faces was bounded only by
num_encoded_symbols, but num_encoded_symbols itself was never bounded against the
remaining bytes in the bitstream.

A malformed input declaring an astronomical num_encoded_symbols could trigger
massive memory allocation in processed_corner_ids_.reserve(num_faces),
processed_connectivity_corners_.reserve(num_faces), and corner_table_->Reset(),
consuming gigabytes of memory and causing Denial of Service (CWE-789) with a
tiny (<100 byte) input file.

Since each edgebreaker symbol requires at least 1 bit in the remaining bitstream,
this commit validates that num_encoded_symbols does not exceed the remaining bit
budget (remaining_size() * 8).

Also adds a unit test RejectExcessiveSymbols with the reproducer payload to
verify that corrupt inputs are cleanly rejected.

Fixes google#1169.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Uncontrolled memory allocation in MeshEdgebreakerDecoderImpl::DecodeConnectivity allows DoS with tiny input

1 participant