Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TCP option size calculation for options with empty payload #404

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fxkr
Copy link

@fxkr fxkr commented Jul 8, 2020

From https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml :

> Options 0 and 1 are exactly one octet which is their kind field.  All
> other options have their one octet kind field, followed by a one octet
> length field, followed by length-2 octets of option data.

Options affected by the libtins bug are those where length is listed as:

  • 2, except for SACK permitted, for which tins has an explicit workaround, or
  • N, for packets where the options payload happens to be empty (N==2)

Without this fix, any affected packet can still be parsed, but trying
to serialize the resulting PDU object again will fail in
Tins::PDU::serialize -> Tins::TCP::write_serialization
-> Tins::Memory::OutputMemoryStream::fill.

I'm attaching a PCAP with an affected packet. This packet is from a real world product. I mention this because Wireshark says "Illegal SCPS Extended Capabilities (2 bytes)". Wireshark still gets the length right, and what's "wrong" (but real) about the packet isn't relevant here (for the curious... SCPS extended capability opts (extended means length!=4) "must" be preceded by a normal SCPS capability opt (normal means length==4). CCSDS 714.0-B-2 section 3.2.5.2.1, available on the Internet Archive. Disclaimer: I'm not a SCPS expert.). But none of that weirdness is related to this libtins bug, and anyway the libtins bug is not specific to SCPS.

tcp ack with scps option without data.zip

(Unrelated note: I'd rather not even deal with the TCP layer and decode the IP payload, whatever that may be, as RawPDU, both for performance as well as the guarantee that any TCP/UDP/... and above headers will come out of tins unmodified, but it seems there's no good way to make libtins do that.)

From https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml :

    > Options 0 and 1 are exactly one octet which is their kind field.  All
    > other options have their one octet kind field, followed by a one octet
    > length field, followed by length-2 octets of option data.

Options affected by the libtins bug are those where length is listed as:

* 2, except for SACK permitted, for which tins has an explicit workaround, or
* N, for packets where the options payload happens to be empty (N==2)

Without this fix, any affected packet can still be parsed, but trying
to serialize the resulting PDU object again will fail in
Tins::PDU::serialize -> Tins::TCP::write_serialization
-> Tins::Memory::OutputMemoryStream::fill.
@fxkr fxkr force-pushed the fix-tcp-options-size-calc branch from e831725 to 8366454 Compare July 9, 2020 05:25
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.

1 participant