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/crt_interceptors.h"
16 :
17 : #include <windows.h>
18 :
19 : #include "base/bind.h"
20 : #include "gtest/gtest.h"
21 : #include "syzygy/agent/asan/unittest_util.h"
22 :
23 : namespace agent {
24 : namespace asan {
25 :
26 : namespace {
27 :
28 : using testing::ScopedAsanAlloc;
29 :
30 : typedef testing::TestAsanRtl CrtInterceptorsTest;
31 :
32 : // An arbitrary size for the buffer we allocate in the different unittests.
33 : const size_t kAllocSize = 13;
34 :
35 E : void AsanErrorCallback(AsanErrorInfo* error_info) {
36 : // Our tests should clean up after themselves and not leave any blocks
37 : // corrupt.
38 E : ASSERT_NE(CORRUPT_BLOCK, error_info->error_type);
39 :
40 : // Raise an exception to prevent the intercepted function from corrupting
41 : // the block. If this error is not handled then this will cause the unittest
42 : // to fail.
43 E : ::RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, 0);
44 i : }
45 :
46 : } // namespace
47 :
48 E : TEST_F(CrtInterceptorsTest, AsanCheckMemset) {
49 E : const size_t kAllocSize = 13;
50 E : ScopedAsanAlloc<uint8> mem(this, kAllocSize);
51 E : ASSERT_TRUE(mem.get() != NULL);
52 E : SetCallBackFunction(&AsanErrorCallback);
53 E : EXPECT_EQ(mem.get(), memsetFunction(mem.GetAs<void*>(), 0xAA, kAllocSize));
54 E : for (size_t i = 0; i < kAllocSize; ++i)
55 E : EXPECT_EQ(0xAA, mem[i]);
56 :
57 E : memsetFunctionFailing(mem.get() - 1, 0xBB, kAllocSize);
58 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
59 E : ResetLog();
60 :
61 E : memsetFunctionFailing(mem.get(), 0xCC, kAllocSize + 1);
62 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
63 E : ResetLog();
64 E : }
65 :
66 E : TEST_F(CrtInterceptorsTest, AsanCheckMemchr) {
67 E : const size_t kAllocSize = 13;
68 E : ScopedAsanAlloc<uint8> mem(this, kAllocSize);
69 E : ASSERT_TRUE(mem.get() != NULL);
70 E : ::memset(mem.get(), 0, kAllocSize);
71 E : mem[4] = 0xAA;
72 :
73 E : SetCallBackFunction(&AsanErrorCallback);
74 E : EXPECT_EQ(mem.get() + 4, memchrFunction(mem.get(), mem[4], kAllocSize));
75 E : EXPECT_EQ(NULL, memchrFunction(mem.get(), mem[4] + 1, kAllocSize));
76 :
77 E : memchrFunctionFailing(mem.get() - 1, mem[4], kAllocSize);
78 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
79 E : ResetLog();
80 :
81 E : memchrFunctionFailing(mem.get() + 1, mem[4], kAllocSize);
82 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
83 E : ResetLog();
84 E : }
85 :
86 E : TEST_F(CrtInterceptorsTest, AsanCheckMemmove) {
87 E : const size_t kAllocSize = 13;
88 E : ScopedAsanAlloc<uint8> mem_src(this, kAllocSize);
89 E : ASSERT_TRUE(mem_src.get() != NULL);
90 : // Fill the array with value going from 0 to kAllocSize;
91 E : for (size_t i = 0; i < kAllocSize; ++i)
92 E : mem_src[i] = i;
93 :
94 E : SetCallBackFunction(&AsanErrorCallback);
95 : // Shift all the value from one index to the right.
96 : EXPECT_EQ(mem_src.get() + 1,
97 E : memmoveFunction(mem_src.get() + 1, mem_src.get(), kAllocSize - 1));
98 E : EXPECT_EQ(0, mem_src[0]);
99 E : for (size_t i = 1; i < kAllocSize; ++i)
100 E : EXPECT_EQ(i - 1, mem_src[i]);
101 :
102 : // Re-shift them to the left.
103 E : memmoveFunctionFailing(mem_src.get(), mem_src.get() + 1, kAllocSize);
104 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
105 E : ResetLog();
106 :
107 E : memmoveFunctionFailing(mem_src.get() - 1, mem_src.get(), kAllocSize);
108 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
109 E : ResetLog();
110 E : }
111 :
112 E : TEST_F(CrtInterceptorsTest, AsanCheckMemcpy) {
113 E : const size_t kAllocSize = 13;
114 E : ScopedAsanAlloc<uint8> mem_src(this, kAllocSize);
115 E : ASSERT_TRUE(mem_src.get() != NULL);
116 E : ScopedAsanAlloc<uint8> mem_dst(this, kAllocSize);
117 E : ASSERT_TRUE(mem_dst.get() != NULL);
118 : // Fill the array with value going from 0 to kAllocSize;
119 E : for (size_t i = 0; i < kAllocSize; ++i) {
120 E : mem_src[i] = i;
121 E : mem_dst[i] = ~i;
122 E : }
123 :
124 E : SetCallBackFunction(&AsanErrorCallback);
125 : EXPECT_EQ(mem_dst.get(),
126 E : memcpyFunction(mem_dst.get(), mem_src.get(), kAllocSize));
127 E : for (size_t i = 0; i < kAllocSize; ++i)
128 E : EXPECT_EQ(mem_dst[i], mem_src[i]);
129 :
130 E : memcpyFunctionFailing(mem_dst.get(), mem_src.get(), kAllocSize + 1);
131 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
132 E : ResetLog();
133 :
134 E : memcpyFunctionFailing(mem_dst.get(), mem_src.get() - 1, kAllocSize);
135 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
136 E : ResetLog();
137 E : }
138 :
139 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrcspn) {
140 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
141 : // this interceptor has been fixed.
142 i : const char* str_value = "abc1";
143 i : ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
144 i : ASSERT_TRUE(str.get() != NULL);
145 :
146 i : const char* str_value_2 = "abc";
147 i : ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
148 i : ASSERT_TRUE(str2.get() != NULL);
149 :
150 : // This should contain at least one value present in |str| but none present
151 : // in |str2|.
152 i : const char* keys_value = "12";
153 i : EXPECT_NE(::strlen(str_value), ::strcspn(str_value, keys_value));
154 i : EXPECT_EQ(::strlen(str_value_2), ::strcspn(str_value_2, keys_value));
155 i : ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
156 i : ASSERT_TRUE(keys.get() != NULL);
157 :
158 i : SetCallBackFunction(&AsanErrorCallback);
159 : EXPECT_EQ(::strcspn(str.get(), keys.get()),
160 i : strcspnFunction(str.get(), keys.get()));
161 :
162 i : strcspnFunctionFailing(str.get() - 1, keys.get());
163 i : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
164 i : ResetLog();
165 :
166 : // The key set should be null terminated, otherwise an overflow should be
167 : // detected.
168 i : size_t keys_len = ::strlen(keys.get());
169 i : keys[keys_len] = 'a';
170 i : strcspnFunctionFailing(str.get(), keys.get());
171 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
172 i : keys[keys_len] = 0;
173 i : ResetLog();
174 :
175 : // The implementation allows a non null terminated input string if it contains
176 : // at least one of the keys, otherwise it'll overflow.
177 :
178 i : size_t str_len = ::strlen(str.get());
179 i : str[str_len] = 'a';
180 : EXPECT_EQ(::strcspn(str.get(), keys.get()),
181 i : strcspnFunction(str.get(), keys.get()));
182 i : str[str_len] = 0;
183 i : ResetLog();
184 :
185 i : size_t str2_len = ::strlen(str2.get());
186 i : str2[str2_len] = 'a';
187 i : strcspnFunctionFailing(str2.get(), keys.get());
188 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
189 i : str2[str2_len] = 0;
190 i : ResetLog();
191 i : }
192 :
193 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanStrcspnImpl) {
194 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
195 : // this interceptor has been fixed.
196 i : EXPECT_EQ(5, asan_strcspn("abcde", "fgh"));
197 i : EXPECT_EQ(5, asan_strcspn("abcde", ""));
198 i : EXPECT_EQ(0, asan_strcspn("abcde", "abcde"));
199 i : EXPECT_EQ(0U, asan_strcspn("abcde", "edcba"));
200 i : EXPECT_EQ(3, asan_strcspn("abcde", "ed"));
201 i : EXPECT_EQ(2, asan_strcspn("abcde", "c"));
202 i : EXPECT_EQ(0U, asan_strcspn("", ""));
203 i : EXPECT_EQ(0U, asan_strcspn("", "abcde"));
204 i : }
205 :
206 E : TEST_F(CrtInterceptorsTest, AsanCheckStrlen) {
207 E : const char* str_value = "test_strlen";
208 E : ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
209 E : ASSERT_TRUE(str != NULL);
210 :
211 E : SetCallBackFunction(&AsanErrorCallback);
212 E : EXPECT_EQ(::strlen(str.get()), strlenFunction(str.get()));
213 :
214 E : strlenFunctionFailing(str.get() - 1);
215 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
216 E : ResetLog();
217 :
218 E : size_t str_len = ::strlen(str.get());
219 E : str[str_len] = 'a';
220 E : strlenFunctionFailing(str.get());
221 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
222 E : ResetLog();
223 E : }
224 :
225 E : TEST_F(CrtInterceptorsTest, AsanCheckStrrchr) {
226 E : const char* str_value = "test_strrchr";
227 E : ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
228 E : ASSERT_TRUE(str != NULL);
229 :
230 E : SetCallBackFunction(&AsanErrorCallback);
231 E : EXPECT_EQ(::strrchr(str.get(), 'c'), strrchrFunction(str.get(), 'c'));
232 E : EXPECT_EQ(::strrchr(str.get(), 'z'), strrchrFunction(str.get(), 'z'));
233 :
234 E : strrchrFunctionFailing(str.get() - 1, 'c');
235 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
236 E : ResetLog();
237 :
238 E : size_t str_len = ::strlen(str.get());
239 E : str[str_len] = 'a';
240 E : strrchrFunctionFailing(str.get(), 'c');
241 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
242 E : ResetLog();
243 E : }
244 :
245 E : TEST_F(CrtInterceptorsTest, AsanCheckWcsrchr) {
246 E : const wchar_t* wstr_value = L"test_wcsrchr";
247 E : ScopedAsanAlloc<wchar_t> wstr(this, ::wcslen(wstr_value) + 1);
248 E : ASSERT_TRUE(wstr != NULL);
249 E : wcscpy(wstr.get(), wstr_value);
250 :
251 E : SetCallBackFunction(&AsanErrorCallback);
252 E : EXPECT_EQ(::wcsrchr(wstr.get(), L'c'), wcsrchrFunction(wstr.get(), L'c'));
253 E : EXPECT_EQ(::wcsrchr(wstr.get(), 'z'), wcsrchrFunction(wstr.get(), 'z'));
254 :
255 E : wcsrchrFunctionFailing(wstr.get() - 1, L'c');
256 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
257 E : ResetLog();
258 :
259 E : size_t str_len = ::wcslen(wstr_value);
260 E : wstr[str_len] = L'a';
261 E : wcsrchrFunctionFailing(wstr.get(), L'c');
262 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
263 E : ResetLog();
264 E : }
265 :
266 E : TEST_F(CrtInterceptorsTest, AsanCheckWcschr) {
267 E : const wchar_t* wstr_value = L"test_wcschr";
268 E : ScopedAsanAlloc<wchar_t> wstr(this, ::wcslen(wstr_value) + 1);
269 E : ASSERT_TRUE(wstr != NULL);
270 E : wcscpy(wstr.get(), wstr_value);
271 :
272 E : SetCallBackFunction(&AsanErrorCallback);
273 E : EXPECT_EQ(::wcschr(wstr.get(), L'c'), wcschrFunction(wstr.get(), L'c'));
274 E : EXPECT_EQ(::wcschr(wstr.get(), 'z'), wcschrFunction(wstr.get(), 'z'));
275 :
276 E : wcschrFunctionFailing(wstr.get() - 1, L'c');
277 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
278 E : ResetLog();
279 :
280 E : size_t str_len = ::wcslen(wstr_value);
281 E : wstr[str_len] = L'a';
282 E : wcschrFunctionFailing(wstr.get(), L'z');
283 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
284 E : ResetLog();
285 E : }
286 :
287 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrcmp) {
288 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
289 : // this interceptor has been fixed.
290 i : const char* str_value = "test_strcmp";
291 i : ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
292 i : ASSERT_TRUE(str.get() != NULL);
293 :
294 i : const char* keys_value = "strcmp";
295 i : ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
296 i : ASSERT_TRUE(keys.get() != NULL);
297 :
298 i : SetCallBackFunction(&AsanErrorCallback);
299 : EXPECT_EQ(::strcmp(str.get(), keys.get()),
300 i : strcmpFunction(str.get(), keys.get()));
301 :
302 i : strcmpFunctionFailing(str.get() - 1, keys.get());
303 i : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
304 i : ResetLog();
305 :
306 i : size_t keys_len = ::strlen(keys.get());
307 i : keys[keys_len] = 'a';
308 i : strcmpFunctionFailing(str.get(), keys.get());
309 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
310 i : keys[keys_len] = 0;
311 i : ResetLog();
312 i : }
313 :
314 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrpbrk) {
315 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
316 : // this interceptor has been fixed.
317 i : const char* str_value = "abc1";
318 i : ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
319 i : ASSERT_TRUE(str.get() != NULL);
320 :
321 i : const char* str_value_2 = "abc";
322 i : ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
323 i : ASSERT_TRUE(str2.get() != NULL);
324 :
325 : // This should contain at least one value present in |str| but none present
326 : // in |str2|.
327 i : const char* keys_value = "12";
328 i : EXPECT_NE(::strlen(str_value), ::strcspn(str_value, keys_value));
329 i : EXPECT_EQ(::strlen(str_value_2), ::strcspn(str_value_2, keys_value));
330 i : ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
331 i : ASSERT_TRUE(keys.get() != NULL);
332 :
333 i : SetCallBackFunction(&AsanErrorCallback);
334 : EXPECT_EQ(::strpbrk(str.get(), keys.get()),
335 i : strpbrkFunction(str.get(), keys.get()));
336 :
337 i : strpbrkFunctionFailing(str.get() - 1, keys.get());
338 i : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
339 i : ResetLog();
340 :
341 i : size_t keys_len = ::strlen(keys.get());
342 i : keys[keys_len] = 'a';
343 i : strpbrkFunctionFailing(str.get(), keys.get());
344 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
345 i : keys[keys_len] = 0;
346 i : ResetLog();
347 :
348 : // The implementation allows a non null terminated input string if it contains
349 : // at least one of the keys, otherwise it'll overflow.
350 :
351 i : size_t str_len = ::strlen(str.get());
352 i : str[str_len] = 'a';
353 : EXPECT_EQ(::strpbrk(str.get(), keys.get()),
354 i : strpbrkFunction(str.get(), keys.get()));
355 i : str[str_len] = 0;
356 i : ResetLog();
357 :
358 i : size_t str2_len = ::strlen(str2.get());
359 i : str2[str2_len] = 'a';
360 i : strpbrkFunctionFailing(str2.get(), keys.get());
361 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
362 i : str2[str2_len] = 0;
363 i : ResetLog();
364 i : }
365 :
366 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanStrpbrkImpl) {
367 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
368 : // this interceptor has been fixed.
369 i : const char* abcde = "abcde";
370 i : const char* empty_string = "";
371 i : EXPECT_EQ(strpbrk(abcde, abcde), asan_strpbrk(abcde, abcde));
372 i : EXPECT_EQ(strpbrk(abcde, "fgh"), asan_strpbrk(abcde, "fgh"));
373 i : EXPECT_EQ(strpbrk(abcde, ""), asan_strpbrk(abcde, ""));
374 i : EXPECT_EQ(strpbrk(abcde, "edcba"), asan_strpbrk(abcde, "edcba"));
375 i : EXPECT_EQ(strpbrk(abcde, "ed"), asan_strpbrk(abcde, "ed"));
376 i : EXPECT_EQ(strpbrk(abcde, "c"), asan_strpbrk(abcde, "c"));
377 i : EXPECT_EQ(strpbrk(empty_string, ""), asan_strpbrk(empty_string, ""));
378 i : EXPECT_EQ(strpbrk(empty_string, abcde), asan_strpbrk(empty_string, abcde));
379 i : }
380 :
381 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrstr) {
382 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
383 : // this interceptor has been fixed.
384 i : const char* str_value = "test_strstr";
385 i : ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
386 i : ASSERT_TRUE(str != NULL);
387 :
388 i : const char* keys_value = "strstr";
389 i : ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
390 i : ASSERT_TRUE(keys.get() != NULL);
391 :
392 i : SetCallBackFunction(&AsanErrorCallback);
393 : EXPECT_EQ(::strstr(str.get(), keys.get()),
394 i : strstrFunction(str.get(), keys.get()));
395 :
396 i : strstrFunctionFailing(str.get() - 1, keys.get());
397 i : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
398 i : ResetLog();
399 :
400 i : size_t keys_len = ::strlen(keys.get());
401 i : keys[keys_len] = 'a';
402 i : strstrFunctionFailing(str.get(), keys.get());
403 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
404 i : keys[keys_len] = 0;
405 i : ResetLog();
406 i : }
407 :
408 E : TEST_F(CrtInterceptorsTest, AsanCheckWcsstr) {
409 E : const wchar_t* str_value = L"test_wcsstr";
410 E : ScopedAsanAlloc<wchar_t> str(this, ::wcslen(str_value) + 1, str_value);
411 E : ASSERT_TRUE(str != NULL);
412 :
413 E : const wchar_t* keys_value = L"wcsstr";
414 E : ScopedAsanAlloc<wchar_t> keys(this, ::wcslen(keys_value) + 1, keys_value);
415 E : ASSERT_TRUE(keys.get() != NULL);
416 :
417 : EXPECT_EQ(::wcsstr(str.get(), keys.get()),
418 E : wcsstrFunction(str.get(), keys.get()));
419 :
420 E : EXPECT_EQ(NULL, wcsstrFunction(str.get(), L"abcd"));
421 :
422 E : SetCallBackFunction(&AsanErrorCallback);
423 E : keys[::wcslen(keys_value)] = L'a';
424 E : wcsstrFunctionFailing(str.get(), keys.get());
425 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
426 E : keys[::wcslen(keys_value)] = 0;
427 :
428 E : ResetLog();
429 E : }
430 :
431 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrspn) {
432 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
433 : // this interceptor has been fixed.
434 i : const char* str_value = "123_abc";
435 i : ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
436 i : ASSERT_TRUE(str.get() != NULL);
437 :
438 i : const char* keys_value = "123";
439 i : EXPECT_EQ(::strlen(keys_value), ::strspn(str_value, keys_value));
440 i : ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
441 i : ASSERT_TRUE(keys.get() != NULL);
442 :
443 : // The second test string should only contains values present in the keys.
444 i : const char* str_value_2 = "12321";
445 i : ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
446 i : EXPECT_EQ(::strlen(str_value_2), ::strspn(str_value_2, keys_value));
447 i : ASSERT_TRUE(str2.get() != NULL);
448 :
449 i : SetCallBackFunction(&AsanErrorCallback);
450 : EXPECT_EQ(::strspn(str.get(), keys.get()),
451 i : strspnFunction(str.get(), keys.get()));
452 :
453 i : strspnFunctionFailing(str.get() - 1, keys.get());
454 i : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
455 i : ResetLog();
456 :
457 i : size_t keys_len = ::strlen(keys.get());
458 i : keys[keys_len] = 'a';
459 i : strspnFunctionFailing(str.get(), keys.get());
460 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
461 i : keys[keys_len] = 0;
462 i : ResetLog();
463 :
464 : // The implementation allows a non null terminated input string if it doesn't
465 : // start with a value contained in the keys, otherwise it'll overflow.
466 :
467 i : size_t str_len = ::strlen(str.get());
468 i : str[str_len] = 'a';
469 : EXPECT_EQ(::strspn(str.get(), keys.get()),
470 i : strspnFunction(str.get(), keys.get()));
471 i : str[str_len] = 0;
472 i : ResetLog();
473 :
474 i : size_t str2_len = ::strlen(str2.get());
475 i : str2[str2_len] = keys[0];
476 i : strspnFunctionFailing(str2.get(), keys.get());
477 i : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
478 i : str2[str2_len] = 0;
479 i : ResetLog();
480 i : }
481 :
482 E : TEST_F(CrtInterceptorsTest, DISABLED_AsanStrspnImpl) {
483 : // TODO(sebmarchand): Reactivate this unittest once the implementation of
484 : // this interceptor has been fixed.
485 i : EXPECT_EQ(5, asan_strspn("abcde", "abcde"));
486 i : EXPECT_EQ(5, asan_strspn("abcde", "edcba"));
487 i : EXPECT_EQ(0U, asan_strspn("abcde", ""));
488 i : EXPECT_EQ(2, asan_strspn("abcde", "ab"));
489 i : EXPECT_EQ(4, asan_strspn("abccde", "abc"));
490 i : EXPECT_EQ(2, asan_strspn("abcde", "fghab"));
491 i : EXPECT_EQ(3, asan_strspn("abcde", "fagbhc"));
492 i : EXPECT_EQ(1, asan_strspn("abcde", "aaa"));
493 i : EXPECT_EQ(0U, asan_strspn("abcde", "fgh"));
494 i : EXPECT_EQ(0U, asan_strspn("", ""));
495 i : EXPECT_EQ(0U, asan_strspn("", "abcde"));
496 i : }
497 :
498 E : TEST_F(CrtInterceptorsTest, AsanCheckStrncpy) {
499 E : const char* str_value = "test_strncpy";
500 E : ScopedAsanAlloc<char> source(this, ::strlen(str_value) + 1, str_value);
501 E : ASSERT_TRUE(source != NULL);
502 :
503 E : const char* long_str_value = "test_strncpy_long_source";
504 : ScopedAsanAlloc<char> long_source(this, ::strlen(long_str_value) + 1,
505 E : long_str_value);
506 E : ASSERT_TRUE(long_source.get() != NULL);
507 :
508 E : ScopedAsanAlloc<char> destination(this, ::strlen(str_value) + 1);
509 E : ASSERT_TRUE(destination != NULL);
510 :
511 E : SetCallBackFunction(&AsanErrorCallback);
512 : EXPECT_EQ(destination.get(),
513 : strncpyFunction(destination.get(),
514 : source.get(),
515 E : ::strlen(str_value)));
516 :
517 : // Test an underflow on the source.
518 : strncpyFunctionFailing(destination.get(),
519 : source.get() - 1,
520 E : ::strlen(str_value));
521 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
522 E : ResetLog();
523 :
524 : // Test an underflow on the destination.
525 : strncpyFunctionFailing(destination.get() - 1,
526 : source.get(),
527 E : ::strlen(str_value));
528 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
529 E : ResetLog();
530 :
531 : // Test an overflow on the destination.
532 E : std::vector<uint8> original_data(::strlen(long_str_value));
533 E : memcpy(&original_data[0], destination.get(), ::strlen(long_str_value));
534 : strncpyFunctionFailing(destination.get(),
535 : long_source.get(),
536 E : ::strlen(long_str_value));
537 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
538 E : ResetLog();
539 :
540 : // Another overflow on the destination.
541 : strncpyFunctionFailing(destination.get(),
542 : source.get(),
543 E : ::strlen(str_value) + 2);
544 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
545 E : ResetLog();
546 :
547 : // Test an overflow on the source.
548 E : size_t source_len = ::strlen(source.get());
549 E : source[source_len] = 'a';
550 : strncpyFunctionFailing(destination.get(),
551 : source.get(),
552 E : ::strlen(source.get()) + 1);
553 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
554 E : source[source_len] = 0;
555 E : ResetLog();
556 E : }
557 :
558 E : TEST_F(CrtInterceptorsTest, AsanCheckStrncat) {
559 E : const char* prefix_value = "test_";
560 E : const char* suffix_value = "strncat";
561 : char buffer[64];
562 :
563 : ScopedAsanAlloc<char> mem(this,
564 E : ::strlen(prefix_value) + ::strlen(suffix_value) + 1, prefix_value);
565 E : ASSERT_TRUE(mem != NULL);
566 E : ::strcpy(buffer, prefix_value);
567 :
568 E : ScopedAsanAlloc<char> suffix(this, ::strlen(suffix_value) + 1, suffix_value);
569 E : ASSERT_TRUE(mem.get() != NULL);
570 :
571 E : SetCallBackFunction(&AsanErrorCallback);
572 : EXPECT_EQ(mem.get(),
573 E : strncatFunction(mem.get(), suffix.get(), ::strlen(suffix_value)));
574 : EXPECT_STRCASEEQ(
575 E : ::strncat(buffer, suffix.get(), ::strlen(suffix_value)), mem.get());
576 :
577 : // Test an underflow on the suffix.
578 E : ::strcpy(mem.get(), prefix_value);
579 E : ::strcpy(buffer, prefix_value);
580 E : strncatFunctionFailing(mem.get(), suffix.get() - 1, ::strlen(suffix_value));
581 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
582 E : ResetLog();
583 :
584 : // Test an underflow on the destination.
585 E : ::strcpy(mem.get(), prefix_value);
586 E : ::strcpy(buffer, prefix_value);
587 E : strncatFunctionFailing(mem.get() - 1, suffix.get(), ::strlen(suffix_value));
588 E : EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
589 E : ResetLog();
590 :
591 : // Test an overflow on the suffix.
592 E : size_t suffix_len = ::strlen(suffix.get());
593 E : suffix[suffix_len] = 'a';
594 E : ::strcpy(mem.get(), prefix_value);
595 E : ::strcpy(buffer, prefix_value);
596 E : strncatFunctionFailing(mem.get(), suffix.get(), ::strlen(suffix.get()) + 1);
597 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
598 E : suffix[suffix_len] = 0;
599 E : ResetLog();
600 :
601 : // Test an overflow on the destination.
602 E : ::strcpy(mem.get(), prefix_value);
603 E : ::strcpy(buffer, prefix_value);
604 E : size_t prefix_len = ::strlen(prefix_value);
605 E : mem[prefix_len] = 'a';
606 E : buffer[prefix_len] = 'a';
607 E : strncatFunctionFailing(mem.get(), suffix.get(), ::strlen(suffix.get()));
608 E : EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
609 E : mem[prefix_len] = 0;
610 E : buffer[prefix_len] = 0;
611 E : ResetLog();
612 E : }
613 :
614 : } // namespace asan
615 : } // namespace agent
|