From 48252675376f60f01f17c71bdb5afff2c82d9167 Mon Sep 17 00:00:00 2001 From: dongresource Date: Sat, 11 Mar 2023 23:16:09 +0100 Subject: [PATCH] Use memcpy() instead of casting to load keys UBSAN complains about the casting approach because it loads a 64-bit integer from the defaultKeys string which isn't guaranteed to be 64-bit aligned, which is undefined behavior. --- src/core/CNProtocol.cpp | 5 +++-- src/servers/CNLoginServer.cpp | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/CNProtocol.cpp b/src/core/CNProtocol.cpp index cd7f808..bfe0ad3 100644 --- a/src/core/CNProtocol.cpp +++ b/src/core/CNProtocol.cpp @@ -41,7 +41,8 @@ int CNSocketEncryption::xorData(uint8_t* buffer, uint8_t* key, int size) { uint64_t CNSocketEncryption::createNewKey(uint64_t uTime, int32_t iv1, int32_t iv2) { uint64_t num = (uint64_t)(iv1 + 1); uint64_t num2 = (uint64_t)(iv2 + 1); - uint64_t dEKey = (uint64_t)(*(uint64_t*)&defaultKey[0]); + uint64_t dEKey; + memcpy(&dEKey, defaultKey, sizeof(dEKey)); return dEKey * (uTime * num * num2); } @@ -65,7 +66,7 @@ CNPacketData::CNPacketData(void *b, uint32_t t, int l, int trnum, void *trs): // ========================================================[[ CNSocket ]]======================================================== CNSocket::CNSocket(SOCKET s, struct sockaddr_in &addr, PacketHandler ph): sock(s), sockaddr(addr), pHandler(ph) { - EKey = (uint64_t)(*(uint64_t*)&CNSocketEncryption::defaultKey[0]); + memcpy(&EKey, CNSocketEncryption::defaultKey, sizeof(EKey)); } bool CNSocket::sendData(uint8_t* data, int size) { diff --git a/src/servers/CNLoginServer.cpp b/src/servers/CNLoginServer.cpp index 95135e9..41e4b04 100644 --- a/src/servers/CNLoginServer.cpp +++ b/src/servers/CNLoginServer.cpp @@ -209,9 +209,12 @@ void CNLoginServer::login(CNSocket* sock, CNPacketData* data) { // send the resp in with original key sock->sendPacket(resp, P_LS2CL_REP_LOGIN_SUCC); + uint64_t defaultKey; + memcpy(&defaultKey, CNSocketEncryption::defaultKey, sizeof(defaultKey)); + // update keys sock->setEKey(CNSocketEncryption::createNewKey(resp.uiSvrTime, resp.iCharCount + 1, resp.iSlotNum + 1)); - sock->setFEKey(CNSocketEncryption::createNewKey((uint64_t)(*(uint64_t*)&CNSocketEncryption::defaultKey[0]), login->iClientVerC, 1)); + sock->setFEKey(CNSocketEncryption::createNewKey(defaultKey, login->iClientVerC, 1)); DEBUGLOG( std::cout << "Login Server: Login success. Welcome " << userLogin << " [" << loginSessions[sock].userID << "]" << std::endl;