Title: [288870] trunk/Source
Revision
288870
Author
[email protected]
Date
2022-02-01 02:26:28 -0800 (Tue, 01 Feb 2022)

Log Message

Revert OSAllocator behavior to pre-Structure-Allocator change one
https://bugs.webkit.org/show_bug.cgi?id=235940

Reviewed by Mark Lam.

Source/_javascript_Core:

* jit/ExecutableAllocator.cpp:
(JSC::initializeJITPageReservation):

Source/WTF:

Before r288815, OSAllocator::reserveAndCommit can fail only for executable memory.

    if (result == MAP_FAILED) {
        if (executable)
            result = 0;
        else
            CRASH();
    }

However, after r288815, this behavior was changed.

Before r288815,

    1. ExecutableAllocator uses PageReservation::reserveWithGuardPages / PageReservation::reserve / PageReservation::reserveAndCommitWithGuardPages
       to reserve memory.
    2. In ARM64 macOS, we use PageReservation::reserveWithGuardPages.
    3. PageReservation::reserveWithGuardPages uses OSAllocator::reserveUncommitted.
    4. OSAllocator::reserveUncommitted used OSAllocator::reserveAndCommit internally before r288815.
    5. OSAllocator::reserveAndCommit can fail for executable memory.

But after r288815,

    1. PageReservation::reserveWithGuardPages uses OSAllocator::reserveUncommitted
    2. OSAllocator::reserveUncommitted now uses OSAllocator::tryReserveUncommitted and crash if it fails.

Thus, r288815 changed the behavior of OSAllocator::reserveUncommitted for executable memory. This is causing a crash when we failed to
allocate JIT memory. And probably, it is happening in SIP-enabled root-installing environment.

In this patch,

1. Accepting failure only for executable memory is ugly hack. We should add PageReservation::tryReserveWithGuardPages.
2. In PageReservation::tryReserveWithGuardPages we should use OSAllocator::tryReserveUncommitted.

So, this patch reverts the behavior back to pre-r288815 state.
We also fix a bug in tryReserveUncommitted where it handles MAP_FAILED incorrectly. We should not return MAP_FAILED from OSAllocator, instead,
we should return nullptr.

* wtf/OSAllocator.h:
* wtf/PageReservation.h:
(WTF::PageReservation::tryReserve):
(WTF::PageReservation::tryReserveWithGuardPages):
(WTF::PageReservation::tryReserveAndCommitWithGuardPages):
* wtf/posix/OSAllocatorPOSIX.cpp:
(WTF::OSAllocator::tryReserveAndCommit):
(WTF::OSAllocator::tryReserveUncommitted):
(WTF::OSAllocator::reserveAndCommit):
(WTF::tryReserveAndCommit): Deleted.
(WTF::tryReserveUncommitted): Deleted.
* wtf/win/OSAllocatorWin.cpp:
(WTF::OSAllocator::tryReserveUncommitted):
(WTF::OSAllocator::reserveUncommitted):
(WTF::OSAllocator::tryReserveAndCommit):
(WTF::OSAllocator::reserveAndCommit):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (288869 => 288870)


--- trunk/Source/_javascript_Core/ChangeLog	2022-02-01 09:33:02 UTC (rev 288869)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-02-01 10:26:28 UTC (rev 288870)
@@ -1,3 +1,13 @@
+2022-01-31  Yusuke Suzuki  <[email protected]>
+
+        Revert OSAllocator behavior to pre-Structure-Allocator change one
+        https://bugs.webkit.org/show_bug.cgi?id=235940
+
+        Reviewed by Mark Lam.
+
+        * jit/ExecutableAllocator.cpp:
+        (JSC::initializeJITPageReservation):
+
 2022-01-31  Zan Dobersek  <[email protected]>
 
         [RISCV64] Add remaining MacroAssemblerRISCV64 branching operations

Modified: trunk/Source/_javascript_Core/jit/ExecutableAllocator.cpp (288869 => 288870)


