Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fwEvent<>::callback destructor can cause stack overflows #2581

Closed
alexguirre opened this issue Jun 8, 2024 · 1 comment
Closed

fwEvent<>::callback destructor can cause stack overflows #2581

alexguirre opened this issue Jun 8, 2024 · 1 comment
Labels
bug crash RedM Issues/PRs related to RedM

Comments

@alexguirre
Copy link

What happened?

The callback struct forms a linked list with pointers to the next callback:

struct callback
{
TFunc function;
std::unique_ptr<callback> next = nullptr;
int order = 0;
size_t cookie = -1;
callback(TFunc func)
: function(func)
{
}
};

Its destructor gets compiled to something like this:

void __fastcall callback_dtor(__int64 a1)
{
  __int64 v1; // rbx
  __int64 v2; // rdx
  __int64 v3; // rcx

  v1 = *(_QWORD *)a1;
  if ( *(_QWORD *)a1 )
  {
    callback_dtor(v1 + 64);
    v3 = *(_QWORD *)(v1 + 56);
    if ( v3 )
    {
      LOBYTE(v2) = v3 != v1;
      (*(void (__fastcall **)(__int64, __int64))(*(_QWORD *)v3 + 32i64))(v3, v2);
      *(_QWORD *)(v1 + 56) = 0i64;
    }
    j_j_free((void *)v1);
  }
}

Notice the recursive call to callback_dtor. When the callbacks list grows large, it can end up causing a stack overflow crash.

Expected result

Don't cause a stack overflow independent of the callbacks list size

Reproduction steps

One possible way to trigger this crash from a resource is with ADD_STATE_BAG_CHANGE_HANDLER. Adding lots of handlers and reloading the resource, causes the crash when the underlying StateBagComponent::OnStateBagChange event deletes its callbacks.

for i=1,40000 do
    AddStateBagChangeHandler(nil, nil, function(bagName, key, value, _unused, replicated)
        print('state bag changed' .. bagName .. ' ' .. key .. ' ' .. value)
    end)
end

Unsure if there are other easy ways to trigger it. In theory, anything that adds fwEvent callbacks dynamically could eventually crash.

Importancy

Crash

Area(s)

FiveM, RedM, FXServer

Specific version(s)

Any

Additional information

Got a crash dump from a user. In this case, it crashed when reloading resources and the stack has like 30K stack frames of the callback destructor, so somehow some event ended up with 30K callbacks. Possibly the stage bag change handlers, but I don't know what his resources are doing exactly.

CfxCrashDump_2024_06_07_14_03_59.zip

@alexguirre alexguirre added bug triage Needs a preliminary assessment to determine the urgency and required action labels Jun 8, 2024
@github-actions github-actions bot added crash RedM Issues/PRs related to RedM labels Jun 8, 2024
@gottfriedleibniz
Copy link
Contributor

Thanks for the report!

@github-actions github-actions bot removed the triage Needs a preliminary assessment to determine the urgency and required action label Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug crash RedM Issues/PRs related to RedM
Projects
None yet
Development

No branches or pull requests

2 participants