Skip to content

GLA AngryMob WeaponTemplate use-after-free on death of some members within the mob. #941

@Mauller

Description

@Mauller

There is a posibility that this mainly occurs after a game load, as it generally is occuring for me in a savegame i have been using to test mass unit movement. in this save i have 20+ angry mobs that i have used to test unit movement with. The game is also running a bit sluggish in this save which could also contribute to some observed behaviour.

The problem appears when an angry mob is attacked and members within the mob are killed, it doesn't always trigger instantly but appears to be a race condtion between the state machine being used and the death of a mob member. The weapon template associated to the mob is getting trashed in one frame then the state machine is attempting to use it in the next.

Callstack

>	generalszh.exe!Weapon::privateFireWeapon(const Object * sourceObj, Object * victimObj, const Coord3D * victimPos, bool isProjectileDetonation, bool ignoreRanges, unsigned int extraBonusFlags, ObjectID * projectileID, bool inflictDamage) Line 2643	C++
 	generalszh.exe!Weapon::fireWeapon(const Object * source, Object * target, ObjectID * projectileID) Line 2722	C++
 	generalszh.exe!Object::fireCurrentWeapon(Object * target) Line 1484	C++
 	generalszh.exe!AIAttackFireWeaponState::update() Line 5245	C++
 	generalszh.exe!StateMachine::updateStateMachine() Line 440	C++
 	generalszh.exe!AIAttackState::update() Line 5688	C++
 	generalszh.exe!AIGuardAttackAggressorState::update() Line 864	C++
 	generalszh.exe!StateMachine::updateStateMachine() Line 440	C++
 	generalszh.exe!AIGuardState::update() Line 6751	C++
 	generalszh.exe!StateMachine::updateStateMachine() Line 440	C++
 	generalszh.exe!AIStateMachine::updateStateMachine() Line 892	C++
 	generalszh.exe!AIUpdateInterface::update() Line 1022	C++
 	generalszh.exe!GameLogic::update() Line 3777	C++
 	generalszh.exe!SubsystemInterface::UPDATE() Line 79	C++
 	generalszh.exe!GameEngine::update() Line 754	C++
 	generalszh.exe!Win32GameEngine::update() Line 90	C++
 	generalszh.exe!GameEngine::execute() Line 815	C++
 	generalszh.exe!GameMain(int argc, char * * argv) Line 44	C++
 	generalszh.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 1040	C++

ASAN report

==7640==ERROR: AddressSanitizer: heap-use-after-free on address 0x22d79494 at pc 0x0084ca52 bp 0x066fdf7c sp 0x066fdf7c
WRITE of size 4 at 0x22d79494 thread T0
==7640==WARNING: Failed to use and restart external symbolizer!
    #0 0x0084ca51 in Weapon::privateFireWeapon C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Weapon.cpp:2643
    #1 0x008465e4 in Weapon::fireWeapon C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Weapon.cpp:2721
    #2 0x00ae6400 in Object::fireCurrentWeapon C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Object.cpp:1484
    #3 0x00c19231 in AIAttackFireWeaponState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:5245
    #4 0x011b01d1 in StateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\StateMachine.cpp:440
    #5 0x00c1b39f in AIAttackState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:5688
    #6 0x01182baa in AIGuardAttackAggressorState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIGuard.cpp:863
    #7 0x011b01d1 in StateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\StateMachine.cpp:440
    #8 0x00c218a5 in AIGuardState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:6751
    #9 0x011b01d1 in StateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\StateMachine.cpp:440
    #10 0x00c025bd in AIStateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:892
    #11 0x00c8cb2a in AIUpdateInterface::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Update\AIUpdate.cpp:1022
    #12 0x006f21ea in GameLogic::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\System\GameLogic.cpp:3777
    #13 0x0063e4c8 in SubsystemInterface::UPDATE C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\System\SubsystemInterface.cpp:78
    #14 0x005e7558 in GameEngine::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\GameEngine.cpp:754
    #15 0x012b9233 in Win32GameEngine::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngineDevice\Source\Win32Device\Common\Win32GameEngine.cpp:90
    #16 0x005e78fe in GameEngine::execute C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\GameEngine.cpp:815
    #17 0x005c7546 in GameMain C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\GameMain.cpp:44
    #18 0x005bac91 in WinMain C:\repos\GeneralsGameCode\GeneralsMD\Code\Main\WinMain.cpp:1040
    #19 0x01a08b5c in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:102
    #20 0x01a08a69 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #21 0x01a0890c in __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
    #22 0x01a08bc7 in WinMainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_winmain.cpp:16
    #23 0x767bfcc8 in BaseThreadInitThunk+0x18 (C:\WINDOWS\System32\KERNEL32.DLL+0x6b81fcc8)
    #24 0x76f382ad in RtlGetAppContainerNamedObjectPath+0x11d (C:\WINDOWS\SYSTEM32\ntdll.dll+0x4b2e82ad)
    #25 0x76f3827d in RtlGetAppContainerNamedObjectPath+0xed (C:\WINDOWS\SYSTEM32\ntdll.dll+0x4b2e827d)