--- trunk/Source/_javascript_Core/jit/ExecutableAllocator.cpp	2022-02-01 09:33:02 UTC (rev 288869)
+++ trunk/Source/_javascript_Core/jit/ExecutableAllocator.cpp	2022-02-01 10:26:28 UTC (rev 288870)
@@ -360,11 +360,11 @@
         // This makes the following JIT code logging broken and some of JIT code is not recorded correctly.
         // To avoid this problem, we use committed reservation if we need perf JITDump logging.
         if (Options::logJITCodeForPerf())
-            return PageReservation::reserveAndCommitWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true, false);
+            return PageReservation::tryReserveAndCommitWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true, false);
 #endif
         if (Options::useJITCage() && JSC_ALLOW_JIT_CAGE_SPECIFIC_RESERVATION)
-            return PageReservation::reserve(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true, Options::useJITCage());
-        return PageReservation::reserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true, false);
+            return PageReservation::tryReserve(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true, Options::useJITCage());
+        return PageReservation::tryReserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true, false);
     };
 
     reservation.pageReservation = tryCreatePageReservation(reservation.size);

Modified: trunk/Source/WTF/ChangeLog (288869 => 288870)


--- trunk/Source/WTF/ChangeLog	2022-02-01 09:33:02 UTC (rev 288869)
+++ trunk/Source/WTF/ChangeLog	2022-02-01 10:26:28 UTC (rev 288870)
@@ -1,3 +1,64 @@
+2022-01-31  Yusuke Suzuki  <[email protected]>
+
+        Revert OSAllocator behavior to pre-Structure-Allocator change one
+        https://bugs.webkit.org/show_bug.cgi?id=235940
+
+        Reviewed by Mark Lam.
+
+        Before r288815, OSAllocator::reserveAndCommit can fail only for executable memory.
+
+            if (result == MAP_FAILED) {
+                if (executable)
+                    result = 0;
+                else
+                    CRASH();
+            }
+
+        However, after r288815, this behavior was changed.
+
+        Before r288815,
+
+            1. ExecutableAllocator uses PageReservation::reserveWithGuardPages / PageReservation::reserve / PageReservation::reserveAndCommitWithGuardPages
+               to reserve memory.
+            2. In ARM64 macOS, we use PageReservation::reserveWithGuardPages.
+            3. PageReservation::reserveWithGuardPages uses OSAllocator::reserveUncommitted.
+            4. OSAllocator::reserveUncommitted used OSAllocator::reserveAndCommit internally before r288815.
+            5. OSAllocator::reserveAndCommit can fail for executable memory.
+
+        But after r288815,
+
+            1. PageReservation::reserveWithGuardPages uses OSAllocator::reserveUncommitted
+            2. OSAllocator::reserveUncommitted now uses OSAllocator::tryReserveUncommitted and crash if it fails.
+
+        Thus, r288815 changed the behavior of OSAllocator::reserveUncommitted for executable memory. This is causing a crash when we failed to
+        allocate JIT memory. And probably, it is happening in SIP-enabled root-installing environment.
+
+        In this patch,
+
+        1. Accepting failure only for executable memory is ugly hack. We should add PageReservation::tryReserveWithGuardPages.
+        2. In PageReservation::tryReserveWithGuardPages we should use OSAllocator::tryReserveUncommitted.
+
+        So, this patch reverts the behavior back to pre-r288815 state.
+        We also fix a bug in tryReserveUncommitted where it handles MAP_FAILED incorrectly. We should not return MAP_FAILED from OSAllocator, instead,
+        we should return nullptr.
+
+        * wtf/OSAllocator.h:
+        * wtf/PageReservation.h:
+        (WTF::PageReservation::tryReserve):
+        (WTF::PageReservation::tryReserveWithGuardPages):
+        (WTF::PageReservation::tryReserveAndCommitWithGuardPages):
+        * wtf/posix/OSAllocatorPOSIX.cpp:
+        (WTF::OSAllocator::tryReserveAndCommit):
+        (WTF::OSAllocator::tryReserveUncommitted):
+        (WTF::OSAllocator::reserveAndCommit):
+        (WTF::tryReserveAndCommit): Deleted.
+        (WTF::tryReserveUncommitted): Deleted.
+        * wtf/win/OSAllocatorWin.cpp:
+        (WTF::OSAllocator::tryReserveUncommitted):
+        (WTF::OSAllocator::reserveUncommitted):
+        (WTF::OSAllocator::tryReserveAndCommit):
+        (WTF::OSAllocator::reserveAndCommit):
+
 2022-02-01  Tim Nguyen  <[email protected]>
 
         Entirely remove support for -apple-trailing-word

