Skip to content

fix(protocols): a declared length running past the data is accepted and zero-filled on rebuild #1325

Closed

Description

@JarryShaw

Describe the bug
Nothing checks that an option or parameter's declared length fits the remaining data; the missing octets are read as zeros. Root cause not established (parse is not rejected, so the reader/OptionField path is suspected).

To Reproduce

  • HIP ACK 01c10100 00000000 after a 40-octet header (declared length 0x0100, 4 present): parses with a 64-entry update_id; from_data rebuilds 304 octets with Header Length 0x25
  • MH BRR 3b010000 00000000 010400000000 0103 (PadN declaring 3, none present): parses with PadOption length=5; rebuilds 24 octets (16 in)

Expected behavior
A truncated record is rejected or kept as-is, not padded with invented octets. Compare #1170.

Found by the internet-v4 round-trip audit (#1202); reproduced on main at 11ae68ebf (repro check D15).

Found by the internet-v4 round-trip audit (#1202). The repro was re-checked by an independent verifier, and I re-ran it on main at 11ae68ebf.

Activity

  1. added
    fixPull requests that fix a defect (fix: subject prefix)
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    on Oct 7, 2026
  2. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    on Oct 7, 2026
  3. JarryShaw commented on Oct 7, 2026

    @JarryShaw
    OwnerAuthor

    Decision needed. The root cause is found, and the fix conflicts with behaviour that is pinned on purpose.

    Cause. OptionField.unpack (corekit/fields/collections.py, about :445) hands each option schema the whole option area, unbounded. A short read is then padded by FieldBase.unpack (field.py:586, ljust(length, b'\x00')). Schema.unpack only warns (schema.py:1007).

    Probed on 13aa677be with a last option that runs past the data:

    • HOPOPT, IPv6-Opts, HIP and MH, plus TCP options without their own length check, zero-fill and rebuild longer than the input.
    • IPv4, TCP MSS/SACK and SCTP already raise.
    • PCAP-NG clamps instead, so the rebuild is the same length but not byte-exact.

    The strict fix exists on branch fix/1325-declared-length-overrun (50dd50f14, no PR yet). An option that reads short raises ProtocolError. Inside a parent layer, the octets are kept as captured, as #1171 does: IPv6 keeps the bad HOPOPT as raw extension data and rebuilds byte-exactly. Fixture info is unchanged. It breaks:

    Options:

    • (1) Strict everywhere. Rewrite the IPv4/TCP pins to expect the option kept as raw octets. Change PCAP-NG from clamping to keep-as-is: the block's option area is kept raw and rebuilt verbatim, so extraction still does not abort, and the round trip becomes byte-exact.
    • (2) Opt-in. Add a strict flag to OptionField, set only for HIP, MH, HOPOPT, IPv6-Opts and SCTP. IPv4, TCP and PCAP-NG keep their current zero-fill or clamp.

    I recommend (1). Invented zeros and the clamp both break the every-round-trip ruling, and keeping the bytes raw satisfies the PCAP-NG concern without aborting. It does change what a truncated IPv4 or TCP option looks like in info.

  4. added
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 7, 2026
  5. JarryShaw commented on Oct 8, 2026

    @JarryShaw
    OwnerAuthor

    take (1) then

  6. JarryShaw commented on Oct 8, 2026

    @JarryShaw
    OwnerAuthor

    Ruling recorded: option (1), strict everywhere. An option whose declared length runs past the data raises ProtocolError. Inside a parent layer, the octets are kept as captured, as #1171 does, so nothing invents zeros.

    A worker is taking fix/1325-declared-length-overrun (50dd50f14) onto current main. The PCAP-NG part waits for #1378, which edits the same files.

  7. removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 8, 2026
  8. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Oct 8, 2026
  9. added a commit that references this issue on Oct 8, 2026
    bc5d90f
  10. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Oct 8, 2026
  11. added this to the PyPCAPKit v1.5 milestone on Oct 26, 2026
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

    fixPull requests that fix a defect (fix: subject prefix)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions