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