diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-08-19 19:32:06 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-08-19 19:32:06 +0200 |
commit | 36e32cc242b3d0eefa8cb19ca97eb9b2f0824bd8 (patch) | |
tree | e17e254e6fe0c6219201eb3481550be277530043 /src | |
parent | 01b754ccc556e0759e24d87ed270708286b61c49 (diff) |
Core/NetworkIO: Restored opcode and size checks lost during ace->boost changes, fixes crashes caused by players sending invalid opcodes/too big packets
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.h | 2 |
2 files changed, 22 insertions, 2 deletions
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index d2602e83944..5945d9fe868 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -16,13 +16,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <memory> #include "WorldSocket.h" #include "BigNumber.h" #include "Opcodes.h" +#include "Player.h" #include "ScriptMgr.h" #include "SHA1.h" #include "PacketLog.h" +#include <memory> using boost::asio::ip::tcp; @@ -63,6 +64,22 @@ void WorldSocket::ReadHeaderHandler() EndianConvertReverse(header->size); EndianConvert(header->cmd); + if (!header->IsValid()) + { + if (_worldSession) + { + Player* player = _worldSession->GetPlayer(); + TC_LOG_ERROR("network", "WorldSocket::ReadHeaderHandler(): client (account: %u, char [GUID: %u, name: %s]) sent malformed packet (size: %hu, cmd: %u)", + _worldSession->GetAccountId(), player ? player->GetGUIDLow() : 0, player ? player->GetName().c_str() : "<none>", header->size, header->cmd); + } + else + TC_LOG_ERROR("network", "WorldSocket::ReadHeaderHandler(): client %s sent malformed packet (size: %hu, cmd: %u)", + GetRemoteIpAddress().to_string().c_str(), header->size, header->cmd); + + CloseSocket(); + return; + } + AsyncReadData(header->size - sizeof(header->cmd)); } @@ -106,7 +123,8 @@ void WorldSocket::ReadDataHandler() if (!_worldSession) { TC_LOG_ERROR("network.opcode", "ProcessIncoming: Client not authed opcode = %u", uint32(opcode)); - break; + CloseSocket(); + return; } // Our Idle timer will reset on any non PING opcodes. diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index faa57b58f93..0667c1b090a 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -48,6 +48,8 @@ struct ClientPktHeader { uint16 size; uint32 cmd; + + bool IsValid() const { return size >= 4 && size < 10240 && cmd < NUM_MSG_TYPES; } }; #pragma pack(pop) |