Modified: trunk/Source/WTF/wtf/OSAllocator.h (288869 => 288870)


--- trunk/Source/WTF/wtf/OSAllocator.h	2022-02-01 09:33:02 UTC (rev 288869)
+++ trunk/Source/WTF/wtf/OSAllocator.h	2022-02-01 10:26:28 UTC (rev 288870)
@@ -44,6 +44,7 @@
     // the memory must all currently be in a decommitted state. reserveUncommitted(Aligned) returns to
     // you memory that is zeroed.
     WTF_EXPORT_PRIVATE static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false, bool includesGuardPages = false);
+    WTF_EXPORT_PRIVATE static void* tryReserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false, bool includesGuardPages = false);
     // This guarantees the memory will be aligned to a multiple of the requested size. The requested
     // size must be a power of two and greater than the system page size.
     WTF_EXPORT_PRIVATE static void* tryReserveUncommittedAligned(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false, bool includesGuardPages = false);
@@ -59,6 +60,7 @@
     // decommitAndRelease should be called on a region of VM allocated by a single reservation,
     // the memory must all currently be in a committed state.
     WTF_EXPORT_PRIVATE static void* reserveAndCommit(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false, bool includesGuardPages = false);
+    WTF_EXPORT_PRIVATE static void* tryReserveAndCommit(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false, bool includesGuardPages = false);
     static void decommitAndRelease(void* base, size_t size);
 
     // These methods are akin to reserveAndCommit/decommitAndRelease, above - however rather than

Modified: trunk/Source/WTF/wtf/PageReservation.h (288869 => 288870)


--- trunk/Source/WTF/wtf/PageReservation.h	2022-02-01 09:33:02 UTC (rev 288869)
+++ trunk/Source/WTF/wtf/PageReservation.h	2022-02-01 10:26:28 UTC (rev 288870)
@@ -93,7 +93,13 @@
         ASSERT(isPageAligned(size));
         return PageReservation(OSAllocator::reserveUncommitted(size, usage, writable, executable, jitCageEnabled, false), size, writable, executable, jitCageEnabled, false);
     }
-    
+
+    static PageReservation tryReserve(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false)
+    {
+        ASSERT(isPageAligned(size));
+        return PageReservation(OSAllocator::tryReserveUncommitted(size, usage, writable, executable, jitCageEnabled, false), size, writable, executable, jitCageEnabled, false);
+    }
+
     static PageReservation reserveWithGuardPages(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false)
     {
         ASSERT(isPageAligned(size));
@@ -100,6 +106,12 @@
         return PageReservation(OSAllocator::reserveUncommitted(size + pageSize() * 2, usage, writable, executable, jitCageEnabled, true), size, writable, executable, jitCageEnabled, true);
     }
 
+    static PageReservation tryReserveWithGuardPages(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false)
+    {
+        ASSERT(isPageAligned(size));
+        return PageReservation(OSAllocator::tryReserveUncommitted(size + pageSize() * 2, usage, writable, executable, jitCageEnabled, true), size, writable, executable, jitCageEnabled, true);
+    }
+
     static PageReservation reserveAndCommitWithGuardPages(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false)
     {
         ASSERT(isPageAligned(size));
@@ -106,6 +118,12 @@
         return PageReservation(OSAllocator::reserveAndCommit(size + pageSize() * 2, usage, writable, executable, jitCageEnabled, true), size, writable, executable, jitCageEnabled, true);
     }
 
