snapshot.cpp
, line 609, data is assigned to aItemSizes
indexed NumItems-1
. If NumItems
is equal zero, data is written before the buffer (index is -1
).
```
File: src/engine/shared/snapshot.cpp
587: int CSnapshotBuilder::Finish(void *pSnapdata)
588: {
[...]
594: pSnap->m_NumItems = m_NumItems;
595:
596: const int NumItems = m_NumItems;
[...]
605: for(int i = 0; i < NumItems-1; i++)
606: {
607: aItemSizes[...snapshot.cpp
, line 317, server controlled integer pDelta->m_NumDeletedItems
is added to pData
pointer. There's a check (line 318) verifying that m_NumDeletedItems
doesn't cause reaching outside the buffer. However, as m_NumDeletedItems
is a signed integer, the server can send negative value and cause pData
to point before the buffer. In line 352, the client dereferences the pointer.
```
File: src/engine/shared/snapshot....char aBuf[128]
defined inside a block. Its address is assigned to pTitle
and it's used later (outside the block).
```
File: src/game/client/components/menus.cpp
1554: int CMenus::Render()
1555: {
[...]
1709: else if(m_Popup == POPUP_CONNECTING)
1710: {
1711: pTitle = Localize("Connecting to");
1712: ...gameclient.cpp
, line 1312, snapshot data is assigned to m_Snap.m_pGameData
. Then, this value is access in line 504.
```
File: src/game/client/gameclient.cpp
1131: void CGameClient::OnNewSnapshot()
1132: {
1133: // clear out the invalid pointers
1134: mem_zero(&m_Snap, sizeof(m_Snap));
1135:
1136: // secure snapshot
1137: {
1138: int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT);
1139: for(int Index ...CSnapshotDelta::UnpackDelta
, Type
and m_SnapshotCurrent
indexes are values coming from the server. The server can send specially crafted data that will reading and writing outside buffers.
```
File: src/engine/shared/snapshot.cpp
302: int CSnapshotDelta::UnpackDelta(const CSnapshot *pFrom, CSnapshot *pTo, const void *pSrcData, int DataSize)
303: {
304: CSnapshotBuilder Builder;
305: const CData *pDelta = (const CData *)p...