Title: [129583] trunk/Source/WebCore
Revision
129583
Author
[email protected]
Date
2012-09-25 19:14:07 -0700 (Tue, 25 Sep 2012)

Log Message

Mask RenderArena freelist entries.
https://bugs.webkit.org/show_bug.cgi?id=97494

Patch by Justin Schuh <[email protected]> on 2012-09-25
Reviewed by Julien Chaffraix.

This is a mitigation for freelist spraying. See http://download.crowdstrike.com/papers/hes-exploiting-a-coalmine.pdf.

No new tests. This is a hardening measure. Found no measurable performance impact with Dromaeo.

* rendering/RenderArena.cpp:
(MaskPtr):
(WebCore::RenderArena::allocate):
(WebCore::RenderArena::free):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (129582 => 129583)


--- trunk/Source/WebCore/ChangeLog	2012-09-26 02:13:54 UTC (rev 129582)
+++ trunk/Source/WebCore/ChangeLog	2012-09-26 02:14:07 UTC (rev 129583)
@@ -1,3 +1,19 @@
+2012-09-25  Justin Schuh  <[email protected]>
+
+        Mask RenderArena freelist entries.
+        https://bugs.webkit.org/show_bug.cgi?id=97494
+
+        Reviewed by Julien Chaffraix.
+
+        This is a mitigation for freelist spraying. See http://download.crowdstrike.com/papers/hes-exploiting-a-coalmine.pdf.
+
+        No new tests. This is a hardening measure. Found no measurable performance impact with Dromaeo.
+
+        * rendering/RenderArena.cpp:
+        (MaskPtr):
+        (WebCore::RenderArena::allocate):
+        (WebCore::RenderArena::free):
+
 2012-09-25  Luke Macpherson   <[email protected]>
 
         Ensure variables are resolved for specialized CSS primitive value types.

Modified: trunk/Source/WebCore/rendering/RenderArena.cpp (129582 => 129583)


--- trunk/Source/WebCore/rendering/RenderArena.cpp	2012-09-26 02:13:54 UTC (rev 129582)
+++ trunk/Source/WebCore/rendering/RenderArena.cpp	2012-09-26 02:14:07 UTC (rev 129583)
@@ -42,6 +42,23 @@
 
 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
 
+#ifdef NDEBUG
+// Mask freelist pointers to detect corruption and prevent freelist spraying.
+// We use an arbitray function and rely on ASLR to randomize it.
+// The first value in RenderObject (or any class) is a vtable pointer, which always
+// overlaps with the next pointer. This change guarantees that the masked vtable/next
+// pointer will never point to valid memory. So, we should immediately crash on the
+// first invalid vtable access for a stale RenderObject pointer.
+// See http://download.crowdstrike.com/papers/hes-exploiting-a-coalmine.pdf.
+static void* MaskPtr(void* p)
+{
+    // The bottom bits are predictable because the binary is loaded on a boundary.
+    // This just shifts most of those predictable bits out.
+    const uintptr_t mask = ~(reinterpret_cast<uintptr_t>(WTF::fastMalloc) >> 13);
+    return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ mask);
+}
+#endif
+
 namespace WebCore {
 
 #ifndef NDEBUG
@@ -103,7 +120,7 @@
         result = m_recyclers[index];
         if (result) {
             // Need to move to the next object
-            void* next = *((void**)result);
+            void* next = MaskPtr(*((void**)result));
             m_recyclers[index] = next;
         }
     }
@@ -143,7 +160,7 @@
         const int index = size >> 2;
         void* currentTop = m_recyclers[index];
         m_recyclers[index] = ptr;
-        *((void**)ptr) = currentTop;
+        *((void**)ptr) = MaskPtr(currentTop);
     }
 #endif
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to