[chromium] harden ScriptWrappable::m_wrapper against tampering
authortsepez@chromium.org <tsepez@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2013 20:51:48 +0000 (20:51 +0000)
committertsepez@chromium.org <tsepez@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2013 20:51:48 +0000 (20:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=107318

Reviewed by Adam Barth.

Patch is correct if existing tests past without crashing.

* bindings/v8/ScriptWrappable.h:
(WebCore::ScriptWrappable::ScriptWrappable):
(WebCore::ScriptWrappable::wrapper):
(WebCore::ScriptWrappable::setWrapper):
(WebCore::ScriptWrappable::clearWrapper):
(WebCore::ScriptWrappable::disposeWrapper):
(WebCore::ScriptWrappable::reportMemoryUsage):
(ScriptWrappable):
(WebCore::ScriptWrappable::maskOrUnmaskPointer):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@140575 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/bindings/v8/ScriptWrappable.h

index a4b97b7..f659edf 100644 (file)
@@ -1,3 +1,22 @@
+2013-01-23  Tom Sepez  <tsepez@chromium.org>
+
+        [chromium] harden ScriptWrappable::m_wrapper against tampering
+        https://bugs.webkit.org/show_bug.cgi?id=107318
+
+        Reviewed by Adam Barth.
+
+        Patch is correct if existing tests past without crashing.
+
+        * bindings/v8/ScriptWrappable.h:
+        (WebCore::ScriptWrappable::ScriptWrappable):
+        (WebCore::ScriptWrappable::wrapper):
+        (WebCore::ScriptWrappable::setWrapper):
+        (WebCore::ScriptWrappable::clearWrapper):
+        (WebCore::ScriptWrappable::disposeWrapper):
+        (WebCore::ScriptWrappable::reportMemoryUsage):
+        (ScriptWrappable):
+        (WebCore::ScriptWrappable::maskOrUnmaskPointer):
+
 2013-01-22  Roger Fong  <roger_fong@apple.com>
 
         WebCore property sheets, modified build scripts, and project files for compiling in VS2010.
index 1c72727..6550017 100644 (file)
@@ -38,42 +38,47 @@ namespace WebCore {
 
 class ScriptWrappable {
 public:
-    ScriptWrappable()
-    {
-    }
+    ScriptWrappable() { }
 
     v8::Persistent<v8::Object> wrapper() const
     {
-        return m_wrapper;
+        return v8::Persistent<v8::Object>(maskOrUnmaskPointer(*m_maskedWrapper));
     }
 
     void setWrapper(v8::Persistent<v8::Object> wrapper)
     {
-        ASSERT(!wrapper.IsEmpty());
-        m_wrapper = wrapper;
+        m_maskedWrapper = maskOrUnmaskPointer(*wrapper);
     }
 
     void clearWrapper()
     {
-        ASSERT(!m_wrapper.IsEmpty());
-        m_wrapper.Clear();
+        ASSERT(!m_maskedWrapper.IsEmpty());
+        m_maskedWrapper.Clear();
     }
 
     void disposeWrapper()
     {
-        ASSERT(!m_wrapper.IsEmpty());
-        m_wrapper.Dispose();
-        m_wrapper.Clear();
+        ASSERT(!m_maskedWrapper.IsEmpty());
+        m_maskedWrapper = wrapper();
+        m_maskedWrapper.Dispose();
+        m_maskedWrapper.Clear();
     }
 
     void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     {
         MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
-        info.ignoreMember(m_wrapper);
+        info.ignoreMember(m_maskedWrapper);
     }
 
 private:
-    v8::Persistent<v8::Object> m_wrapper;
+    v8::Persistent<v8::Object> m_maskedWrapper;
+
+    static inline v8::Object* maskOrUnmaskPointer(const v8::Object* object)
+    {
+        const uintptr_t objectPointer = reinterpret_cast<uintptr_t>(object);
+        const uintptr_t randomMask = ~(reinterpret_cast<uintptr_t>(&WebCoreMemoryTypes::DOM) >> 13); // Entropy via ASLR.
+        return reinterpret_cast<v8::Object*>((objectPointer ^ randomMask) & (!objectPointer - 1)); // Preserve null without branching.
+    }
 };
 
 } // namespace WebCore