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 before and after 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 before 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 // This test fails on MinGW-w64 because it still ships a static copy of strnlen 114 // despite it being available from UCRT. 115 #if defined(__MINGW32__) 116 # define MAYBE_StrNLenOOBTest DISABLED_StrNLenOOBTest 117 #else 118 # define MAYBE_StrNLenOOBTest StrNLenOOBTest 119 #endif 120 121 #if SANITIZER_TEST_HAS_STRNLEN 122 TEST(AddressSanitizer, MAYBE_StrNLenOOBTest) { 123 size_t size = Ident(123); 124 char *str = MallocAndMemsetString(size); 125 // Normal strnlen calls. 126 Ident(strnlen(str - 1, 0)); 127 Ident(strnlen(str, size)); 128 Ident(strnlen(str + size - 1, 1)); 129 str[size - 1] = '\0'; 130 Ident(strnlen(str, 2 * size)); 131 // Argument points to not allocated memory. 132 EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1)); 133 EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0)); 134 // Overwrite the terminating '\0' and hit unallocated memory. 135 str[size - 1] = 'z'; 136 EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0)); 137 free(str); 138 } 139 #endif // SANITIZER_TEST_HAS_STRNLEN 140 141 // This test fails with the WinASan dynamic runtime because we fail to intercept 142 // strdup. 143 #if (defined(_MSC_VER) && defined(_DLL)) || defined(__MINGW32__) 144 # define MAYBE_StrDupOOBTest DISABLED_StrDupOOBTest 145 #else 146 # define MAYBE_StrDupOOBTest StrDupOOBTest 147 #endif 148 149 TEST(AddressSanitizer, MAYBE_StrDupOOBTest) { 150 size_t size = Ident(42); 151 char *str = MallocAndMemsetString(size); 152 char *new_str; 153 // Normal strdup calls. 154 str[size - 1] = '\0'; 155 new_str = strdup(str); 156 free(new_str); 157 new_str = strdup(str + size - 1); 158 free(new_str); 159 // Argument points to not allocated memory. 160 EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1)); 161 EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0)); 162 // Overwrite the terminating '\0' and hit unallocated memory. 163 str[size - 1] = 'z'; 164 EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0)); 165 free(str); 166 } 167 168 #if SANITIZER_TEST_HAS_STRNDUP 169 TEST(AddressSanitizer, MAYBE_StrNDupOOBTest) { 170 size_t size = Ident(42); 171 char *str = MallocAndMemsetString(size); 172 char *new_str; 173 // Normal strndup calls. 174 str[size - 1] = '\0'; 175 new_str = strndup(str, size - 13); 176 free(new_str); 177 new_str = strndup(str + size - 1, 13); 178 free(new_str); 179 // Argument points to not allocated memory. 180 EXPECT_DEATH(Ident(strndup(str - 1, 13)), LeftOOBReadMessage(1)); 181 EXPECT_DEATH(Ident(strndup(str + size, 13)), RightOOBReadMessage(0)); 182 // Overwrite the terminating '\0' and hit unallocated memory. 183 str[size - 1] = 'z'; 184 EXPECT_DEATH(Ident(strndup(str, size + 13)), RightOOBReadMessage(0)); 185 // Check handling of non 0 terminated strings. 186 Ident(new_str = strndup(str + size - 1, 0)); 187 free(new_str); 188 Ident(new_str = strndup(str + size - 1, 1)); 189 free(new_str); 190 EXPECT_DEATH(Ident(strndup(str + size - 1, 2)), RightOOBReadMessage(0)); 191 free(str); 192 } 193 #endif // SANITIZER_TEST_HAS_STRNDUP 194 195 TEST(AddressSanitizer, StrCpyOOBTest) { 196 size_t to_size = Ident(30); 197 size_t from_size = Ident(6); // less than to_size 198 char *to = Ident((char*)malloc(to_size)); 199 char *from = Ident((char*)malloc(from_size)); 200 // Normal strcpy calls. 201 strcpy(from, "hello"); 202 strcpy(to, from); 203 strcpy(to + to_size - from_size, from); 204 // Length of "from" is too small. 205 EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0)); 206 // "to" or "from" points to not allocated memory. 207 EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1)); 208 EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1)); 209 EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0)); 210 EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0)); 211 // Overwrite the terminating '\0' character and hit unallocated memory. 212 from[from_size - 1] = '!'; 213 EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0)); 214 free(to); 215 free(from); 216 } 217 218 TEST(AddressSanitizer, StrNCpyOOBTest) { 219 size_t to_size = Ident(20); 220 size_t from_size = Ident(6); // less than to_size 221 char *to = Ident((char*)malloc(to_size)); 222 // From is a zero-terminated string "hello\0" of length 6 223 char *from = Ident((char*)malloc(from_size)); 224 strcpy(from, "hello"); 225 // copy 0 bytes 226 strncpy(to, from, 0); 227 strncpy(to - 1, from - 1, 0); 228 // normal strncpy calls 229 strncpy(to, from, from_size); 230 strncpy(to, from, to_size); 231 strncpy(to, from + from_size - 1, to_size); 232 strncpy(to + to_size - 1, from, 1); 233 // One of {to, from} points to not allocated memory 234 EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)), 235 LeftOOBReadMessage(1)); 236 EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)), 237 LeftOOBWriteMessage(1)); 238 EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)), 239 RightOOBReadMessage(0)); 240 EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)), 241 RightOOBWriteMessage(0)); 242 // Length of "to" is too small 243 EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)), 244 RightOOBWriteMessage(0)); 245 EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)), 246 RightOOBWriteMessage(0)); 247 // Overwrite terminator in from 248 from[from_size - 1] = '!'; 249 // normal strncpy call 250 strncpy(to, from, from_size); 251 // Length of "from" is too small 252 EXPECT_DEATH(Ident(strncpy(to, from, to_size)), 253 RightOOBReadMessage(0)); 254 free(to); 255 free(from); 256 } 257 258 // Users may have different definitions of "strchr" and "index", so provide 259 // function pointer typedefs and overload RunStrChrTest implementation. 260 // We can't use macro for RunStrChrTest body here, as this macro would 261 // confuse EXPECT_DEATH gtest macro. 262 typedef char*(*PointerToStrChr1)(const char*, int); 263 typedef char*(*PointerToStrChr2)(char*, int); 264 265 template<typename StrChrFn> 266 static void RunStrChrTestImpl(StrChrFn *StrChr) { 267 size_t size = Ident(100); 268 char *str = MallocAndMemsetString(size); 269 str[10] = 'q'; 270 str[11] = '\0'; 271 EXPECT_EQ(str, StrChr(str, 'z')); 272 EXPECT_EQ(str + 10, StrChr(str, 'q')); 273 EXPECT_EQ(NULL, StrChr(str, 'a')); 274 // StrChr argument points to not allocated memory. 275 EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1)); 276 EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0)); 277 // Overwrite the terminator and hit not allocated memory. 278 str[11] = 'z'; 279 EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0)); 280 free(str); 281 } 282 283 // Prefer to use the standard signature if both are available. 284 UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr, ...) { 285 RunStrChrTestImpl(StrChr); 286 } 287 UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr, int) { 288 RunStrChrTestImpl(StrChr); 289 } 290 291 TEST(AddressSanitizer, StrChrAndIndexOOBTest) { 292 RunStrChrTest(&strchr, 0); 293 // No index() on Windows and on Android L. 294 #if !defined(_WIN32) && !defined(__ANDROID__) 295 RunStrChrTest(&index, 0); 296 #endif 297 } 298 299 TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) { 300 // strcmp 301 EXPECT_EQ(0, strcmp("", "")); 302 EXPECT_EQ(0, strcmp("abcd", "abcd")); 303 EXPECT_GT(0, strcmp("ab", "ac")); 304 EXPECT_GT(0, strcmp("abc", "abcd")); 305 EXPECT_LT(0, strcmp("acc", "abc")); 306 EXPECT_LT(0, strcmp("abcd", "abc")); 307 308 // strncmp 309 EXPECT_EQ(0, strncmp("a", "b", 0)); 310 EXPECT_EQ(0, strncmp("abcd", "abcd", 10)); 311 EXPECT_EQ(0, strncmp("abcd", "abcef", 3)); 312 EXPECT_GT(0, strncmp("abcde", "abcfa", 4)); 313 EXPECT_GT(0, strncmp("a", "b", 5)); 314 EXPECT_GT(0, strncmp("bc", "bcde", 4)); 315 EXPECT_LT(0, strncmp("xyz", "xyy", 10)); 316 EXPECT_LT(0, strncmp("baa", "aaa", 1)); 317 EXPECT_LT(0, strncmp("zyx", "", 2)); 318 319 #if !defined(_WIN32) // no str[n]casecmp on Windows. 320 // strcasecmp 321 EXPECT_EQ(0, strcasecmp("", "")); 322 EXPECT_EQ(0, strcasecmp("zzz", "zzz")); 323 EXPECT_EQ(0, strcasecmp("abCD", "ABcd")); 324 EXPECT_GT(0, strcasecmp("aB", "Ac")); 325 EXPECT_GT(0, strcasecmp("ABC", "ABCd")); 326 EXPECT_LT(0, strcasecmp("acc", "abc")); 327 EXPECT_LT(0, strcasecmp("ABCd", "abc")); 328 329 // strncasecmp 330 EXPECT_EQ(0, strncasecmp("a", "b", 0)); 331 EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10)); 332 EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3)); 333 EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4)); 334 EXPECT_GT(0, strncasecmp("a", "B", 5)); 335 EXPECT_GT(0, strncasecmp("bc", "BCde", 4)); 336 EXPECT_LT(0, strncasecmp("xyz", "xyy", 10)); 337 EXPECT_LT(0, strncasecmp("Baa", "aaa", 1)); 338 EXPECT_LT(0, strncasecmp("zyx", "", 2)); 339 #endif 340 341 // memcmp 342 EXPECT_EQ(0, memcmp("a", "b", 0)); 343 EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4)); 344 EXPECT_GT(0, memcmp("\0ab", "\0ac", 3)); 345 EXPECT_GT(0, memcmp("abb\0", "abba", 4)); 346 EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5)); 347 EXPECT_LT(0, memcmp("zza", "zyx", 3)); 348 } 349 350 typedef int(*PointerToStrCmp)(const char*, const char*); 351 void RunStrCmpTest(PointerToStrCmp StrCmp) { 352 size_t size = Ident(100); 353 int fill = 'o'; 354 char *s1 = MallocAndMemsetString(size, fill); 355 char *s2 = MallocAndMemsetString(size, fill); 356 s1[size - 1] = '\0'; 357 s2[size - 1] = '\0'; 358 // Normal StrCmp calls 359 Ident(StrCmp(s1, s2)); 360 Ident(StrCmp(s1, s2 + size - 1)); 361 Ident(StrCmp(s1 + size - 1, s2 + size - 1)); 362 // One of arguments points to not allocated memory. 363 EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1)); 364 EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1)); 365 EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0)); 366 EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0)); 367 // Hit unallocated memory and die. 368 s1[size - 1] = fill; 369 EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0)); 370 EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0)); 371 free(s1); 372 free(s2); 373 } 374 375 TEST(AddressSanitizer, StrCmpOOBTest) { 376 RunStrCmpTest(&strcmp); 377 } 378 379 #if !defined(_WIN32) // no str[n]casecmp on Windows. 380 TEST(AddressSanitizer, StrCaseCmpOOBTest) { 381 RunStrCmpTest(&strcasecmp); 382 } 383 #endif 384 385 typedef int(*PointerToStrNCmp)(const char*, const char*, size_t); 386 void RunStrNCmpTest(PointerToStrNCmp StrNCmp) { 387 size_t size = Ident(100); 388 char *s1 = MallocAndMemsetString(size); 389 char *s2 = MallocAndMemsetString(size); 390 s1[size - 1] = '\0'; 391 s2[size - 1] = '\0'; 392 // Normal StrNCmp calls 393 Ident(StrNCmp(s1, s2, size + 2)); 394 s1[size - 1] = 'z'; 395 s2[size - 1] = 'x'; 396 Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size)); 397 s2[size - 1] = 'z'; 398 Ident(StrNCmp(s1 - 1, s2 - 1, 0)); 399 Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1)); 400 // One of arguments points to not allocated memory. 401 EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1)); 402 EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1)); 403 EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0)); 404 EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0)); 405 // Hit unallocated memory and die. 406 EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0)); 407 EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0)); 408 free(s1); 409 free(s2); 410 } 411 412 TEST(AddressSanitizer, StrNCmpOOBTest) { 413 RunStrNCmpTest(&strncmp); 414 } 415 416 #if !defined(_WIN32) // no str[n]casecmp on Windows. 417 TEST(AddressSanitizer, StrNCaseCmpOOBTest) { 418 RunStrNCmpTest(&strncasecmp); 419 } 420 #endif 421 422 TEST(AddressSanitizer, StrCatOOBTest) { 423 // strcat() reads strlen(to) bytes from |to| before concatenating. 424 size_t to_size = Ident(100); 425 char *to = MallocAndMemsetString(to_size); 426 to[0] = '\0'; 427 size_t from_size = Ident(20); 428 char *from = MallocAndMemsetString(from_size); 429 from[from_size - 1] = '\0'; 430 // Normal strcat calls. 431 strcat(to, from); 432 strcat(to, from); 433 strcat(to + from_size, from + from_size - 2); 434 // Passing an invalid pointer is an error even when concatenating an empty 435 // string. 436 EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1)); 437 // One of arguments points to not allocated memory. 438 EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1)); 439 EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1)); 440 EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0)); 441 442 // "from" is not zero-terminated. 443 from[from_size - 1] = 'z'; 444 EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0)); 445 from[from_size - 1] = '\0'; 446 // "to" is too short to fit "from". 447 memset(to, 'z', to_size); 448 to[to_size - from_size + 1] = '\0'; 449 EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0)); 450 // length of "to" is just enough. 451 strcat(to, from + 1); 452 453 free(to); 454 free(from); 455 } 456 457 TEST(AddressSanitizer, StrNCatOOBTest) { 458 // strncat() reads strlen(to) bytes from |to| before concatenating. 459 size_t to_size = Ident(100); 460 char *to = MallocAndMemsetString(to_size); 461 to[0] = '\0'; 462 size_t from_size = Ident(20); 463 char *from = MallocAndMemsetString(from_size); 464 // Normal strncat calls. 465 strncat(to, from, 0); 466 strncat(to, from, from_size); 467 from[from_size - 1] = '\0'; 468 strncat(to, from, 2 * from_size); 469 strncat(to, from + from_size - 1, 10); 470 // One of arguments points to not allocated memory. 471 EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1)); 472 EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1)); 473 EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0)); 474 475 memset(from, 'z', from_size); 476 memset(to, 'z', to_size); 477 to[0] = '\0'; 478 // "from" is too short. 479 EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0)); 480 // "to" is too short to fit "from". 481 to[0] = 'z'; 482 to[to_size - from_size + 1] = '\0'; 483 EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0)); 484 // "to" is just enough. 485 strncat(to, from, from_size - 2); 486 487 free(to); 488 free(from); 489 } 490 491 static std::string OverlapErrorMessage(const std::string &func) { 492 return func + "-param-overlap"; 493 } 494 495 TEST(AddressSanitizer, StrArgsOverlapTest) { 496 size_t size = Ident(100); 497 char *str = Ident((char*)malloc(size)); 498 499 // Do not check memcpy() on OS X 10.7 and later, where it actually aliases 500 // memmove(). 501 #if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \ 502 (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) 503 // Check "memcpy". Use Ident() to avoid inlining. 504 #if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 505 memset(str, 'z', size); 506 Ident(memcpy)(str + 1, str + 11, 10); 507 Ident(memcpy)(str, str, 0); 508 EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy")); 509 EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy")); 510 #endif 511 #endif 512 513 // We do not treat memcpy with to==from as a bug. 514 // See http://llvm.org/bugs/show_bug.cgi?id=11763. 515 // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1), 516 // OverlapErrorMessage("memcpy")); 517 518 // Check "strcpy". 519 memset(str, 'z', size); 520 str[9] = '\0'; 521 strcpy(str + 10, str); 522 EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy")); 523 EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy")); 524 strcpy(str, str + 5); 525 526 // Check "strncpy". 527 memset(str, 'z', size); 528 strncpy(str, str + 10, 10); 529 EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy")); 530 EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy")); 531 str[10] = '\0'; 532 strncpy(str + 11, str, 20); 533 EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy")); 534 535 // Check "strcat". 536 memset(str, 'z', size); 537 str[10] = '\0'; 538 str[20] = '\0'; 539 strcat(str, str + 10); 540 EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat")); 541 str[10] = '\0'; 542 strcat(str + 11, str); 543 EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat")); 544 EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat")); 545 EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat")); 546 547 // Check "strncat". 548 memset(str, 'z', size); 549 str[10] = '\0'; 550 strncat(str, str + 10, 10); // from is empty 551 EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat")); 552 str[10] = '\0'; 553 str[20] = '\0'; 554 strncat(str + 5, str, 5); 555 str[10] = '\0'; 556 EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat")); 557 EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat")); 558 559 free(str); 560 } 561 562 typedef void(*PointerToCallAtoi)(const char*); 563 564 void RunAtoiOOBTest(PointerToCallAtoi Atoi) { 565 char *array = MallocAndMemsetString(10, '1'); 566 // Invalid pointer to the string. 567 EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1)); 568 EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1)); 569 // Die if a buffer doesn't have terminating NULL. 570 EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 571 // Make last symbol a terminating NULL 572 array[9] = '\0'; 573 Atoi(array); 574 // Sometimes we need to detect overflow if no digits are found. 575 memset(array, ' ', 10); 576 EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 577 array[9] = '-'; 578 EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 579 EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0)); 580 free(array); 581 } 582 583 #if !defined(_WIN32) // FIXME: Fix and enable on Windows. 584 void CallAtoi(const char *nptr) { 585 Ident(atoi(nptr)); 586 } 587 void CallAtol(const char *nptr) { 588 Ident(atol(nptr)); 589 } 590 void CallAtoll(const char *nptr) { 591 Ident(atoll(nptr)); 592 } 593 TEST(AddressSanitizer, AtoiAndFriendsOOBTest) { 594 RunAtoiOOBTest(&CallAtoi); 595 RunAtoiOOBTest(&CallAtol); 596 RunAtoiOOBTest(&CallAtoll); 597 } 598 #endif 599 600 typedef void(*PointerToCallStrtol)(const char*, char**, int); 601 602 void RunStrtolOOBTest(PointerToCallStrtol Strtol) { 603 char *array = MallocAndMemsetString(3); 604 array[0] = '1'; 605 array[1] = '2'; 606 array[2] = '3'; 607 // Invalid pointer to the string. 608 EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0)); 609 EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1)); 610 // Buffer overflow if there is no terminating null (depends on base). 611 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 612 array[2] = 'z'; 613 EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0)); 614 // Add terminating zero to get rid of overflow. 615 array[2] = '\0'; 616 Strtol(array, NULL, 36); 617 // Sometimes we need to detect overflow if no digits are found. 618 array[0] = array[1] = array[2] = ' '; 619 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 620 array[2] = '+'; 621 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 622 array[2] = '-'; 623 EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 624 free(array); 625 } 626 627 #if !defined(_WIN32) // FIXME: Fix and enable on Windows. 628 void CallStrtol(const char *nptr, char **endptr, int base) { 629 Ident(strtol(nptr, endptr, base)); 630 } 631 void CallStrtoll(const char *nptr, char **endptr, int base) { 632 Ident(strtoll(nptr, endptr, base)); 633 } 634 TEST(AddressSanitizer, StrtollOOBTest) { 635 RunStrtolOOBTest(&CallStrtoll); 636 } 637 TEST(AddressSanitizer, StrtolOOBTest) { 638 RunStrtolOOBTest(&CallStrtol); 639 } 640 #endif 641 642 TEST(AddressSanitizer, StrtolOverflow) { 643 if (sizeof(long) == 4) { 644 // Check that errno gets set correctly on 32-bit strtol overflow. 645 long res; 646 errno = 0; 647 res = Ident(strtol("2147483647", NULL, 0)); 648 EXPECT_EQ(errno, 0); 649 EXPECT_EQ(res, 2147483647); 650 651 res = Ident(strtol("2147483648", NULL, 0)); 652 EXPECT_EQ(errno, ERANGE); 653 EXPECT_EQ(res, 2147483647); 654 655 errno = 0; 656 res = Ident(strtol("-2147483648", NULL, 0)); 657 EXPECT_EQ(errno, 0); 658 EXPECT_EQ(res, -2147483648); 659 660 res = Ident(strtol("-2147483649", NULL, 0)); 661 EXPECT_EQ(errno, ERANGE); 662 EXPECT_EQ(res, -2147483648); 663 } 664 } 665