Title: [249608] trunk/Source
Revision
249608
Author
mark....@apple.com
Date
2019-09-06 22:42:11 -0700 (Fri, 06 Sep 2019)

Log Message

Harden protection of the Gigacage Config parameters.
https://bugs.webkit.org/show_bug.cgi?id=201570
<rdar://problem/55134229>

Reviewed by Saam Barati.

Source/bmalloc:

1. Rename protectGigacageBasePtrs() and unprotectGigacageBasePtrs() to
   freezeGigacageConfig() and unfreezeGigacageConfig() respectively.

   Also move the alignment check in protectGigacageBasePtrs() into ensureGigacage().
   There's no need to check it more than once.

2. Introduce permanentlyFreezeGigacageConfig() which permanently makes the
   Config ReadOnly.  Once invoked, the Config cannot be made writable again.

   This is made possible by using vm_protect with a true set_maximum argument.
   We also add a g_gigacageConfig.isPermanentlyFrozen flag that we assert.
   Note: this permanence is only true for OS(DARWIN) since vm_protect is Mach API.

3. Rename disableDisablingPrimitiveGigacageIfShouldBeEnabled() to
   forbidDisablingPrimitiveGigacage() because "disablingDisabling" is a tongue
   twister.

   Also, we don't want to make it conditional on "IfShouldBeEnabled".  We want
   forbidDisablingPrimitiveGigacage() to be irreversible.  It is up to the client
   to ensure that the Gigacage is already initialized (if possible) before
   invoking forbidDisablingPrimitiveGigacage().  Conceptually, the forbidding
   isn't about guaranteeing that the Gigacage is enabled.  It only takes away the
   option to disable it.

   That said, forbidDisablingPrimitiveGigacage() is only invoked by clients that
   care about keeping the Gigacage enabled.  So, it does a sanity check (with an
   assertion) that if !GIGACAGE_ALLOCATION_CAN_FAIL, then the Gigacage should be
   have been initialized and enabled before invoking it.

   We also make sure that forbidDisablingPrimitiveGigacage() calls
   permanentlyFreezeGigacageConfig() unconditionally.  It is safe to call it more
   than once.  This guarantees that the Config is permanently frozen after this,
   even if a bug should inadvertantly set the
   g_gigacageConfig.disablingPrimitiveGigacageIsForbidden flag before
   forbidDisablingPrimitiveGigacage() is invoked.

4. Assert that ensureGigacage() is only called once.

5. Assert that shouldBeEnabled() is only called once.
   Also moved its cached result into the Config so that it can be frozen.

* bmalloc/Gigacage.cpp:
(Gigacage::bmalloc::freezeGigacageConfig):
(Gigacage::bmalloc::unfreezeGigacageConfig):
(Gigacage::bmalloc::permanentlyFreezeGigacageConfig):
(Gigacage::bmalloc::UnfreezeGigacageConfigScope::UnfreezeGigacageConfigScope):
(Gigacage::bmalloc::UnfreezeGigacageConfigScope::~UnfreezeGigacageConfigScope):
(Gigacage::ensureGigacage):
(Gigacage::disablePrimitiveGigacage):
(Gigacage::verifyGigacageIsEnabled):
(Gigacage::forbidDisablingPrimitiveGigacage):
(Gigacage::isDisablingPrimitiveGigacageForbidden):
(Gigacage::shouldBeEnabled):
(Gigacage::bmalloc::protectGigacageBasePtrs): Deleted.
(Gigacage::bmalloc::unprotectGigacageBasePtrs): Deleted.
(Gigacage::bmalloc::UnprotectGigacageBasePtrsScope::UnprotectGigacageBasePtrsScope): Deleted.
(Gigacage::bmalloc::UnprotectGigacageBasePtrsScope::~UnprotectGigacageBasePtrsScope): Deleted.
(Gigacage::primitiveGigacageDisabled): Deleted.
(Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled): Deleted.
(Gigacage::isDisablingPrimitiveGigacageDisabled): Deleted.
* bmalloc/Gigacage.h:
(Gigacage::isPrimitiveGigacagePermanentlyEnabled):
(Gigacage::canPrimitiveGigacageBeDisabled):
(Gigacage::forbidDisablingPrimitiveGigacage):
(Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled): Deleted.

Source/_javascript_Core:

Just renaming some function names here.

* assembler/testmasm.cpp:
(JSC::testCagePreservesPACFailureBit):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::cageConditionally):
* jsc.cpp:
(jscmain):

