1 //=-- asan_str_test.cpp ---------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of AddressSanitizer, an address sanity checker. 10 // 11 //===----------------------------------------------------------------------===// 12 #include "asan_test_utils.h" 13 14 #if defined(__APPLE__) 15 #include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_* 16 #endif 17 18 // Used for string functions tests 19 static char global_string[] = "global"; 20 static size_t global_string_length = 6; 21 22 const char kStackReadUnderflow[] = 23 #if !GTEST_USES_SIMPLE_RE 24 ASAN_PCRE_DOTALL 25 "READ.*" 26 #endif 27 "underflows this variable"; 28 const char kStackReadOverflow[] = 29 #if !GTEST_USES_SIMPLE_RE 30 ASAN_PCRE_DOTALL 31 "READ.*" 32 #endif 33 "overflows this variable"; 34 35 namespace { 36 enum class OOBKind { 37 Heap, 38 Stack, 39 Global, 40 }; 41 42 std::string LeftOOBReadMessage(OOBKind oob_kind, int oob_distance) { 43 return oob_kind == OOBKind::Stack ? kStackReadUnderflow 44 : ::LeftOOBReadMessage(oob_distance); 45 } 46 47 std::string RightOOBReadMessage(OOBKind oob_kind, int oob_distance) { 48 return oob_kind == OOBKind::Stack ? kStackReadOverflow 49 : ::RightOOBReadMessage(oob_distance); 50 } 51 } // namespace 52 53 // Input to a test is a zero-terminated string str with given length 54 // Accesses to the bytes to the left and to the right of str 55 // are presumed to produce OOB errors 56 void StrLenOOBTestTemplate(char *str, size_t length, OOBKind oob_kind) { 57 // Normal strlen calls 58 EXPECT_EQ(strlen(str), length); 59 if (length > 0) { 60 EXPECT_EQ(length - 1, strlen(str + 1)); 61 EXPECT_EQ(0U, strlen(str + length)); 62 } 63 // Arg of strlen is not malloced, OOB access 64 if (oob_kind != OOBKind::Global) { 65 // We don't insert RedZones to the left of global variables 66 EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(oob_kind, 1)); 67 EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(oob_kind, 5)); 68 } 69 EXPECT_DEATH(Ident(strlen(str + length + 1)), 70 RightOOBReadMessage(oob_kind, 0)); 71 // Overwrite terminator 72 str[length] = 'a'; 73 // String is not zero-terminated, strlen will lead to OOB access 74 EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(oob_kind, 0)); 75 EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(oob_kind, 0)); 76 // Restore terminator 77 str[length] = 0; 78 } 79 TEST(AddressSanitizer, StrLenOOBTest) { 80 // Check heap-allocated string 81 size_t length = Ident(10); 82 char *heap_string = Ident((char*)malloc(length + 1)); 83 char stack_string[10 + 1]; 84 break_optimization(&stack_string); 85 for (size_t i = 0; i < length; i++) { 86 heap_string[i] = 'a'; 87 stack_string[i] = 'b'; 88 } 89 heap_string[length] = 0; 90 stack_string[length] = 0; 91 StrLenOOBTestTemplate(heap_string, length, OOBKind::Heap); 92 StrLenOOBTestTemplate(stack_string, length, OOBKind::Stack); 93 StrLenOOBTestTemplate(global_string, global_string_length, OOBKind::Global); 94 free(heap_string); 95 } 96 97 // 32-bit android libc++-based NDK toolchain links wcslen statically, disabling 98 // the interceptor. 99 #if !defined(__ANDROID__) || defined(__LP64__) 100 TEST(AddressSanitizer, WcsLenTest) { 101 EXPECT_EQ(0U, wcslen(Ident(L""))); 102 size_t hello_len = 13; 103 size_t hello_size = (hello_len + 1) * sizeof(wchar_t); 104 EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!"))); 105 wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size)); 106 memcpy(heap_string, L"Hello, World!", hello_size); 107 EXPECT_EQ(hello_len, Ident(wcslen(heap_string))); 108 EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0)); 109 free(heap_string); 110 } 111 #endif 112 113 #if SANITIZER_TEST_HAS_STRNLEN 114 TEST(AddressSanitizer, StrNLenOOBTest) { 115 size_t size = Ident(123); 116 char *str = MallocAndMemsetString(size); 117 // Normal strnlen calls. 118 Ident(strnlen(str - 1, 0)); 119 Ident(strnlen(str, size)); 120 Ident(strnlen(str + size - 1, 1)); 121 str[size - 1] = '\0'; 122 Ident(strnlen(str, 2 * size)); 123 // Argument points to not allocated memory. 124 EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1)); 125 EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0)); 126 // Overwrite the terminating '\0' and hit unallocated memory. 127 str[size - 1] = 'z'; 128 EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0)); 129 free(str); 130 } 131 #endif // SANITIZER_TEST_HAS_STRNLEN 132 133 // This test fails with the WinASan dynamic runtime because we fail to intercept 134 // strdup. 135 #if defined(_MSC_VER) && defined(_DLL) 136 #define MAYBE_StrDupOOBTest DISABLED_StrDupOOBTest 137 #else 138 #define MAYBE_StrDupOOBTest StrDupOOBTest 139 #endif 140 141 TEST(AddressSanitizer, MAYBE_StrDupOOBTest) { 142 size_t size = Ident(42); 143 char *str = MallocAndMemsetString(size); 144 char *new_str; 145 // Normal strdup calls. 146 str[size - 1] = '\0'; 147 new_str = strdup(str); 148 free(new_str); 149 new_str = strdup(str + size - 1); 150 free(new_str); 151 // Argument points to not allocated memory. 152 EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1)); 153 EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0)); 154 // Overwrite the terminating '\0' and hit unallocated memory. 155 str[size - 1] = 'z'; 156 EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0)); 157 free(str); 158 } 159 160 #if SANITIZER_TEST_HAS_STRNDUP 161 TEST(AddressSanitizer, MAYBE_StrNDupOOBTest) { 162 size_t size = Ident(42); 163 char *str = MallocAndMemsetString(size); 164 char *new_str; 165 // Normal strndup calls. 166 str[size - 1] = '\0'; 167 new_str = strndup(str, size - 13); 168 free(new_str); 169 new_str = strndup(str + size - 1, 13); 170 free(new_str); 171 // Argument points to not allocated memory. 172 EXPECT_DEATH(Ident(strndup(str - 1, 13)), LeftOOBReadMessage(1)); 173 EXPECT_DEATH(Ident(strndup(str + size, 13)), RightOOBReadMessage(0)); 174 // Overwrite the terminating '\0' and hit unallocated memory. 175 str[size - 1] = 'z'; 176 EXPECT_DEATH(Ident(strndup(str, size + 13)), RightOOBReadMessage(0)); 177 // Check handling of non 0 terminated strings. 178 Ident(new_str = strndup(str + size - 1, 0)); 179 free(new_str); 180 Ident(new_str = strndup(str + size - 1, 1)); 181 free(new_str); 182 EXPECT_DEATH(Ident(strndup(str + size - 1, 2)), RightOOBReadMessage(0)); 183 free(str); 184 } 185 #endif // SANITIZER_TEST_HAS_STRNDUP 186 187 TEST(AddressSanitizer, StrCpyOOBTest) { 188 size_t to_size = Ident(30); 189 size_t from_size = Ident(6); // less than to_size 190 char *to = Ident((char*)malloc(to_size)); 191 char *from = Ident((char*)malloc(from_size)); 192 // Normal strcpy calls. 193 strcpy(from, "hello"); 194 strcpy(to, from); 195 strcpy(to + to_size - from_size, from); 196 // Length of "from" is too small. 197 EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0)); 198 // "to" or "from" points to not allocated memory. 199 EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1)); 200 EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1)); 201 EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0)); 202 EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0)); 203 // Overwrite the terminating '\0' character and hit unallocated memory. 204 from[from_size - 1] = '!'; 205 EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0)); 206 free(to); 207 free(from); 208 } 209 210 TEST(AddressSanitizer, StrNCpyOOBTest) { 211 size_t to_size = Ident(20); 212 size_t from_size = Ident(6); // less than to_size 213 char *to = Ident((char*)malloc(to_size)); 214 // From is a zero-terminated string "hello\0" of length 6 215 char *from = Ident((char*)malloc(from_size)); 216 strcpy(from, "hello"); 217 // copy 0 bytes 218 strncpy(to, from, 0); 219 strncpy(to - 1, from - 1, 0); 220 // normal strncpy calls 221 strncpy(to, from, from_size); 222 strncpy(to, from, to_size); 223 strncpy(to, from + from_size - 1, to_size); 224 strncpy(to + to_size - 1, from, 1); 225 // One of {to, from} points to not allocated memory 226 EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)), 227 LeftOOBReadMessage(1)); 228 EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)), 229 LeftOOBWriteMessage(1)); 230 EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)), 231 RightOOBReadMessage(0)); 232 EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)), 233 RightOOBWriteMessage(0)); 234 // Length of "to" is too small 235 EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)), 236 RightOOBWriteMessage(0)); 237 EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)), 238 RightOOBWriteMessage(0)); 239 // Overwrite terminator in from 240 from[from_size - 1] = '!'; 241 // normal strncpy call 242 strncpy(to, from, from_size); 243 // Length of "from" is too small 244 EXPECT_DEATH(Ident(strncpy(to, from, to_size)), 245 RightOOBReadMessage(0)); 246 free(to); 247 free(from); 248 } 249 250 // Users may have different definitions of "strchr" and "index", so provide 251 // function pointer typedefs and overload RunStrChrTest implementation. 252 // We can't use macro for RunStrChrTest body here, as this macro would 253 // confuse EXPECT_DEATH gtest macro. 254 typedef char*(*PointerToStrChr1)(const char*, int); 255 typedef char*(*PointerToStrChr2)(char*, int); 256 257 template<typename StrChrFn> 258 static void RunStrChrTestImpl(StrChrFn *StrChr) { 259 size_t size = Ident(100); 260 char *str = MallocAndMemsetString(size); 261 str[10] = 'q'; 262 str[11] = '\0'; 263 EXPECT_EQ(str, StrChr(str, 'z')); 264 EXPECT_EQ(str + 10, StrChr(str, 'q')); 265 EXPECT_EQ(NULL, StrChr(str, 'a')); 266 // StrChr argument points to not allocated memory. 267 EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1)); 268 EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0)); 269 // Overwrite the terminator and hit not allocated memory. 270 str[11] = 'z'; 271 EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0)); 272 free(str); 273 } 274 275 // Prefer to use the standard signature if both are available. 276 UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr, ...) { 277 RunStrChrTestImpl(StrChr); 278 } 279 UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr, int) { 280 RunStrChrTestImpl(StrChr); 281 } 282 283 TEST(AddressSanitizer, StrChrAndIndexOOBTest) { 284 RunStrChrTest(&strchr, 0); 285 // No index() on Windows and on Android L. 286 #if !defined(_WIN32) && !defined(__ANDROID__) 287 RunStrChrTest(&index, 0); 288 #endif 289 } 290 291 TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) { 292 // strcmp 293 EXPECT_EQ(0, strcmp("", "")); 294 EXPECT_EQ(0, strcmp("abcd", "abcd")); 295 EXPECT_GT(0, strcmp("ab", "ac")); 296 EXPECT_GT(0, strcmp("abc", "abcd")); 297 EXPECT_LT(0, strcmp("acc", "abc")); 298 EXPECT_LT(0, strcmp("abcd", "abc")); 299 300 // strncmp 301 EXPECT_EQ(0, strncmp("a", "b", 0)); 302 EXPECT_EQ(0, strncmp("abcd", "abcd", 10)); 303 EXPECT_EQ(0, strncmp("abcd", "abcef", 3)); 304 EXPECT_GT(0, strncmp("abcde", "abcfa", 4)); 305 EXPECT_GT(0, strncmp("a", "b", 5)); 306 EXPECT_GT(0, strncmp("bc", "bcde", 4)); 307 EXPECT_LT(0, strncmp("xyz", "xyy", 10)); 308 EXPECT_LT(0, strncmp("baa", "aaa", 1)); 309 EXPECT_LT(0, strncmp("zyx", "", 2)); 310 311 #if !defined(_WIN32) // no str[n]casecmp on Windows. 312 // strcasecmp 313 EXPECT_EQ(0, strcasecmp("", "")); 314 EXPECT_EQ(0, strcasecmp("zzz", "zzz")); 315 EXPECT_EQ(0, strcasecmp("abCD", "ABcd")); 316 EXPECT_GT(0, strcasecmp("aB", "Ac")); 317 EXPECT_GT(0, strcasecmp("ABC", "ABCd")); 318 EXPECT_LT(0, strcasecmp("acc", "abc")); 319 EXPECT_LT(0, strcasecmp("ABCd", "abc")); 320 321 // strncasecmp 322 EXPECT_EQ(0, strncasecmp("a", "b", 0)); 323 EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10)); 324 EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3)); 325 EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4)); 326 EXPECT_GT(0, strncasecmp("a", "B", 5)); 327 EXPECT_GT(0, strncasecmp("bc", "BCde", 4)); 328 EXPECT_LT(0, strncasecmp("xyz", "xyy", 10)); 329 EXPECT_LT(0, strncasecmp("Baa", "aaa", 1)); 330 EXPECT_LT(0, strncasecmp("zyx", "", 2)); 331 #endif 332 333 // memcmp 334 EXPECT_EQ(0, memcmp("a", "b", 0)); 335 EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4)); 336 EXPECT_GT(0, memcmp("\0ab", "\0ac", 3)); 337 EXPECT_GT(0, memcmp("abb\0", "abba", 4)); 338 EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5)); 339 EXPECT_LT(0, memcmp("zza", "zyx", 3)); 340 } 341 342 typedef int(*PointerToStrCmp)(const char*, const char*); 343 void RunStrCmpTest(PointerToStrCmp StrCmp) { 344 size_t size = Ident(100); 345 int fill = 'o'; 346 char *s1 = MallocAndMemsetString(size, fill); 347 char *s2 = MallocAndMemsetString(size, fill); 348 s1[size - 1] = '\0'; 349 s2[size - 1] = '\0'; 350 // Normal StrCmp calls 351 Ident(StrCmp(s1, s2)); 352 Ident(StrCmp(s1, s2 + size - 1)); 353 Ident(StrCmp(s1 + size - 1, s2 + size - 1)); 354 // One of arguments points to not allocated memory. 355 EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1)); 356 EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1)); 357 EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0)); 358 EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0)); 359 // Hit unallocated memory and die. 360 s1[size - 1] = fill; 361 EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0)); 362 EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0)); 363 free(s1); 364 free(s2); 365 } 366 367 TEST(AddressSanitizer, StrCmpOOBTest) { 368 RunStrCmpTest(&strcmp); 369 } 370 371 #if !defined(_WIN32) // no str[n]casecmp on Windows. 372 TEST(AddressSanitizer, StrCaseCmpOOBTest) { 373 RunStrCmpTest(&strcasecmp); 374 } 375 #endif 376 377 typedef int(*PointerToStrNCmp)(const char*, const char*, size_t); 378 void RunStrNCmpTest(PointerToStrNCmp StrNCmp) { 379 size_t size = Ident(100); 380 char *s1 = MallocAndMemsetString(size); 381 char *s2 = MallocAndMemsetString(size); 382 s1[size - 1] = '\0'; 383 s2[size - 1] = '\0'; 384 // Normal StrNCmp calls 385 Ident(StrNCmp(s1, s2, size + 2)); 386 s1[size - 1] = 'z'; 387 s2[size - 1] = 'x'; 388 Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size)); 389 s2[size - 1] = 'z'; 390 Ident(StrNCmp(s1 - 1, s2 - 1, 0)); 391 Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1)); 392 // One of arguments points to not allocated memory. 393 EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1)); 394 EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1)); 395 EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0)); 396 EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0)); 397 // Hit unallocated memory and die. 398 EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0)); 399 EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0)); 400 free(s1); 401 free(s2); 402 } 403 404 TEST(AddressSanitizer, StrNCmpOOBTest) { 405 RunStrNCmpTest(&strncmp); 406 } 407 408 #if !defined(_WIN32) // no str[n]casecmp on Windows. 409 TEST(AddressSanitizer, StrNCaseCmpOOBTest) { 410 RunStrNCmpTest(&strncasecmp); 411 } 412 #endif 413 414 TEST(AddressSanitizer, StrCatOOBTest) { 415 // strcat() reads strlen(to) bytes from |to| before concatenating. 416 size_t to_size = Ident(100); 417 char *to = MallocAndMemsetString(to_size); 418 to[0] = '\0'; 419 size_t from_size = Ident(20); 420 char *from = MallocAndMemsetString(from_size); 421 from[from_size - 1] = '\0'; 422 // Normal strcat calls. 423 strcat(to, from); 424 strcat(to, from); 425 strcat(to + from_size, from + from_size - 2); 426 // Passing an invalid pointer is an error even when concatenating an empty 427 // string. 428 EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1)); 429 // One of arguments points to not allocated memory. 430 EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1)); 431 EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1)); 432 EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0)); 433 434 // "from" is not zero-terminated. 435 from[from_size - 1] = 'z'; 436 EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0)); 437 from[from_size - 1] = '\0'; 438 // "to" is too short to fit "from". 439 memset(to, 'z', to_size); 440 to[to_size - from_size + 1] = '\0'; 441 EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0)); 442 // length of "to" is just enough. 443 strcat(to, from + 1); 444 445 free(to); 446 free(from); 447 } 448 449 TEST(AddressSanitizer, StrNCatOOBTest) { 450 // strncat() reads strlen(to) bytes from |to| before concatenating. 451 size_t to_size = Ident(100); 452 char *to = MallocAndMemsetString(to_size); 453 to[0] = '\0'; 454 size_t from_size = Ident(20); 455 char *from = MallocAndMemsetString(from_size); 456 // Normal strncat calls. 457 strncat(to, from, 0); 458 strncat(to, from, from_size); 459 from[from_size - 1] = '\0'; 460 strncat(to, from, 2 * from_size); 461 strncat(to, from + from_size - 1, 10); 462 // One of arguments points to not allocated memory. 463 EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1)); 464 EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1)); 465 EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0)); 466 467 memset(from, 'z', from_size); 468 memset(to, 'z', to_size); 469 to[0] = '\0'; 470 // "from" is too short. 471 EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0)); 472 // "to" is too short to fit "from". 473 to[0] = 'z'; 474 to[to_size - from_size + 1] = '\0'; 475 EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0)); 476 // "to" is just enough. 477 strncat(to, from, from_size - 2); 478 479 free(to); 480 free(from); 481 } 482 483 static std::string OverlapErrorMessage(const std::string &func) { 484 return func + "-param-overlap"; 485 } 486 487 TEST(AddressSanitizer, StrArgsOverlapTest) { 488 size_t size = Ident(100); 489 char *str = Ident((char*)malloc(size)); 490 491 // Do not check memcpy() on OS X 10.7 and later, where it actually aliases 492 // memmove(). 493 #if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \ 494 (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) 495 // Check "memcpy". Use Ident() to avoid inlining. 496 #if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 497 memset(str, 'z', size); 498 Ident(memcpy)(str + 1, str + 11, 10); 499 Ident(memcpy)(str, str, 0); 500 EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy")); 501 EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy")); 502 #endif 503 #endif 504 505 // We do not treat memcpy with to==from as a bug. 506 // See http://llvm.org/bugs/show_bug.cgi?id=11763. 507 // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1), 508 // OverlapErrorMessage("memcpy")); 509 510 // Check "strcpy". 511 memset(str, 'z', size); 512 str[9] = '\0'; 513 strcpy(str + 10, str); 514 EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy")); 515 EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy")); 516 strcpy(str, str + 5); 517 518 // Check "strncpy". 519 memset(str, 'z', size); 520 strncpy(str, str + 10, 10); 521 EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy")); 522 EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy")); 523 str[10] = '\0'; 524 strncpy(str + 11, str, 20); 525 EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy")); 526 527 // Check "strcat". 528 memset(str, 'z', size); 529 str[10] = '\0'; 530 str[20] = '\0'; 531 strcat(str, str + 10); 532 EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat")); 533 str[10] = '\0'; 534 strcat(str + 11, str); 535 EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat")); 536 EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat")); 537 EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat")); 538 539 // Check "strncat". 540 memset(str, 'z', size); 541 str[10] = '\0'; 542 strncat(str, str + 10, 10); // from is empty 543 EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat")); 544 str[10] = '\0'; 545 str[20] = '\0'; 546 strncat(str + 5, str, 5); 547 str[10] = '\0'; 548 EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat")); 549 EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat")); 550 551 free(str); 552 } 553 554 typedef void(*PointerToCallAtoi)(const char*); 555 556 void RunAtoiOOBTest(PointerToCallAtoi Atoi) { 557 char *array = MallocAndMemsetString(10, '1'); 558 // Invalid pointer to the string. 559 EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1)); 560 EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1)); 561 // Die if a buffer doesn't have terminating NULL. 562 EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 563 // Make last symbol a terminating NULL 564 array[9] = '\0'; 565 Atoi(array); 566 // Sometimes we need to detect overflow if no digits are found. 567 memset(array, ' ', 10); 568 EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 569 array[9] = '-'; 570 EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 571 EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0)); 572 free(array); 573 } 574 575 #if !defined(_WIN32) // FIXME: Fix and enable on Windows. 576 void CallAtoi(const char *nptr) { 577 Ident(atoi(nptr)); 578 } 579 void CallAtol(const char *nptr) { 580 Ident(atol(nptr)); 581 } 582 void CallAtoll(const char *nptr) { 583 Ident(atoll(nptr)); 584 } 585 TEST(AddressSanitizer, AtoiAndFriendsOOBTest) { 586 RunAtoiOOBTest(&CallAtoi); 587 RunAtoiOOBTest(&CallAtol); 588 RunAtoiOOBTest(&CallAtoll); 589 } 590 #endif 591 592 typedef void(*PointerToCallStrtol)(const char*, char**, int); 593 594 void RunStrtolOOBTest(PointerToCallStrtol Strtol) { 595 char *array = MallocAndMemsetString(3); 596 array[0] = '1'; 597 array[1] = '2'; 598 array[2] = '3'; 599 // Invalid pointer to the string. 600 EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0)); 601 EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1)); 602 // Buffer overflow if there is no terminating null (depends on base). 603 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 604 array[2] = 'z'; 605 EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0)); 606 // Add terminating zero to get rid of overflow. 607 array[2] = '\0'; 608 Strtol(array, NULL, 36); 609 // Sometimes we need to detect overflow if no digits are found. 610 array[0] = array[1] = array[2] = ' '; 611 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 612 array[2] = '+'; 613 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 614 array[2] = '-'; 615 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 616 free(array); 617 } 618 619 #if !defined(_WIN32) // FIXME: Fix and enable on Windows. 620 void CallStrtol(const char *nptr, char **endptr, int base) { 621 Ident(strtol(nptr, endptr, base)); 622 } 623 void CallStrtoll(const char *nptr, char **endptr, int base) { 624 Ident(strtoll(nptr, endptr, base)); 625 } 626 TEST(AddressSanitizer, StrtollOOBTest) { 627 RunStrtolOOBTest(&CallStrtoll); 628 } 629 TEST(AddressSanitizer, StrtolOOBTest) { 630 RunStrtolOOBTest(&CallStrtol); 631 } 632 #endif 633