1 // RUN: %clang_analyze_cc1 -verify %s -Wno-null-dereference \ 2 // RUN: -analyzer-checker=core \ 3 // RUN: -analyzer-checker=unix.cstring \ 4 // RUN: -analyzer-checker=unix.Malloc \ 5 // RUN: -analyzer-checker=alpha.unix.cstring \ 6 // RUN: -analyzer-checker=debug.ExprInspection \ 7 // RUN: -analyzer-config eagerly-assume=false 8 // 9 // RUN: %clang_analyze_cc1 -verify %s -Wno-null-dereference -DUSE_BUILTINS \ 10 // RUN: -analyzer-checker=core \ 11 // RUN: -analyzer-checker=unix.cstring \ 12 // RUN: -analyzer-checker=unix.Malloc \ 13 // RUN: -analyzer-checker=alpha.unix.cstring \ 14 // RUN: -analyzer-checker=debug.ExprInspection \ 15 // RUN: -analyzer-config eagerly-assume=false 16 // 17 // RUN: %clang_analyze_cc1 -verify %s -Wno-null-dereference -DVARIANT \ 18 // RUN: -analyzer-checker=core \ 19 // RUN: -analyzer-checker=unix.cstring \ 20 // RUN: -analyzer-checker=unix.Malloc \ 21 // RUN: -analyzer-checker=alpha.unix.cstring \ 22 // RUN: -analyzer-checker=debug.ExprInspection \ 23 // RUN: -analyzer-config eagerly-assume=false 24 // 25 // RUN: %clang_analyze_cc1 -verify %s -Wno-null-dereference \ 26 // RUN: -DUSE_BUILTINS -DVARIANT \ 27 // RUN: -analyzer-checker=core \ 28 // RUN: -analyzer-checker=alpha.security.taint \ 29 // RUN: -analyzer-checker=unix.cstring \ 30 // RUN: -analyzer-checker=unix.Malloc \ 31 // RUN: -analyzer-checker=alpha.unix.cstring \ 32 // RUN: -analyzer-checker=debug.ExprInspection \ 33 // RUN: -analyzer-config eagerly-assume=false 34 // 35 // RUN: %clang_analyze_cc1 -verify %s -Wno-null-dereference \ 36 // RUN: -DSUPPRESS_OUT_OF_BOUND \ 37 // RUN: -analyzer-checker=core \ 38 // RUN: -analyzer-checker=unix.cstring \ 39 // RUN: -analyzer-checker=unix.Malloc \ 40 // RUN: -analyzer-checker=alpha.unix.cstring.BufferOverlap \ 41 // RUN: -analyzer-checker=alpha.unix.cstring.NotNullTerminated \ 42 // RUN: -analyzer-checker=debug.ExprInspection \ 43 // RUN: -analyzer-config eagerly-assume=false 44 45 //===----------------------------------------------------------------------=== 46 // Declarations 47 //===----------------------------------------------------------------------=== 48 49 // Some functions are so similar to each other that they follow the same code 50 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is 51 // defined, make sure to use the variants instead to make sure they are still 52 // checked by the analyzer. 53 54 // Some functions are implemented as builtins. These should be #defined as 55 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined. 56 57 // Functions that have variants and are also available as builtins should be 58 // declared carefully! See memcpy() for an example. 59 60 #ifdef USE_BUILTINS 61 # define BUILTIN(f) __builtin_ ## f 62 #else /* USE_BUILTINS */ 63 # define BUILTIN(f) f 64 #endif /* USE_BUILTINS */ 65 66 #define NULL 0 67 typedef typeof(sizeof(int)) size_t; 68 69 void clang_analyzer_eval(int); 70 71 int scanf(const char *restrict format, ...); 72 void *malloc(size_t); 73 void free(void *); 74 75 //===----------------------------------------------------------------------=== 76 // strlen() 77 //===----------------------------------------------------------------------=== 78 79 #define strlen BUILTIN(strlen) 80 size_t strlen(const char *s); 81 82 void strlen_constant0() { 83 clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}} 84 } 85 86 void strlen_constant1() { 87 const char *a = "123"; 88 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}} 89 } 90 91 void strlen_constant2(char x) { 92 char a[] = "123"; 93 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}} 94 95 a[0] = x; 96 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}} 97 } 98 99 size_t strlen_null() { 100 return strlen(0); // expected-warning{{Null pointer passed as 1st argument to string length function}} 101 } 102 103 size_t strlen_fn() { 104 return strlen((char*)&strlen_fn); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} 105 } 106 107 size_t strlen_nonloc() { 108 label: 109 return strlen((char*)&&label); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}} 110 } 111 112 void strlen_subregion() { 113 struct two_strings { char a[2], b[2]; }; 114 extern void use_two_strings(struct two_strings *); 115 116 struct two_strings z; 117 use_two_strings(&z); 118 119 size_t a = strlen(z.a); 120 z.b[0] = 5; 121 size_t b = strlen(z.a); 122 if (a == 0) 123 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 124 125 use_two_strings(&z); 126 127 size_t c = strlen(z.a); 128 if (a == 0) 129 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 130 } 131 132 extern void use_string(char *); 133 void strlen_argument(char *x) { 134 size_t a = strlen(x); 135 size_t b = strlen(x); 136 if (a == 0) 137 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 138 139 use_string(x); 140 141 size_t c = strlen(x); 142 if (a == 0) 143 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 144 } 145 146 extern char global_str[]; 147 void strlen_global() { 148 size_t a = strlen(global_str); 149 size_t b = strlen(global_str); 150 if (a == 0) { 151 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 152 // Make sure clang_analyzer_eval does not invalidate globals. 153 clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}} 154 } 155 156 // Call a function with unknown effects, which should invalidate globals. 157 use_string(0); 158 159 size_t c = strlen(global_str); 160 if (a == 0) 161 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 162 } 163 164 void strlen_indirect(char *x) { 165 size_t a = strlen(x); 166 char *p = x; 167 char **p2 = &p; 168 size_t b = strlen(x); 169 if (a == 0) 170 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 171 172 extern void use_string_ptr(char*const*); 173 use_string_ptr(p2); 174 175 size_t c = strlen(x); 176 if (a == 0) 177 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 178 } 179 180 void strlen_indirect2(char *x) { 181 size_t a = strlen(x); 182 char *p = x; 183 char **p2 = &p; 184 extern void use_string_ptr2(char**); 185 use_string_ptr2(p2); 186 187 size_t c = strlen(x); 188 if (a == 0) 189 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 190 } 191 192 void strlen_liveness(const char *x) { 193 if (strlen(x) < 5) 194 return; 195 clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}} 196 } 197 198 199 size_t strlenWrapper(const char *str) { 200 return strlen(str); 201 } 202 203 extern void invalidate(char *s); 204 205 void testStrlenCallee() { 206 char str[42]; 207 invalidate(str); 208 size_t lenBefore = strlenWrapper(str); 209 invalidate(str); 210 size_t lenAfter = strlenWrapper(str); 211 clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}} 212 } 213 214 215 //===----------------------------------------------------------------------=== 216 // strnlen() 217 //===----------------------------------------------------------------------=== 218 219 size_t strnlen(const char *s, size_t maxlen); 220 221 void strnlen_constant0() { 222 clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}} 223 } 224 225 void strnlen_constant1() { 226 const char *a = "123"; 227 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}} 228 } 229 230 void strnlen_constant2(char x) { 231 char a[] = "123"; 232 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}} 233 a[0] = x; 234 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}} 235 } 236 237 void strnlen_constant4() { 238 clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}} 239 } 240 241 void strnlen_constant5() { 242 const char *a = "123456"; 243 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}} 244 } 245 246 void strnlen_constant6(char x) { 247 char a[] = "123456"; 248 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}} 249 a[0] = x; 250 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}} 251 } 252 253 size_t strnlen_null() { 254 return strnlen(0, 3); // expected-warning{{Null pointer passed as 1st argument to string length function}} 255 } 256 257 size_t strnlen_fn() { 258 return strnlen((char*)&strlen_fn, 3); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} 259 } 260 261 size_t strnlen_nonloc() { 262 label: 263 return strnlen((char*)&&label, 3); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}} 264 } 265 266 void strnlen_zero() { 267 clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}} 268 clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}} 269 } 270 271 size_t strnlen_compound_literal() { 272 // This used to crash because we don't model the string lengths of 273 // compound literals. 274 return strnlen((char[]) { 'a', 'b', 0 }, 1); 275 } 276 277 size_t strnlen_unknown_limit(float f) { 278 // This used to crash because we don't model the integer values of floats. 279 return strnlen("abc", (int)f); 280 } 281 282 void strnlen_is_not_strlen(char *x) { 283 clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}} 284 } 285 286 void strnlen_at_limit(char *x) { 287 size_t len = strnlen(x, 10); 288 clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}} 289 clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}} 290 clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}} 291 } 292 293 void strnlen_at_actual(size_t limit) { 294 size_t len = strnlen("abc", limit); 295 clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}} 296 // This is due to eager assertion in strnlen. 297 if (limit == 0) { 298 clang_analyzer_eval(len == 0); // expected-warning{{TRUE}} 299 } else { 300 clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}} 301 clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}} 302 } 303 } 304 305 //===----------------------------------------------------------------------=== 306 // strcpy() 307 //===----------------------------------------------------------------------=== 308 309 #ifdef VARIANT 310 311 #define __strcpy_chk BUILTIN(__strcpy_chk) 312 char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen); 313 314 #define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1) 315 316 #else /* VARIANT */ 317 318 #define strcpy BUILTIN(strcpy) 319 char *strcpy(char *restrict s1, const char *restrict s2); 320 321 #endif /* VARIANT */ 322 323 324 void strcpy_null_dst(char *x) { 325 strcpy(NULL, x); // expected-warning{{Null pointer passed as 1st argument to string copy function}} 326 } 327 328 void strcpy_null_src(char *x) { 329 strcpy(x, NULL); // expected-warning{{Null pointer passed as 2nd argument to string copy function}} 330 } 331 332 void strcpy_fn(char *x) { 333 strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} 334 } 335 336 void strcpy_fn_const(char *x) { 337 strcpy(x, (const char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} 338 } 339 340 extern int globalInt; 341 void strcpy_effects(char *x, char *y) { 342 char a = x[0]; 343 if (globalInt != 42) 344 return; 345 346 clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}} 347 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}} 348 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 349 clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} 350 } 351 352 #ifndef SUPPRESS_OUT_OF_BOUND 353 void strcpy_overflow(char *y) { 354 char x[4]; 355 if (strlen(y) == 4) 356 strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} 357 } 358 #endif 359 360 void strcpy_no_overflow(char *y) { 361 char x[4]; 362 if (strlen(y) == 3) 363 strcpy(x, y); // no-warning 364 } 365 366 //===----------------------------------------------------------------------=== 367 // stpcpy() 368 //===----------------------------------------------------------------------=== 369 370 #ifdef VARIANT 371 372 #define __stpcpy_chk BUILTIN(__stpcpy_chk) 373 char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen); 374 375 #define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1) 376 377 #else /* VARIANT */ 378 379 #define stpcpy BUILTIN(stpcpy) 380 char *stpcpy(char *restrict s1, const char *restrict s2); 381 382 #endif /* VARIANT */ 383 384 385 void stpcpy_effect(char *x, char *y) { 386 char a = x[0]; 387 388 clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}} 389 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}} 390 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 391 } 392 393 #ifndef SUPPRESS_OUT_OF_BOUND 394 void stpcpy_overflow(char *y) { 395 char x[4]; 396 if (strlen(y) == 4) 397 stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} 398 } 399 #endif 400 401 void stpcpy_no_overflow(char *y) { 402 char x[4]; 403 if (strlen(y) == 3) 404 stpcpy(x, y); // no-warning 405 } 406 407 //===----------------------------------------------------------------------=== 408 // strcat() 409 //===----------------------------------------------------------------------=== 410 411 #ifdef VARIANT 412 413 #define __strcat_chk BUILTIN(__strcat_chk) 414 char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen); 415 416 #define strcat(a,b) __strcat_chk(a,b,(size_t)-1) 417 418 #else /* VARIANT */ 419 420 #define strcat BUILTIN(strcat) 421 char *strcat(char *restrict s1, const char *restrict s2); 422 423 #endif /* VARIANT */ 424 425 426 void strcat_null_dst(char *x) { 427 strcat(NULL, x); // expected-warning{{Null pointer passed as 1st argument to string concatenation function}} 428 } 429 430 void strcat_null_src(char *x) { 431 strcat(x, NULL); // expected-warning{{Null pointer passed as 2nd argument to string concatenation function}} 432 } 433 434 void strcat_fn(char *x) { 435 strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to string concatenation function is the address of the function 'strcat_fn', which is not a null-terminated string}} 436 } 437 438 void strcat_effects(char *y) { 439 char x[8] = "123"; 440 size_t orig_len = strlen(x); 441 char a = x[0]; 442 443 if (strlen(y) != 4) 444 return; 445 446 clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}} 447 clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 448 } 449 450 #ifndef SUPPRESS_OUT_OF_BOUND 451 void strcat_overflow_0(char *y) { 452 char x[4] = "12"; 453 if (strlen(y) == 4) 454 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 455 } 456 457 void strcat_overflow_1(char *y) { 458 char x[4] = "12"; 459 if (strlen(y) == 3) 460 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 461 } 462 463 void strcat_overflow_2(char *y) { 464 char x[4] = "12"; 465 if (strlen(y) == 2) 466 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 467 } 468 #endif 469 470 void strcat_no_overflow(char *y) { 471 char x[5] = "12"; 472 if (strlen(y) == 2) 473 strcat(x, y); // no-warning 474 } 475 476 void strcat_symbolic_dst_length(char *dst) { 477 strcat(dst, "1234"); 478 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 479 } 480 481 void strcat_symbolic_dst_length_taint(char *dst) { 482 scanf("%s", dst); // Taint data. 483 strcat(dst, "1234"); 484 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 485 } 486 487 void strcat_unknown_src_length(char *src, int offset) { 488 char dst[8] = "1234"; 489 strcat(dst, &src[offset]); 490 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 491 } 492 493 // There is no strcat_unknown_dst_length because if we can't get a symbolic 494 // length for the "before" strlen, we won't be able to set one for "after". 495 496 void strcat_too_big(char *dst, char *src) { 497 // We assume this can never actually happen, so we don't get a warning. 498 if (strlen(dst) != (((size_t)0) - 2)) 499 return; 500 if (strlen(src) != 2) 501 return; 502 strcat(dst, src); 503 } 504 505 506 //===----------------------------------------------------------------------=== 507 // strncpy() 508 //===----------------------------------------------------------------------=== 509 510 #ifdef VARIANT 511 512 #define __strncpy_chk BUILTIN(__strncpy_chk) 513 char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 514 515 #define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1) 516 517 #else /* VARIANT */ 518 519 #define strncpy BUILTIN(strncpy) 520 char *strncpy(char *restrict s1, const char *restrict s2, size_t n); 521 522 #endif /* VARIANT */ 523 524 525 void strncpy_null_dst(char *x) { 526 strncpy(NULL, x, 5); // expected-warning{{Null pointer passed as 1st argument to string copy function}} 527 } 528 529 void strncpy_null_src(char *x) { 530 strncpy(x, NULL, 5); // expected-warning{{Null pointer passed as 2nd argument to string copy function}} 531 } 532 533 void strncpy_fn(char *x) { 534 strncpy(x, (char*)&strcpy_fn, 5); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} 535 } 536 537 void strncpy_effects(char *x, char *y) { 538 char a = x[0]; 539 540 clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}} 541 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}} 542 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 543 } 544 545 #ifndef SUPPRESS_OUT_OF_BOUND 546 // Enabling the malloc checker enables some of the buffer-checking portions 547 // of the C-string checker. 548 void cstringchecker_bounds_nocrash() { 549 char *p = malloc(2); 550 strncpy(p, "AAA", sizeof("AAA")); // expected-warning {{Size argument is greater than the length of the destination buffer}} 551 free(p); 552 } 553 554 void strncpy_overflow(char *y) { 555 char x[4]; 556 if (strlen(y) == 4) 557 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} 558 #ifndef VARIANT 559 // expected-warning@-2{{size argument is too large; destination buffer has size 4, but size argument is 5}} 560 #endif 561 } 562 563 void strncpy_no_overflow(char *y) { 564 char x[4]; 565 if (strlen(y) == 3) 566 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} 567 #ifndef VARIANT 568 // expected-warning@-2{{size argument is too large; destination buffer has size 4, but size argument is 5}} 569 #endif 570 } 571 572 void strncpy_no_overflow2(char *y, int n) { 573 if (n <= 4) 574 return; 575 576 char x[4]; 577 if (strlen(y) == 3) 578 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}} 579 } 580 #endif 581 582 void strncpy_truncate(char *y) { 583 char x[4]; 584 if (strlen(y) == 4) 585 strncpy(x, y, 3); // no-warning 586 } 587 588 void strncpy_no_truncate(char *y) { 589 char x[4]; 590 if (strlen(y) == 3) 591 strncpy(x, y, 3); // no-warning 592 } 593 594 void strncpy_exactly_matching_buffer(char *y) { 595 char x[4]; 596 strncpy(x, y, 4); // no-warning 597 598 // strncpy does not null-terminate, so we have no idea what the strlen is 599 // after this. 600 clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}} 601 } 602 603 void strncpy_zero(char *src) { 604 char dst[] = "123"; 605 strncpy(dst, src, 0); // no-warning 606 } 607 608 void strncpy_empty() { 609 char dst[] = "123"; 610 char src[] = ""; 611 strncpy(dst, src, 4); // no-warning 612 } 613 614 //===----------------------------------------------------------------------=== 615 // strncat() 616 //===----------------------------------------------------------------------=== 617 618 #ifdef VARIANT 619 620 #define __strncat_chk BUILTIN(__strncat_chk) 621 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 622 623 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1) 624 625 #else /* VARIANT */ 626 627 #define strncat BUILTIN(strncat) 628 char *strncat(char *restrict s1, const char *restrict s2, size_t n); 629 630 #endif /* VARIANT */ 631 632 633 void strncat_null_dst(char *x) { 634 strncat(NULL, x, 4); // expected-warning{{Null pointer passed as 1st argument to string concatenation function}} 635 } 636 637 void strncat_null_src(char *x) { 638 strncat(x, NULL, 4); // expected-warning{{Null pointer passed as 2nd argument to string concatenation function}} 639 } 640 641 void strncat_fn(char *x) { 642 strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to string concatenation function is the address of the function 'strncat_fn', which is not a null-terminated string}} 643 } 644 645 void strncat_effects(char *y) { 646 char x[8] = "123"; 647 size_t orig_len = strlen(x); 648 char a = x[0]; 649 650 if (strlen(y) != 4) 651 return; 652 653 clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}} 654 clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 655 } 656 657 #ifndef SUPPRESS_OUT_OF_BOUND 658 void strncat_overflow_0(char *y) { 659 char x[4] = "12"; 660 if (strlen(y) == 4) 661 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 662 } 663 664 void strncat_overflow_1(char *y) { 665 char x[4] = "12"; 666 if (strlen(y) == 3) 667 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 668 } 669 670 void strncat_overflow_2(char *y) { 671 char x[4] = "12"; 672 if (strlen(y) == 2) 673 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 674 } 675 676 void strncat_overflow_3(char *y) { 677 char x[4] = "12"; 678 if (strlen(y) == 4) 679 strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 680 } 681 #endif 682 683 void strncat_no_overflow_1(char *y) { 684 char x[5] = "12"; 685 if (strlen(y) == 2) 686 strncat(x, y, strlen(y)); // no-warning 687 } 688 689 void strncat_no_overflow_2(char *y) { 690 char x[4] = "12"; 691 if (strlen(y) == 4) 692 strncat(x, y, 1); // no-warning 693 } 694 695 void strncat_symbolic_dst_length(char *dst) { 696 strncat(dst, "1234", 5); 697 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 698 } 699 700 #ifndef SUPPRESS_OUT_OF_BOUND 701 void strncat_symbolic_src_length(char *src) { 702 char dst[8] = "1234"; 703 strncat(dst, src, 3); 704 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 705 706 char dst2[8] = "1234"; 707 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 708 } 709 710 void strncat_unknown_src_length(char *src, int offset) { 711 char dst[8] = "1234"; 712 strncat(dst, &src[offset], 3); 713 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 714 715 char dst2[8] = "1234"; 716 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 717 } 718 #endif 719 720 // There is no strncat_unknown_dst_length because if we can't get a symbolic 721 // length for the "before" strlen, we won't be able to set one for "after". 722 723 void strncat_symbolic_limit(unsigned limit) { 724 char dst[6] = "1234"; 725 char src[] = "567"; 726 strncat(dst, src, limit); // no-warning 727 728 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 729 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 730 } 731 732 void strncat_unknown_limit(float limit) { 733 char dst[6] = "1234"; 734 char src[] = "567"; 735 strncat(dst, src, (size_t)limit); // no-warning 736 737 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 738 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 739 } 740 741 void strncat_too_big(char *dst, char *src) { 742 // We assume this will never actually happen, so we don't get a warning. 743 if (strlen(dst) != (((size_t)0) - 2)) 744 return; 745 if (strlen(src) != 2) 746 return; 747 strncat(dst, src, 2); 748 } 749 750 void strncat_zero(char *src) { 751 char dst[] = "123"; 752 strncat(dst, src, 0); // no-warning 753 } 754 755 void strncat_empty() { 756 char dst[8] = "123"; 757 char src[] = ""; 758 strncat(dst, src, 4); // no-warning 759 } 760 761 //===----------------------------------------------------------------------=== 762 // strcmp() 763 //===----------------------------------------------------------------------=== 764 765 #define strcmp BUILTIN(strcmp) 766 int strcmp(const char * s1, const char * s2); 767 768 void strcmp_check_modelling() { 769 char *x = "aa"; 770 char *y = "a"; 771 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 772 clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}} 773 clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}} 774 775 clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}} 776 clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}} 777 clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}} 778 } 779 780 void strcmp_constant0() { 781 clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}} 782 } 783 784 void strcmp_constant_and_var_0() { 785 char *x = "123"; 786 clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}} 787 } 788 789 void strcmp_constant_and_var_1() { 790 char *x = "123"; 791 clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}} 792 } 793 794 void strcmp_0() { 795 char *x = "123"; 796 char *y = "123"; 797 clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}} 798 } 799 800 void strcmp_1() { 801 char *x = "234"; 802 char *y = "123"; 803 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 804 } 805 806 void strcmp_2() { 807 char *x = "123"; 808 char *y = "234"; 809 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 810 } 811 812 void strcmp_null_0() { 813 char *x = NULL; 814 char *y = "123"; 815 strcmp(x, y); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 816 } 817 818 void strcmp_null_1() { 819 char *x = "123"; 820 char *y = NULL; 821 strcmp(x, y); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 822 } 823 824 void strcmp_diff_length_0() { 825 char *x = "12345"; 826 char *y = "234"; 827 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 828 } 829 830 void strcmp_diff_length_1() { 831 char *x = "123"; 832 char *y = "23456"; 833 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 834 } 835 836 void strcmp_diff_length_2() { 837 char *x = "12345"; 838 char *y = "123"; 839 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 840 } 841 842 void strcmp_diff_length_3() { 843 char *x = "123"; 844 char *y = "12345"; 845 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 846 } 847 848 void strcmp_embedded_null () { 849 clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}} 850 } 851 852 void strcmp_unknown_arg (char *unknown) { 853 clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}} 854 } 855 856 union argument { 857 char *f; 858 }; 859 860 void function_pointer_cast_helper(char **a) { 861 strcmp("Hi", *a); // PR24951 crash 862 } 863 864 void strcmp_union_function_pointer_cast(union argument a) { 865 void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper; 866 867 fPtr(&a); 868 } 869 870 int strcmp_null_argument(char *a) { 871 char *b = 0; 872 // Do not warn about the first argument! 873 return strcmp(a, b); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 874 } 875 876 //===----------------------------------------------------------------------=== 877 // strncmp() 878 //===----------------------------------------------------------------------=== 879 880 #define strncmp BUILTIN(strncmp) 881 int strncmp(const char *s1, const char *s2, size_t n); 882 883 void strncmp_check_modelling() { 884 char *x = "aa"; 885 char *y = "a"; 886 clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}} 887 clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 888 clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 889 890 clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}} 891 clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 892 clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 893 } 894 895 void strncmp_constant0() { 896 clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}} 897 } 898 899 void strncmp_constant_and_var_0() { 900 char *x = "123"; 901 clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}} 902 } 903 904 void strncmp_constant_and_var_1() { 905 char *x = "123"; 906 clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}} 907 } 908 909 void strncmp_0() { 910 char *x = "123"; 911 char *y = "123"; 912 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 913 } 914 915 void strncmp_1() { 916 char *x = "234"; 917 char *y = "123"; 918 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 919 } 920 921 void strncmp_2() { 922 char *x = "123"; 923 char *y = "234"; 924 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 925 } 926 927 void strncmp_null_0() { 928 char *x = NULL; 929 char *y = "123"; 930 strncmp(x, y, 3); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 931 } 932 933 void strncmp_null_1() { 934 char *x = "123"; 935 char *y = NULL; 936 strncmp(x, y, 3); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 937 } 938 939 void strncmp_diff_length_0() { 940 char *x = "12345"; 941 char *y = "234"; 942 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 943 } 944 945 void strncmp_diff_length_1() { 946 char *x = "123"; 947 char *y = "23456"; 948 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 949 } 950 951 void strncmp_diff_length_2() { 952 char *x = "12345"; 953 char *y = "123"; 954 clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}} 955 } 956 957 void strncmp_diff_length_3() { 958 char *x = "123"; 959 char *y = "12345"; 960 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 961 } 962 963 void strncmp_diff_length_4() { 964 char *x = "123"; 965 char *y = "12345"; 966 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 967 } 968 969 void strncmp_diff_length_5() { 970 char *x = "012"; 971 char *y = "12345"; 972 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 973 } 974 975 void strncmp_diff_length_6() { 976 char *x = "234"; 977 char *y = "12345"; 978 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 979 } 980 981 void strncmp_embedded_null () { 982 clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 983 } 984 985 int strncmp_null_argument(char *a, size_t n) { 986 char *b = 0; 987 // Do not warn about the first argument! 988 return strncmp(a, b, n); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 989 } 990 991 //===----------------------------------------------------------------------=== 992 // strcasecmp() 993 //===----------------------------------------------------------------------=== 994 995 #define strcasecmp BUILTIN(strcasecmp) 996 int strcasecmp(const char *s1, const char *s2); 997 998 void strcasecmp_check_modelling() { 999 char *x = "aa"; 1000 char *y = "a"; 1001 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1002 clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}} 1003 clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}} 1004 1005 clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}} 1006 clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}} 1007 clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}} 1008 } 1009 1010 void strcasecmp_constant0() { 1011 clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}} 1012 } 1013 1014 void strcasecmp_constant_and_var_0() { 1015 char *x = "abc"; 1016 clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}} 1017 } 1018 1019 void strcasecmp_constant_and_var_1() { 1020 char *x = "abc"; 1021 clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}} 1022 } 1023 1024 void strcasecmp_0() { 1025 char *x = "abc"; 1026 char *y = "Abc"; 1027 clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}} 1028 } 1029 1030 void strcasecmp_1() { 1031 char *x = "Bcd"; 1032 char *y = "abc"; 1033 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1034 } 1035 1036 void strcasecmp_2() { 1037 char *x = "abc"; 1038 char *y = "Bcd"; 1039 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1040 } 1041 1042 void strcasecmp_null_0() { 1043 char *x = NULL; 1044 char *y = "123"; 1045 strcasecmp(x, y); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 1046 } 1047 1048 void strcasecmp_null_1() { 1049 char *x = "123"; 1050 char *y = NULL; 1051 strcasecmp(x, y); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1052 } 1053 1054 void strcasecmp_diff_length_0() { 1055 char *x = "abcde"; 1056 char *y = "aBd"; 1057 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1058 } 1059 1060 void strcasecmp_diff_length_1() { 1061 char *x = "abc"; 1062 char *y = "aBdef"; 1063 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1064 } 1065 1066 void strcasecmp_diff_length_2() { 1067 char *x = "aBcDe"; 1068 char *y = "abc"; 1069 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1070 } 1071 1072 void strcasecmp_diff_length_3() { 1073 char *x = "aBc"; 1074 char *y = "abcde"; 1075 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1076 } 1077 1078 void strcasecmp_embedded_null () { 1079 clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}} 1080 } 1081 1082 int strcasecmp_null_argument(char *a) { 1083 char *b = 0; 1084 // Do not warn about the first argument! 1085 return strcasecmp(a, b); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1086 } 1087 1088 //===----------------------------------------------------------------------=== 1089 // strncasecmp() 1090 //===----------------------------------------------------------------------=== 1091 1092 #define strncasecmp BUILTIN(strncasecmp) 1093 int strncasecmp(const char *s1, const char *s2, size_t n); 1094 1095 void strncasecmp_check_modelling() { 1096 char *x = "aa"; 1097 char *y = "a"; 1098 clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}} 1099 clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 1100 clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 1101 1102 clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}} 1103 clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 1104 clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 1105 } 1106 1107 void strncasecmp_constant0() { 1108 clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}} 1109 } 1110 1111 void strncasecmp_constant_and_var_0() { 1112 char *x = "abc"; 1113 clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}} 1114 } 1115 1116 void strncasecmp_constant_and_var_1() { 1117 char *x = "abc"; 1118 clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}} 1119 } 1120 1121 void strncasecmp_0() { 1122 char *x = "abc"; 1123 char *y = "Abc"; 1124 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1125 } 1126 1127 void strncasecmp_1() { 1128 char *x = "Bcd"; 1129 char *y = "abc"; 1130 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1131 } 1132 1133 void strncasecmp_2() { 1134 char *x = "abc"; 1135 char *y = "Bcd"; 1136 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1137 } 1138 1139 void strncasecmp_null_0() { 1140 char *x = NULL; 1141 char *y = "123"; 1142 strncasecmp(x, y, 3); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 1143 } 1144 1145 void strncasecmp_null_1() { 1146 char *x = "123"; 1147 char *y = NULL; 1148 strncasecmp(x, y, 3); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1149 } 1150 1151 void strncasecmp_diff_length_0() { 1152 char *x = "abcde"; 1153 char *y = "aBd"; 1154 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1155 } 1156 1157 void strncasecmp_diff_length_1() { 1158 char *x = "abc"; 1159 char *y = "aBdef"; 1160 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1161 } 1162 1163 void strncasecmp_diff_length_2() { 1164 char *x = "aBcDe"; 1165 char *y = "abc"; 1166 clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}} 1167 } 1168 1169 void strncasecmp_diff_length_3() { 1170 char *x = "aBc"; 1171 char *y = "abcde"; 1172 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1173 } 1174 1175 void strncasecmp_diff_length_4() { 1176 char *x = "abcde"; 1177 char *y = "aBc"; 1178 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1179 } 1180 1181 void strncasecmp_diff_length_5() { 1182 char *x = "abcde"; 1183 char *y = "aBd"; 1184 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1185 } 1186 1187 void strncasecmp_diff_length_6() { 1188 char *x = "aBDe"; 1189 char *y = "abc"; 1190 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1191 } 1192 1193 void strncasecmp_embedded_null () { 1194 clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 1195 } 1196 1197 int strncasecmp_null_argument(char *a, size_t n) { 1198 char *b = 0; 1199 // Do not warn about the first argument! 1200 return strncasecmp(a, b, n); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1201 } 1202 1203 //===----------------------------------------------------------------------=== 1204 // strsep() 1205 //===----------------------------------------------------------------------=== 1206 1207 char *strsep(char **stringp, const char *delim); 1208 1209 void strsep_null_delim(char *s) { 1210 strsep(&s, NULL); // expected-warning{{Null pointer passed as 2nd argument to strsep()}} 1211 } 1212 1213 void strsep_null_search() { 1214 strsep(NULL, ""); // expected-warning{{Null pointer passed as 1st argument to strsep()}} 1215 } 1216 1217 void strsep_return_original_pointer(char *s) { 1218 char *original = s; 1219 char *result = strsep(&s, ""); // no-warning 1220 clang_analyzer_eval(original == result); // expected-warning{{TRUE}} 1221 } 1222 1223 void strsep_null_string() { 1224 char *s = NULL; 1225 char *result = strsep(&s, ""); // no-warning 1226 clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}} 1227 } 1228 1229 void strsep_changes_input_pointer(char *s) { 1230 char *original = s; 1231 strsep(&s, ""); // no-warning 1232 clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}} 1233 clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}} 1234 1235 // Check that the value is symbolic. 1236 if (s == NULL) { 1237 clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}} 1238 } 1239 } 1240 1241 void strsep_changes_input_string() { 1242 char str[] = "abc"; 1243 1244 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}} 1245 1246 char *s = str; 1247 strsep(&s, "b"); // no-warning 1248 1249 // The real strsep will change the first delimiter it finds into a NUL 1250 // character. For now, we just model the invalidation. 1251 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} 1252 } 1253 1254 //===----------------------------------------------------------------------=== 1255 // memset() / explicit_bzero() / bzero() 1256 //===----------------------------------------------------------------------=== 1257 1258 void *memset(void *dest, int ch, size_t count); 1259 1260 void bzero(void *dst, size_t count); 1261 void explicit_bzero(void *dest, size_t count); 1262 1263 void *malloc(size_t size); 1264 void free(void *); 1265 1266 void memset1_char_array_null() { 1267 char str[] = "abcd"; 1268 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1269 memset(str, '\0', 2); 1270 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1271 } 1272 1273 void memset2_char_array_null() { 1274 char str[] = "abcd"; 1275 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1276 memset(str, '\0', strlen(str) + 1); 1277 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1278 clang_analyzer_eval(str[2] == 0); // expected-warning{{TRUE}} 1279 } 1280 1281 void memset3_char_malloc_null() { 1282 char *str = (char *)malloc(10 * sizeof(char)); 1283 memset(str + 1, '\0', 8); 1284 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1285 free(str); 1286 } 1287 1288 void memset4_char_malloc_null() { 1289 char *str = (char *)malloc(10 * sizeof(char)); 1290 //void *str = malloc(10 * sizeof(char)); 1291 memset(str, '\0', 10); 1292 clang_analyzer_eval(str[1] == 0); // expected-warning{{TRUE}} 1293 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1294 free(str); 1295 } 1296 1297 #ifdef SUPPRESS_OUT_OF_BOUND 1298 void memset5_char_malloc_overflow_null() { 1299 char *str = (char *)malloc(10 * sizeof(char)); 1300 memset(str, '\0', 12); 1301 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1302 free(str); 1303 } 1304 #endif 1305 1306 void memset6_char_array_nonnull() { 1307 char str[] = "abcd"; 1308 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1309 memset(str, '0', 2); 1310 clang_analyzer_eval(str[0] == 'a'); // expected-warning{{UNKNOWN}} 1311 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{UNKNOWN}} 1312 } 1313 1314 #ifdef SUPPRESS_OUT_OF_BOUND 1315 void memset8_char_array_nonnull() { 1316 char str[5] = "abcd"; 1317 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1318 memset(str, '0', 10); // expected-warning{{'memset' will always overflow; destination buffer has size 5, but size argument is 10}} 1319 clang_analyzer_eval(str[0] != '0'); // expected-warning{{UNKNOWN}} 1320 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1321 clang_analyzer_eval(strlen(str) < 10); // expected-warning{{FALSE}} 1322 } 1323 #endif 1324 1325 struct POD_memset { 1326 int num; 1327 char c; 1328 }; 1329 1330 void memset10_struct() { 1331 struct POD_memset pod; 1332 char *str = (char *)&pod; 1333 pod.num = 1; 1334 pod.c = 1; 1335 clang_analyzer_eval(pod.num == 0); // expected-warning{{FALSE}} 1336 memset(str, 0, sizeof(struct POD_memset)); 1337 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1338 } 1339 1340 #ifdef SUPPRESS_OUT_OF_BOUND 1341 void memset11_struct_field() { 1342 struct POD_memset pod; 1343 pod.num = 1; 1344 pod.c = '1'; 1345 memset(&pod.num, 0, sizeof(struct POD_memset)); 1346 1347 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1348 clang_analyzer_eval(pod.c == '\0'); // expected-warning{{TRUE}} 1349 } 1350 1351 void memset12_struct_field() { 1352 struct POD_memset pod; 1353 pod.num = 1; 1354 pod.c = '1'; 1355 memset(&pod.c, 0, sizeof(struct POD_memset)); // expected-warning {{'memset' will always overflow; destination buffer has size 4, but size argument is 8}} 1356 clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}} 1357 clang_analyzer_eval(pod.c == 0); // expected-warning{{UNKNOWN}} 1358 } 1359 1360 union U_memset { 1361 int i; 1362 double d; 1363 char c; 1364 }; 1365 1366 void memset13_union_field() { 1367 union U_memset u; 1368 u.i = 5; 1369 memset(&u.i, '\0', sizeof(union U_memset)); 1370 // Note: This should be TRUE, analyzer can't handle union perfectly now. 1371 clang_analyzer_eval(u.d == 0); // expected-warning{{UNKNOWN}} 1372 } 1373 #endif 1374 1375 void memset14_region_cast() { 1376 char *str = (char *)malloc(10 * sizeof(int)); 1377 int *array = (int *)str; 1378 memset(array, 0, 10 * sizeof(int)); 1379 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{TRUE}} 1380 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1381 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1382 free(str); 1383 } 1384 1385 void memset15_region_cast() { 1386 char *str = (char *)malloc(10 * sizeof(int)); 1387 int *array = (int *)str; 1388 memset(array, 0, 5 * sizeof(int)); 1389 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{UNKNOWN}} 1390 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1391 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1392 free(str); 1393 } 1394 1395 int memset20_scalar() { 1396 int *x = malloc(sizeof(int)); 1397 *x = 10; 1398 memset(x, 0, sizeof(int)); 1399 int num = 1 / *x; // expected-warning{{Division by zero}} 1400 free(x); 1401 return num; 1402 } 1403 1404 int memset21_scalar() { 1405 int *x = malloc(sizeof(int)); 1406 memset(x, 0, 1); 1407 int num = 1 / *x; 1408 free(x); 1409 return num; 1410 } 1411 1412 void memset22_array() { 1413 int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 1414 clang_analyzer_eval(array[1] == 2); // expected-warning{{TRUE}} 1415 memset(array, 0, sizeof(array)); 1416 clang_analyzer_eval(array[1] == 0); // expected-warning{{TRUE}} 1417 } 1418 1419 void memset23_array_pod_object() { 1420 struct POD_memset array[10]; 1421 array[1].num = 10; 1422 array[1].c = 'c'; 1423 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1424 memset(&array[1], 0, sizeof(struct POD_memset)); 1425 clang_analyzer_eval(array[1].num == 0); // expected-warning{{UNKNOWN}} 1426 } 1427 1428 void memset24_array_pod_object() { 1429 struct POD_memset array[10]; 1430 array[1].num = 10; 1431 array[1].c = 'c'; 1432 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1433 memset(array, 0, sizeof(array)); 1434 clang_analyzer_eval(array[1].num == 0); // expected-warning{{TRUE}} 1435 } 1436 1437 void memset25_symbol(char c) { 1438 char array[10] = {1}; 1439 if (c != 0) 1440 return; 1441 1442 memset(array, c, 10); 1443 1444 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1445 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1446 } 1447 1448 void memset26_upper_UCHAR_MAX() { 1449 char array[10] = {1}; 1450 1451 memset(array, 1024, 10); 1452 1453 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1454 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1455 } 1456 1457 void bzero1_null() { 1458 char *a = NULL; 1459 1460 bzero(a, 10); // expected-warning{{Null pointer passed as 1st argument to memory clearance function}} 1461 } 1462 1463 void bzero2_char_array_null() { 1464 char str[] = "abcd"; 1465 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1466 bzero(str, 2); 1467 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1468 } 1469 1470 void bzero3_char_ptr_null() { 1471 char *str = "abcd"; 1472 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1473 bzero(str + 2, 2); 1474 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{FALSE}} 1475 } 1476 1477 void explicit_bzero1_null() { 1478 char *a = NULL; 1479 1480 explicit_bzero(a, 10); // expected-warning{{Null pointer passed as 1st argument to memory clearance function}} 1481 } 1482 1483 void explicit_bzero2_clear_mypassword() { 1484 char passwd[7] = "passwd"; 1485 1486 explicit_bzero(passwd, sizeof(passwd)); // no-warning 1487 1488 clang_analyzer_eval(strlen(passwd) == 0); // expected-warning{{TRUE}} 1489 clang_analyzer_eval(passwd[0] == '\0'); // expected-warning{{TRUE}} 1490 } 1491 1492 void explicit_bzero3_out_ofbound() { 1493 char *privkey = (char *)malloc(7); 1494 const char newprivkey[10] = "mysafekey"; 1495 1496 strcpy(privkey, "random"); 1497 explicit_bzero(privkey, sizeof(newprivkey)); 1498 #ifndef SUPPRESS_OUT_OF_BOUND 1499 // expected-warning@-2 {{Memory clearance function accesses out-of-bound array element}} 1500 #endif 1501 clang_analyzer_eval(privkey[0] == '\0'); 1502 #ifdef SUPPRESS_OUT_OF_BOUND 1503 // expected-warning@-2 {{UNKNOWN}} 1504 #endif 1505 free(privkey); 1506 } 1507 1508 //===----------------------------------------------------------------------=== 1509 // FIXMEs 1510 //===----------------------------------------------------------------------=== 1511 1512 // The analyzer_eval call below should evaluate to true. We are being too 1513 // aggressive in marking the (length of) src symbol dead. The length of dst 1514 // depends on src. This could be explicitly specified in the checker or the 1515 // logic for handling MetadataSymbol in SymbolManager needs to change. 1516 void strcat_symbolic_src_length(char *src) { 1517 char dst[8] = "1234"; 1518 strcat(dst, src); 1519 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}} 1520 } 1521 1522 1523 // The analyzer_eval call below should evaluate to true. Most likely the same 1524 // issue as the test above. 1525 void strncpy_exactly_matching_buffer2(char *y) { 1526 if (strlen(y) >= 4) 1527 return; 1528 1529 char x[4]; 1530 strncpy(x, y, 4); // no-warning 1531 1532 // This time, we know that y fits in x anyway. 1533 clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}} 1534 } 1535 1536 void memset7_char_array_nonnull() { 1537 char str[5] = "abcd"; 1538 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1539 memset(str, '0', 5); 1540 // FIXME: This should be TRUE. 1541 clang_analyzer_eval(str[0] == '0'); // expected-warning{{UNKNOWN}} 1542 clang_analyzer_eval(strlen(str) >= 5); // expected-warning{{TRUE}} 1543 } 1544 1545 void memset16_region_cast() { 1546 char *str = (char *)malloc(10 * sizeof(int)); 1547 int *array = (int *)str; 1548 memset(array, '0', 10 * sizeof(int)); 1549 // FIXME: This should be TRUE. 1550 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1551 clang_analyzer_eval(strlen((char *)array) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1552 clang_analyzer_eval(strlen(str) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1553 free(str); 1554 } 1555 1556 #ifdef SUPPRESS_OUT_OF_BOUND 1557 void memset17_region_cast() { 1558 char *str = (char *)malloc(10 * sizeof(int)); 1559 int *array = (int *)str; 1560 memset(array, '0', 12 * sizeof(int)); 1561 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1562 clang_analyzer_eval(strlen((char *)array) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1563 clang_analyzer_eval(strlen(str) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1564 free(str); 1565 } 1566 1567 void memset18_memset_multiple_times() { 1568 char *str = (char *)malloc(10 * sizeof(char)); 1569 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1570 1571 memset(str + 2, '\0', 10 * sizeof(char)); 1572 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1573 clang_analyzer_eval(str[1] == '\0'); // expected-warning{{UNKNOWN}} 1574 1575 memset(str, '0', 10 * sizeof(char)); 1576 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1577 // FIXME: This should be TRUE. 1578 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1579 1580 free(str); 1581 } 1582 1583 void memset19_memset_multiple_times() { 1584 char *str = (char *)malloc(10 * sizeof(char)); 1585 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1586 1587 memset(str, '0', 10 * sizeof(char)); 1588 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1589 // FIXME: This should be TRUE. 1590 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1591 1592 memset(str + 2, '\0', 10 * sizeof(char)); 1593 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{UNKNOWN}} 1594 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1595 1596 free(str); 1597 } 1598 #endif 1599 1600 // The analyzer does not support binding a symbol with default binding. 1601 void memset27_symbol(char c) { 1602 char array[10] = {0}; 1603 if (c < 10) 1604 return; 1605 1606 memset(array, c, 10); 1607 1608 clang_analyzer_eval(strlen(array) >= 10); // expected-warning{{TRUE}} 1609 // FIXME: This should be TRUE. 1610 clang_analyzer_eval(array[4] >= 10); // expected-warning{{UNKNOWN}} 1611 } 1612 1613 void memset28() { 1614 short x; 1615 memset(&x, 1, sizeof(short)); 1616 // This should be true. 1617 clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}} 1618 } 1619 1620 void memset29_plain_int_zero() { 1621 short x; 1622 memset(&x, 0, sizeof(short)); 1623 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} 1624 } 1625 1626 void test_memset_chk() { 1627 int x; 1628 __builtin___memset_chk(&x, 0, sizeof(x), __builtin_object_size(&x, 0)); 1629 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} 1630 } 1631