Title: [134290] branches/safari-536.28-branch/Source/WebCore
Revision
134290
Author
[email protected]
Date
2012-11-12 13:04:37 -0800 (Mon, 12 Nov 2012)

Log Message

Merged r133469.  <rdar://problem/12636795>

Modified Paths

Diff

Modified: branches/safari-536.28-branch/Source/WebCore/ChangeLog (134289 => 134290)


--- branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-12 21:02:11 UTC (rev 134289)
+++ branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-12 21:04:37 UTC (rev 134290)
@@ -1,5 +1,30 @@
 2012-11-12  Lucas Forschler  <[email protected]>
 
+        Merge r133469
+
+    2012-11-05  Antti Koivisto  <[email protected]>
+
+            Protect against resource deletion during iteration in MemoryCache::pruneDeadResourcesToSize
+            https://bugs.webkit.org/show_bug.cgi?id=101211
+
+            Reviewed by Andreas Kling.
+
+            Some crashes have been seen under MemoryCache::pruneDeadResourcesToSize. A possible cause is that
+            destroyDecodedData() call ends up evicting the resource pointed by 'previous' pointer during iteration
+            and deleting the object. This looks in principle possible via stylesheets and SVG images.
+
+            Speculative fix, no repro, no obvious way to construct a test.
+
+            * loader/cache/MemoryCache.cpp:
+            (WebCore::MemoryCache::pruneDeadResourcesToSize):
+
+                Use CachedResourceHandle to protect the 'previous' pointer during iteration. Check if the
+                resource has been kicked out from the cache during destroyDecodedData() and stop iterating
+                if has (as it may die when CachedResourceHandle releases it).
+                The 'current' pointer is not protected as the resource it points to is allowed to die.
+
+2012-11-12  Lucas Forschler  <[email protected]>
+
         Merge r131077
 
     2012-10-11  Dan Bernstein  <[email protected]>
@@ -207371,3 +207396,4 @@
 .
 .
 .
+.

Modified: branches/safari-536.28-branch/Source/WebCore/loader/cache/MemoryCache.cpp (134289 => 134290)


--- branches/safari-536.28-branch/Source/WebCore/loader/cache/MemoryCache.cpp	2012-11-12 21:02:11 UTC (rev 134289)
+++ branches/safari-536.28-branch/Source/WebCore/loader/cache/MemoryCache.cpp	2012-11-12 21:04:37 UTC (rev 134290)
@@ -305,23 +305,30 @@
         
         // First flush all the decoded data in this queue.
         while (current) {
-            CachedResource* prev = current->m_prevInAllResourcesList;
+            // Protect 'previous' so it can't get deleted during destroyDecodedData().
+            CachedResourceHandle<CachedResource> previous = current->m_prevInAllResourcesList;
+            ASSERT(!previous || previous->inCache());
             if (!current->hasClients() && !current->isPreloaded() && current->isLoaded()) {
                 // Destroy our decoded data. This will remove us from 
                 // m_liveDecodedResources, and possibly move us to a different 
                 // LRU list in m_allResources.
                 current->destroyDecodedData();
-                
+
                 if (targetSize && m_deadSize <= targetSize)
                     return;
             }
-            current = prev;
+            // Decoded data may reference other resources. Stop iterating if 'previous' somehow got
+            // kicked out of cache during destroyDecodedData().
+            if (previous && !previous->inCache())
+                break;
+            current = previous.get();
         }
 
         // Now evict objects from this queue.
         current = m_allResources[i].m_tail;
         while (current) {
-            CachedResource* prev = current->m_prevInAllResourcesList;
+            CachedResourceHandle<CachedResource> previous = current->m_prevInAllResourcesList;
+            ASSERT(!previous || previous->inCache());
             if (!current->hasClients() && !current->isPreloaded() && !current->isCacheValidator()) {
                 if (!makeResourcePurgeable(current))
                     evict(current);
@@ -329,7 +336,9 @@
                 if (targetSize && m_deadSize <= targetSize)
                     return;
             }
-            current = prev;
+            if (previous && !previous->inCache())
+                break;
+            current = previous.get();
         }
             
         // Shrink the vector back down so we don't waste time inspecting
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to