Source/WebKit:

Just renaming a function name here.

* WebProcess/WebProcess.cpp:

Source/WTF:

Just renaming some function names here.

* wtf/Gigacage.h:
(Gigacage::forbidDisablingPrimitiveGigacage):
(Gigacage::isDisablingPrimitiveGigacageForbidden):
(Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled): Deleted.
(Gigacage::isDisablingPrimitiveGigacageDisabled): Deleted.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (249607 => 249608)


--- trunk/Source/_javascript_Core/ChangeLog	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-09-07 05:42:11 UTC (rev 249608)
@@ -1,3 +1,20 @@
+2019-09-06  Mark Lam  <mark....@apple.com>
+
+        Harden protection of the Gigacage Config parameters.
+        https://bugs.webkit.org/show_bug.cgi?id=201570
+        <rdar://problem/55134229>
+
+        Reviewed by Saam Barati.
+
+        Just renaming some function names here.
+
+        * assembler/testmasm.cpp:
+        (JSC::testCagePreservesPACFailureBit):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::cageConditionally):
+        * jsc.cpp:
+        (jscmain):
+
 2019-09-06  Ross Kirsling  <ross.kirsl...@sony.com>
 
         Math.round() produces wrong result for value prior to 0.5

Modified: trunk/Source/_javascript_Core/assembler/testmasm.cpp (249607 => 249608)


