| 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 |