0x22d79494 is located 36 bytes inside of 80-byte region [0x22d79470,0x22d794c0)
freed by thread T0 here:
    #0 0x7a37e6ed in _asan_wrap__CrtIsValidHeapPointer+0xa1d (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\bin\HostX64\x86\clang_rt.asan_dynamic-i386.dll+0x1003e6ed)
    #1 0x7a39087c in _asan_wrap__except_handler4+0x484c (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\bin\HostX64\x86\clang_rt.asan_dynamic-i386.dll+0x1005087c)
    #2 0x005c1c6c in operator delete C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\System\GameMemoryNull.cpp:167
    #3 0x01a07b03 in operator delete D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win_delete_scalar_size_thunk.cpp:44
    #4 0x0085a5c1 in Weapon::`scalar deleting destructor'+0x21 (F:\EA Games\Command and Conquer Generals Zero Hour\Command and Conquer Generals Zero Hour\generalszh.exe+0x70a5c1)
    #5 0x005f3c8b in MemoryPoolObject::deleteInstanceInternal C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Include\Common\GameMemoryNull.h:113
    #6 0x005f3bdb in deleteInstance C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Include\Common\GameMemoryNull.h:119
    #7 0x00bc3204 in WeaponSet::updateWeaponSet C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\WeaponSet.cpp:320
    #8 0x00ae7169 in Object::setWeaponSetFlag C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Object.cpp:3055
    #9 0x00adbd3f in Object::onVeterancyLevelChanged C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Object.cpp:3123
    #10 0x00db960a in ExperienceTracker::addExperiencePoints C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\ExperienceTracker.cpp:188
    #11 0x00adb9fc in Object::scoreTheKill C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Object.cpp:2961
    #12 0x00ff3005 in ActiveBody::attemptDamage C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Body\ActiveBody.cpp:670
    #13 0x00ada22d in Object::attemptDamage C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Object.cpp:1820
    #14 0x00843a93 in WeaponTemplate::dealDamageInternal C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Weapon.cpp:1494
    #15 0x00840a14 in WeaponTemplate::fireWeaponTemplate C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Weapon.cpp:1066
    #16 0x0084ca35 in Weapon::privateFireWeapon C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Weapon.cpp:2640
    #17 0x008465e4 in Weapon::fireWeapon C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Weapon.cpp:2721
    #18 0x00ae6400 in Object::fireCurrentWeapon C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Object.cpp:1484
    #19 0x00c19231 in AIAttackFireWeaponState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:5245
    #20 0x011b01d1 in StateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\StateMachine.cpp:440
    #21 0x00c1b39f in AIAttackState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:5688
    #22 0x01182baa in AIGuardAttackAggressorState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIGuard.cpp:863
    #23 0x011b01d1 in StateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\StateMachine.cpp:440
    #24 0x00c218a5 in AIGuardState::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:6751
    #25 0x011b01d1 in StateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\StateMachine.cpp:440
    #26 0x00c025bd in AIStateMachine::updateStateMachine C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\AI\AIStates.cpp:892
    #27 0x00c8cb2a in AIUpdateInterface::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Update\AIUpdate.cpp:1022

