Skip to content

Unbounded allocation in FieldBase.unpack: a wire-declared length drives rjust() with no bound #554

Description

@JarryShaw

pcapkit/corekit/fields/field.py:240-244:

length = self.length

if not isinstance(buffer, bytes):
    buffer = buffer.read(length)
value = struct.unpack(self.template, buffer[:length].rjust(length, b'\x00'))[0]

length derives from the field's configured length, which for several schemas is a callable resolved against the packet under parse — so it can be attacker-influenced by a length written on the wire. rjust(length, b'\x00') then allocates length bytes regardless of how much data actually arrived.

The consequence is that a small crafted input can force a very large allocation. A roughly 40-octet PCAP-NG Decryption Secrets Block is enough to drive a multi-gigabyte rjust, because the block's own declared length feeds the field length while the file supplies almost no bytes.

This is the only memory-safety-shaped finding from a sweep of deferred work across this release's 68 merged PRs, and it was never raised in review.

Why it is worth a real fix rather than a cap

pcapkit parses untrusted capture files by design — that is the whole use case — so "the input is hostile" is the normal condition rather than an edge case. A plain upper bound would stop the allocation but silently truncate legitimate large fields; better is to refuse when the declared length exceeds the bytes actually available, which is a genuine format error and already has an in-library exception for it.

Note only in-library exceptions from pcapkit.utilities.exceptions should be used, and FieldValueError is the existing precedent for an impossible field value.

Coverage

A test that feeds a short buffer declaring a huge length and asserts a bounded in-library exception rather than an allocation. It must not actually attempt the allocation when run against the fixed code, and should be proven to fail — by raising MemoryError or hanging under a timeout — against the current code.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions