Skip to content

Commit 2fe28a3

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

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-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: 33 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,7 +75,7 @@ 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) {
@@ -84,22 +84,42 @@ void NetCommandWrapperListNode::copyChunkData(NetWrapperCommandMsg *msg) {
8484
return;
8585
}
8686

87-
DEBUG_ASSERTCRASH(msg->getChunkNumber() < m_numChunks, ("MunkeeChunk %d of %d",
88-
msg->getChunkNumber(), m_numChunks));
89-
if (msg->getChunkNumber() >= m_numChunks)
87+
UnsignedInt chunkNumber = msg->getChunkNumber();
88+
89+
if (chunkNumber >= m_numChunks) {
90+
DEBUG_CRASH(("Data chunk number exceeds the number of chunks expected; chunk %d of %d", chunkNumber, m_numChunks));
9091
return;
92+
}
9193

92-
DEBUG_LOG(("NetCommandWrapperListNode::copyChunkData() - copying chunk %d",
93-
msg->getChunkNumber()));
94+
// we already received this chunk, no need to recopy it.
95+
if (m_chunksPresent[chunkNumber] == TRUE) {
96+
return;
97+
}
9498

95-
if (m_chunksPresent[msg->getChunkNumber()] == TRUE) {
96-
// we already received this chunk, no need to recopy it.
99+
UnsignedInt chunkDataOffset = msg->getDataOffset();
100+
UnsignedInt chunkDataLength = msg->getDataLength();
101+
102+
// TheSuperHackers @bugfix Mauller 04/12/2025 Prevent out of bounds memory access
103+
if (chunkDataOffset >= m_totalDataLength) {
104+
DEBUG_CRASH(("Data chunk offset beyond data size"));
97105
return;
98106
}
99107

100-
m_chunksPresent[msg->getChunkNumber()] = TRUE;
101-
UnsignedInt offset = msg->getDataOffset();
102-
memcpy(m_data + offset, msg->getData(), msg->getDataLength());
108+
if (chunkDataLength > MAX_PACKET_SIZE ) {
109+
DEBUG_CRASH(("Data Chunk size greater than packet size"));
110+
return;
111+
}
112+
113+
if (chunkDataOffset + chunkDataLength >= m_totalDataLength) {
114+
DEBUG_CRASH(("Data chunk exceeds data array size"));
115+
return;
116+
}
117+
118+
DEBUG_LOG(("NetCommandWrapperListNode::copyChunkData() - copying chunk %d", chunkNumber));
119+
120+
memcpy(m_data + chunkDataOffset, msg->getData(), chunkDataLength);
121+
122+
m_chunksPresent[chunkNumber] = TRUE;
103123
++m_numChunksPresent;
104124
}
105125

0 commit comments

Comments
 (0)