Skip to content

Bound attacker-controlled block lengths in LightPcapNg (OOM/OOB in EPB parsing)#2182

Draft
vsaraikin wants to merge 1 commit into
seladb:masterfrom
vsaraikin:fix/lightpcapng-epb-unbounded-length
Draft

Bound attacker-controlled block lengths in LightPcapNg (OOM/OOB in EPB parsing)#2182
vsaraikin wants to merge 1 commit into
seladb:masterfrom
vsaraikin:fix/lightpcapng-epb-unbounded-length

Conversation

@vsaraikin

Copy link
Copy Markdown

Fixes #2180.

The vendored LightPcapNg parser trusts several length fields read straight from the input, which lets a malformed pcapng drive an attacker-controlled calloc()/memcpy():

  • In parse_by_block_type(), the LIGHT_ENHANCED_PACKET_BLOCK handler reads captured_packet_length from the block body, pads it, and uses it directly to size a calloc() and then memcpy() — before validating it against the block. A block can keep block_total_length small while setting captured_packet_length huge, causing a multi-gigabyte allocation and an out-of-bounds read past the input buffer. LIGHT_CUSTOM_DATA_BLOCK has the same pattern with its len field.
  • The only length sanity checks in __parse_mem_copy() use the DCHECK_* macros, which are no-ops in release builds (light_stop expands to (void)0), so block_total_length itself is never bounded against the remaining buffer.

The fix adds real (release-active) bounds:

  1. In __parse_mem_copy(), reject a block whose block_total_length is smaller than the mandatory framing or larger than the bytes left in the buffer, before dispatching to the per-block parser.
  2. In the EPB and custom-block handlers, clamp captured_packet_length / len to the space the block can actually hold (mirroring how LIGHT_SIMPLE_PACKET_BLOCK already derives its length from block_total_length), so a bogus length can't over-size the calloc()/memcpy().

Testing (AddressSanitizer)

Verified against the parser (light_read_from_memory) directly, since the DCHECK-based checks are compiled out in release:

  • Malformed EPB (block_total_length = 32, captured_packet_length = 0x10000): before the fix ASan reports stack-buffer-overflow READ of size 65536 in parse_by_block_type (light_pcapng.c:172, the memcpy); after the fix it is bounded and clean.
  • Valid EPB (captured_packet_length = 8, correctly framed): parses unchanged — captured_packet_length is preserved (not clamped) and the packet bytes are copied correctly, so well-formed captures are unaffected.

The bug originates from OSS-Fuzz (FuzzTargetNg); the project's fuzzers exercise this path going forward. Happy to also add a regression sample to Tests/Fuzzers/RegressionTests if you'd like one in the corpus.

Note

3rdParty/LightPcapNg is vendored, so the change follows the surrounding vendored style and is marked with // PCPP Patch (GH #2180) comments consistent with the existing patches in this file.

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.

OOM in LightPcapNg EPB parsing due to unbounded captured_packet_length

1 participant