From d172286c6cf071522f2433bc4bf053895ad9301c Mon Sep 17 00:00:00 2001 From: Redix Date: Sun, 11 Oct 2020 18:14:12 +0200 Subject: [PATCH] Fix out of bounds access in snapshot delta handling --- src/engine/shared/snapshot.cpp | 14 ++++++++++---- src/engine/shared/snapshot.h | 7 +++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/engine/shared/snapshot.cpp b/src/engine/shared/snapshot.cpp index 802ef2b80..9b846f1cb 100644 --- a/src/engine/shared/snapshot.cpp +++ b/src/engine/shared/snapshot.cpp @@ -189,6 +189,8 @@ CSnapshotDelta::CSnapshotDelta(const CSnapshotDelta &old) void CSnapshotDelta::SetStaticsize(int ItemType, int Size) { + if(ItemType < 0 || ItemType >= MAX_NETOBJSIZES) + return; m_aItemSizes[ItemType] = Size; } @@ -248,20 +250,22 @@ int CSnapshotDelta::CreateDelta(CSnapshot *pFrom, CSnapshot *pTo, void *pDstData pCurItem = pTo->GetItem(i); // O(1) .. O(n) PastIndex = aPastIndices[i]; + bool IncludeSize = pCurItem->Type() >= MAX_NETOBJSIZES || !m_aItemSizes[pCurItem->Type()]; + if(PastIndex != -1) { int *pItemDataDst = pData + 3; pPastItem = pFrom->GetItem(PastIndex); - if(m_aItemSizes[pCurItem->Type()]) + if(!IncludeSize) pItemDataDst = pData + 2; if(DiffItem(pPastItem->Data(), pCurItem->Data(), pItemDataDst, ItemSize / 4)) { *pData++ = pCurItem->Type(); *pData++ = pCurItem->ID(); - if(!m_aItemSizes[pCurItem->Type()]) + if(IncludeSize) *pData++ = ItemSize / 4; pData += ItemSize / 4; pDelta->m_NumUpdateItems++; @@ -271,7 +275,7 @@ int CSnapshotDelta::CreateDelta(CSnapshot *pFrom, CSnapshot *pTo, void *pDstData { *pData++ = pCurItem->Type(); *pData++ = pCurItem->ID(); - if(!m_aItemSizes[pCurItem->Type()]) + if(IncludeSize) *pData++ = ItemSize / 4; mem_copy(pData, pCurItem->Data(), ItemSize); @@ -368,8 +372,10 @@ int CSnapshotDelta::UnpackDelta(CSnapshot *pFrom, CSnapshot *pTo, void *pSrcData return -1; Type = *pData++; + if(Type < 0) + return -1; ID = *pData++; - if((unsigned int)Type < sizeof(m_aItemSizes) / sizeof(m_aItemSizes[0]) && m_aItemSizes[Type]) + if(Type < MAX_NETOBJSIZES && m_aItemSizes[Type]) ItemSize = m_aItemSizes[Type]; else { diff --git a/src/engine/shared/snapshot.h b/src/engine/shared/snapshot.h index 85a69add7..7aae3feac 100644 --- a/src/engine/shared/snapshot.h +++ b/src/engine/shared/snapshot.h @@ -67,8 +67,11 @@ public: }; private: - // TODO: strange arbitrary number - short m_aItemSizes[64]; + enum + { + MAX_NETOBJSIZES = 64 + }; + short m_aItemSizes[MAX_NETOBJSIZES]; int m_aSnapshotDataRate[0xffff]; int m_aSnapshotDataUpdates[0xffff]; int m_SnapshotCurrent;