From 1ee78149c214d8a16d4689f093d7f40ca5b0f787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Thu, 21 Jul 2022 15:56:08 +0200 Subject: [PATCH] Fix unaligned accesses of snapshot data ``` src/engine/shared/snapshot.cpp:29:41: runtime error: member call on misaligned address 0x558618e3767f for type 'struct CSnapshotItem', which requires 4 byte alignment 0x558618e3767f: note: pointer points here 00 00 00 00 00 4b f5 fe f9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ 0 0x558615c3c909 in CSnapshot::GetItemType(int) const src/engine/shared/snapshot.cpp:29 1 0x558614aebaba in CClient::UnpackAndValidateSnapshot(CSnapshot*, CSnapshot*) src/engine/client/client.cpp:2264 2 0x558614af87cb in CClient::OnDemoPlayerSnapshot(void*, int) src/engine/client/client.cpp:2598 3 0x558615b9db1a in CDemoPlayer::DoTick() src/engine/shared/demo.cpp:659 4 0x558615babd3f in CDemoPlayer::Update(bool) src/engine/shared/demo.cpp:1007 5 0x558614afb08b in CClient::Update() src/engine/client/client.cpp:2686 6 0x558614b1d9eb in CClient::Run() src/engine/client/client.cpp:3296 7 0x558614b8e64f in main src/engine/client/client.cpp:4761 src/engine/shared/snapshot.h:16:28: runtime error: member access within misaligned address 0x558618e3767f for type 'const struct CSnapshotItem', which requires 4 byte alignment 0x558618e3767f: note: pointer points here 00 00 00 00 00 4b f5 fe f9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ 0 0x558614b9bdc3 in CSnapshotItem::Type() const src/engine/shared/snapshot.h:16 1 0x558615c3c911 in CSnapshot::GetItemType(int) const src/engine/shared/snapshot.cpp:29 2 0x558614aebaba in CClient::UnpackAndValidateSnapshot(CSnapshot*, CSnapshot*) src/engine/client/client.cpp:2264 3 0x558614af87cb in CClient::OnDemoPlayerSnapshot(void*, int) src/engine/client/client.cpp:2598 4 0x558615b9db1a in CDemoPlayer::DoTick() src/engine/shared/demo.cpp:659 5 0x558615babd3f in CDemoPlayer::Update(bool) src/engine/shared/demo.cpp:1007 6 0x558614afb08b in CClient::Update() src/engine/client/client.cpp:2686 7 0x558614b1d9eb in CClient::Run() src/engine/client/client.cpp:3296 8 0x558614b8e64f in main src/engine/client/client.cpp:4761 ``` --- src/engine/client/client.cpp | 10 +++++----- src/engine/client/client.h | 2 +- src/engine/server/server.cpp | 6 +++--- src/engine/shared/demo.cpp | 4 ++-- src/engine/shared/demo.h | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index c72f09916d8..99fc479a384 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -1985,8 +1985,8 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy) { static CSnapshot Emptysnap; CSnapshot *pDeltaShot = &Emptysnap; - unsigned char aTmpBuffer2[CSnapshot::MAX_SIZE]; - unsigned char aTmpBuffer3[CSnapshot::MAX_SIZE]; + alignas(CSnapshotDelta::CData) unsigned char aTmpBuffer2[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) unsigned char aTmpBuffer3[CSnapshot::MAX_SIZE]; CSnapshot *pTmpBuffer3 = (CSnapshot *)aTmpBuffer3; // Fix compiler warning for strict-aliasing // reset snapshoting @@ -2079,7 +2079,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy) m_aSnapshotStorage[Conn].PurgeUntil(PurgeTick); // create a verified and unpacked snapshot - unsigned char aAltSnapBuffer[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) unsigned char aAltSnapBuffer[CSnapshot::MAX_SIZE]; CSnapshot *pAltSnapBuffer = (CSnapshot *)aAltSnapBuffer; const int AltSnapSize = UnpackAndValidateSnapshot(pTmpBuffer3, pAltSnapBuffer); if(AltSnapSize < 0) @@ -2094,7 +2094,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy) if(!Dummy) { // for antiping: if the projectile netobjects from the server contains extra data, this is removed and the original content restored before recording demo - unsigned char aExtraInfoRemoved[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) unsigned char aExtraInfoRemoved[CSnapshot::MAX_SIZE]; mem_copy(aExtraInfoRemoved, pTmpBuffer3, SnapSize); SnapshotRemoveExtraProjectileInfo(aExtraInfoRemoved); @@ -2579,7 +2579,7 @@ void CClient::OnDemoPlayerSnapshot(void *pData, int Size) m_aPrevGameTick[g_Config.m_ClDummy] = pInfo->m_PreviousTick; // create a verified and unpacked snapshot - unsigned char aAltSnapBuffer[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) unsigned char aAltSnapBuffer[CSnapshot::MAX_SIZE]; CSnapshot *pAltSnapBuffer = (CSnapshot *)aAltSnapBuffer; const int AltSnapSize = UnpackAndValidateSnapshot((CSnapshot *)pData, pAltSnapBuffer); if(AltSnapSize < 0) diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 5814cea0fbe..a92515e7007 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -238,7 +238,7 @@ class CClient : public IClient, public CDemoPlayer::IListener CSnapshotStorage::CHolder *m_aapSnapshots[NUM_DUMMIES][NUM_SNAPSHOT_TYPES]; int m_aReceivedSnapshots[NUM_DUMMIES]; - char m_aaSnapshotIncomingData[NUM_DUMMIES][CSnapshot::MAX_SIZE]; + alignas(CSnapshot) char m_aaSnapshotIncomingData[NUM_DUMMIES][CSnapshot::MAX_SIZE]; int m_aSnapshotIncomingDataSize[NUM_DUMMIES]; CSnapshotStorage::CHolder m_aDemorecSnapshotHolders[NUM_SNAPSHOT_TYPES]; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 8b1377a657a..7be85f18e4d 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -888,7 +888,7 @@ void CServer::DoSnapshot() // create snapshot for demo recording if(m_aDemoRecorder[MAX_CLIENTS].IsRecording()) { - char aData[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) char aData[CSnapshot::MAX_SIZE]; // build snap and possibly add some messages m_SnapshotBuilder.Init(); @@ -920,7 +920,7 @@ void CServer::DoSnapshot() GameServer()->OnSnap(i); // finish snapshot - char aData[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) char aData[CSnapshot::MAX_SIZE]; CSnapshot *pData = (CSnapshot *)aData; // Fix compiler warning for strict-aliasing int SnapshotSize = m_SnapshotBuilder.Finish(pData); @@ -960,7 +960,7 @@ void CServer::DoSnapshot() // create delta m_SnapshotDelta.SetStaticsize(protocol7::NETEVENTTYPE_SOUNDWORLD, m_aClients[i].m_Sixup); m_SnapshotDelta.SetStaticsize(protocol7::NETEVENTTYPE_DAMAGE, m_aClients[i].m_Sixup); - char aDeltaData[CSnapshot::MAX_SIZE]; + alignas(CSnapshotDelta::CData) char aDeltaData[CSnapshot::MAX_SIZE]; int DeltaSize = m_SnapshotDelta.CreateDelta(pDeltashot, pData, aDeltaData); if(DeltaSize) diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index b29d526da92..2be90a6c6f7 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -583,7 +583,7 @@ void CDemoPlayer::DoTick() // read the chunk int DataSize = 0; - static char s_aData[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) static char s_aData[CSnapshot::MAX_SIZE]; if(ChunkSize) { static char s_aCompresseddata[CSnapshot::MAX_SIZE]; @@ -621,7 +621,7 @@ void CDemoPlayer::DoTick() if(ChunkType == CHUNKTYPE_DELTA) { // process delta snapshot - static char s_aNewsnap[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) static char s_aNewsnap[CSnapshot::MAX_SIZE]; CSnapshot *pNewsnap = (CSnapshot *)s_aNewsnap; DataSize = m_pSnapshotDelta->UnpackDelta((CSnapshot *)m_aLastSnapshotData, pNewsnap, s_aData, DataSize); diff --git a/src/engine/shared/demo.h b/src/engine/shared/demo.h index 116fe4b07d6..3a497a41db5 100644 --- a/src/engine/shared/demo.h +++ b/src/engine/shared/demo.h @@ -21,7 +21,7 @@ class CDemoRecorder : public IDemoRecorder int m_LastTickMarker; int m_LastKeyFrame; int m_FirstTick; - unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE]; class CSnapshotDelta *m_pSnapshotDelta; int m_NumTimelineMarkers; int m_aTimelineMarkers[MAX_TIMELINE_MARKERS]; @@ -113,7 +113,7 @@ class CDemoPlayer : public IDemoPlayer CPlaybackInfo m_Info; int m_DemoType; - unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE]; + alignas(CSnapshot) unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE]; int m_LastSnapshotDataSize; class CSnapshotDelta *m_pSnapshotDelta;