Skip to content

Commit 3d36e1d

Browse files
committed
bugfix(network): Fix out of bounds memory access for wrapped net commands
1 parent e6c28a4 commit 3d36e1d

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

Core/GameEngine/Include/GameNetwork/NetCommandWrapperList.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class NetCommandWrapperListNode : public MemoryPoolObject
4949
protected:
5050
UnsignedShort m_commandID;
5151
UnsignedByte *m_data;
52-
UnsignedInt m_dataLength;
52+
UnsignedInt m_totalDataLength;
5353
Bool *m_chunksPresent;
5454
UnsignedInt m_numChunks;
5555
UnsignedInt m_numChunksPresent;

Core/GameEngine/Source/GameNetwork/NetCommandWrapperList.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ NetCommandWrapperListNode::NetCommandWrapperListNode(NetWrapperCommandMsg *msg)
4545
m_chunksPresent[i] = FALSE;
4646
}
4747

48-
m_dataLength = msg->getTotalDataLength();
49-
m_data = NEW UnsignedByte[m_dataLength]; // pool[]ify
48+
m_totalDataLength = msg->getTotalDataLength();
49+
m_data = NEW UnsignedByte[m_totalDataLength]; // pool[]ify
5050

5151
m_commandID = msg->getWrappedCommandID();
5252
}
@@ -75,31 +75,52 @@ UnsignedShort NetCommandWrapperListNode::getCommandID() {
7575
}
7676

7777
UnsignedInt NetCommandWrapperListNode::getRawDataLength() {
78-
return m_dataLength;
78+
return m_totalDataLength;
7979
}
8080

8181
void NetCommandWrapperListNode::copyChunkData(NetWrapperCommandMsg *msg) {
82+
8283
if (msg == NULL) {
8384
DEBUG_CRASH(("Trying to copy data from a non-existent wrapper command message"));
8485
return;
8586
}
8687

87-
DEBUG_ASSERTCRASH(msg->getChunkNumber() < m_numChunks, ("MunkeeChunk %d of %d",
88-
msg->getChunkNumber(), m_numChunks));
89-
if (msg->getChunkNumber() >= m_numChunks)
88+
UnsignedInt chunkNumber = msg->getChunkNumber();
89+
90+
if (chunkNumber >= m_numChunks) {
91+
DEBUG_CRASH(("Data chunk number exceeds the number of chunks expected; chunk %d of %d", chunkNumber, m_numChunks));
92+
return;
93+
}
94+
95+
// we already received this chunk, no need to recopy it.
96+
if (m_chunksPresent[chunkNumber] == TRUE) {
97+
return;
98+
}
99+
100+
UnsignedInt chunkDataOffset = msg->getDataOffset();
101+
UnsignedInt chunkDataLength = msg->getDataLength();
102+
103+
// TheSuperHackers @bugfix Mauller 04/12/2025 Prevent out of bounds memory access
104+
if (chunkDataOffset >= m_totalDataLength) {
105+
DEBUG_CRASH(("Data chunk offset beyond data size"));
90106
return;
107+
}
91108

92-
DEBUG_LOG(("NetCommandWrapperListNode::copyChunkData() - copying chunk %d",
93-
msg->getChunkNumber()));
109+
if (chunkDataLength > MAX_PACKET_SIZE ) {
110+
DEBUG_CRASH(("Data Chunk size greater than packet size"));
111+
return;
112+
}
94113

95-
if (m_chunksPresent[msg->getChunkNumber()] == TRUE) {
96-
// we already received this chunk, no need to recopy it.
114+
if (chunkDataOffset + chunkDataLength >= m_totalDataLength) {
115+
DEBUG_CRASH(("Data chunk exceeds data array size"));
97116
return;
98117
}
99118

100-
m_chunksPresent[msg->getChunkNumber()] = TRUE;
101-
UnsignedInt offset = msg->getDataOffset();
102-
memcpy(m_data + offset, msg->getData(), msg->getDataLength());
119+
DEBUG_LOG(("NetCommandWrapperListNode::copyChunkData() - copying chunk %d", chunkNumber));
120+
121+
memcpy(m_data + chunkDataOffset, msg->getData(), chunkDataLength);
122+
123+
m_chunksPresent[chunkNumber] = TRUE;
103124
++m_numChunksPresent;
104125
}
105126

0 commit comments

Comments
 (0)