--- trunk/Source/_javascript_Core/assembler/testmasm.cpp	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/_javascript_Core/assembler/testmasm.cpp	2019-09-07 05:42:11 UTC (rev 249608)
@@ -1210,7 +1210,7 @@
 static void testCagePreservesPACFailureBit()
 {
 #if GIGACAGE_ENABLED
-    ASSERT(!Gigacage::isDisablingPrimitiveGigacageDisabled());
+    ASSERT(!Gigacage::isDisablingPrimitiveGigacageForbidden());
     auto cage = compile([] (CCallHelpers& jit) {
         emitFunctionPrologue(jit);
         jit.cageConditionally(Gigacage::Primitive, GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2);

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (249607 => 249608)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2019-09-07 05:42:11 UTC (rev 249608)
@@ -1588,7 +1588,7 @@
     {
 #if GIGACAGE_ENABLED
         if (Gigacage::isEnabled(kind)) {
-            if (kind != Gigacage::Primitive || Gigacage::isDisablingPrimitiveGigacageDisabled())
+            if (kind != Gigacage::Primitive || Gigacage::isDisablingPrimitiveGigacageForbidden())
                 cageWithoutUntagging(kind, storage);
             else {
 #if CPU(ARM64E)

Modified: trunk/Source/_javascript_Core/jsc.cpp (249607 => 249608)


--- trunk/Source/_javascript_Core/jsc.cpp	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/_javascript_Core/jsc.cpp	2019-09-07 05:42:11 UTC (rev 249608)
@@ -3086,7 +3086,7 @@
 #if ENABLE(WEBASSEMBLY)
     JSC::Wasm::enableFastMemory();
 #endif
-    Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled();
+    Gigacage::forbidDisablingPrimitiveGigacage();
 
 #if PLATFORM(COCOA)
     auto& memoryPressureHandler = MemoryPressureHandler::singleton();

Modified: trunk/Source/WTF/ChangeLog (249607 => 249608)


--- trunk/Source/WTF/ChangeLog	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/WTF/ChangeLog	2019-09-07 05:42:11 UTC (rev 249608)
@@ -1,3 +1,19 @@
+2019-09-06  Mark Lam  <mark....@apple.com>
+
+        Harden protection of the Gigacage Config parameters.
+        https://bugs.webkit.org/show_bug.cgi?id=201570
+        <rdar://problem/55134229>
+
+        Reviewed by Saam Barati.
+
+        Just renaming some function names here.
+
+        * wtf/Gigacage.h:
+        (Gigacage::forbidDisablingPrimitiveGigacage):
+        (Gigacage::isDisablingPrimitiveGigacageForbidden):
+        (Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled): Deleted.
+        (Gigacage::isDisablingPrimitiveGigacageDisabled): Deleted.
+
 2019-09-05  Mark Lam  <mark....@apple.com>
 
         Refactor the Gigacage code to require less pointer casting.

Modified: trunk/Source/WTF/wtf/Gigacage.h (249607 => 249608)


--- trunk/Source/WTF/wtf/Gigacage.h	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/WTF/wtf/Gigacage.h	2019-09-07 05:42:11 UTC (rev 249608)
@@ -49,9 +49,9 @@
 inline void addPrimitiveDisableCallback(void (*)(void*), void*) { }
 inline void removePrimitiveDisableCallback(void (*)(void*), void*) { }
 
-inline void disableDisablingPrimitiveGigacageIfShouldBeEnabled() { }
+inline void forbidDisablingPrimitiveGigacage() { }
 
-inline bool isDisablingPrimitiveGigacageDisabled() { return false; }
+inline bool isDisablingPrimitiveGigacageForbidden() { return false; }
 inline bool isPrimitiveGigacagePermanentlyEnabled() { return false; }
 inline bool canPrimitiveGigacageBeDisabled() { return true; }
 

Modified: trunk/Source/WebKit/ChangeLog (249607 => 249608)


--- trunk/Source/WebKit/ChangeLog	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/WebKit/ChangeLog	2019-09-07 05:42:11 UTC (rev 249608)
@@ -1,3 +1,15 @@
+2019-09-06  Mark Lam  <mark....@apple.com>
+
+        Harden protection of the Gigacage Config parameters.
+        https://bugs.webkit.org/show_bug.cgi?id=201570
+        <rdar://problem/55134229>
+
+        Reviewed by Saam Barati.
+
+        Just renaming a function name here.
+
+        * WebProcess/WebProcess.cpp:
+
 2019-09-06  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Incorrect selection rect revealed after pasting images in a contenteditable element

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (249607 => 249608)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2019-09-07 05:42:11 UTC (rev 249608)
@@ -220,7 +220,7 @@
     ResourceLoadObserver::setShared(*new WebResourceLoadObserver);
 #endif
     
-    Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled();
+    Gigacage::forbidDisablingPrimitiveGigacage();
 }
 
 WebProcess::~WebProcess()

Modified: trunk/Source/bmalloc/ChangeLog (249607 => 249608)


--- trunk/Source/bmalloc/ChangeLog	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/bmalloc/ChangeLog	2019-09-07 05:42:11 UTC (rev 249608)
@@ -1,5 +1,79 @@
 2019-09-06  Mark Lam  <mark....@apple.com>
 
+        Harden protection of the Gigacage Config parameters.
+        https://bugs.webkit.org/show_bug.cgi?id=201570
+        <rdar://problem/55134229>
+
+        Reviewed by Saam Barati.
+
+        1. Rename protectGigacageBasePtrs() and unprotectGigacageBasePtrs() to
+           freezeGigacageConfig() and unfreezeGigacageConfig() respectively.
+
+           Also move the alignment check in protectGigacageBasePtrs() into ensureGigacage().
+           There's no need to check it more than once.
+
+        2. Introduce permanentlyFreezeGigacageConfig() which permanently makes the
+           Config ReadOnly.  Once invoked, the Config cannot be made writable again.
+
+           This is made possible by using vm_protect with a true set_maximum argument.
+           We also add a g_gigacageConfig.isPermanentlyFrozen flag that we assert.
+           Note: this permanence is only true for OS(DARWIN) since vm_protect is Mach API.
+
+        3. Rename disableDisablingPrimitiveGigacageIfShouldBeEnabled() to
+           forbidDisablingPrimitiveGigacage() because "disablingDisabling" is a tongue
+           twister.
+
+           Also, we don't want to make it conditional on "IfShouldBeEnabled".  We want
+           forbidDisablingPrimitiveGigacage() to be irreversible.  It is up to the client
+           to ensure that the Gigacage is already initialized (if possible) before
+           invoking forbidDisablingPrimitiveGigacage().  Conceptually, the forbidding
+           isn't about guaranteeing that the Gigacage is enabled.  It only takes away the
+           option to disable it.
+
+           That said, forbidDisablingPrimitiveGigacage() is only invoked by clients that
+           care about keeping the Gigacage enabled.  So, it does a sanity check (with an
+           assertion) that if !GIGACAGE_ALLOCATION_CAN_FAIL, then the Gigacage should be
+           have been initialized and enabled before invoking it.
+
+           We also make sure that forbidDisablingPrimitiveGigacage() calls
+           permanentlyFreezeGigacageConfig() unconditionally.  It is safe to call it more
+           than once.  This guarantees that the Config is permanently frozen after this,
+           even if a bug should inadvertantly set the
+           g_gigacageConfig.disablingPrimitiveGigacageIsForbidden flag before
+           forbidDisablingPrimitiveGigacage() is invoked.
+
+        4. Assert that ensureGigacage() is only called once.
+
+        5. Assert that shouldBeEnabled() is only called once.
+           Also moved its cached result into the Config so that it can be frozen.
+
+        * bmalloc/Gigacage.cpp:
+        (Gigacage::bmalloc::freezeGigacageConfig):
+        (Gigacage::bmalloc::unfreezeGigacageConfig):
+        (Gigacage::bmalloc::permanentlyFreezeGigacageConfig):
+        (Gigacage::bmalloc::UnfreezeGigacageConfigScope::UnfreezeGigacageConfigScope):
+        (Gigacage::bmalloc::UnfreezeGigacageConfigScope::~UnfreezeGigacageConfigScope):
+        (Gigacage::ensureGigacage):
+        (Gigacage::disablePrimitiveGigacage):
+        (Gigacage::verifyGigacageIsEnabled):
+        (Gigacage::forbidDisablingPrimitiveGigacage):
+        (Gigacage::isDisablingPrimitiveGigacageForbidden):
+        (Gigacage::shouldBeEnabled):
+        (Gigacage::bmalloc::protectGigacageBasePtrs): Deleted.
+        (Gigacage::bmalloc::unprotectGigacageBasePtrs): Deleted.
+        (Gigacage::bmalloc::UnprotectGigacageBasePtrsScope::UnprotectGigacageBasePtrsScope): Deleted.
+        (Gigacage::bmalloc::UnprotectGigacageBasePtrsScope::~UnprotectGigacageBasePtrsScope): Deleted.
+        (Gigacage::primitiveGigacageDisabled): Deleted.
+        (Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled): Deleted.
+        (Gigacage::isDisablingPrimitiveGigacageDisabled): Deleted.
+        * bmalloc/Gigacage.h:
+        (Gigacage::isPrimitiveGigacagePermanentlyEnabled):
+        (Gigacage::canPrimitiveGigacageBeDisabled):
+        (Gigacage::forbidDisablingPrimitiveGigacage):
+        (Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled): Deleted.
+
+2019-09-06  Mark Lam  <mark....@apple.com>
+
         Use FailureAction everywhere in bmalloc instead of a crashOnFailure boolean.
         https://bugs.webkit.org/show_bug.cgi?id=201553
 

Modified: trunk/Source/bmalloc/bmalloc/Gigacage.cpp (249607 => 249608)


--- trunk/Source/bmalloc/bmalloc/Gigacage.cpp	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.cpp	2019-09-07 05:42:11 UTC (rev 249608)
@@ -35,6 +35,10 @@
 #include <cstdio>
 #include <mutex>
 
+#if BOS(DARWIN)
+#include <mach/mach.h>
+#endif
+
 #if GIGACAGE_ENABLED
 
 namespace Gigacage {
@@ -81,30 +85,63 @@
 
 namespace {
 
-bool s_isDisablingPrimitiveGigacageDisabled;
+#if BOS(DARWIN)
+enum {
+    AllowPermissionChangesAfterThis = false,
+    DisallowPermissionChangesAfterThis = true
+};
+#endif
 
-void protectGigacageBasePtrs()
+static void freezeGigacageConfig()
 {
-    // We might only get page size alignment, but that's also the minimum we need.
-    RELEASE_BASSERT(!(reinterpret_cast<size_t>(&g_gigacageConfig) & (vmPageSize() - 1)));
-    mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ);
+    int result;
+#if BOS(DARWIN)
+    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&g_gigacageConfig), configSizeToProtect, AllowPermissionChangesAfterThis, VM_PROT_READ);
+#else
+    result = mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ);
+#endif
+    RELEASE_BASSERT(!result);
 }
 
-void unprotectGigacageBasePtrs()
+static void unfreezeGigacageConfig()
 {
-    mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ | PROT_WRITE);
+    RELEASE_BASSERT(!g_gigacageConfig.isPermanentlyFrozen);
+    int result;
+#if BOS(DARWIN)
+    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&g_gigacageConfig), configSizeToProtect, AllowPermissionChangesAfterThis, VM_PROT_READ | VM_PROT_WRITE);
+#else
+    result = mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ | PROT_WRITE);
+#endif
+    RELEASE_BASSERT(!result);
 }
 
