Follow-up from @Dav1dde's review comment on #1004: #1004 (comment)
Problem
PeEmbeddedPortablePDB::decompress_to (symbolic-debuginfo/src/pe.rs) inflates the entire deflate stream into the output writer with no size cap. #1004 removed the speculative Vec::with_capacity(get_size()) pre-allocation (the uncompressed_size field is an attacker-controlled u32 PE header value), so we no longer over-allocate from an untrusted size — but a crafted PE can still expand a small compressed blob into a very large output (a classic decompression bomb).
Notably, ParseObjectOptions::max_decompressed_embedded_source_size already exists and is honored for source bundles / PPDB source files, but it is not wired into the embedded-PPDB extraction path.
Proposed fix
Thread a decompression limit into the embedded-PPDB path:
- Store the relevant limit on
PeObject during parse_with_opts (currently _opts is ignored at pe.rs:400) and pass it down to PeEmbeddedPortablePDB.
- Enforce the cap in
decompress_to (e.g. wrap the writer in a byte-counting/limited writer and error out once the limit is exceeded), rather than trusting the header size.
- Reuse
max_decompressed_embedded_source_size if its semantics fit ("compressed data embedded in an object"), or add a dedicated ParseObjectOptions field.
This is a symbolic-debuginfo core change (affects native + all consumers), which is why it's split out rather than bolted onto the WASM PR.
Notes / non-urgency
Follow-up from @Dav1dde's review comment on #1004: #1004 (comment)
Problem
PeEmbeddedPortablePDB::decompress_to(symbolic-debuginfo/src/pe.rs) inflates the entire deflate stream into the output writer with no size cap. #1004 removed the speculativeVec::with_capacity(get_size())pre-allocation (theuncompressed_sizefield is an attacker-controlled u32 PE header value), so we no longer over-allocate from an untrusted size — but a crafted PE can still expand a small compressed blob into a very large output (a classic decompression bomb).Notably,
ParseObjectOptions::max_decompressed_embedded_source_sizealready exists and is honored for source bundles / PPDB source files, but it is not wired into the embedded-PPDB extraction path.Proposed fix
Thread a decompression limit into the embedded-PPDB path:
PeObjectduringparse_with_opts(currently_optsis ignored atpe.rs:400) and pass it down toPeEmbeddedPortablePDB.decompress_to(e.g. wrap the writer in a byte-counting/limited writer and error out once the limit is exceeded), rather than trusting the header size.max_decompressed_embedded_source_sizeif its semantics fit ("compressed data embedded in an object"), or add a dedicatedParseObjectOptionsfield.This is a
symbolic-debuginfocore change (affects native + all consumers), which is why it's split out rather than bolted onto the WASM PR.Notes / non-urgency
ObjectFile.asPe()/PeFile.embeddedPpdb()API added in feat(wasm): expose ObjectFile.embeddedPpdb() for embedded Portable PDB extraction #1004 does not change.