Title: [291494] trunk/Source/WebCore
Revision
291494
Author
[email protected]
Date
2022-03-18 12:42:42 -0700 (Fri, 18 Mar 2022)

Log Message

Keep a strong reference to session in [WebCoreNSURLSessionDataTask _restart]
https://bugs.webkit.org/show_bug.cgi?id=238061
<rdar://88242622>

Patch by Alex Christensen <[email protected]> on 2022-03-18
Reviewed by Eric Carlson.

_session is a WeakObjCPtr<WebCoreNSURLSession> and since we're not using ARC self.session
returns a raw pointer to an object that may be deallocated and null out its loader on a different thread.
To prevent null crashes, keep a strong reference to the session when using it.

* platform/network/cocoa/WebCoreNSURLSession.mm:
(-[WebCoreNSURLSession dealloc]):
(-[WebCoreNSURLSessionDataTask _restart]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (291493 => 291494)


--- trunk/Source/WebCore/ChangeLog	2022-03-18 19:36:58 UTC (rev 291493)
+++ trunk/Source/WebCore/ChangeLog	2022-03-18 19:42:42 UTC (rev 291494)
@@ -1,3 +1,19 @@
+2022-03-18  Alex Christensen  <[email protected]>
+
+        Keep a strong reference to session in [WebCoreNSURLSessionDataTask _restart]
+        https://bugs.webkit.org/show_bug.cgi?id=238061
+        <rdar://88242622>
+
+        Reviewed by Eric Carlson.
+
+        _session is a WeakObjCPtr<WebCoreNSURLSession> and since we're not using ARC self.session
+        returns a raw pointer to an object that may be deallocated and null out its loader on a different thread.
+        To prevent null crashes, keep a strong reference to the session when using it.
+
+        * platform/network/cocoa/WebCoreNSURLSession.mm:
+        (-[WebCoreNSURLSession dealloc]):
+        (-[WebCoreNSURLSessionDataTask _restart]):
+
 2022-03-18  Simon Fraser  <[email protected]>
 
         REGRESSION (r290628): Scrubber makes a visual trail when scrubbing on tv.youtube.com

Modified: trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm (291493 => 291494)


--- trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm	2022-03-18 19:36:58 UTC (rev 291493)
+++ trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm	2022-03-18 19:42:42 UTC (rev 291494)
@@ -300,7 +300,7 @@
             [task setSession:nil];
     }
 
-    callOnMainThread([loader = WTFMove(_loader)] {
+    callOnMainThread([loader = std::exchange(_loader, nullptr)] {
     });
     [super dealloc];
 }
@@ -740,13 +740,14 @@
 
     [self _cancel];
 
-    if (!self.session)
+    RetainPtr<WebCoreNSURLSession> retainedSession = self.session;
+    if (!retainedSession)
         return;
 
-    if ([self.session rangeResponseGenerator].willHandleRequest(self, self.originalRequest))
+    if ([retainedSession rangeResponseGenerator].willHandleRequest(self, self.originalRequest))
         return;
 
-    _resource = self.session.loader.requestResource(self.originalRequest, PlatformMediaResourceLoader::LoadOption::DisallowCaching);
+    _resource = [retainedSession loader].requestResource(self.originalRequest, PlatformMediaResourceLoader::LoadOption::DisallowCaching);
     if (_resource) {
         _resource->setClient(adoptRef(*new WebCoreNSURLSessionDataTaskClient(self)));
         return;
@@ -764,7 +765,7 @@
         _resource->setClient(nullptr);
         _resource = nil;
     }
-    if (auto *session = self.session)
+    if (RetainPtr<WebCoreNSURLSession> session = self.session)
         [session rangeResponseGenerator].removeTask(self);
 }
 
@@ -884,20 +885,21 @@
     ASSERT(response.source() == ResourceResponse::Source::Network || response.source() == ResourceResponse::Source::DiskCache || response.source() == ResourceResponse::Source::DiskCacheAfterValidation || response.source() == ResourceResponse::Source::ServiceWorker);
     ASSERT_UNUSED(resource, !resource || resource == _resource);
     ASSERT(isMainThread());
-    [self.session task:self didReceiveResponseFromOrigin:SecurityOrigin::create(response.url())];
-    [self.session task:self didReceiveCORSAccessCheckResult:resource ? resource->didPassAccessControlCheck() : YES];
+    RetainPtr<WebCoreNSURLSession> strongSession { self.session };
+    [strongSession task:self didReceiveResponseFromOrigin:SecurityOrigin::create(response.url())];
+    [strongSession task:self didReceiveCORSAccessCheckResult:resource ? resource->didPassAccessControlCheck() : YES];
     self.countOfBytesExpectedToReceive = response.expectedContentLength();
     RetainPtr<NSURLResponse> strongResponse = response.nsURLResponse();
 
-    if (resource && self.session && [self.session rangeResponseGenerator].willSynthesizeRangeResponses(self, *resource, response)) {
+    if (resource && strongSession && [strongSession rangeResponseGenerator].willSynthesizeRangeResponses(self, *resource, response)) {
         _resource = nullptr;
         return completionHandler(ShouldContinuePolicyCheck::Yes);
     }
     
     RetainPtr<WebCoreNSURLSessionDataTask> strongSelf { self };
-    if (!self.session)
+    if (!strongSession)
         return completionHandler(ShouldContinuePolicyCheck::No);
-    [self.session addDelegateOperation:[strongSelf, strongResponse, completionHandler = WTFMove(completionHandler)] () mutable {
+    [strongSession addDelegateOperation:[strongSelf, strongResponse, completionHandler = WTFMove(completionHandler)] () mutable {
         strongSelf->_response = strongResponse.get();
 
         id<NSURLSessionDataDelegate> dataDelegate = (id<NSURLSessionDataDelegate>)strongSelf.get().session.delegate;
@@ -934,7 +936,8 @@
 - (void)resource:(PlatformMediaResource*)resource receivedData:(RetainPtr<NSData>&&)data
 {
     ASSERT_UNUSED(resource, !resource || resource == _resource);
-    [self.session addDelegateOperation:[strongSelf = RetainPtr { self }, data = "" {
+    RetainPtr<WebCoreNSURLSession> strongSession { self.session };
+    [strongSession addDelegateOperation:[strongSelf = RetainPtr { self }, data = "" {
         strongSelf.get().countOfBytesReceived += [data length];
         id<NSURLSessionDataDelegate> dataDelegate = (id<NSURLSessionDataDelegate>)strongSelf.get().session.delegate;
         if ([dataDelegate respondsToSelector:@selector(URLSession:dataTask:didReceiveData:)])
@@ -945,7 +948,8 @@
 - (void)resource:(PlatformMediaResource*)resource receivedRedirect:(const ResourceResponse&)response request:(ResourceRequest&&)request completionHandler:(CompletionHandler<void(ResourceRequest&&)>&&)completionHandler
 {
     ASSERT_UNUSED(resource, !resource || resource == _resource);
-    [self.session addDelegateOperation:[strongSelf = retainPtr(self), response = retainPtr(response.nsURLResponse()), request = request.isolatedCopy(), completionHandler = WTFMove(completionHandler)] () mutable {
+    RetainPtr<WebCoreNSURLSession> strongSession { self.session };
+    [strongSession addDelegateOperation:[strongSelf = retainPtr(self), response = retainPtr(response.nsURLResponse()), request = request.isolatedCopy(), completionHandler = WTFMove(completionHandler)] () mutable {
         if (![response isKindOfClass:[NSHTTPURLResponse class]]) {
             ASSERT_NOT_REACHED();
             callOnMainThread([request = WTFMove(request), completionHandler = WTFMove(completionHandler)] () mutable {
@@ -981,7 +985,7 @@
     RetainPtr<WebCoreNSURLSession> strongSession { self.session };
     RetainPtr<NSError> strongError { error };
     auto taskMetrics = adoptNS([[WebCoreNSURLSessionTaskMetrics alloc] _initWithMetrics:NetworkLoadMetrics(metrics)]);
-    [self.session addDelegateOperation:[strongSelf, strongSession, strongError, taskMetrics = WTFMove(taskMetrics)] () mutable {
+    [strongSession addDelegateOperation:[strongSelf, strongSession, strongError, taskMetrics = WTFMove(taskMetrics)] () mutable {
         id<NSURLSessionTaskDelegate> delegate = (id<NSURLSessionTaskDelegate>)strongSession.get().delegate;
 
         if ([delegate respondsToSelector:@selector(URLSession:task:didFinishCollectingMetrics:)])
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to