1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "third_party/base/allocator/partition_allocator/address_space_randomization.h" 6 7 #include "build/build_config.h" 8 #include "third_party/base/allocator/partition_allocator/page_allocator.h" 9 #include "third_party/base/allocator/partition_allocator/random.h" 10 #include "third_party/base/allocator/partition_allocator/spin_lock.h" 11 #include "third_party/base/logging.h" 12 13 #if defined(OS_WIN) 14 #include <windows.h> // Must be in front of other Windows header files. 15 16 #include <VersionHelpers.h> 17 #endif 18 19 namespace pdfium { 20 namespace base { 21 GetRandomPageBase()22void* GetRandomPageBase() { 23 uintptr_t random = static_cast<uintptr_t>(RandomValue()); 24 25 #if defined(ARCH_CPU_64_BITS) 26 random <<= 32ULL; 27 random |= static_cast<uintptr_t>(RandomValue()); 28 29 // The kASLRMask and kASLROffset constants will be suitable for the 30 // OS and build configuration. 31 #if defined(OS_WIN) && !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 32 // Windows >= 8.1 has the full 47 bits. Use them where available. 33 static bool windows_81 = false; 34 static bool windows_81_initialized = false; 35 if (!windows_81_initialized) { 36 windows_81 = IsWindows8Point1OrGreater(); 37 windows_81_initialized = true; 38 } 39 if (!windows_81) { 40 random &= internal::kASLRMaskBefore8_10; 41 } else { 42 random &= internal::kASLRMask; 43 } 44 random += internal::kASLROffset; 45 #else 46 random &= internal::kASLRMask; 47 random += internal::kASLROffset; 48 #endif // defined(OS_WIN) && !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 49 #else // defined(ARCH_CPU_32_BITS) 50 #if defined(OS_WIN) 51 // On win32 host systems the randomization plus huge alignment causes 52 // excessive fragmentation. Plus most of these systems lack ASLR, so the 53 // randomization isn't buying anything. In that case we just skip it. 54 // TODO(palmer): Just dump the randomization when HE-ASLR is present. 55 static BOOL is_wow64 = -1; 56 if (is_wow64 == -1 && !IsWow64Process(GetCurrentProcess(), &is_wow64)) 57 is_wow64 = FALSE; 58 if (!is_wow64) 59 return nullptr; 60 #endif // defined(OS_WIN) 61 random &= internal::kASLRMask; 62 random += internal::kASLROffset; 63 #endif // defined(ARCH_CPU_32_BITS) 64 65 DCHECK_EQ(0ULL, (random & kPageAllocationGranularityOffsetMask)); 66 return reinterpret_cast<void*>(random); 67 } 68 69 } // namespace base 70 } // namespace pdfium 71