OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <fcntl.h> | 5 #include <fcntl.h> |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
(...skipping 16 matching lines...) Expand all Loading... |
27 using std::numeric_limits; | 27 using std::numeric_limits; |
28 | 28 |
29 namespace { | 29 namespace { |
30 | 30 |
31 // This function acts as a compiler optimization barrier. We use it to | 31 // This function acts as a compiler optimization barrier. We use it to |
32 // prevent the compiler from making an expression a compile-time constant. | 32 // prevent the compiler from making an expression a compile-time constant. |
33 // We also use it so that the compiler doesn't discard certain return values | 33 // We also use it so that the compiler doesn't discard certain return values |
34 // as something we don't need (see the comment with calloc below). | 34 // as something we don't need (see the comment with calloc below). |
35 template <typename Type> | 35 template <typename Type> |
36 Type HideValueFromCompiler(volatile Type value) { | 36 Type HideValueFromCompiler(volatile Type value) { |
| 37 #if defined(__GNUC__) |
| 38 // In a GCC compatible compiler (GCC or Clang), make this compiler barrier |
| 39 // more robust than merely using "volatile". |
| 40 __asm__ volatile ("" : "+r" (value)); |
| 41 #endif // __GNUC__ |
37 return value; | 42 return value; |
38 } | 43 } |
39 | 44 |
40 // - NO_TCMALLOC (should be defined if we compile with linux_use_tcmalloc=0) | 45 // - NO_TCMALLOC (should be defined if we compile with linux_use_tcmalloc=0) |
41 // - ADDRESS_SANITIZER because it has its own memory allocator | 46 // - ADDRESS_SANITIZER because it has its own memory allocator |
42 // - IOS does not use tcmalloc | 47 // - IOS does not use tcmalloc |
43 // - OS_MACOSX does not use tcmalloc | 48 // - OS_MACOSX does not use tcmalloc |
44 #if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \ | 49 #if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \ |
45 !defined(OS_IOS) && !defined(OS_MACOSX) | 50 !defined(OS_IOS) && !defined(OS_MACOSX) |
46 #define TCMALLOC_TEST(function) function | 51 #define TCMALLOC_TEST(function) function |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNewArray)) { | 137 TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNewArray)) { |
133 if (!IsTcMallocBypassed()) { | 138 if (!IsTcMallocBypassed()) { |
134 scoped_ptr<char[]> ptr( | 139 scoped_ptr<char[]> ptr( |
135 HideValueFromCompiler(new (nothrow) char[kTooBigAllocSize])); | 140 HideValueFromCompiler(new (nothrow) char[kTooBigAllocSize])); |
136 ASSERT_TRUE(!ptr); | 141 ASSERT_TRUE(!ptr); |
137 } | 142 } |
138 } | 143 } |
139 | 144 |
140 // The tests bellow check for overflows in new[] and calloc(). | 145 // The tests bellow check for overflows in new[] and calloc(). |
141 | 146 |
142 #if defined(OS_IOS) || defined(OS_WIN) | 147 #if defined(OS_IOS) |
143 #define DISABLE_ON_IOS_AND_WIN(function) DISABLED_##function | 148 #define DISABLE_ON_IOS(function) DISABLED_##function |
144 #else | 149 #else |
145 #define DISABLE_ON_IOS_AND_WIN(function) function | 150 #define DISABLE_ON_IOS(function) function |
146 #endif | 151 #endif |
147 | 152 |
148 #if defined(ADDRESS_SANITIZER) | 153 #if defined(ADDRESS_SANITIZER) |
149 #define DISABLE_ON_ASAN(function) DISABLED_##function | 154 #define DISABLE_ON_ASAN(function) DISABLED_##function |
150 #else | 155 #else |
151 #define DISABLE_ON_ASAN(function) function | 156 #define DISABLE_ON_ASAN(function) function |
152 #endif | 157 #endif |
153 | 158 |
154 // There are platforms where these tests are known to fail. We would like to | 159 // There are platforms where these tests are known to fail. We would like to |
155 // be able to easily check the status on the bots, but marking tests as | 160 // be able to easily check the status on the bots, but marking tests as |
156 // FAILS_ is too clunky. | 161 // FAILS_ is too clunky. |
157 void OverflowTestsSoftExpectTrue(bool overflow_detected) { | 162 void OverflowTestsSoftExpectTrue(bool overflow_detected) { |
158 if (!overflow_detected) { | 163 if (!overflow_detected) { |
159 #if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX) | 164 #if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX) |
160 // Sadly, on Linux, Android, and OSX we don't have a good story yet. Don't | 165 // Sadly, on Linux, Android, and OSX we don't have a good story yet. Don't |
161 // fail the test, but report. | 166 // fail the test, but report. |
162 printf("Platform has overflow: %s\n", | 167 printf("Platform has overflow: %s\n", |
163 !overflow_detected ? "yes." : "no."); | 168 !overflow_detected ? "yes." : "no."); |
164 #else | 169 #else |
165 // Otherwise, fail the test. (Note: EXPECT are ok in subfunctions, ASSERT | 170 // Otherwise, fail the test. (Note: EXPECT are ok in subfunctions, ASSERT |
166 // aren't). | 171 // aren't). |
167 EXPECT_TRUE(overflow_detected); | 172 EXPECT_TRUE(overflow_detected); |
168 #endif | 173 #endif |
169 } | 174 } |
170 } | 175 } |
171 | 176 |
172 // TODO(jln): crbug.com/174947 This can't even compile on Win64. | |
173 #if !(defined(OS_WIN) && defined(ARCH_CPU_X86_64)) | |
174 | |
175 // Test array[TooBig][X] and array[X][TooBig] allocations for int overflows. | 177 // Test array[TooBig][X] and array[X][TooBig] allocations for int overflows. |
176 // IOS doesn't honor nothrow, so disable the test there. | 178 // IOS doesn't honor nothrow, so disable the test there. |
177 // Disable on Windows, we suspect some are failing because of it. | 179 TEST(SecurityTest, DISABLE_ON_IOS(NewOverflow)) { |
178 TEST(SecurityTest, DISABLE_ON_IOS_AND_WIN(NewOverflow)) { | |
179 const size_t kArraySize = 4096; | 180 const size_t kArraySize = 4096; |
180 // We want something "dynamic" here, so that the compiler doesn't | 181 // We want something "dynamic" here, so that the compiler doesn't |
181 // immediately reject crazy arrays. | 182 // immediately reject crazy arrays. |
182 const size_t kDynamicArraySize = HideValueFromCompiler(kArraySize); | 183 const size_t kDynamicArraySize = HideValueFromCompiler(kArraySize); |
183 // numeric_limits are still not constexpr until we switch to C++11, so we | 184 // numeric_limits are still not constexpr until we switch to C++11, so we |
184 // use an ugly cast. | 185 // use an ugly cast. |
185 const size_t kMaxSizeT = ~static_cast<size_t>(0); | 186 const size_t kMaxSizeT = ~static_cast<size_t>(0); |
186 ASSERT_EQ(numeric_limits<size_t>::max(), kMaxSizeT); | 187 ASSERT_EQ(numeric_limits<size_t>::max(), kMaxSizeT); |
187 const size_t kArraySize2 = kMaxSizeT / kArraySize + 10; | 188 const size_t kArraySize2 = kMaxSizeT / kArraySize + 10; |
188 const size_t kDynamicArraySize2 = HideValueFromCompiler(kArraySize2); | 189 const size_t kDynamicArraySize2 = HideValueFromCompiler(kArraySize2); |
189 { | 190 { |
190 scoped_ptr<char[][kArraySize]> array_pointer(new (nothrow) | 191 scoped_ptr<char[][kArraySize]> array_pointer(new (nothrow) |
191 char[kDynamicArraySize2][kArraySize]); | 192 char[kDynamicArraySize2][kArraySize]); |
192 OverflowTestsSoftExpectTrue(!array_pointer); | 193 OverflowTestsSoftExpectTrue(!array_pointer); |
193 } | 194 } |
| 195 // On windows, the compiler prevents static array sizes of more than |
| 196 // 0x7fffffff (error C2148). |
| 197 #if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS) |
194 { | 198 { |
195 scoped_ptr<char[][kArraySize2]> array_pointer(new (nothrow) | 199 scoped_ptr<char[][kArraySize2]> array_pointer(new (nothrow) |
196 char[kDynamicArraySize][kArraySize2]); | 200 char[kDynamicArraySize][kArraySize2]); |
197 OverflowTestsSoftExpectTrue(!array_pointer); | 201 OverflowTestsSoftExpectTrue(!array_pointer); |
198 } | 202 } |
| 203 #endif // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS) |
199 } | 204 } |
200 #endif | |
201 | 205 |
202 // Call calloc(), eventually free the memory and return whether or not | 206 // Call calloc(), eventually free the memory and return whether or not |
203 // calloc() did succeed. | 207 // calloc() did succeed. |
204 bool CallocReturnsNull(size_t nmemb, size_t size) { | 208 bool CallocReturnsNull(size_t nmemb, size_t size) { |
205 scoped_ptr<char, base::FreeDeleter> array_pointer( | 209 scoped_ptr<char, base::FreeDeleter> array_pointer( |
206 static_cast<char*>(calloc(nmemb, size))); | 210 static_cast<char*>(calloc(nmemb, size))); |
207 // We need the call to HideValueFromCompiler(): we have seen LLVM | 211 // We need the call to HideValueFromCompiler(): we have seen LLVM |
208 // optimize away the call to calloc() entirely and assume | 212 // optimize away the call to calloc() entirely and assume |
209 // the pointer to not be NULL. | 213 // the pointer to not be NULL. |
210 return HideValueFromCompiler(array_pointer.get()) == NULL; | 214 return HideValueFromCompiler(array_pointer.get()) == NULL; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 // kRandomMask, so we use it as an additional detection mechanism. | 297 // kRandomMask, so we use it as an additional detection mechanism. |
294 const uintptr_t kRandomMask = 0x3fffffffffffULL; | 298 const uintptr_t kRandomMask = 0x3fffffffffffULL; |
295 bool impossible_random_address = | 299 bool impossible_random_address = |
296 reinterpret_cast<uintptr_t>(ptr.get()) & ~kRandomMask; | 300 reinterpret_cast<uintptr_t>(ptr.get()) & ~kRandomMask; |
297 EXPECT_FALSE(impossible_random_address); | 301 EXPECT_FALSE(impossible_random_address); |
298 } | 302 } |
299 | 303 |
300 #endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__) | 304 #endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__) |
301 | 305 |
302 } // namespace | 306 } // namespace |
OLD | NEW |