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
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.
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-flightUrlRequestthat is destroyed before it settles leads to a use-after-free.UrlRequest_Apple.mm'sSendAsync()builds a completion handler that writesm_statusCode,m_headers,m_responseString/m_responseBufferand callsSetError(...)— so it implicitly captures a rawthis. Nothing keeps theImplalive for the duration of the task:UrlRequest::Implthere has no destructor.m_cancellationSource.[task cancel].ImplBase::~ImplBase()callsAbort(), butAbort()only doesm_cancellationSource.cancel(), which this backend ignores. So destroying aUrlRequestneither stops the resumedNSURLSessionDataTasknor extends the impl's lifetime — the task keeps running and its handler later writes into freed memory.Impact
Any caller that drops a
UrlRequestbefore 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'sImpl, making an unrelated, previously-passing test reportNSURLErrorCancelled(-999) with a non-emptyErrorString/ErrorSymbol.Notes
Possible fixes
Implinheritstd::enable_shared_from_thisand capture a strong reference in the completion handler, so the impl outlives the task.Abort()actually cancel theNSURLSessionDataTaskon this backend, honoringm_cancellationSource.