Bug 1236530 - Make ExecutableAllocator::reprotectRegion fallible and handle in asm.js (r=jandem)

This commit is contained in:
Luke Wagner 2016-01-05 10:58:12 -06:00
parent bd2edbf59a
commit 69a0d7750b
6 changed files with 26 additions and 14 deletions

View File

@ -1003,7 +1003,10 @@ Module::dynamicallyLink(JSContext* cx, Handle<ArrayBufferObjectMaybeShared*> hea
specializeToHeap(heap);
// See AllocateCode comment above.
ExecutableAllocator::makeExecutable(code(), pod.codeBytes_);
if (!ExecutableAllocator::makeExecutable(code(), pod.codeBytes_)) {
ReportOutOfMemory(cx);
return false;
}
sendCodeRangesToProfiler(cx);
return true;

View File

@ -357,7 +357,8 @@ ExecutableAllocator::reprotectPool(JSRuntime* rt, ExecutablePool* pool, Protecti
MOZ_ASSERT(rt->jitRuntime()->preventBackedgePatching() || rt->handlingJitInterrupt());
char* start = pool->m_allocation.pages;
reprotectRegion(start, pool->m_freePtr - start, protection);
if (!reprotectRegion(start, pool->m_freePtr - start, protection))
MOZ_CRASH();
#endif
}

View File

@ -204,17 +204,23 @@ class ExecutableAllocator
static void reprotectPool(JSRuntime* rt, ExecutablePool* pool, ProtectionSetting protection);
public:
static void makeWritable(void* start, size_t size)
MOZ_WARN_UNUSED_RESULT
static bool makeWritable(void* start, size_t size)
{
#ifdef NON_WRITABLE_JIT_CODE
reprotectRegion(start, size, Writable);
return reprotectRegion(start, size, Writable);
#else
return true;
#endif
}
static void makeExecutable(void* start, size_t size)
MOZ_WARN_UNUSED_RESULT
static bool makeExecutable(void* start, size_t size)
{
#ifdef NON_WRITABLE_JIT_CODE
reprotectRegion(start, size, Executable);
return reprotectRegion(start, size, Executable);
#else
return true;
#endif
}
@ -301,7 +307,8 @@ class ExecutableAllocator
ExecutableAllocator(const ExecutableAllocator&) = delete;
void operator=(const ExecutableAllocator&) = delete;
static void reprotectRegion(void*, size_t, ProtectionSetting);
MOZ_WARN_UNUSED_RESULT
static bool reprotectRegion(void*, size_t, ProtectionSetting);
void reprotectAll(ProtectionSetting);
// These are strong references; they keep pools alive.

View File

@ -78,7 +78,7 @@ ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc)
static const unsigned FLAGS_RW = PROT_READ | PROT_WRITE;
static const unsigned FLAGS_RX = PROT_READ | PROT_EXEC;
void
bool
ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting)
{
MOZ_ASSERT(NON_WRITABLE_JIT_CODE);
@ -95,7 +95,7 @@ ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting
size += (pageSize - 1);
size &= ~(pageSize - 1);
mprotect(pageStart, size, (setting == Writable) ? FLAGS_RW : FLAGS_RX);
return !mprotect(pageStart, size, (setting == Writable) ? FLAGS_RW : FLAGS_RX);
}
/* static */ unsigned

View File

@ -239,7 +239,7 @@ ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc)
DeallocateExecutableMemory(alloc.pages, alloc.size, pageSize);
}
void
bool
ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting)
{
MOZ_ASSERT(NON_WRITABLE_JIT_CODE);
@ -258,8 +258,7 @@ ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting
DWORD oldProtect;
int flags = (setting == Writable) ? PAGE_READWRITE : PAGE_EXECUTE_READ;
if (!VirtualProtect(pageStart, size, flags, &oldProtect))
MOZ_CRASH();
return VirtualProtect(pageStart, size, flags, &oldProtect);
}
/* static */ unsigned

View File

@ -543,7 +543,8 @@ class MOZ_STACK_CLASS AutoWritableJitCode
: preventPatching_(rt), rt_(rt), addr_(addr), size_(size)
{
rt_->toggleAutoWritableJitCodeActive(true);
ExecutableAllocator::makeWritable(addr_, size_);
if (!ExecutableAllocator::makeWritable(addr_, size_))
MOZ_CRASH();
}
AutoWritableJitCode(void* addr, size_t size)
: AutoWritableJitCode(TlsPerThreadData.get()->runtimeFromMainThread(), addr, size)
@ -552,7 +553,8 @@ class MOZ_STACK_CLASS AutoWritableJitCode
: AutoWritableJitCode(code->runtimeFromMainThread(), code->raw(), code->bufferSize())
{}
~AutoWritableJitCode() {
ExecutableAllocator::makeExecutable(addr_, size_);
if (!ExecutableAllocator::makeExecutable(addr_, size_))
MOZ_CRASH();
rt_->toggleAutoWritableJitCodeActive(false);
}
};