previously allocated by thread T0 here:
    #0 0x7a37e7ed in _asan_wrap__CrtIsValidHeapPointer+0xb1d (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\bin\HostX64\x86\clang_rt.asan_dynamic-i386.dll+0x1003e7ed)
    #1 0x005c1bae in operator new C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\System\GameMemoryNull.cpp:158
    #2 0x008600be in WeaponStore::allocateNewWeapon C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Include\GameLogic\Weapon.h:841
    #3 0x00bc28eb in WeaponSet::xfer C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\WeaponSet.cpp:274
    #4 0x00d69ff7 in XferLoad::xferSnapshot C:\repos\GeneralsGameCode\Core\GameEngine\Source\Common\System\XferLoad.cpp:186
    #5 0x00aefe0b in Object::xfer C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Object.cpp:4401
    #6 0x00d69ff7 in XferLoad::xferSnapshot C:\repos\GeneralsGameCode\Core\GameEngine\Source\Common\System\XferLoad.cpp:186
    #7 0x006fd6a9 in GameLogic::xfer C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\System\GameLogic.cpp:4834
    #8 0x00d69ff7 in XferLoad::xferSnapshot C:\repos\GeneralsGameCode\Core\GameEngine\Source\Common\System\XferLoad.cpp:186
    #9 0x007bc4ca in GameState::xferSaveData C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\System\SaveGame\GameState.cpp:1461
    #10 0x007b8238 in GameState::loadGame C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\System\SaveGame\GameState.cpp:695
    #11 0x01037d41 in doLoadGame C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GUICallbacks\Menus\PopupSaveLoad.cpp:417
    #12 0x0103815c in processLoadButtonPress C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GUICallbacks\Menus\PopupSaveLoad.cpp:502
    #13 0x01036cad in SaveLoadMenuSystem C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GUICallbacks\Menus\PopupSaveLoad.cpp:607
    #14 0x00983b74 in GameWindowManager::winSendSystemMsg C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GameWindowManager.cpp:709
    #15 0x009875eb in PassSelectedButtonsToParentSystem C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GameWindowManager.cpp:151
    #16 0x00983b74 in GameWindowManager::winSendSystemMsg C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GameWindowManager.cpp:709
    #17 0x0101c8ba in GadgetPushButtonInput C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\Gadget\GadgetPushButton.cpp:223
    #18 0x00983c44 in GameWindowManager::winSendInputMsg C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GameWindowManager.cpp:728
    #19 0x00980df4 in GameWindowManager::winProcessMouseEvent C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\GUI\GameWindowManager.cpp:924
    #20 0x010f60a5 in WindowTranslator::translateGameMessage C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameClient\MessageStream\WindowXlat.cpp:247
    #21 0x00622dda in MessageStream::propagateMessages C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\MessageStream.cpp:1095
    #22 0x005e7495 in GameEngine::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\GameEngine.cpp:741
    #23 0x012b9233 in Win32GameEngine::update C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngineDevice\Source\Win32Device\Common\Win32GameEngine.cpp:90
    #24 0x005e78fe in GameEngine::execute C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\GameEngine.cpp:815
    #25 0x005c7546 in GameMain C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\Common\GameMain.cpp:44
    #26 0x005bac91 in WinMain C:\repos\GeneralsGameCode\GeneralsMD\Code\Main\WinMain.cpp:1040
    #27 0x01a08b5c in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:102

SUMMARY: AddressSanitizer: heap-use-after-free C:\repos\GeneralsGameCode\GeneralsMD\Code\GameEngine\Source\GameLogic\Object\Weapon.cpp:2643 in Weapon::privateFireWeapon
Shadow bytes around the buggy address:
  0x22d79200: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x22d79280: 00 fa fa fa fa fa 00 00 00 00 00 00 00 00 00 fa
  0x22d79300: fa fa fa fa 00 00 00 00 00 00 00 00 00 fa fa fa
  0x22d79380: fa fa 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
  0x22d79400: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fd fd
=>0x22d79480: fd fd[fd]fd fd fd fd fd fa fa fa fa 00 00 00 00
  0x22d79500: 00 00 00 00 06 fa fa fa fa fa 00 00 00 00 00 00
  0x22d79580: 00 00 00 00 fa fa fa fa fd fd fd fd fd fd fd fd
  0x22d79600: fd fa fa fa fa fa 00 00 00 00 00 00 00 00 06 fa
  0x22d79680: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
  0x22d79700: fa fa 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
Address Sanitizer Error: Use of deallocated memory

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething is not working right, typically is user facingMajorSeverity: Minor < Major < Critical < BlockerMemoryIs memory related

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions