From 36dd5c507552bd1e77240145ac99b6923a252e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sat, 27 May 2023 20:57:02 +0200 Subject: [PATCH] Fix undefined behavior in `CSnapshotDelta::DiffItem` Cast `int`s to `unsigned` before subtracting to ensure that integer wrapping is being used instead of causing undefined behavior. Same as in `UndiffItem`. ``` SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/master/src/base/math.h:16:40 in src/master/src/engine/shared/snapshot.cpp:206:21: runtime error: signed integer overflow: 256 - -2147483648 cannot be represented in type 'int' 0 0x7650b7 in CSnapshotDelta::DiffItem(int const*, int const*, int*, int) src/master/src/engine/shared/snapshot.cpp:206:21 1 0x765cea in CSnapshotDelta::CreateDelta(CSnapshot*, CSnapshot*, void*) src/master/src/engine/shared/snapshot.cpp:323:7 2 0x51a0e2 in CServer::DoSnapshot() src/master/src/engine/server/server.cpp:964:36 3 0x537486 in CServer::Run() src/master/src/engine/server/server.cpp:2818:6 4 0x4feeb7 in main src/master/src/engine/server/main.cpp:190:21 5 0x7fc51ec27d09 in __libc_start_main csu/../csu/libc-start.c:308:16 6 0x4c3819 in _start (servers/DDNet-Server-ubsan+0x4c3819) src/master/src/engine/shared/snapshot.cpp:206:21: runtime error: signed integer overflow: 1645289600 - -2139062144 cannot be represented in type 'int' 0 0x7650b7 in CSnapshotDelta::DiffItem(int const*, int const*, int*, int) src/master/src/engine/shared/snapshot.cpp:206:21 1 0x765cea in CSnapshotDelta::CreateDelta(CSnapshot*, CSnapshot*, void*) src/master/src/engine/shared/snapshot.cpp:323:7 2 0x51a0e2 in CServer::DoSnapshot() src/master/src/engine/server/server.cpp:964:36 3 0x537486 in CServer::Run() src/master/src/engine/server/server.cpp:2818:6 4 0x4feeb7 in main src/master/src/engine/server/main.cpp:190:21 5 0x7efd50c4ed09 in __libc_start_main csu/../csu/libc-start.c:308:16 6 0x4c3819 in _start (servers/DDNet-Server-ubsan+0x4c3819) ``` See #6650. --- src/engine/shared/snapshot.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/shared/snapshot.cpp b/src/engine/shared/snapshot.cpp index d9acce0f3..4e4c53e30 100644 --- a/src/engine/shared/snapshot.cpp +++ b/src/engine/shared/snapshot.cpp @@ -203,7 +203,8 @@ int CSnapshotDelta::DiffItem(const int *pPast, const int *pCurrent, int *pOut, i int Needed = 0; while(Size) { - *pOut = *pCurrent - *pPast; + // subtraction with wrapping by casting to unsigned + *pOut = (unsigned)*pCurrent - (unsigned)*pPast; Needed |= *pOut; pOut++; pPast++;