+    static PageReservation tryReserveAndCommitWithGuardPages(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false)
+    {
+        ASSERT(isPageAligned(size));
+        return PageReservation(OSAllocator::tryReserveAndCommit(size + pageSize() * 2, usage, writable, executable, jitCageEnabled, true), size, writable, executable, jitCageEnabled, true);
+    }
+
     void deallocate()
     {
         ASSERT(!m_committed);

Modified: trunk/Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp (288869 => 288870)


--- trunk/Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp	2022-02-01 09:33:02 UTC (rev 288869)
+++ trunk/Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp	2022-02-01 10:26:28 UTC (rev 288870)
@@ -50,7 +50,7 @@
 
 namespace WTF {
 
-static void* tryReserveAndCommit(size_t bytes, OSAllocator::Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages)
+void* OSAllocator::tryReserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages)
 {
     // All POSIX reservations start out logically committed.
     int protection = PROT_READ;
@@ -113,7 +113,7 @@
     return result;
 }
 
-static void* tryReserveUncommitted(size_t bytes, OSAllocator::Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages)
+void* OSAllocator::tryReserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages)
 {
 #if OS(LINUX)
     UNUSED_PARAM(usage);
@@ -123,7 +123,9 @@
     UNUSED_PARAM(includesGuardPages);
 
     void* result = mmap(0, bytes, PROT_NONE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0);
-    if (result != MAP_FAILED)
+    if (result == MAP_FAILED)
+        result = nullptr;
+    if (result)
         madvise(result, bytes, MADV_DONTNEED);
 #else
     void* result = tryReserveAndCommit(bytes, usage, writable, executable, jitCageEnabled, includesGuardPages);
@@ -199,7 +201,7 @@
 void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages)
 {
     void* result = tryReserveAndCommit(bytes, usage, writable, executable, jitCageEnabled, includesGuardPages);
-    RELEASE_ASSERT(result || executable);
+    RELEASE_ASSERT(result);
     return result;
 }
 

Modified: trunk/Source/WTF/wtf/win/OSAllocatorWin.cpp (288869 => 288870)


--- trunk/Source/WTF/wtf/win/OSAllocatorWin.cpp	2022-02-01 09:33:02 UTC (rev 288869)
+++ trunk/Source/WTF/wtf/win/OSAllocatorWin.cpp	2022-02-01 10:26:28 UTC (rev 288870)
@@ -44,11 +44,15 @@
         (writable ? PAGE_READWRITE : PAGE_READONLY);
 }
 
-void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool writable, bool executable, bool, bool)
+void* OSAllocator::tryReserveUncommitted(size_t bytes, Usage, bool writable, bool executable, bool, bool)
 {
-    void* result = VirtualAlloc(nullptr, bytes, MEM_RESERVE, protection(writable, executable));
-    if (!result)
-        CRASH();
+    return VirtualAlloc(nullptr, bytes, MEM_RESERVE, protection(writable, executable));
+}
+
+void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages)
+{
+    void* result = tryReserveUncommitted(bytes, usage, writable, executable, jitCageEnabled, includesGuardPages);
+    RELEASE_ASSERT(result);
     return result;
 }
 
@@ -70,11 +74,15 @@
     return aligned;
 }
 
-void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool writable, bool executable, bool, bool)
+void* OSAllocator::tryReserveAndCommit(size_t bytes, Usage, bool writable, bool executable, bool, bool)
 {
-    void* result = VirtualAlloc(nullptr, bytes, MEM_RESERVE | MEM_COMMIT, protection(writable, executable));
-    if (!result)
-        CRASH();
+    return VirtualAlloc(nullptr, bytes, MEM_RESERVE | MEM_COMMIT, protection(writable, executable));
+}
+
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages)
+{
+    void* result = tryReserveAndCommit(bytes, usage, writable, executable, jitCageEnabled, includesGuardPages);
+    RELEASE_ASSERT(result);
     return result;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to