OLD | NEW |
1 // Copyright 2014 Google Inc. All Rights Reserved. | 1 // Copyright 2014 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 | 79 |
80 // Restore the checksum to make sure that the corruption gets detected. | 80 // Restore the checksum to make sure that the corruption gets detected. |
81 fake_block.block_info.header->checksum = header_checksum; | 81 fake_block.block_info.header->checksum = header_checksum; |
82 | 82 |
83 EXPECT_TRUE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); | 83 EXPECT_TRUE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); |
84 ASSERT_EQ(1, corrupt_ranges.size()); | 84 ASSERT_EQ(1, corrupt_ranges.size()); |
85 AsanCorruptBlockRange range_info = *corrupt_ranges.begin(); | 85 AsanCorruptBlockRange range_info = *corrupt_ranges.begin(); |
86 | 86 |
87 EXPECT_EQ(1, range_info.block_count); | 87 EXPECT_EQ(1, range_info.block_count); |
88 ShadowWalker shadow_walker( | 88 ShadowWalker shadow_walker( |
89 runtime_->shadow(), false, | 89 runtime_->shadow(), reinterpret_cast<const uint8_t*>(range_info.address), |
90 reinterpret_cast<const uint8_t*>(range_info.address), | |
91 reinterpret_cast<const uint8_t*>(range_info.address) + range_info.length); | 90 reinterpret_cast<const uint8_t*>(range_info.address) + range_info.length); |
92 BlockInfo block_info = {}; | 91 BlockInfo block_info = {}; |
93 EXPECT_TRUE(shadow_walker.Next(&block_info)); | 92 EXPECT_TRUE(shadow_walker.Next(&block_info)); |
94 EXPECT_EQ(fake_block.block_info.header, block_info.header); | 93 EXPECT_EQ(fake_block.block_info.header, block_info.header); |
95 EXPECT_FALSE(shadow_walker.Next(&block_info)); | 94 EXPECT_FALSE(shadow_walker.Next(&block_info)); |
96 | 95 |
97 fake_block.block_info.header->checksum = header_checksum; | 96 fake_block.block_info.header->checksum = header_checksum; |
98 fake_block.block_info.RawBody(0) = original_value; | 97 fake_block.block_info.RawBody(0) = original_value; |
99 EXPECT_FALSE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); | 98 EXPECT_FALSE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); |
100 } | 99 } |
(...skipping 12 matching lines...) Expand all Loading... |
113 | 112 |
114 // Corrupt the header of the block and ensure that the heap corruption gets | 113 // Corrupt the header of the block and ensure that the heap corruption gets |
115 // detected. | 114 // detected. |
116 fake_block.block_info.header->magic = ~fake_block.block_info.header->magic; | 115 fake_block.block_info.header->magic = ~fake_block.block_info.header->magic; |
117 EXPECT_TRUE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); | 116 EXPECT_TRUE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); |
118 ASSERT_EQ(1, corrupt_ranges.size()); | 117 ASSERT_EQ(1, corrupt_ranges.size()); |
119 AsanCorruptBlockRange range_info = *corrupt_ranges.begin(); | 118 AsanCorruptBlockRange range_info = *corrupt_ranges.begin(); |
120 | 119 |
121 EXPECT_EQ(1, range_info.block_count); | 120 EXPECT_EQ(1, range_info.block_count); |
122 ShadowWalker shadow_walker( | 121 ShadowWalker shadow_walker( |
123 runtime_->shadow(), false, | 122 runtime_->shadow(), reinterpret_cast<const uint8_t*>(range_info.address), |
124 reinterpret_cast<const uint8_t*>(range_info.address), | |
125 reinterpret_cast<const uint8_t*>(range_info.address) + range_info.length); | 123 reinterpret_cast<const uint8_t*>(range_info.address) + range_info.length); |
126 BlockInfo block_info = {}; | 124 BlockInfo block_info = {}; |
127 EXPECT_TRUE(shadow_walker.Next(&block_info)); | 125 EXPECT_TRUE(shadow_walker.Next(&block_info)); |
128 EXPECT_EQ(fake_block.block_info.header, block_info.header); | 126 EXPECT_EQ(fake_block.block_info.header, block_info.header); |
129 EXPECT_FALSE(shadow_walker.Next(&block_info)); | 127 EXPECT_FALSE(shadow_walker.Next(&block_info)); |
130 | 128 |
131 fake_block.block_info.header->magic = ~fake_block.block_info.header->magic; | 129 fake_block.block_info.header->magic = ~fake_block.block_info.header->magic; |
132 EXPECT_FALSE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); | 130 EXPECT_FALSE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); |
133 } | 131 } |
134 | 132 |
135 TEST_F(HeapCheckerTest, IsHeapCorrupt) { | 133 TEST_F(HeapCheckerTest, IsHeapCorrupt) { |
136 const size_t kAllocSize = 100; | 134 const size_t kAllocSize = 100; |
137 | 135 |
138 BlockLayout block_layout = {}; | 136 BlockLayout block_layout = {}; |
139 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, kAllocSize, 0, 0, | 137 EXPECT_TRUE(BlockPlanLayout(kShadowRatio, kShadowRatio, kAllocSize, 0, 0, |
140 &block_layout)); | 138 &block_layout)); |
141 | 139 |
142 const size_t kNumberOfBlocks = 4; | 140 const size_t kNumberOfBlocks = 4; |
143 size_t total_alloc_size = block_layout.block_size * kNumberOfBlocks; | 141 size_t total_alloc_size = block_layout.block_size * kNumberOfBlocks; |
144 uint8_t* global_alloc = | 142 uint8_t* global_alloc = |
145 reinterpret_cast<uint8_t*>(::malloc(total_alloc_size)); | 143 reinterpret_cast<uint8_t*>(::malloc(total_alloc_size)); |
146 | 144 |
147 uint8_t* blocks[kNumberOfBlocks]; | 145 uint8_t* blocks[kNumberOfBlocks]; |
148 BlockHeader* block_headers[kNumberOfBlocks]; | 146 BlockHeader* block_headers[kNumberOfBlocks]; |
149 | 147 |
150 for (size_t i = 0; i < kNumberOfBlocks; ++i) { | 148 for (size_t i = 0; i < kNumberOfBlocks; ++i) { |
151 blocks[i] = global_alloc + i * block_layout.block_size; | 149 blocks[i] = global_alloc + i * block_layout.block_size; |
152 BlockInfo block_info = {}; | 150 BlockInfo block_info = {}; |
153 BlockInitialize(block_layout, blocks[i], false, &block_info); | 151 BlockInitialize(block_layout, blocks[i], &block_info); |
154 runtime_->shadow()->PoisonAllocatedBlock(block_info); | 152 runtime_->shadow()->PoisonAllocatedBlock(block_info); |
155 BlockSetChecksum(block_info); | 153 BlockSetChecksum(block_info); |
156 block_headers[i] = block_info.header; | 154 block_headers[i] = block_info.header; |
157 EXPECT_EQ(block_headers[i], reinterpret_cast<BlockHeader*>(blocks[i])); | 155 EXPECT_EQ(block_headers[i], reinterpret_cast<BlockHeader*>(blocks[i])); |
158 } | 156 } |
159 | 157 |
160 HeapChecker heap_checker(runtime_->shadow()); | 158 HeapChecker heap_checker(runtime_->shadow()); |
161 HeapChecker::CorruptRangesVector corrupt_ranges; | 159 HeapChecker::CorruptRangesVector corrupt_ranges; |
162 EXPECT_FALSE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); | 160 EXPECT_FALSE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); |
163 | 161 |
164 // Corrupt the header of the first two blocks and of the last one. | 162 // Corrupt the header of the first two blocks and of the last one. |
165 block_headers[0]->magic++; | 163 block_headers[0]->magic++; |
166 block_headers[1]->magic++; | 164 block_headers[1]->magic++; |
167 block_headers[kNumberOfBlocks - 1]->magic++; | 165 block_headers[kNumberOfBlocks - 1]->magic++; |
168 | 166 |
169 EXPECT_TRUE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); | 167 EXPECT_TRUE(heap_checker.IsHeapCorrupt(&corrupt_ranges)); |
170 | 168 |
171 // We expect the heap to contain 2 ranges of corrupt blocks, the first one | 169 // We expect the heap to contain 2 ranges of corrupt blocks, the first one |
172 // containing the 2 first blocks and the second one containing the last block. | 170 // containing the 2 first blocks and the second one containing the last block. |
173 | 171 |
174 EXPECT_EQ(2, corrupt_ranges.size()); | 172 EXPECT_EQ(2, corrupt_ranges.size()); |
175 | 173 |
176 BlockInfo block_info = {}; | 174 BlockInfo block_info = {}; |
177 ShadowWalker shadow_walker_1( | 175 ShadowWalker shadow_walker_1( |
178 runtime_->shadow(), false, | 176 runtime_->shadow(), |
179 reinterpret_cast<const uint8_t*>(corrupt_ranges[0].address), | 177 reinterpret_cast<const uint8_t*>(corrupt_ranges[0].address), |
180 reinterpret_cast<const uint8_t*>(corrupt_ranges[0].address) + | 178 reinterpret_cast<const uint8_t*>(corrupt_ranges[0].address) + |
181 corrupt_ranges[0].length); | 179 corrupt_ranges[0].length); |
182 EXPECT_TRUE(shadow_walker_1.Next(&block_info)); | 180 EXPECT_TRUE(shadow_walker_1.Next(&block_info)); |
183 EXPECT_EQ(reinterpret_cast<const BlockHeader*>(block_info.header), | 181 EXPECT_EQ(reinterpret_cast<const BlockHeader*>(block_info.header), |
184 block_headers[0]); | 182 block_headers[0]); |
185 EXPECT_TRUE(shadow_walker_1.Next(&block_info)); | 183 EXPECT_TRUE(shadow_walker_1.Next(&block_info)); |
186 EXPECT_EQ(reinterpret_cast<const BlockHeader*>(block_info.header), | 184 EXPECT_EQ(reinterpret_cast<const BlockHeader*>(block_info.header), |
187 block_headers[1]); | 185 block_headers[1]); |
188 EXPECT_FALSE(shadow_walker_1.Next(&block_info)); | 186 EXPECT_FALSE(shadow_walker_1.Next(&block_info)); |
189 | 187 |
190 ShadowWalker shadow_walker_2( | 188 ShadowWalker shadow_walker_2( |
191 runtime_->shadow(), false, | 189 runtime_->shadow(), |
192 reinterpret_cast<const uint8_t*>(corrupt_ranges[1].address), | 190 reinterpret_cast<const uint8_t*>(corrupt_ranges[1].address), |
193 reinterpret_cast<const uint8_t*>(corrupt_ranges[1].address) + | 191 reinterpret_cast<const uint8_t*>(corrupt_ranges[1].address) + |
194 corrupt_ranges[1].length); | 192 corrupt_ranges[1].length); |
195 EXPECT_TRUE(shadow_walker_2.Next(&block_info)); | 193 EXPECT_TRUE(shadow_walker_2.Next(&block_info)); |
196 EXPECT_EQ(reinterpret_cast<const BlockHeader*>(block_info.header), | 194 EXPECT_EQ(reinterpret_cast<const BlockHeader*>(block_info.header), |
197 block_headers[kNumberOfBlocks - 1]); | 195 block_headers[kNumberOfBlocks - 1]); |
198 EXPECT_FALSE(shadow_walker_2.Next(&block_info)); | 196 EXPECT_FALSE(shadow_walker_2.Next(&block_info)); |
199 | 197 |
200 // Restore the checksum of the blocks. | 198 // Restore the checksum of the blocks. |
201 block_headers[0]->magic--; | 199 block_headers[0]->magic--; |
202 block_headers[1]->magic--; | 200 block_headers[1]->magic--; |
203 block_headers[kNumberOfBlocks - 1]->magic--; | 201 block_headers[kNumberOfBlocks - 1]->magic--; |
204 | 202 |
205 runtime_->shadow()->Unpoison(global_alloc, total_alloc_size); | 203 runtime_->shadow()->Unpoison(global_alloc, total_alloc_size); |
206 ::free(global_alloc); | 204 ::free(global_alloc); |
207 } | 205 } |
208 | 206 |
209 } // namespace asan | 207 } // namespace asan |
210 } // namespace agent | 208 } // namespace agent |
OLD | NEW |