bugfix(object): Avoid crash with dangling contain module in Object::onDestroy() when Troop Crawler is destroyed while en route to Reinforcement Pad - #3165
Conversation
…o Object::m_containedByID (TheSuperHackers#2868)" This reverts commit a20992d.
…bject::onDestroy() when Reinforcement Pad is destroyed before Troop Crawler drop (TheSuperHackers#2747)" This reverts commit df2224b.
PR Summary by QodoPrevent crash from dangling containment modules during destruction
AI Description
Diagram
High-Level Assessment
Files changed (6)
|
Code Review by Qodo
1. onDestroy() dereferences dangling m_containedBy
|
7668805 to
4d14036
Compare
4d14036 to
831ff73
Compare
|
Code review by qodo was updated up to the latest commit 831ff73 |
The purpose of the two pull requests was to avoid a crash while retaining retail compatibility, but the fix is rather convoluted. Additionally, this is the second time I came across one or more replays that mismatch because of those changes. So the purpose of this PR is to revert the previous two and fix the crash with a different implementation.
Here's a replay that mismatches with the current implementation. It mismatches because it relied on use-after-free bugs, which was intentionally prevented to avoid potential crashes:
18-11-57_2v4_0_24_HardAI_HardAI_HardAI_HardAI.zip
If a troop crawler that's en route (by plane) to the reinforcement pad gets destroyed, the occupants are left in a state of limbo (see issue). They hold on to the pointer of the destroyed troop crawler, which leads to use-after-free bugs. When the occupants' objects eventually get destroyed (e.g. when a player surrenders or the game ends), the use-after-free bug may crash the game when
OpenContain::m_containListis accessed after its destruction.GeneralsGameCode/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp
Line 437 in a40cdb6
Here's a minimal crash reproduction that shows why the crash happens during the call to
std::find:https://godbolt.org/z/znjGGrTvG
https://godbolt.org/z/MzYz6eeMb
See commits for cleaner diff.
TODO: