Title: [284971] trunk
Revision
284971
Author
you...@apple.com
Date
2021-10-28 00:32:31 -0700 (Thu, 28 Oct 2021)

Log Message

Fetch API: Network process leaks when blobs are unused
https://bugs.webkit.org/show_bug.cgi?id=232371
<rdar://problem/84704184>

Reviewed by Geoffrey Garen.

Source/WebCore:

Make sure to unregister the internal URL when the blob gets destroyed.

Test: http/wpt/fetch/blob-gc.html

* fileapi/Blob.cpp:
* fileapi/ThreadableBlobRegistry.h:
* testing/Internals.cpp:
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Make sure to unregister blobs created by a WebProcess in case WebProcess terminates.

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
* NetworkProcess/NetworkConnectionToWebProcess.h:

LayoutTests:

* http/wpt/fetch/blob-gc-expected.txt: Added.
* http/wpt/fetch/blob-gc.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (284970 => 284971)


--- trunk/LayoutTests/ChangeLog	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/LayoutTests/ChangeLog	2021-10-28 07:32:31 UTC (rev 284971)
@@ -1,3 +1,14 @@
+2021-10-28  Youenn Fablet  <you...@apple.com>
+
+        Fetch API: Network process leaks when blobs are unused
+        https://bugs.webkit.org/show_bug.cgi?id=232371
+        <rdar://problem/84704184>
+
+        Reviewed by Geoffrey Garen.
+
+        * http/wpt/fetch/blob-gc-expected.txt: Added.
+        * http/wpt/fetch/blob-gc.html: Added.
+
 2021-10-27  Gabriel Nava Marino  <gnavamar...@apple.com>
 
         Assertions in findFirstSlotElement hit when removing two slots with the same name in a single shadow tree

Added: trunk/LayoutTests/http/wpt/fetch/blob-gc-expected.txt (0 => 284971)


--- trunk/LayoutTests/http/wpt/fetch/blob-gc-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/blob-gc-expected.txt	2021-10-28 07:32:31 UTC (rev 284971)
@@ -0,0 +1,3 @@
+
+PASS A GCed blob should get unregistered
+

Added: trunk/LayoutTests/http/wpt/fetch/blob-gc.html (0 => 284971)


--- trunk/LayoutTests/http/wpt/fetch/blob-gc.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/blob-gc.html	2021-10-28 07:32:31 UTC (rev 284971)
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Blob and GC</title>
+    <meta name="help" href=""
+    <script src=""
+    <script src=""
+    <script src=""
+  </head>
+  <body>
+    <script>
+async function createBlobAndGetURL()
+{
+    const blob = new Blob([new ArrayBuffer(1024)]);
+    const url = ""
+    assert_true(await internals.isBlobInternalURLRegistered(url));
+    return url;
+}
+
+promise_test(async () => {
+    if (!window.internals)
+        return Promise.reject("no internals");
+
+    const url = "" createBlobAndGetURL();
+    let counter = 0;
+    do {
+       gc();
+       await new Promise(resolve => setTimeout(resolve, 50));
+    } while (await internals.isBlobInternalURLRegistered(url) && counter++ < 100)
+
+    assert_false(await internals.isBlobInternalURLRegistered(url));
+}, "A GCed blob should get unregistered");
+    </script>
+  </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (284970 => 284971)


--- trunk/Source/WebCore/ChangeLog	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebCore/ChangeLog	2021-10-28 07:32:31 UTC (rev 284971)
@@ -1,3 +1,21 @@
+2021-10-28  Youenn Fablet  <you...@apple.com>
+
+        Fetch API: Network process leaks when blobs are unused
+        https://bugs.webkit.org/show_bug.cgi?id=232371
+        <rdar://problem/84704184>
+
+        Reviewed by Geoffrey Garen.
+
+        Make sure to unregister the internal URL when the blob gets destroyed.
+
+        Test: http/wpt/fetch/blob-gc.html
+
+        * fileapi/Blob.cpp:
+        * fileapi/ThreadableBlobRegistry.h:
+        * testing/Internals.cpp:
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2021-10-27  Gabriel Nava Marino  <gnavamar...@apple.com>
 
         Assertions in findFirstSlotElement hit when removing two slots with the same name in a single shadow tree

Modified: trunk/Source/WebCore/fileapi/Blob.cpp (284970 => 284971)


--- trunk/Source/WebCore/fileapi/Blob.cpp	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebCore/fileapi/Blob.cpp	2021-10-28 07:32:31 UTC (rev 284971)
@@ -154,6 +154,7 @@
 
 Blob::~Blob()
 {
+    ThreadableBlobRegistry::unregisterBlobURL(m_internalURL);
     while (!m_blobLoaders.isEmpty())
         (*m_blobLoaders.begin())->cancel();
 }

Modified: trunk/Source/WebCore/fileapi/Blob.idl (284970 => 284971)


--- trunk/Source/WebCore/fileapi/Blob.idl	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebCore/fileapi/Blob.idl	2021-10-28 07:32:31 UTC (rev 284971)
@@ -32,6 +32,7 @@
 
 [
     ActiveDOMObject,
+    ExportToWrappedFunction,
     Exposed=(Window,Worker),
     GenerateIsReachable=Impl,
     CustomToJSObject,

Modified: trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h (284970 => 284971)


--- trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h	2021-10-28 07:32:31 UTC (rev 284971)
@@ -52,7 +52,7 @@
     static void registerBlobURLHandle(const URL&);
     static void unregisterBlobURLHandle(const URL&);
 
-    static unsigned long long blobSize(const URL&);
+    WEBCORE_EXPORT static unsigned long long blobSize(const URL&);
 
     // Returns the origin for the given blob URL. This is because we are not able to embed the unique security origin or the origin of file URL
     // in the blob URL.

Modified: trunk/Source/WebCore/testing/Internals.cpp (284970 => 284971)


--- trunk/Source/WebCore/testing/Internals.cpp	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebCore/testing/Internals.cpp	2021-10-28 07:32:31 UTC (rev 284971)
@@ -38,6 +38,7 @@
 #include "BackForwardCache.h"
 #include "BackForwardController.h"
 #include "BitmapImage.h"
+#include "Blob.h"
 #include "CSSKeyframesRule.h"
 #include "CSSMediaRule.h"
 #include "CSSPropertyParser.h"
@@ -210,6 +211,7 @@
 #include "SystemSoundManager.h"
 #include "TextIterator.h"
 #include "TextPlaceholderElement.h"
+#include "ThreadableBlobRegistry.h"
 #include "TreeScope.h"
 #include "TypeConversions.h"
 #include "UserGestureIndicator.h"
@@ -835,6 +837,16 @@
     return responseSourceToString(response.resourceResponse());
 }
 
+String Internals::blobInternalURL(const Blob& blob)
+{
+    return blob.url().string();
+}
+
+void Internals::isBlobInternalURLRegistered(const String& url, DOMPromiseDeferred<IDLBoolean>&& promise)
+{
+    promise.resolve(!!ThreadableBlobRegistry::blobSize(URL { { }, url }));
+}
+
 bool Internals::isSharingStyleSheetContents(HTMLLinkElement& a, HTMLLinkElement& b)
 {
     if (!a.sheet() || !b.sheet())

Modified: trunk/Source/WebCore/testing/Internals.h (284970 => 284971)


--- trunk/Source/WebCore/testing/Internals.h	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebCore/testing/Internals.h	2021-10-28 07:32:31 UTC (rev 284971)
@@ -54,6 +54,7 @@
 class AudioContext;
 class AudioTrack;
 class BaseAudioContext;
+class Blob;
 class CacheStorageConnection;
 class DOMPointReadOnly;
 class DOMRect;
@@ -651,6 +652,9 @@
 
     String getImageSourceURL(Element&);
 
+    String blobInternalURL(const Blob&);
+    void isBlobInternalURLRegistered(const String&, DOMPromiseDeferred<IDLBoolean>&&);
+
 #if ENABLE(VIDEO)
     unsigned mediaElementCount();
     Vector<String> mediaResponseSources(HTMLMediaElement&);

Modified: trunk/Source/WebCore/testing/Internals.idl (284970 => 284971)


--- trunk/Source/WebCore/testing/Internals.idl	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebCore/testing/Internals.idl	2021-10-28 07:32:31 UTC (rev 284971)
@@ -915,6 +915,9 @@
     undefined setResponseSizeWithPadding(FetchResponse response, unsigned long long size);
     unsigned long long responseSizeWithPadding(FetchResponse response);
 
+    DOMString blobInternalURL(Blob blob);
+    Promise<boolean> isBlobInternalURLRegistered(DOMString url);
+
     undefined updateQuotaBasedOnSpaceUsage();
 
     undefined setConsoleMessageListener(StringCallback callback);

Modified: trunk/Source/WebKit/ChangeLog (284970 => 284971)


--- trunk/Source/WebKit/ChangeLog	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebKit/ChangeLog	2021-10-28 07:32:31 UTC (rev 284971)
@@ -1,3 +1,16 @@
+2021-10-28  Youenn Fablet  <you...@apple.com>
+
+        Fetch API: Network process leaks when blobs are unused
+        https://bugs.webkit.org/show_bug.cgi?id=232371
+        <rdar://problem/84704184>
+
+        Reviewed by Geoffrey Garen.
+
+        Make sure to unregister blobs created by a WebProcess in case WebProcess terminates.
+
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+
 2021-10-27  David Kilzer  <ddkil...@apple.com>
 
         [WebKit] Enable -Wformat=2 warnings

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (284970 => 284971)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2021-10-28 07:32:31 UTC (rev 284971)
@@ -379,8 +379,13 @@
     while (!m_networkResourceLoaders.isEmpty())
         m_networkResourceLoaders.begin()->value->abort();
 
-    if (auto* networkSession = this->networkSession())
+    if (auto* networkSession = this->networkSession()) {
         networkSession->broadcastChannelRegistry().removeConnection(connection);
+        for (auto& url : m_blobURLs)
+            networkSession->blobRegistry().unregisterBlobURL(url);
+        for (auto& url : m_blobURLHandles)
+            networkSession->blobRegistry().unregisterBlobURLHandle(url);
+    }
 
     // All trackers of resources that were in the middle of being loaded were
     // stopped with the abort() calls above, but we still need to sweep up the
@@ -833,6 +838,7 @@
     if (!session)
         return;
 
+    m_blobURLs.add(url);
     session->blobRegistry().registerFileBlobURL(url, BlobDataFileReferenceWithSandboxExtension::create(path, replacementPath, SandboxExtension::create(WTFMove(extensionHandle))), contentType);
 }
 
@@ -842,6 +848,7 @@
     if (!session)
         return;
 
+    m_blobURLs.add(url);
     session->blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType);
 }
 
@@ -851,6 +858,7 @@
     if (!session)
         return;
 
+    m_blobURLs.add(url);
     session->blobRegistry().registerBlobURL(url, srcURL, WTFMove(policyContainer));
 }
 
@@ -862,6 +870,7 @@
     if (!session)
         return;
 
+    m_blobURLs.add(url);
     session->blobRegistry().registerBlobURLOptionallyFileBacked(url, srcURL, BlobDataFileReferenceWithSandboxExtension::create(fileBackedPath), contentType, { });
 }
 
@@ -871,6 +880,7 @@
     if (!session)
         return;
 
+    m_blobURLs.add(url);
     session->blobRegistry().registerBlobURLForSlice(url, srcURL, start, end, contentType);
 }
 
@@ -880,6 +890,7 @@
     if (!session)
         return;
 
+    m_blobURLs.remove(url);
     session->blobRegistry().unregisterBlobURL(url);
 }
 
@@ -889,6 +900,7 @@
     if (!session)
         return;
 
+    m_blobURLHandles.add(url);
     session->blobRegistry().registerBlobURLHandle(url);
 }
 
@@ -898,6 +910,7 @@
     if (!session)
         return;
 
+    m_blobURLHandles.remove(url);
     session->blobRegistry().unregisterBlobURLHandle(url);
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h (284970 => 284971)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h	2021-10-28 06:52:55 UTC (rev 284970)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h	2021-10-28 07:32:31 UTC (rev 284971)
@@ -54,6 +54,7 @@
 #include <WebCore/WebSocketIdentifier.h>
 #include <wtf/OptionSet.h>
 #include <wtf/RefCounted.h>
+#include <wtf/URLHash.h>
 
 namespace PAL {
 class SessionID;
@@ -411,6 +412,9 @@
     HashSet<WebCore::MessagePortIdentifier> m_processEntangledPorts;
     HashMap<uint64_t, Function<void()>> m_messageBatchDeliveryCompletionHandlers;
     Ref<NetworkSchemeRegistry> m_schemeRegistry;
+        
+    HashSet<URL> m_blobURLs;
+    HashSet<URL> m_blobURLHandles;
 };
 
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to