summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Stt.c
diff options
context:
space:
mode:
authorPaul Boca <pboca@cloudbasesolutions.com>2016-06-06 16:45:05 +0000
committerBen Pfaff <blp@ovn.org>2016-06-07 10:52:19 -0700
commitde8856900636be073caa5625140564f9ce56f44c (patch)
tree0e94058a9ae274b0e0ca19cb16ea5e49710e6433 /datapath-windows/ovsext/Stt.c
parentbfc27f614262c54fd7fb3b47bb5a3c7d714e9e59 (diff)
downloadopenvswitch-de8856900636be073caa5625140564f9ce56f44c.tar.gz
datapath-windows: STT reassemble small fix
Fixed possible deadlock in case NdisGetDataBuffer fails Validate the segment length and offset on reassemble to avoid buffer overflow Signed-off-by: Paul-Daniel Boca <pboca@cloudbasesolutions.com> Acked-by: Sairam Venugopal <vsairam@vmware.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Stt.c')
-rw-r--r--datapath-windows/ovsext/Stt.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/datapath-windows/ovsext/Stt.c b/datapath-windows/ovsext/Stt.c
index 934525510..fd9b32b04 100644
--- a/datapath-windows/ovsext/Stt.c
+++ b/datapath-windows/ovsext/Stt.c
@@ -612,9 +612,6 @@ OvsSttReassemble(POVS_SWITCH_CONTEXT switchContext,
SttHdr *sttHdr = NULL;
sourceNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
- /* XXX optimize this lock */
- NdisAcquireSpinLock(&OvsSttSpinLock);
-
/* If this is the first fragment, copy the STT header */
if (segOffset == 0) {
sttHdr = NdisGetDataBuffer(sourceNb, sizeof(SttHdr), &stt, 1, 0);
@@ -626,6 +623,14 @@ OvsSttReassemble(POVS_SWITCH_CONTEXT switchContext,
startOffset = startOffset + STT_HDR_LEN;
}
+ if (offset + fragmentLength > innerPacketLen) {
+ // avoid buffer overflow on copy
+ return NULL;
+ }
+
+ /* XXX optimize this lock */
+ NdisAcquireSpinLock(&OvsSttSpinLock);
+
/* Lookup fragment */
OVS_STT_PKT_KEY pktKey = OvsGeneratePacketKey(ipHdr, tcp);
UINT32 hash = OvsSttGetPktHash(&pktKey);
@@ -652,6 +657,7 @@ OvsSttReassemble(POVS_SWITCH_CONTEXT switchContext,
}
/* Copy the data from Source to new buffer */
+ entry->allocatedLen = innerPacketLen;
entry->packetBuf = OvsAllocateMemoryWithTag(innerPacketLen,
OVS_STT_POOL_TAG);
if (OvsGetPacketBytes(curNbl, fragmentLength, startOffset,
@@ -664,6 +670,10 @@ OvsSttReassemble(POVS_SWITCH_CONTEXT switchContext,
InsertHeadList(&OvsSttPktFragHash[hash & STT_HASH_TABLE_MASK],
&entry->link);
} else {
+ if (offset + fragmentLength > pktFragEntry->allocatedLen) {
+ // don't copy more than it is allocated
+ goto handle_error;
+ }
/* Add to recieved length to identify if this is the last fragment */
pktFragEntry->recvdLen += fragmentLength;
lastPacket = (pktFragEntry->recvdLen == innerPacketLen);