-class UnprotectGigacageBasePtrsScope {
+static void permanentlyFreezeGigacageConfig()
+{
+    if (!g_gigacageConfig.isPermanentlyFrozen) {
+        unfreezeGigacageConfig();
+        g_gigacageConfig.isPermanentlyFrozen = true;
+    }
+
+    // There's no going back now!
+    int result;
+#if BOS(DARWIN)
+    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&g_gigacageConfig), configSizeToProtect, DisallowPermissionChangesAfterThis, VM_PROT_READ);
+#else
+    result = mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ);
+#endif
+    RELEASE_BASSERT(!result);
+}
+
+class UnfreezeGigacageConfigScope {
 public:
-    UnprotectGigacageBasePtrsScope()
+    UnfreezeGigacageConfigScope()
     {
-        unprotectGigacageBasePtrs();
+        unfreezeGigacageConfig();
     }
     
-    ~UnprotectGigacageBasePtrsScope()
+    ~UnfreezeGigacageConfigScope()
     {
-        protectGigacageBasePtrs();
+        freezeGigacageConfig();
     }
 };
 
@@ -129,9 +166,16 @@
     std::call_once(
         onceFlag,
         [] {
+            RELEASE_BASSERT(!g_gigacageConfig.ensureGigacageHasBeenCalled);
+            g_gigacageConfig.ensureGigacageHasBeenCalled = true;
+
             if (!shouldBeEnabled())
                 return;
             
+            // We might only get page size alignment, but that's also the minimum
+            // alignment we need for freezing the Config.
+            RELEASE_BASSERT(!(reinterpret_cast<size_t>(&g_gigacageConfig) & (vmPageSize() - 1)));
+
             Kind shuffledKinds[NumberOfKinds];
             for (unsigned i = 0; i < NumberOfKinds; ++i)
                 shuffledKinds[i] = static_cast<Kind>(i);
@@ -191,12 +235,18 @@
             
             vmDeallocatePhysicalPages(base, totalSize);
             g_gigacageConfig.isEnabled = true;
-            protectGigacageBasePtrs();
+            freezeGigacageConfig();
         });
 }
 
 void disablePrimitiveGigacage()
 {
+    if (g_gigacageConfig.disablingPrimitiveGigacageIsForbidden)
+        fprintf(stderr, "FATAL: Disabling Primitive gigacage is forbidden, but we don't want that in this process.\n");
+
+    RELEASE_BASSERT(!g_gigacageConfig.disablingPrimitiveGigacageIsForbidden);
+    RELEASE_BASSERT(!g_gigacageConfig.isPermanentlyFrozen);
+
     ensureGigacage();
     if (!g_gigacageConfig.basePtrs[Primitive]) {
         // It was never enabled. That means that we never even saved any callbacks. Or, we had already disabled
@@ -209,7 +259,7 @@
     for (Callback& callback : callbacks.callbacks)
         callback.function(callback.argument);
     callbacks.callbacks.shrink(0);
-    UnprotectGigacageBasePtrsScope unprotectScope;
+    UnfreezeGigacageConfigScope unfreezeScope;
     g_gigacageConfig.basePtrs[Primitive] = nullptr;
 }
 
@@ -241,37 +291,39 @@
     }
 }
 
