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