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/rtl_utils.h"
16 :
17 : #include <windows.h>
18 :
19 : #include "base/bind.h"
20 : #include "base/rand_util.h"
21 : #include "gtest/gtest.h"
22 : #include "syzygy/agent/asan/runtime.h"
23 : #include "syzygy/agent/asan/shadow.h"
24 :
25 : namespace agent {
26 : namespace asan {
27 :
28 : namespace {
29 :
30 : using agent::asan::Shadow;
31 :
32 : // A flag used in asan callback to ensure that a memory error has been detected.
33 : bool memory_error_detected = false;
34 : // Will save the information about the last Asan error.
35 : AsanErrorInfo last_error_info = {};
36 :
37 E : void AsanErrorCallBack(AsanErrorInfo* error_info) {
38 E : EXPECT_NE(reinterpret_cast<AsanErrorInfo*>(NULL), error_info);
39 E : memory_error_detected = true;
40 E : last_error_info = *error_info;
41 E : }
42 :
43 : class TestAsanRuntime : public AsanRuntime {
44 : public:
45 E : TestAsanRuntime() {
46 E : memory_error_detected = false;
47 E : SetUp(L"");
48 E : SetErrorCallBack(base::Bind(AsanErrorCallBack));
49 E : }
50 :
51 E : ~TestAsanRuntime() {
52 E : TearDown();
53 E : }
54 : };
55 :
56 : } // namespace
57 :
58 E : TEST(AsanRtlUtilsTest, ContextToAsanContext) {
59 E : CONTEXT context = {};
60 E : AsanContext asan_context = {};
61 E : base::RandBytes(reinterpret_cast<void*>(&context), sizeof(context));
62 E : ContextToAsanContext(context, &asan_context);
63 :
64 E : EXPECT_EQ(context.Eax, asan_context.original_eax);
65 E : EXPECT_EQ(context.Ebp, asan_context.original_ebp);
66 E : EXPECT_EQ(context.Ebx, asan_context.original_ebx);
67 E : EXPECT_EQ(context.Ecx, asan_context.original_ecx);
68 E : EXPECT_EQ(context.Edi, asan_context.original_edi);
69 E : EXPECT_EQ(context.Edx, asan_context.original_edx);
70 E : EXPECT_EQ(context.Eip, asan_context.original_eip);
71 E : EXPECT_EQ(context.Esi, asan_context.original_esi);
72 E : EXPECT_EQ(context.Esp, asan_context.original_esp);
73 E : EXPECT_EQ(context.EFlags, asan_context.original_eflags);
74 E : }
75 :
76 E : TEST(AsanRtlUtilsTest, ReportBadMemoryAccess) {
77 E : TestAsanRuntime runtime;
78 E : SetAsanRuntimeInstance(&runtime);
79 E : void* bad_location = reinterpret_cast<void*>(0xBAD0ADD5);
80 E : AccessMode access_mode = ASAN_READ_ACCESS;
81 E : size_t access_size = 4;
82 E : AsanContext asan_context = {};
83 E : base::RandBytes(reinterpret_cast<void*>(&asan_context), sizeof(asan_context));
84 E : ReportBadMemoryAccess(bad_location, access_mode, access_size, asan_context);
85 :
86 E : EXPECT_TRUE(memory_error_detected);
87 E : EXPECT_EQ(bad_location, last_error_info.location);
88 E : EXPECT_EQ(access_size, last_error_info.access_size);
89 E : EXPECT_EQ(access_mode, last_error_info.access_mode);
90 E : EXPECT_EQ(asan_context.original_eax, last_error_info.context.Eax);
91 E : EXPECT_EQ(asan_context.original_ebp, last_error_info.context.Ebp);
92 E : EXPECT_EQ(asan_context.original_ebx, last_error_info.context.Ebx);
93 E : EXPECT_EQ(asan_context.original_ecx, last_error_info.context.Ecx);
94 E : EXPECT_EQ(asan_context.original_edi, last_error_info.context.Edi);
95 E : EXPECT_EQ(asan_context.original_edx, last_error_info.context.Edx);
96 E : EXPECT_EQ(asan_context.original_eip, last_error_info.context.Eip);
97 E : EXPECT_EQ(asan_context.original_esi, last_error_info.context.Esi);
98 E : EXPECT_EQ(asan_context.original_esp, last_error_info.context.Esp);
99 E : EXPECT_EQ(asan_context.original_eflags, last_error_info.context.EFlags);
100 E : }
101 :
102 E : TEST(AsanRtlUtilsTest, ReportBadAccess) {
103 E : TestAsanRuntime runtime;
104 E : SetAsanRuntimeInstance(&runtime);
105 E : uint8* bad_location = reinterpret_cast<uint8*>(0xBAD0ADD5);
106 E : AccessMode access_mode = ASAN_READ_ACCESS;
107 E : ReportBadAccess(bad_location, access_mode);
108 :
109 E : EXPECT_TRUE(memory_error_detected);
110 E : EXPECT_EQ(bad_location, last_error_info.location);
111 E : EXPECT_EQ(access_mode, last_error_info.access_mode);
112 E : }
113 :
114 E : TEST(AsanRtlUtilsTest, TestMemoryRange) {
115 E : TestAsanRuntime runtime;
116 E : SetAsanRuntimeInstance(&runtime);
117 E : AccessMode access_mode = ASAN_READ_ACCESS;
118 E : const size_t kTestBufferSize = 64;
119 E : scoped_ptr<uint8> test_buffer(new uint8[kTestBufferSize]);
120 :
121 : TestMemoryRange(runtime.shadow(), test_buffer.get(), kTestBufferSize,
122 E : access_mode);
123 E : EXPECT_FALSE(memory_error_detected);
124 :
125 : // Poison the second half of the buffer.
126 : runtime.shadow()->Poison(test_buffer.get() + kTestBufferSize / 2,
127 E : kTestBufferSize / 2, kUserRedzoneMarker);
128 :
129 : // Test the first half of the buffer, no error should be detected.
130 : TestMemoryRange(runtime.shadow(), test_buffer.get(), kTestBufferSize / 2,
131 E : access_mode);
132 E : EXPECT_FALSE(memory_error_detected);
133 :
134 : // Test the second half of the buffer, we should get an invalid access on its
135 : // last byte.
136 : TestMemoryRange(runtime.shadow(), test_buffer.get(), kTestBufferSize,
137 E : access_mode);
138 E : EXPECT_TRUE(memory_error_detected);
139 E : EXPECT_EQ(test_buffer.get() + kTestBufferSize - 1, last_error_info.location);
140 E : EXPECT_EQ(access_mode, last_error_info.access_mode);
141 :
142 E : runtime.shadow()->Unpoison(test_buffer.get(), kTestBufferSize);
143 E : }
144 :
145 E : TEST(AsanRtlUtilsTest, TestStructure) {
146 E : TestAsanRuntime runtime;
147 E : SetAsanRuntimeInstance(&runtime);
148 E : AccessMode access_mode = ASAN_READ_ACCESS;
149 E : scoped_ptr<double> test_struct(new double);
150 :
151 E : TestStructure(runtime.shadow(), test_struct.get(), access_mode);
152 E : EXPECT_FALSE(memory_error_detected);
153 :
154 : runtime.shadow()->Poison(test_struct.get(), sizeof(double),
155 E : kUserRedzoneMarker);
156 :
157 E : TestStructure(runtime.shadow(), test_struct.get(), access_mode);
158 E : EXPECT_TRUE(memory_error_detected);
159 E : EXPECT_EQ(test_struct.get(), last_error_info.location);
160 E : EXPECT_EQ(access_mode, last_error_info.access_mode);
161 :
162 E : runtime.shadow()->Unpoison(test_struct.get(), sizeof(double));
163 E : }
164 :
165 : } // namespace asan
166 : } // namespace agent
|