Skip to content

IP fragment reassembly overwrites already-received bytes on an overlapping fragment, unconditionally #477

Description

@JarryShaw

What

Found while fixing #443 (TCP stream reassembly's analogous last-write-wins
overwrite). Investigating whether that code path was shared with IP fragment
reassembly, I found pcapkit/foundation/reassembly/ip.py has a structurally
similar defect, but it is a separate implementation governed by a
different RFC, so it is filed separately rather than folded into #443's
fix (which only touches pcapkit/foundation/reassembly/tcp.py and its data
model).

pcapkit/foundation/reassembly/ip.py:133:

# put data into data buffer
start = FO
stop = TL - IHL + FO
self._buffer[BUFID].datagram[start:stop] = info.payload

This slice-assigns the arriving fragment's payload into the preallocated
65535-byte datagram buffer with no check of RCVBT (the fragment-received
bit table, set immediately after at line 138) beforehand. So when two IP
fragments claim an overlapping byte range within the same datagram (same
source, destination, protocol, and IP identification field) but carry
different bytes, the later-arriving one silently wins -- the same
last-write-wins-with-no-record shape as #443, just one layer down.

Why this is a separate issue, not scope creep on #443

Reproduction shape (not yet executed)

Two fragments with the same (src, dst, id, proto) buffer identifier and
overlapping fo/tl ranges, differing in the overlapping bytes, followed by
enough fragments to complete the datagram. Expect (unverified) the same
shape as #443's original report: the datagram reports complete with the
later fragment's bytes silently kept in the overlap, and nothing on the
returned Datagram records the disagreement.

Scope

Not fixing here. Whoever picks this up should first determine whether RFC
791/815/1122 specify a resolution (unlike RFC 9293 for TCP, which is explicit
about first-write-wins), then decide whether the same "record a conflict
range, additive field on Datagram" shape from #443 fits, or something else
is more appropriate for fragment reassembly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions