VirtualAlloc on Windows 7 does not currently provide sufficient randomization to...
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 Aug 2010 15:27:25 +0000 (15:27 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 Aug 2010 15:27:25 +0000 (15:27 +0000)
This patch manually randomizes the allocation address for PAGE_EXECUTE_READWRITE regions between kAllocationRandomAddressMin and kAllocationRandomAddressMax.

BUG=none
TEST=allocate lots of javascript code and check for contiguous allocations

Patch by Paul Mehta <pmehta@chromium.org>

Review URL: http://codereview.chromium.org/2832095

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5169 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/platform-linux.cc
src/platform-win32.cc

index 7e8a558..d3a4498 100644 (file)
@@ -236,6 +236,7 @@ size_t OS::AllocateAlignment() {
 void* OS::Allocate(const size_t requested,
                    size_t* allocated,
                    bool is_executable) {
+  // TODO(805): Port randomization of allocated executable memory to Linux.
   const size_t msize = RoundUp(requested, sysconf(_SC_PAGESIZE));
   int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
   void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
index e2d123c..af3e9b2 100644 (file)
@@ -838,12 +838,38 @@ size_t OS::AllocateAlignment() {
 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
+  // 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 = 0x000004FFFFFFFFFF;
+#else
+  static const intptr_t kAllocationRandomAddressMin = 0x04000000;
+  static const intptr_t kAllocationRandomAddressMax = 0x4FFFFFFF;
+#endif
+
   // VirtualAlloc rounds allocated size to page size automatically.
   size_t msize = RoundUp(requested, static_cast<int>(GetPageSize()));
+  intptr_t address = NULL;
 
   // Windows XP SP2 allows Data Excution Prevention (DEP).
   int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
-  LPVOID mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);
+
+  // For exectutable pages try and randomize the allocation address
+  if (prot == PAGE_EXECUTE_READWRITE && msize >= Page::kPageSize) {
+      address = (V8::Random() << kPageSizeBits) | kAllocationRandomAddressMin;
+      address &= kAllocationRandomAddressMax;
+  }
+
+  LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address),
+                              msize,
+                              MEM_COMMIT | MEM_RESERVE,
+                              prot);
+  if (mbase == NULL && address != NULL)
+    mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);
+
   if (mbase == NULL) {
     LOG(StringEvent("OS::Allocate", "VirtualAlloc failed"));
     return NULL;