-static void primitiveGigacageDisabled(void*)
+static bool verifyGigacageIsEnabled()
 {
-    if (GIGACAGE_ALLOCATION_CAN_FAIL && !isEnabled())
-        return;
-
-    static bool s_false;
-    fprintf(stderr, "FATAL: Primitive gigacage disabled, but we don't want that in this process.\n");
-    if (!s_false)
-        BCRASH();
+    bool isEnabled = g_gigacageConfig.isEnabled;
+    for (size_t i = 0; i < NumberOfKinds; ++i)
+        isEnabled = isEnabled && g_gigacageConfig.basePtrs[i];
+    return isEnabled;
 }
 
-void disableDisablingPrimitiveGigacageIfShouldBeEnabled()
+void forbidDisablingPrimitiveGigacage()
 {
-    if (shouldBeEnabled()) {
-        addPrimitiveDisableCallback(primitiveGigacageDisabled, nullptr);
-        s_isDisablingPrimitiveGigacageDisabled = true;
+    RELEASE_BASSERT(GIGACAGE_ALLOCATION_CAN_FAIL || verifyGigacageIsEnabled());
+    if (!g_gigacageConfig.disablingPrimitiveGigacageIsForbidden) {
+        unfreezeGigacageConfig();
+        g_gigacageConfig.disablingPrimitiveGigacageIsForbidden = true;
     }
+    permanentlyFreezeGigacageConfig();
+    RELEASE_BASSERT(isDisablingPrimitiveGigacageForbidden());
 }
 
-bool isDisablingPrimitiveGigacageDisabled()
+BNO_INLINE bool isDisablingPrimitiveGigacageForbidden()
 {
-    return s_isDisablingPrimitiveGigacageDisabled;
+    return g_gigacageConfig.disablingPrimitiveGigacageIsForbidden;
 }
 
 bool shouldBeEnabled()
 {
-    static bool cached = false;
     static std::once_flag onceFlag;
     std::call_once(
         onceFlag,
         [] {
+            RELEASE_BASSERT(!g_gigacageConfig.shouldBeEnabledHasBeenCalled);
+            g_gigacageConfig.shouldBeEnabledHasBeenCalled = true;
+
             bool debugHeapEnabled = Environment::get()->isDebugHeapEnabled();
             if (debugHeapEnabled)
                 return;
@@ -287,13 +339,11 @@
                     fprintf(stderr, "Warning: invalid argument to GIGACAGE_ENABLED: %s\n", gigacageEnabled);
             }
             
-            cached = true;
+            g_gigacageConfig.shouldBeEnabled = true;
         });
-    return cached;
+    return g_gigacageConfig.shouldBeEnabled;
 }
 
 } // namespace Gigacage
 
 #endif // GIGACAGE_ENABLED
