1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (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
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/agent/asan/block_utils.h"
16 :
17 : #include "gtest/gtest.h"
18 : #include "syzygy/agent/asan/logger.h"
19 : #include "syzygy/agent/asan/unittest_util.h"
20 :
21 : namespace agent {
22 : namespace asan {
23 :
24 : namespace {
25 :
26 : typedef testing::TestWithAsanRuntime BlockUtilTest;
27 :
28 : } // namespace
29 :
30 E : TEST_F(BlockUtilTest, IsBlockCorruptInvalidMagicNumber) {
31 E : const size_t kAllocSize = 100;
32 : testing::FakeAsanBlock fake_block(
33 E : runtime_->shadow(), kShadowRatioLog, runtime_->stack_cache());
34 E : EXPECT_TRUE(fake_block.InitializeBlock(kAllocSize));
35 :
36 : fake_block.block_info.header->magic =
37 E : static_cast<unsigned>(~kBlockHeaderMagic);
38 E : EXPECT_TRUE(IsBlockCorrupt(fake_block.block_info));
39 E : fake_block.block_info.header->magic = kBlockHeaderMagic;
40 E : EXPECT_FALSE(IsBlockCorrupt(fake_block.block_info));
41 E : }
42 :
43 E : TEST_F(BlockUtilTest, IsBlockCorruptInvalidChecksum) {
44 E : const size_t kAllocSize = 100;
45 : static const size_t kChecksumRepeatCount = 10;
46 :
47 : // This can fail because of a checksum collision. However, we run it a
48 : // handful of times to keep the chances as small as possible.
49 E : for (size_t i = 0; i < kChecksumRepeatCount; ++i) {
50 : testing::FakeAsanBlock fake_block(
51 E : runtime_->shadow(), kShadowRatioLog, runtime_->stack_cache());
52 E : EXPECT_TRUE(fake_block.InitializeBlock(kAllocSize));
53 E : EXPECT_TRUE(fake_block.MarkBlockAsQuarantined());
54 :
55 : // Change some of the block content and verify that the block is now being
56 : // seen as corrupt.
57 E : uint8 original_value = fake_block.block_info.RawBody(0);
58 E : fake_block.block_info.RawBody(0)++;
59 :
60 : // Try again for all but the last attempt if this appears to have failed.
61 : if (!IsBlockCorrupt(fake_block.block_info) &&
62 E : i + 1 < kChecksumRepeatCount) {
63 i : continue;
64 : }
65 :
66 E : ASSERT_TRUE(IsBlockCorrupt(fake_block.block_info));
67 E : fake_block.block_info.RawBody(0) = original_value;
68 E : ASSERT_FALSE(IsBlockCorrupt(fake_block.block_info));
69 E : break;
70 i : }
71 E : }
72 :
73 E : TEST_F(BlockUtilTest, IsBlockCorruptInvalidFloodFilledBody) {
74 E : const size_t kAllocSize = 100;
75 :
76 : testing::FakeAsanBlock fake_block(
77 E : runtime_->shadow(), kShadowRatioLog, runtime_->stack_cache());
78 E : EXPECT_TRUE(fake_block.InitializeBlock(kAllocSize));
79 E : EXPECT_TRUE(fake_block.MarkBlockAsQuarantined());
80 E : fake_block.block_info.header->state = QUARANTINED_FLOODED_BLOCK;
81 : ::memset(fake_block.block_info.RawBody(),
82 : kBlockFloodFillByte,
83 E : fake_block.block_info.body_size);
84 E : BlockSetChecksum(fake_block.block_info);
85 E : ASSERT_FALSE(IsBlockCorrupt(fake_block.block_info));
86 :
87 E : fake_block.block_info.RawBody(1) ^= 0x3C;
88 E : ASSERT_TRUE(IsBlockCorrupt(fake_block.block_info));
89 E : }
90 :
91 : } // namespace asan
92 : } // namespace agent
|