[rwx][mac] Fix jitless mode, pt.2

... when com.apple.security.cs.allow-jit entitlement is not enabled.

Bug: v8:12797, chromium:1324829
Change-Id: I660008e1f8abbac3436dd78ea90937971599b5d0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3644960
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80646}
This commit is contained in:
Igor Sheludko 2022-05-19 16:15:23 +02:00 committed by V8 LUCI CQ
parent 16a7150bae
commit 86656444a2
6 changed files with 73 additions and 27 deletions

View File

@ -6,14 +6,22 @@
#define V8_COMMON_CODE_MEMORY_ACCESS_INL_H_
#include "src/common/code-memory-access.h"
#include "src/logging/log.h"
#include "src/flags/flags.h"
namespace v8 {
namespace internal {
RwxMemoryWriteScope::RwxMemoryWriteScope(const char* comment) { SetWritable(); }
RwxMemoryWriteScope::RwxMemoryWriteScope(const char* comment) {
if (!FLAG_jitless) {
SetWritable();
}
}
RwxMemoryWriteScope::~RwxMemoryWriteScope() { SetExecutable(); }
RwxMemoryWriteScope::~RwxMemoryWriteScope() {
if (!FLAG_jitless) {
SetExecutable();
}
}
#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT
@ -21,6 +29,12 @@ RwxMemoryWriteScope::~RwxMemoryWriteScope() { SetExecutable(); }
// __builtin_available.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
// static
bool RwxMemoryWriteScope::IsAllowed() {
return pthread_jit_write_protect_supported_np();
}
// static
void RwxMemoryWriteScope::SetWritable() {
if (code_space_write_nesting_level_ == 0) {
@ -40,8 +54,13 @@ void RwxMemoryWriteScope::SetExecutable() {
#else // !V8_HAS_PTHREAD_JIT_WRITE_PROTECT
// static
bool RwxMemoryWriteScope::IsAllowed() { return true; }
// static
void RwxMemoryWriteScope::SetWritable() {}
// static
void RwxMemoryWriteScope::SetExecutable() {}
#endif // V8_HAS_PTHREAD_JIT_WRITE_PROTECT

View File

@ -22,7 +22,9 @@ class CodeSpaceWriteScope;
// This scope is a wrapper for APRR/MAP_JIT machinery on MacOS on ARM64
// ("Apple M1"/Apple Silicon) with respective semantics.
// See pthread_jit_write_protect_np() for details.
// On other platforms the scope is a no-op.
// The scope must not be used if the process does not have the
// "com.apple.security.cs.allow-jit" entitlement (see IsAllowed()).
// On other platforms the scope is a no-op and thus it's allowed to be used.
//
// The semantics is the following: the scope switches permissions between
// writable and executable for all the pages allocated with RWX permissions.
@ -42,6 +44,12 @@ class V8_NODISCARD RwxMemoryWriteScope final {
RwxMemoryWriteScope(const RwxMemoryWriteScope&) = delete;
RwxMemoryWriteScope& operator=(const RwxMemoryWriteScope&) = delete;
// Returns true if the configuration of the binary allows using of MAP_JIT
// machinery.
// This method is intended to be used for checking that the state of --jitless
// flag does not contradict the allowance of the MAP_JIT feature.
V8_INLINE static bool IsAllowed();
private:
friend class CodePageCollectionMemoryModificationScope;
friend class CodePageMemoryModificationScope;

View File

@ -602,12 +602,13 @@ AlwaysAllocateScopeForTesting::AlwaysAllocateScopeForTesting(Heap* heap)
: scope_(heap) {}
CodeSpaceMemoryModificationScope::CodeSpaceMemoryModificationScope(Heap* heap)
: heap_(heap) {
:
#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
rwx_write_scope_("A part of CodeSpaceMemoryModificationScope"),
#endif
heap_(heap) {
DCHECK_EQ(ThreadId::Current(), heap_->isolate()->thread_id());
heap_->safepoint()->AssertActive();
if (V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT) {
RwxMemoryWriteScope::SetWritable();
}
if (heap_->write_protect_code_memory()) {
heap_->increment_code_space_memory_modification_scope_depth();
heap_->code_space()->SetCodeModificationPermissions();
@ -633,17 +634,15 @@ CodeSpaceMemoryModificationScope::~CodeSpaceMemoryModificationScope() {
page = page->next_page();
}
}
if (V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT) {
RwxMemoryWriteScope::SetExecutable();
}
}
CodePageCollectionMemoryModificationScope::
CodePageCollectionMemoryModificationScope(Heap* heap)
: heap_(heap) {
if (V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT) {
RwxMemoryWriteScope::SetWritable();
}
:
#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
rwx_write_scope_("A part of CodePageCollectionMemoryModificationScope"),
#endif
heap_(heap) {
if (heap_->write_protect_code_memory()) {
heap_->IncrementCodePageCollectionMemoryModificationScopeDepth();
}
@ -657,14 +656,17 @@ CodePageCollectionMemoryModificationScope::
heap_->ProtectUnprotectedMemoryChunks();
}
}
if (V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT) {
RwxMemoryWriteScope::SetExecutable();
}
}
#ifdef V8_ENABLE_THIRD_PARTY_HEAP
CodePageMemoryModificationScope::CodePageMemoryModificationScope(Code code)
: chunk_(nullptr), scope_active_(false) {}
:
#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
rwx_write_scope_("A part of CodePageMemoryModificationScope"),
#endif
chunk_(nullptr),
scope_active_(false) {
}
#else
CodePageMemoryModificationScope::CodePageMemoryModificationScope(Code code)
: CodePageMemoryModificationScope(BasicMemoryChunk::FromHeapObject(code)) {}
@ -672,12 +674,13 @@ CodePageMemoryModificationScope::CodePageMemoryModificationScope(Code code)
CodePageMemoryModificationScope::CodePageMemoryModificationScope(
BasicMemoryChunk* chunk)
: chunk_(chunk),
:
#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
rwx_write_scope_("A part of CodePageMemoryModificationScope"),
#endif
chunk_(chunk),
scope_active_(chunk_->heap()->write_protect_code_memory() &&
chunk_->IsFlagSet(MemoryChunk::IS_EXECUTABLE)) {
if (V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT) {
RwxMemoryWriteScope::SetWritable();
}
if (scope_active_) {
DCHECK(chunk_->owner()->identity() == CODE_SPACE ||
(chunk_->owner()->identity() == CODE_LO_SPACE));
@ -689,9 +692,6 @@ CodePageMemoryModificationScope::~CodePageMemoryModificationScope() {
if (scope_active_) {
MemoryChunk::cast(chunk_)->SetDefaultCodePermissions();
}
if (V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT) {
RwxMemoryWriteScope::SetExecutable();
}
}
IgnoreLocalGCRequests::IgnoreLocalGCRequests(Heap* heap) : heap_(heap) {

View File

@ -5694,6 +5694,11 @@ void Heap::SetUp(LocalHeap* main_thread_local_heap) {
reinterpret_cast<uintptr_t>(v8::internal::GetRandomMmapAddr()) &
~kMmapRegionMask;
// Ensure that RwxMemoryWriteScope and other dependent scopes (in particular,
// CodePage*ModificationScope and CodeSpaceMemoryModificationScope)
// are allowed to be used when jitless mode is not enabled.
CHECK_IMPLIES(!FLAG_jitless, RwxMemoryWriteScope::IsAllowed());
v8::PageAllocator* code_page_allocator;
if (isolate_->RequiresCodeRange() || code_range_size_ != 0) {
const size_t requested_size =

View File

@ -24,6 +24,7 @@
#include "src/base/platform/mutex.h"
#include "src/builtins/accessors.h"
#include "src/common/assert-scope.h"
#include "src/common/code-memory-access.h"
#include "src/common/globals.h"
#include "src/heap/allocation-observer.h"
#include "src/heap/allocation-result.h"
@ -2621,6 +2622,9 @@ class V8_NODISCARD CodeSpaceMemoryModificationScope {
inline ~CodeSpaceMemoryModificationScope();
private:
#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
V8_NO_UNIQUE_ADDRESS RwxMemoryWriteScope rwx_write_scope_;
#endif
Heap* heap_;
};
@ -2632,6 +2636,9 @@ class V8_NODISCARD CodePageCollectionMemoryModificationScope {
inline ~CodePageCollectionMemoryModificationScope();
private:
#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
V8_NO_UNIQUE_ADDRESS RwxMemoryWriteScope rwx_write_scope_;
#endif
Heap* heap_;
};
@ -2694,6 +2701,9 @@ class V8_NODISCARD CodePageMemoryModificationScope {
inline ~CodePageMemoryModificationScope();
private:
#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
V8_NO_UNIQUE_ADDRESS RwxMemoryWriteScope rwx_write_scope_;
#endif
BasicMemoryChunk* chunk_;
bool scope_active_;

View File

@ -1886,7 +1886,11 @@ NativeModule::~NativeModule() {
WasmCodeManager::WasmCodeManager()
: max_committed_code_space_(FLAG_wasm_max_code_space * MB),
critical_committed_code_space_(max_committed_code_space_ / 2),
memory_protection_key_(AllocateMemoryProtectionKey()) {}
memory_protection_key_(AllocateMemoryProtectionKey()) {
// Ensure that RwxMemoryWriteScope and other dependent scopes (in particular,
// wasm::CodeSpaceWriteScope) are allowed to be used.
CHECK(RwxMemoryWriteScope::IsAllowed());
}
WasmCodeManager::~WasmCodeManager() {
// No more committed code space.