Skip to content
Permalink
Browse files Browse the repository at this point in the history
Drop unreliable segments with weird offset/size.
And be more deliberate about limits of unreliable message/segment sizes.
  • Loading branch information
zpostfacto committed Sep 3, 2020
1 parent e950c99 commit e0c86dc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
Expand Up @@ -234,7 +234,7 @@ int64 CSteamNetworkConnectionBase::SNP_SendMessage( CSteamNetworkingMessage *pSe
}

// Check if they try to send a really large message
if ( cbData > k_cbMaxUnreliableMsgSize && !( pSendMessage->m_nFlags & k_nSteamNetworkingSend_Reliable ) )
if ( cbData > k_cbMaxUnreliableMsgSizeSend && !( pSendMessage->m_nFlags & k_nSteamNetworkingSend_Reliable ) )
{
SpewWarningRateLimited( usecNow, "Trying to send a very large (%d bytes) unreliable message. Sending as reliable instead.\n", cbData );
pSendMessage->m_nFlags |= k_nSteamNetworkingSend_Reliable;
Expand Down Expand Up @@ -577,11 +577,23 @@ bool CSteamNetworkConnectionBase::ProcessPlainTextDataChunk( int usecTimeSinceLa
// Decode size, locate segment data
//
READ_SEGMENT_DATA_SIZE( unreliable )
Assert( cbSegmentSize > 0 ); // !TEST! Bogus assert, zero byte messages are OK. Remove after testing

// Receive the segment
bool bLastSegmentInMessage = ( nFrameType & 0x20 ) != 0;
SNP_ReceiveUnreliableSegment( nCurMsgNum, nOffset, pSegmentData, cbSegmentSize, bLastSegmentInMessage, usecNow );
// Check if offset+size indicates a message larger than what we support. (Also,
// protect against malicious sender sending *extremely* large offset causing overflow.)
if ( (int64)nOffset + cbSegmentSize > k_cbMaxUnreliableMsgSizeRecv || cbSegmentSize > k_cbMaxUnreliableSegmentSizeRecv )
{

// Since this is unreliable data, we can just ignore the segment.
SpewWarningRateLimited( usecNow, "[%s] Ignoring unreliable segment with invalid offset %u size %d\n",
GetDescription(), nOffset, cbSegmentSize );
}
else
{

// Receive the segment
bool bLastSegmentInMessage = ( nFrameType & 0x20 ) != 0;
SNP_ReceiveUnreliableSegment( nCurMsgNum, nOffset, pSegmentData, cbSegmentSize, bLastSegmentInMessage, usecNow );
}
}
else if ( ( nFrameType & 0xe0 ) == 0x40 )
{
Expand Down
Expand Up @@ -90,7 +90,14 @@ constexpr int k_nMaxBufferedUnreliableSegments = 20;
// If app tries to send a message larger than N bytes unreliably,
// complain about it, and automatically convert to reliable.
// About 15 segments.
constexpr int k_cbMaxUnreliableMsgSize = 15*1100;
constexpr int k_cbMaxUnreliableMsgSizeSend = 15*1100;

// Max possible size of an unreliable segment we could receive.
constexpr int k_cbMaxUnreliableSegmentSizeRecv = k_cbSteamNetworkingSocketsMaxPlaintextPayloadRecv;

// Largest possible total unreliable message we can receive, based on the constraints above
constexpr int k_cbMaxUnreliableMsgSizeRecv = k_nMaxBufferedUnreliableSegments*k_cbMaxUnreliableSegmentSizeRecv;
COMPILE_TIME_ASSERT( k_cbMaxUnreliableMsgSizeRecv > k_cbMaxUnreliableMsgSizeSend + 4096 ); // Postel's law; confirm how much slack we have here

class CSteamNetworkConnectionBase;
class CConnectionTransport;
Expand Down Expand Up @@ -468,7 +475,7 @@ struct SSNPRecvUnreliableSegmentData
{
int m_cbSegSize = -1;
bool m_bLast = false;
char m_buf[ k_cbSteamNetworkingSocketsMaxPlaintextPayloadRecv ];
char m_buf[ k_cbMaxUnreliableSegmentSizeRecv ];
};

struct SSNPPacketGap
Expand Down

0 comments on commit e0c86dc

Please sign in to comment.