From 575cf5d789a3ace673dcecd4ee1417e14006fc1e Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sun, 7 Jul 2019 23:59:54 -0700 Subject: [PATCH] subchannel: check MAX_FRAME_LENGTH, 2**32 minus headers Anyone sending 4GB in a single `transport.write()` is in for a surprise, but at least we'll surprise them with an assertion *before* spending the time and memory encrypting that monster. --- src/wormhole/_dilation/subchannel.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wormhole/_dilation/subchannel.py b/src/wormhole/_dilation/subchannel.py index 8b0e7bf..bcdff6a 100644 --- a/src/wormhole/_dilation/subchannel.py +++ b/src/wormhole/_dilation/subchannel.py @@ -12,6 +12,13 @@ from twisted.internet.error import ConnectionDone from automat import MethodicalMachine from .._interfaces import ISubChannel, IDilationManager +# each subchannel frame (the data passed into transport.write(data)) gets a +# 9-byte header prefix (type, subchannel id, and sequence number), then gets +# encrypted (adding a 16-byte authentication tag). The result is transmitted +# with a 4-byte length prefix (which only covers the padded message, not the +# length prefix itself), so the padded message must be less than 2**32 bytes +# long. +MAX_FRAME_LENGTH = 2**32 - 1 - 9 - 16; @attrs class Once(object): @@ -173,6 +180,7 @@ class SubChannel(object): # ITransport def write(self, data): assert isinstance(data, type(b"")) + assert len(data) <= MAX_FRAME_LENGTH self.local_data(data) def writeSequence(self, iovec):