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> |
11 | 11 |
12 #include <algorithm> | 12 #include <algorithm> |
13 #include <limits> | 13 #include <limits> |
14 | 14 |
15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
19 | 19 |
20 using std::nothrow; | 20 using std::nothrow; |
21 using std::numeric_limits; | 21 using std::numeric_limits; |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 // This function acts as a compiler optimization barrier. We use it to | |
26 // prevent the compiler from making an expression a compile-time constant. | |
27 // We also use it so that the compiler doesn't discard certain return values | |
28 // as something we don't need (see the comment with calloc below). | |
29 template <typename Type> | |
30 Type HideValueFromCompiler(volatile Type value) { | |
31 return value; | |
32 } | |
33 | |
25 // Check that we can not allocate a memory range that cannot be indexed | 34 // Check that we can not allocate a memory range that cannot be indexed |
26 // via an int. This is used to mitigate vulnerabilities in libraries that use | 35 // via an int. This is used to mitigate vulnerabilities in libraries that use |
27 // int instead of size_t. | 36 // int instead of size_t. |
28 // See crbug.com/169327. | 37 // See crbug.com/169327. |
29 | 38 |
30 // - NO_TCMALLOC because we only patched tcmalloc | 39 // - NO_TCMALLOC because we only patched tcmalloc |
31 // - ADDRESS_SANITIZER because it has its own memory allocator | 40 // - ADDRESS_SANITIZER because it has its own memory allocator |
32 // - IOS does not seem to honor nothrow in new properly | 41 // - IOS does not seem to honor nothrow in new properly |
33 // - OS_MACOSX does not use tcmalloc | 42 // - OS_MACOSX does not use tcmalloc |
34 #if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \ | 43 #if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \ |
(...skipping 19 matching lines...) Expand all Loading... | |
54 } | 63 } |
55 | 64 |
56 // Fake test that allow to know the state of TCMalloc by looking at bots. | 65 // Fake test that allow to know the state of TCMalloc by looking at bots. |
57 TEST(SecurityTest, ALLOC_TEST(IsTCMallocDynamicallyBypassed)) { | 66 TEST(SecurityTest, ALLOC_TEST(IsTCMallocDynamicallyBypassed)) { |
58 printf("Malloc is dynamically bypassed: %s\n", | 67 printf("Malloc is dynamically bypassed: %s\n", |
59 IsTcMallocBypassed() ? "yes." : "no."); | 68 IsTcMallocBypassed() ? "yes." : "no."); |
60 } | 69 } |
61 | 70 |
62 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsMalloc)) { | 71 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsMalloc)) { |
63 if (!IsTcMallocBypassed()) { | 72 if (!IsTcMallocBypassed()) { |
64 scoped_ptr<char, base::FreeDeleter> | 73 scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>( |
65 ptr(static_cast<char*>(malloc(kTooBigAllocSize))); | 74 HideValueFromCompiler(malloc(kTooBigAllocSize)))); |
66 ASSERT_TRUE(ptr == NULL); | 75 ASSERT_TRUE(ptr == NULL); |
awong
2013/02/05 22:42:22
drive-by nit: this would be cleaner as ASSERT_TRUE
jln (very slow on Chromium)
2013/02/06 00:05:01
This used to not work with scoped ptr. In general
| |
67 } | 76 } |
68 } | 77 } |
69 | 78 |
70 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsCalloc)) { | 79 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsCalloc)) { |
71 if (!IsTcMallocBypassed()) { | 80 if (!IsTcMallocBypassed()) { |
72 scoped_ptr<char, base::FreeDeleter> | 81 scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>( |
73 ptr(static_cast<char*>(calloc(kTooBigAllocSize, 1))); | 82 HideValueFromCompiler(calloc(kTooBigAllocSize, 1)))); |
74 ASSERT_TRUE(ptr == NULL); | 83 ASSERT_TRUE(ptr == NULL); |
75 } | 84 } |
76 } | 85 } |
77 | 86 |
78 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsRealloc)) { | 87 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsRealloc)) { |
79 if (!IsTcMallocBypassed()) { | 88 if (!IsTcMallocBypassed()) { |
80 char* orig_ptr = static_cast<char*>(malloc(1)); | 89 char* orig_ptr = static_cast<char*>(malloc(1)); |
81 ASSERT_TRUE(orig_ptr != NULL); | 90 ASSERT_TRUE(orig_ptr != NULL); |
82 scoped_ptr<char, base::FreeDeleter> | 91 scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>( |
83 ptr(static_cast<char*>(realloc(orig_ptr, kTooBigAllocSize))); | 92 HideValueFromCompiler(realloc(orig_ptr, kTooBigAllocSize)))); |
84 ASSERT_TRUE(ptr == NULL); | 93 ASSERT_TRUE(ptr == NULL); |
85 // If realloc() did not succeed, we need to free orig_ptr. | 94 // If realloc() did not succeed, we need to free orig_ptr. |
86 free(orig_ptr); | 95 free(orig_ptr); |
87 } | 96 } |
88 } | 97 } |
89 | 98 |
90 typedef struct { | 99 typedef struct { |
91 char large_array[kTooBigAllocSize]; | 100 char large_array[kTooBigAllocSize]; |
92 } VeryLargeStruct; | 101 } VeryLargeStruct; |
93 | 102 |
94 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsNew)) { | 103 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsNew)) { |
95 if (!IsTcMallocBypassed()) { | 104 if (!IsTcMallocBypassed()) { |
96 scoped_ptr<VeryLargeStruct> ptr(new (nothrow) VeryLargeStruct); | 105 scoped_ptr<VeryLargeStruct> ptr( |
106 HideValueFromCompiler(new (nothrow) VeryLargeStruct)); | |
97 ASSERT_TRUE(ptr == NULL); | 107 ASSERT_TRUE(ptr == NULL); |
98 } | 108 } |
99 } | 109 } |
100 | 110 |
101 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsNewArray)) { | 111 TEST(SecurityTest, ALLOC_TEST(MemoryAllocationRestrictionsNewArray)) { |
102 if (!IsTcMallocBypassed()) { | 112 if (!IsTcMallocBypassed()) { |
103 scoped_ptr<char[]> ptr(new (nothrow) char[kTooBigAllocSize]); | 113 scoped_ptr<char[]> ptr( |
114 HideValueFromCompiler(new (nothrow) char[kTooBigAllocSize])); | |
104 ASSERT_TRUE(ptr == NULL); | 115 ASSERT_TRUE(ptr == NULL); |
105 } | 116 } |
106 } | 117 } |
107 | 118 |
108 // The tests bellow check for overflows in new[] and calloc(). | 119 // The tests bellow check for overflows in new[] and calloc(). |
109 | 120 |
110 #if defined(OS_IOS) || defined(OS_WIN) | 121 #if defined(OS_IOS) || defined(OS_WIN) |
111 #define DISABLE_ON_IOS_AND_WIN(function) DISABLED_##function | 122 #define DISABLE_ON_IOS_AND_WIN(function) DISABLED_##function |
112 #else | 123 #else |
113 #define DISABLE_ON_IOS_AND_WIN(function) function | 124 #define DISABLE_ON_IOS_AND_WIN(function) function |
(...skipping 16 matching lines...) Expand all Loading... | |
130 printf("Platform has overflow: %s\n", | 141 printf("Platform has overflow: %s\n", |
131 !overflow_detected ? "yes." : "no."); | 142 !overflow_detected ? "yes." : "no."); |
132 #else | 143 #else |
133 // Otherwise, fail the test. (Note: EXPECT are ok in subfunctions, ASSERT | 144 // Otherwise, fail the test. (Note: EXPECT are ok in subfunctions, ASSERT |
134 // aren't). | 145 // aren't). |
135 EXPECT_TRUE(overflow_detected); | 146 EXPECT_TRUE(overflow_detected); |
136 #endif | 147 #endif |
137 } | 148 } |
138 } | 149 } |
139 | 150 |
140 // This function acts as a compiler optimization barrier. We use it to | |
141 // prevent the compiler from making an expression a compile-time constant. | |
142 // We also use it so that the compiler doesn't discard certain return values | |
143 // as something we don't need (see the comment with calloc below). | |
144 template <typename Type> | |
145 Type HideValueFromCompiler(volatile Type value) { | |
146 return value; | |
147 } | |
148 | |
149 // Test array[TooBig][X] and array[X][TooBig] allocations for int overflows. | 151 // Test array[TooBig][X] and array[X][TooBig] allocations for int overflows. |
150 // IOS doesn't honor nothrow, so disable the test there. | 152 // IOS doesn't honor nothrow, so disable the test there. |
151 // Disable on Windows, we suspect some are failing because of it. | 153 // Disable on Windows, we suspect some are failing because of it. |
152 TEST(SecurityTest, DISABLE_ON_IOS_AND_WIN(NewOverflow)) { | 154 TEST(SecurityTest, DISABLE_ON_IOS_AND_WIN(NewOverflow)) { |
153 const size_t kArraySize = 4096; | 155 const size_t kArraySize = 4096; |
154 // We want something "dynamic" here, so that the compiler doesn't | 156 // We want something "dynamic" here, so that the compiler doesn't |
155 // immediately reject crazy arrays. | 157 // immediately reject crazy arrays. |
156 const size_t kDynamicArraySize = HideValueFromCompiler(kArraySize); | 158 const size_t kDynamicArraySize = HideValueFromCompiler(kArraySize); |
157 // numeric_limits are still not constexpr until we switch to C++11, so we | 159 // numeric_limits are still not constexpr until we switch to C++11, so we |
158 // use an ugly cast. | 160 // use an ugly cast. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 return; // Test passes. | 247 return; // Test passes. |
246 } | 248 } |
247 } | 249 } |
248 } | 250 } |
249 ASSERT_TRUE(false); // NOTREACHED(); | 251 ASSERT_TRUE(false); // NOTREACHED(); |
250 } | 252 } |
251 | 253 |
252 #endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__) | 254 #endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__) |
253 | 255 |
254 } // namespace | 256 } // namespace |
OLD | NEW |