You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
UrlLib: Apple backend use-after-free when a UrlRequest is destroyed in flight #214
Split out from review feedback on BabylonJS/UrlLib#37 (filed here because BabylonJS/UrlLib has Issues disabled).
Problem
On the Apple (NSURLSession) backend, an in-flight UrlRequest that is destroyed before it settles leads to a use-after-free.
UrlRequest_Apple.mm's SendAsync() builds a completion handler that writes m_statusCode, m_headers, m_responseString / m_responseBuffer and calls SetError(...) — so it implicitly captures a raw this. Nothing keeps the Impl alive for the duration of the task:
UrlRequest::Impl there has no destructor.
It never reads m_cancellationSource.
It never calls [task cancel].
ImplBase::~ImplBase() calls Abort(), but Abort() only does m_cancellationSource.cancel(), which this backend ignores. So destroying a UrlRequest neither stops the resumed NSURLSessionDataTask nor extends the impl's lifetime — the task keeps running and its handler later writes into freed memory.
Impact
Any caller that drops a UrlRequest before it completes (e.g. abandoning a request on teardown) can corrupt whatever the freed allocation is reused for. This is not theoretical: it was observed in UrlLib CI, where an abandoned request's late failure handler wrote its error into a subsequent test's Impl, making an unrelated, previously-passing test report NSURLErrorCancelled (-999) with a non-empty ErrorString/ErrorSymbol.
Notes
Pre-existing; not introduced by UWP Support #37. That PR's new test was simply the first code to exercise it, and now works around it by waiting for the request to settle before leaving scope.
Worth auditing the other backends for the same pattern.
Possible fixes
Have Impl inherit std::enable_shared_from_this and capture a strong reference in the completion handler, so the impl outlives the task.
And/or make Abort() actually cancel the NSURLSessionDataTask on this backend, honoring m_cancellationSource.
Activity
Wait for the transport request to settle instead of abandoning it