Index: src/platform-win32.cc |
=================================================================== |
--- src/platform-win32.cc (revision 10878) |
+++ src/platform-win32.cc (working copy) |
@@ -831,44 +831,63 @@ |
} |
-void* OS::Allocate(const size_t requested, |
- size_t* allocated, |
- bool is_executable) { |
- // The address range used to randomize RWX allocations in OS::Allocate |
- // Try not to map pages into the default range that windows loads DLLs |
- // Use a multiple of 64k to prevent committing unused memory. |
- // Note: This does not guarantee RWX regions will be within the |
- // range kAllocationRandomAddressMin to kAllocationRandomAddressMax |
+static void* GetRandomAddr() { |
+ Isolate* isolate = Isolate::UncheckedCurrent(); |
+ // Note that the current isolate isn't set up in a call path via |
+ // CpuFeatures::Probe. We don't care about randomization in this case because |
+ // the code page is immediately freed. |
+ if (isolate != NULL) { |
+ // The address range used to randomize RWX allocations in OS::Allocate |
+ // Try not to map pages into the default range that windows loads DLLs |
+ // Use a multiple of 64k to prevent committing unused memory. |
+ // Note: This does not guarantee RWX regions will be within the |
+ // range kAllocationRandomAddressMin to kAllocationRandomAddressMax |
#ifdef V8_HOST_ARCH_64_BIT |
- static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000; |
- static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000; |
+ static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000; |
+ static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000; |
#else |
- static const intptr_t kAllocationRandomAddressMin = 0x04000000; |
- static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000; |
+ static const intptr_t kAllocationRandomAddressMin = 0x04000000; |
+ static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000; |
#endif |
+ uintptr_t address = (V8::RandomPrivate(isolate) << kPageSizeBits) |
+ | kAllocationRandomAddressMin; |
+ address &= kAllocationRandomAddressMax; |
+ return reinterpret_cast<void *>(address); |
+ } |
+ return NULL; |
+} |
+ |
+static void* RandomizedVirtualAlloc(size_t size, int action, int protection) { |
+ LPVOID base = NULL; |
+ |
+ if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) { |
+ // For exectutable pages try and randomize the allocation address |
+ for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) { |
+ base = VirtualAlloc(GetRandomAddr(), size, action, protection); |
+ } |
+ } |
+ |
+ // After three attempts give up and let the OS find an address to use. |
+ if (base == NULL) base = VirtualAlloc(NULL, size, action, protection); |
+ |
+ return base; |
+} |
+ |
+ |
+void* OS::Allocate(const size_t requested, |
+ size_t* allocated, |
+ bool is_executable) { |
// VirtualAlloc rounds allocated size to page size automatically. |
size_t msize = RoundUp(requested, static_cast<int>(GetPageSize())); |
- intptr_t address = 0; |
// Windows XP SP2 allows Data Excution Prevention (DEP). |
int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; |
- // For exectutable pages try and randomize the allocation address |
- if (prot == PAGE_EXECUTE_READWRITE && |
- msize >= static_cast<size_t>(Page::kPageSize)) { |
- address = (V8::RandomPrivate(Isolate::Current()) << kPageSizeBits) |
- | kAllocationRandomAddressMin; |
- address &= kAllocationRandomAddressMax; |
- } |
+ LPVOID mbase = RandomizedVirtualAlloc(msize, |
+ MEM_COMMIT | MEM_RESERVE, |
+ prot); |
- LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address), |
- msize, |
- MEM_COMMIT | MEM_RESERVE, |
- prot); |
- if (mbase == NULL && address != 0) |
- mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot); |
- |
if (mbase == NULL) { |
LOG(ISOLATE, StringEvent("OS::Allocate", "VirtualAlloc failed")); |
return NULL; |
@@ -1471,7 +1490,7 @@ |
void* VirtualMemory::ReserveRegion(size_t size) { |
- return VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS); |
+ return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS); |
} |
@@ -1507,7 +1526,6 @@ |
} |
- |
// ---------------------------------------------------------------------------- |
// Win32 thread support. |