Title: [255788] trunk/Source/_javascript_Core
Revision
255788
Author
[email protected]
Date
2020-02-04 23:12:53 -0800 (Tue, 04 Feb 2020)

Log Message

[JSC] Structure::setMaxOffset and setTransitionOffset are racy
https://bugs.webkit.org/show_bug.cgi?id=207249

Reviewed by Mark Lam.

We hit crash in JSTests/stress/array-slice-osr-exit-2.js. The situation is following.

    1. The mutator thread (A) is working.
    2. The concurrent collector (B) is working.
    3. A attempts to set m_maxOffset in StructureRareData by allocating it. First, A sets Structure::m_maxOffset to useRareDataFlag.
    3. B is in JSObject::visitButterflyImpl, and executing Structure::maxOffset().
    4. B detects that m_maxOffset is useRareDataFlag.
    5. B attempts to load rareData, but this is not a StructureRareData since A is just now setting up StructureRareData.
    6. B crashes.

Set useRareDataFlag after StructureRareData is set. Ensuring this store-order by using storeStoreFence.

* runtime/Structure.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (255787 => 255788)


--- trunk/Source/_javascript_Core/ChangeLog	2020-02-05 04:48:35 UTC (rev 255787)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-02-05 07:12:53 UTC (rev 255788)
@@ -1,3 +1,24 @@
+2020-02-04  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Structure::setMaxOffset and setTransitionOffset are racy
+        https://bugs.webkit.org/show_bug.cgi?id=207249
+
+        Reviewed by Mark Lam.
+
+        We hit crash in JSTests/stress/array-slice-osr-exit-2.js. The situation is following.
+
+            1. The mutator thread (A) is working.
+            2. The concurrent collector (B) is working.
+            3. A attempts to set m_maxOffset in StructureRareData by allocating it. First, A sets Structure::m_maxOffset to useRareDataFlag.
+            3. B is in JSObject::visitButterflyImpl, and executing Structure::maxOffset().
+            4. B detects that m_maxOffset is useRareDataFlag.
+            5. B attempts to load rareData, but this is not a StructureRareData since A is just now setting up StructureRareData.
+            6. B crashes.
+
+        Set useRareDataFlag after StructureRareData is set. Ensuring this store-order by using storeStoreFence.
+
+        * runtime/Structure.h:
+
 2020-02-04  Adrian Perez de Castro  <[email protected]>
 
         Non-unified build fixes early February 2020 edition

Modified: trunk/Source/_javascript_Core/runtime/Structure.h (255787 => 255788)


--- trunk/Source/_javascript_Core/runtime/Structure.h	2020-02-05 04:48:35 UTC (rev 255787)
+++ trunk/Source/_javascript_Core/runtime/Structure.h	2020-02-05 07:12:53 UTC (rev 255788)
@@ -357,11 +357,12 @@
 
     PropertyOffset maxOffset() const
     {
-        if (m_maxOffset == shortInvalidOffset)
+        uint16_t maxOffset = m_maxOffset;
+        if (maxOffset == shortInvalidOffset)
             return invalidOffset;
-        if (m_maxOffset == useRareDataFlag)
+        if (maxOffset == useRareDataFlag)
             return rareData()->m_maxOffset;
-        return m_maxOffset;
+        return maxOffset;
     }
 
     void setMaxOffset(VM& vm, PropertyOffset offset)
@@ -370,19 +371,23 @@
             m_maxOffset = shortInvalidOffset;
         else if (offset < useRareDataFlag && offset < shortInvalidOffset)
             m_maxOffset = offset;
+        else if (m_maxOffset == useRareDataFlag)
+            rareData()->m_maxOffset = offset;
         else {
+            ensureRareData(vm)->m_maxOffset = offset;
+            WTF::storeStoreFence();
             m_maxOffset = useRareDataFlag;
-            ensureRareData(vm)->m_maxOffset = offset;
         }
     }
 
     PropertyOffset transitionOffset() const
     {
-        if (m_transitionOffset == shortInvalidOffset)
+        uint16_t transitionOffset = m_transitionOffset;
+        if (transitionOffset == shortInvalidOffset)
             return invalidOffset;
-        if (m_transitionOffset == useRareDataFlag)
+        if (transitionOffset == useRareDataFlag)
             return rareData()->m_transitionOffset;
-        return m_transitionOffset;
+        return transitionOffset;
     }
 
     void setTransitionOffset(VM& vm, PropertyOffset offset)
@@ -391,9 +396,12 @@
             m_transitionOffset = shortInvalidOffset;
         else if (offset < useRareDataFlag && offset < shortInvalidOffset)
             m_transitionOffset = offset;
+        else if (m_transitionOffset == useRareDataFlag)
+            rareData()->m_transitionOffset = offset;
         else {
+            ensureRareData(vm)->m_transitionOffset = offset;
+            WTF::storeStoreFence();
             m_transitionOffset = useRareDataFlag;
-            ensureRareData(vm)->m_transitionOffset = offset;
         }
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to