-
-

Modified: trunk/Source/bmalloc/bmalloc/Gigacage.h (249607 => 249608)


--- trunk/Source/bmalloc/bmalloc/Gigacage.h	2019-09-07 04:19:52 UTC (rev 249607)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.h	2019-09-07 05:42:11 UTC (rev 249608)
@@ -113,7 +113,21 @@
 
     union {
         struct {
+            // All the fields in this struct should be chosen such that their
+            // initial value is 0 / null / falsy because Config is instantiated
+            // as a global singleton.
+
             bool isEnabled;
+            bool isPermanentlyFrozen;
+            bool disablingPrimitiveGigacageIsForbidden;
+            bool shouldBeEnabled;
+
+            // We would like to just put the std::once_flag for these functions
+            // here, but we can't because std::once_flag has a implicitly-deleted
+            // default constructor. So, we use a boolean instead.
+            bool shouldBeEnabledHasBeenCalled;
+            bool ensureGigacageHasBeenCalled;
+
             void* basePtrs[NumberOfKinds];
         };
         char ensureSize[configSizeToProtect];
@@ -138,11 +152,11 @@
 BEXPORT void addPrimitiveDisableCallback(void (*)(void*), void*);
 BEXPORT void removePrimitiveDisableCallback(void (*)(void*), void*);
 
-BEXPORT void disableDisablingPrimitiveGigacageIfShouldBeEnabled();
+BEXPORT void forbidDisablingPrimitiveGigacage();
 
-BEXPORT bool isDisablingPrimitiveGigacageDisabled();
-inline bool isPrimitiveGigacagePermanentlyEnabled() { return isDisablingPrimitiveGigacageDisabled(); }
-inline bool canPrimitiveGigacageBeDisabled() { return !isDisablingPrimitiveGigacageDisabled(); }
+BEXPORT bool isDisablingPrimitiveGigacageForbidden();
+inline bool isPrimitiveGigacagePermanentlyEnabled() { return isDisablingPrimitiveGigacageForbidden(); }
+inline bool canPrimitiveGigacageBeDisabled() { return !isDisablingPrimitiveGigacageForbidden(); }
 
 BINLINE void* basePtr(Kind kind)
 {
@@ -233,7 +247,7 @@
 BINLINE bool isEnabled(Kind) { return false; }
 template<typename T> BINLINE T* caged(Kind, T* ptr) { return ptr; }
 template<typename T> BINLINE T* cagedMayBeNull(Kind, T* ptr) { return ptr; }
-BINLINE void disableDisablingPrimitiveGigacageIfShouldBeEnabled() { }
+BINLINE void forbidDisablingPrimitiveGigacage() { }
 BINLINE bool canPrimitiveGigacageBeDisabled() { return false; }
 BINLINE void disablePrimitiveGigacage() { }
 BINLINE void addPrimitiveDisableCallback(void (*)(void*), void*) { }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to