Summary
When a client calls HCHttpCallPerformAsync or HCWebSocketConnectAsync on one thread while another thread calls HCCleanup / HCCleanupAsync, there is a window that can result in attempted termination of a null queue.
Affected Code
- Source/Global/global_publics.cpp — HCHttpCallPerformAsync
- Source/Global/global.cpp — http_singleton::CleanupAsyncProvider
- Source/Global/NetworkState.cpp — HttpCallPerformAsyncProvider, CleanupAsyncProvider
- Source/HTTP/httpcall.cpp - PerfomAsyncProvider
Background
The root cause of this issue is that requests are added to m_activeHttpRequests before they successfully complete HC_CALL::PerfomAsyncProvider::Begin. As such, cancellation during cleanup may result in an attempt to terminate a queue that has not yet been created.
Timeline of the race:
- Thread A: NetworkState::HttpCallPerformAsyncProvider inserts request into m_activeHttpRequests (line 163)
- Thread A: NetworkState::HttpCallPerformAsyncProvider calls HC_CALL::PerformAsync which enters HC_CALL::PerfomAsyncProvider::Begin
- Thread A: HC_CALL::PerfomAsyncProvider::Begin creates the workQueue (line 88)
- Thread B: NetworkState::CleanupAsyncProvider::Begin snapshots m_activeHttpRequests (includes Thread A's request)
- Thread B: NetworkState::CleanupAsyncProvider::Begin calls XAsyncCancel on each active request, which propagates to HC_CALL::PerfomAsyncProvider::Cancel
- Thread B: HC_CALL::PerfomAsyncProvider::Canceltries to call XTaskQueueTerminate(context→workQueue, ...)
- Problem: If step 5 occurs before step 3, context→workQueue is nullptr
Impact
- Intermittent crash (null dereference / UB) during shutdown when HTTP requests are
submitted concurrently with HCCleanup.
- Timing-dependent; more likely under load or with frequent init/cleanup cycles.
Relationship to other work
Issue #999 addressed TOCTOU issues which made this issue less likely to observe during our internal testing. This issue was observed prior to PR #1000, but has become more noticeable with the related issue resolved.
Summary
When a client calls HCHttpCallPerformAsync or HCWebSocketConnectAsync on one thread while another thread calls HCCleanup / HCCleanupAsync, there is a window that can result in attempted termination of a null queue.
Affected Code
Background
The root cause of this issue is that requests are added to m_activeHttpRequests before they successfully complete HC_CALL::PerfomAsyncProvider::Begin. As such, cancellation during cleanup may result in an attempt to terminate a queue that has not yet been created.
Timeline of the race:
Impact
submitted concurrently with HCCleanup.
Relationship to other work
Issue #999 addressed TOCTOU issues which made this issue less likely to observe during our internal testing. This issue was observed prior to PR #1000, but has become more noticeable with the related issue resolved.