Skip to content

Commit 2cb2911

Browse files
committed
-fixed an issue where the stack could crash if a TCP based sender sends a Content-Length that is less that the actual SIP body transmitted
in order to trigger this condition the SIP message body must arrive in a separate read request, either from the start or part way through the body and there must be data following the body in the same read.
1 parent 878cedb commit 2cb2911

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

Diff for: resip/stack/ConnectionBase.cxx

+35-5
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ ConnectionBase::preparseNewBytes(int bytesRead)
397397
mBufferSize = size;
398398

399399
DebugLog (<< "Extra bytes after message: " << overHang);
400-
DebugLog (<< Data(mBuffer, overHang));
400+
//DebugLog (<< Data(mBuffer, overHang));
401401

402402
bytesRead = overHang;
403403
}
@@ -471,11 +471,36 @@ ConnectionBase::preparseNewBytes(int bytesRead)
471471
}
472472

473473
mBufferPos += bytesRead;
474-
if (mBufferPos == contentLength)
474+
if (mBufferPos >= contentLength)
475475
{
476+
int overHang = mBufferPos - (int)contentLength;
477+
char *overHangStart = mBuffer + contentLength;
478+
476479
mMessage->addBuffer(mBuffer);
477480
mMessage->setBody(mBuffer, (UInt32)contentLength);
478-
mBuffer=0;
481+
mConnState = NewMessage;
482+
mBuffer = 0;
483+
484+
if (overHang > 0)
485+
{
486+
// The next message has been partially read.
487+
size_t size = overHang * 3 / 2;
488+
if (size < ConnectionBase::ChunkSize)
489+
{
490+
size = ConnectionBase::ChunkSize;
491+
}
492+
char* newBuffer = MsgHeaderScanner::allocateBuffer((int)size);
493+
memcpy(newBuffer, overHangStart, overHang);
494+
mBuffer = newBuffer;
495+
mBufferPos = 0;
496+
mBufferSize = size;
497+
498+
DebugLog(<< "Extra bytes after message: " << overHang);
499+
//DebugLog(<< Data(mBuffer, overHang));
500+
501+
bytesRead = overHang;
502+
}
503+
479504
// .bwc. basicCheck takes up substantial CPU. Don't bother doing it
480505
// if we're overloaded.
481506
CongestionManager::RejectionBehavior b=mTransport->getRejectionBehaviorForIncoming();
@@ -515,11 +540,16 @@ ConnectionBase::preparseNewBytes(int bytesRead)
515540
mTransport->pushRxMsgUp(mMessage);
516541
mMessage = 0;
517542
}
518-
mConnState = NewMessage;
543+
544+
if (overHang > 0)
545+
{
546+
goto start;
547+
}
519548
}
520549
else if (mBufferPos == mBufferSize)
521550
{
522-
// .bwc. We've filled our buffer; go ahead and make more room.
551+
// .bwc. We've filled our buffer and haven't read contentLength bytes yet; go ahead and make more room.
552+
assert(contentLength >= mBufferSize);
523553
size_t newSize = resipMin(mBufferSize*3/2, contentLength);
524554
char* newBuffer = 0;
525555
try

0 commit comments

Comments
 (0)