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 |