| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "wtf/PageAllocator.h" | 32 #include "wtf/PageAllocator.h" |
| 33 | 33 |
| 34 #include "wtf/AddressSpaceRandomization.h" |
| 34 #include "wtf/Assertions.h" | 35 #include "wtf/Assertions.h" |
| 35 #include "wtf/ProcessID.h" | |
| 36 #include "wtf/SpinLock.h" | |
| 37 | 36 |
| 38 #include <limits.h> | 37 #include <limits.h> |
| 39 | 38 |
| 40 #if OS(POSIX) | 39 #if OS(POSIX) |
| 41 | 40 |
| 42 #include <sys/mman.h> | 41 #include <sys/mman.h> |
| 43 | 42 |
| 44 #ifndef MADV_FREE | 43 #ifndef MADV_FREE |
| 45 #define MADV_FREE MADV_DONTNEED | 44 #define MADV_FREE MADV_DONTNEED |
| 46 #endif | 45 #endif |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 } | 94 } |
| 96 size_t postLen = (basePtr + baseLen) - (trimPtr + trimLen); | 95 size_t postLen = (basePtr + baseLen) - (trimPtr + trimLen); |
| 97 if (postLen) { | 96 if (postLen) { |
| 98 int ret = munmap(trimPtr + trimLen, postLen); | 97 int ret = munmap(trimPtr + trimLen, postLen); |
| 99 RELEASE_ASSERT(!ret); | 98 RELEASE_ASSERT(!ret); |
| 100 } | 99 } |
| 101 return true; | 100 return true; |
| 102 #endif | 101 #endif |
| 103 } | 102 } |
| 104 | 103 |
| 105 // This is the same PRNG as used by tcmalloc for mapping address randomness; | |
| 106 // see http://burtleburtle.net/bob/rand/smallprng.html | |
| 107 struct ranctx { | |
| 108 int lock; | |
| 109 bool initialized; | |
| 110 uint32_t a; | |
| 111 uint32_t b; | |
| 112 uint32_t c; | |
| 113 uint32_t d; | |
| 114 }; | |
| 115 | |
| 116 #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) | |
| 117 | |
| 118 uint32_t ranvalInternal(ranctx* x) | |
| 119 { | |
| 120 uint32_t e = x->a - rot(x->b, 27); | |
| 121 x->a = x->b ^ rot(x->c, 17); | |
| 122 x->b = x->c + x->d; | |
| 123 x->c = x->d + e; | |
| 124 x->d = e + x->a; | |
| 125 return x->d; | |
| 126 } | |
| 127 | |
| 128 #undef rot | |
| 129 | |
| 130 uint32_t ranval(ranctx* x) | |
| 131 { | |
| 132 spinLockLock(&x->lock); | |
| 133 if (UNLIKELY(!x->initialized)) { | |
| 134 x->initialized = true; | |
| 135 char c; | |
| 136 uint32_t seed = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&c)); | |
| 137 seed ^= static_cast<uint32_t>(getCurrentProcessID()); | |
| 138 x->a = 0xf1ea5eed; | |
| 139 x->b = x->c = x->d = seed; | |
| 140 for (int i = 0; i < 20; ++i) { | |
| 141 (void) ranvalInternal(x); | |
| 142 } | |
| 143 } | |
| 144 uint32_t ret = ranvalInternal(x); | |
| 145 spinLockUnlock(&x->lock); | |
| 146 return ret; | |
| 147 } | |
| 148 | |
| 149 static struct ranctx s_ranctx; | |
| 150 | |
| 151 // This internal function calculates a random preferred mapping address. | |
| 152 // It is used when the client of allocPages() passes null as the address. | |
| 153 // In calculating an address, we balance good ASLR against not fragmenting the | |
| 154 // address space too badly. | |
| 155 static void* getRandomPageBase() | |
| 156 { | |
| 157 uintptr_t random; | |
| 158 random = static_cast<uintptr_t>(ranval(&s_ranctx)); | |
| 159 #if CPU(X86_64) | |
| 160 random <<= 32UL; | |
| 161 random |= static_cast<uintptr_t>(ranval(&s_ranctx)); | |
| 162 // This address mask gives a low liklihood of address space collisions. | |
| 163 // We handle the situation gracefully if there is a collision. | |
| 164 #if OS(WIN) | |
| 165 // 64-bit Windows has a bizarrely small 8TB user address space. | |
| 166 // Allocates in the 1-5TB region. | |
| 167 random &= 0x3ffffffffffUL; | |
| 168 random += 0x10000000000UL; | |
| 169 #else | |
| 170 // Linux and OS X support the full 47-bit user space of x64 processors. | |
| 171 random &= 0x3fffffffffffUL; | |
| 172 #endif | |
| 173 #elif CPU(ARM64) | |
| 174 // ARM64 on Linux has 39-bit user space. | |
| 175 random &= 0x3fffffffffUL; | |
| 176 random += 0x1000000000UL; | |
| 177 #else // !CPU(X86_64) && !CPU(ARM64) | |
| 178 // This is a good range on Windows, Linux and Mac. | |
| 179 // Allocates in the 0.5-1.5GB region. | |
| 180 random &= 0x3fffffff; | |
| 181 random += 0x20000000; | |
| 182 #endif // CPU(X86_64) | |
| 183 random &= kPageAllocationGranularityBaseMask; | |
| 184 return reinterpret_cast<void*>(random); | |
| 185 } | |
| 186 | |
| 187 void* allocPages(void* addr, size_t len, size_t align) | 104 void* allocPages(void* addr, size_t len, size_t align) |
| 188 { | 105 { |
| 189 ASSERT(len >= kPageAllocationGranularity); | 106 ASSERT(len >= kPageAllocationGranularity); |
| 190 ASSERT(!(len & kPageAllocationGranularityOffsetMask)); | 107 ASSERT(!(len & kPageAllocationGranularityOffsetMask)); |
| 191 ASSERT(align >= kPageAllocationGranularity); | 108 ASSERT(align >= kPageAllocationGranularity); |
| 192 ASSERT(!(align & kPageAllocationGranularityOffsetMask)); | 109 ASSERT(!(align & kPageAllocationGranularityOffsetMask)); |
| 193 ASSERT(!(reinterpret_cast<uintptr_t>(addr) & kPageAllocationGranularityOffse
tMask)); | 110 ASSERT(!(reinterpret_cast<uintptr_t>(addr) & kPageAllocationGranularityOffse
tMask)); |
| 194 size_t alignOffsetMask = align - 1; | 111 size_t alignOffsetMask = align - 1; |
| 195 size_t alignBaseMask = ~alignOffsetMask; | 112 size_t alignBaseMask = ~alignOffsetMask; |
| 196 ASSERT(!(reinterpret_cast<uintptr_t>(addr) & alignOffsetMask)); | 113 ASSERT(!(reinterpret_cast<uintptr_t>(addr) & alignOffsetMask)); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 ASSERT(!(len & kSystemPageOffsetMask)); | 216 ASSERT(!(len & kSystemPageOffsetMask)); |
| 300 #if OS(POSIX) | 217 #if OS(POSIX) |
| 301 (void) addr; | 218 (void) addr; |
| 302 #else | 219 #else |
| 303 setSystemPagesAccessible(addr, len); | 220 setSystemPagesAccessible(addr, len); |
| 304 #endif | 221 #endif |
| 305 } | 222 } |
| 306 | 223 |
| 307 } // namespace WTF | 224 } // namespace WTF |
| 308 | 225 |
| OLD | NEW |