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 the 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 the 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 concatenation function overflows the 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 concatenation function overflows the 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 concatenation function overflows the 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")); 551 // expected-warning@-1 {{String copy function overflows the destination buffer}} 552 free(p); 553 } 554 555 void strncpy_overflow(char *y) { 556 char x[4]; 557 if (strlen(y) == 4) 558 strncpy(x, y, 5); 559 // expected-warning@-1 {{String copy function overflows the destination buffer}} 560 #ifndef VARIANT 561 // expected-warning@-3 {{size argument is too large; destination buffer has size 4, but size argument is 5}} 562 #endif 563 } 564 565 void strncpy_no_overflow(char *y) { 566 char x[4]; 567 if (strlen(y) == 3) 568 strncpy(x, y, 5); 569 // expected-warning@-1 {{String copy function overflows the destination buffer}} 570 #ifndef VARIANT 571 // expected-warning@-3 {{size argument is too large; destination buffer has size 4, but size argument is 5}} 572 #endif 573 } 574 575 void strncpy_no_overflow2(char *y, int n) { 576 if (n <= 4) 577 return; 578 579 char x[4]; 580 if (strlen(y) == 3) 581 strncpy(x, y, n); 582 // expected-warning@-1 {{String copy function overflows the destination buffer}} 583 } 584 #endif 585 586 void strncpy_truncate(char *y) { 587 char x[4]; 588 if (strlen(y) == 4) 589 strncpy(x, y, 3); // no-warning 590 } 591 592 void strncpy_no_truncate(char *y) { 593 char x[4]; 594 if (strlen(y) == 3) 595 strncpy(x, y, 3); // no-warning 596 } 597 598 void strncpy_exactly_matching_buffer(char *y) { 599 char x[4]; 600 strncpy(x, y, 4); // no-warning 601 602 // strncpy does not null-terminate, so we have no idea what the strlen is 603 // after this. 604 clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}} 605 } 606 607 void strncpy_zero(char *src) { 608 char dst[] = "123"; 609 strncpy(dst, src, 0); // no-warning 610 } 611 612 void strncpy_empty() { 613 char dst[] = "123"; 614 char src[] = ""; 615 strncpy(dst, src, 4); // no-warning 616 } 617 618 //===----------------------------------------------------------------------=== 619 // strncat() 620 //===----------------------------------------------------------------------=== 621 622 #ifdef VARIANT 623 624 #define __strncat_chk BUILTIN(__strncat_chk) 625 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 626 627 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1) 628 629 #else /* VARIANT */ 630 631 #define strncat BUILTIN(strncat) 632 char *strncat(char *restrict s1, const char *restrict s2, size_t n); 633 634 #endif /* VARIANT */ 635 636 637 void strncat_null_dst(char *x) { 638 strncat(NULL, x, 4); // expected-warning{{Null pointer passed as 1st argument to string concatenation function}} 639 } 640 641 void strncat_null_src(char *x) { 642 strncat(x, NULL, 4); // expected-warning{{Null pointer passed as 2nd argument to string concatenation function}} 643 } 644 645 void strncat_fn(char *x) { 646 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}} 647 } 648 649 void strncat_effects(char *y) { 650 char x[8] = "123"; 651 size_t orig_len = strlen(x); 652 char a = x[0]; 653 654 if (strlen(y) != 4) 655 return; 656 657 clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}} 658 clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 659 } 660 661 #ifndef SUPPRESS_OUT_OF_BOUND 662 void strncat_overflow_0(char *y) { 663 char x[4] = "12"; 664 if (strlen(y) == 4) 665 strncat(x, y, strlen(y)); 666 // expected-warning@-1 {{String concatenation function overflows the destination buffer}} 667 } 668 669 void strncat_overflow_1(char *y) { 670 char x[4] = "12"; 671 if (strlen(y) == 3) 672 strncat(x, y, strlen(y)); 673 // expected-warning@-1 {{String concatenation function overflows the destination buffer}} 674 } 675 676 void strncat_overflow_2(char *y) { 677 char x[4] = "12"; 678 if (strlen(y) == 2) 679 strncat(x, y, strlen(y)); 680 // expected-warning@-1 {{String concatenation function overflows the destination buffer}} 681 } 682 683 void strncat_overflow_3(char *y) { 684 char x[4] = "12"; 685 if (strlen(y) == 4) 686 strncat(x, y, 2); 687 // expected-warning@-1 {{String concatenation function overflows the destination buffer}} 688 } 689 #endif 690 691 void strncat_no_overflow_1(char *y) { 692 char x[5] = "12"; 693 if (strlen(y) == 2) 694 strncat(x, y, strlen(y)); // no-warning 695 } 696 697 void strncat_no_overflow_2(char *y) { 698 char x[4] = "12"; 699 if (strlen(y) == 4) 700 strncat(x, y, 1); // no-warning 701 } 702 703 void strncat_symbolic_dst_length(char *dst) { 704 strncat(dst, "1234", 5); 705 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 706 } 707 708 #ifndef SUPPRESS_OUT_OF_BOUND 709 void strncat_symbolic_src_length(char *src) { 710 char dst[8] = "1234"; 711 strncat(dst, src, 3); 712 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 713 714 char dst2[8] = "1234"; 715 strncat(dst2, src, 4); 716 // expected-warning@-1 {{String concatenation function overflows the destination buffer}} 717 } 718 719 void strncat_unknown_src_length(char *src, int offset) { 720 char dst[8] = "1234"; 721 strncat(dst, &src[offset], 3); 722 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 723 724 char dst2[8] = "1234"; 725 strncat(dst2, &src[offset], 4); 726 // expected-warning@-1 {{String concatenation function overflows the destination buffer}} 727 } 728 #endif 729 730 // There is no strncat_unknown_dst_length because if we can't get a symbolic 731 // length for the "before" strlen, we won't be able to set one for "after". 732 733 void strncat_symbolic_limit(unsigned limit) { 734 char dst[6] = "1234"; 735 char src[] = "567"; 736 strncat(dst, src, limit); // no-warning 737 738 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 739 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 740 } 741 742 void strncat_unknown_limit(float limit) { 743 char dst[6] = "1234"; 744 char src[] = "567"; 745 strncat(dst, src, (size_t)limit); // no-warning 746 747 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 748 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 749 } 750 751 void strncat_too_big(char *dst, char *src) { 752 // We assume this will never actually happen, so we don't get a warning. 753 if (strlen(dst) != (((size_t)0) - 2)) 754 return; 755 if (strlen(src) != 2) 756 return; 757 strncat(dst, src, 2); 758 } 759 760 void strncat_zero(char *src) { 761 char dst[] = "123"; 762 strncat(dst, src, 0); // no-warning 763 } 764 765 void strncat_empty() { 766 char dst[8] = "123"; 767 char src[] = ""; 768 strncat(dst, src, 4); // no-warning 769 } 770 771 //===----------------------------------------------------------------------=== 772 // strcmp() 773 //===----------------------------------------------------------------------=== 774 775 #define strcmp BUILTIN(strcmp) 776 int strcmp(const char * s1, const char * s2); 777 778 void strcmp_check_modelling() { 779 char *x = "aa"; 780 char *y = "a"; 781 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 782 clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}} 783 clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}} 784 785 clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}} 786 clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}} 787 clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}} 788 } 789 790 void strcmp_constant0() { 791 clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}} 792 } 793 794 void strcmp_constant_and_var_0() { 795 char *x = "123"; 796 clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}} 797 } 798 799 void strcmp_constant_and_var_1() { 800 char *x = "123"; 801 clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}} 802 } 803 804 void strcmp_0() { 805 char *x = "123"; 806 char *y = "123"; 807 clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}} 808 } 809 810 void strcmp_1() { 811 char *x = "234"; 812 char *y = "123"; 813 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 814 } 815 816 void strcmp_2() { 817 char *x = "123"; 818 char *y = "234"; 819 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 820 } 821 822 void strcmp_null_0() { 823 char *x = NULL; 824 char *y = "123"; 825 strcmp(x, y); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 826 } 827 828 void strcmp_null_1() { 829 char *x = "123"; 830 char *y = NULL; 831 strcmp(x, y); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 832 } 833 834 void strcmp_diff_length_0() { 835 char *x = "12345"; 836 char *y = "234"; 837 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 838 } 839 840 void strcmp_diff_length_1() { 841 char *x = "123"; 842 char *y = "23456"; 843 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 844 } 845 846 void strcmp_diff_length_2() { 847 char *x = "12345"; 848 char *y = "123"; 849 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 850 } 851 852 void strcmp_diff_length_3() { 853 char *x = "123"; 854 char *y = "12345"; 855 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 856 } 857 858 void strcmp_embedded_null () { 859 clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}} 860 } 861 862 void strcmp_unknown_arg (char *unknown) { 863 clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}} 864 } 865 866 union argument { 867 char *f; 868 }; 869 870 void function_pointer_cast_helper(char **a) { 871 strcmp("Hi", *a); // PR24951 crash 872 } 873 874 void strcmp_union_function_pointer_cast(union argument a) { 875 void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper; 876 877 fPtr(&a); 878 } 879 880 int strcmp_null_argument(char *a) { 881 char *b = 0; 882 // Do not warn about the first argument! 883 return strcmp(a, b); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 884 } 885 886 //===----------------------------------------------------------------------=== 887 // strncmp() 888 //===----------------------------------------------------------------------=== 889 890 #define strncmp BUILTIN(strncmp) 891 int strncmp(const char *s1, const char *s2, size_t n); 892 893 void strncmp_check_modelling() { 894 char *x = "aa"; 895 char *y = "a"; 896 clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}} 897 clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 898 clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 899 900 clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}} 901 clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 902 clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 903 } 904 905 void strncmp_constant0() { 906 clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}} 907 } 908 909 void strncmp_constant_and_var_0() { 910 char *x = "123"; 911 clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}} 912 } 913 914 void strncmp_constant_and_var_1() { 915 char *x = "123"; 916 clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}} 917 } 918 919 void strncmp_0() { 920 char *x = "123"; 921 char *y = "123"; 922 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 923 } 924 925 void strncmp_1() { 926 char *x = "234"; 927 char *y = "123"; 928 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 929 } 930 931 void strncmp_2() { 932 char *x = "123"; 933 char *y = "234"; 934 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 935 } 936 937 void strncmp_null_0() { 938 char *x = NULL; 939 char *y = "123"; 940 strncmp(x, y, 3); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 941 } 942 943 void strncmp_null_1() { 944 char *x = "123"; 945 char *y = NULL; 946 strncmp(x, y, 3); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 947 } 948 949 void strncmp_diff_length_0() { 950 char *x = "12345"; 951 char *y = "234"; 952 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 953 } 954 955 void strncmp_diff_length_1() { 956 char *x = "123"; 957 char *y = "23456"; 958 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 959 } 960 961 void strncmp_diff_length_2() { 962 char *x = "12345"; 963 char *y = "123"; 964 clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}} 965 } 966 967 void strncmp_diff_length_3() { 968 char *x = "123"; 969 char *y = "12345"; 970 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 971 } 972 973 void strncmp_diff_length_4() { 974 char *x = "123"; 975 char *y = "12345"; 976 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 977 } 978 979 void strncmp_diff_length_5() { 980 char *x = "012"; 981 char *y = "12345"; 982 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 983 } 984 985 void strncmp_diff_length_6() { 986 char *x = "234"; 987 char *y = "12345"; 988 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 989 } 990 991 void strncmp_embedded_null () { 992 clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 993 } 994 995 int strncmp_null_argument(char *a, size_t n) { 996 char *b = 0; 997 // Do not warn about the first argument! 998 return strncmp(a, b, n); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 999 } 1000 1001 //===----------------------------------------------------------------------=== 1002 // strcasecmp() 1003 //===----------------------------------------------------------------------=== 1004 1005 #define strcasecmp BUILTIN(strcasecmp) 1006 int strcasecmp(const char *s1, const char *s2); 1007 1008 void strcasecmp_check_modelling() { 1009 char *x = "aa"; 1010 char *y = "a"; 1011 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1012 clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}} 1013 clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}} 1014 1015 clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}} 1016 clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}} 1017 clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}} 1018 } 1019 1020 void strcasecmp_constant0() { 1021 clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}} 1022 } 1023 1024 void strcasecmp_constant_and_var_0() { 1025 char *x = "abc"; 1026 clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}} 1027 } 1028 1029 void strcasecmp_constant_and_var_1() { 1030 char *x = "abc"; 1031 clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}} 1032 } 1033 1034 void strcasecmp_0() { 1035 char *x = "abc"; 1036 char *y = "Abc"; 1037 clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}} 1038 } 1039 1040 void strcasecmp_1() { 1041 char *x = "Bcd"; 1042 char *y = "abc"; 1043 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1044 } 1045 1046 void strcasecmp_2() { 1047 char *x = "abc"; 1048 char *y = "Bcd"; 1049 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1050 } 1051 1052 void strcasecmp_null_0() { 1053 char *x = NULL; 1054 char *y = "123"; 1055 strcasecmp(x, y); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 1056 } 1057 1058 void strcasecmp_null_1() { 1059 char *x = "123"; 1060 char *y = NULL; 1061 strcasecmp(x, y); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1062 } 1063 1064 void strcasecmp_diff_length_0() { 1065 char *x = "abcde"; 1066 char *y = "aBd"; 1067 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1068 } 1069 1070 void strcasecmp_diff_length_1() { 1071 char *x = "abc"; 1072 char *y = "aBdef"; 1073 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1074 } 1075 1076 void strcasecmp_diff_length_2() { 1077 char *x = "aBcDe"; 1078 char *y = "abc"; 1079 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1080 } 1081 1082 void strcasecmp_diff_length_3() { 1083 char *x = "aBc"; 1084 char *y = "abcde"; 1085 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1086 } 1087 1088 void strcasecmp_embedded_null () { 1089 clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}} 1090 } 1091 1092 int strcasecmp_null_argument(char *a) { 1093 char *b = 0; 1094 // Do not warn about the first argument! 1095 return strcasecmp(a, b); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1096 } 1097 1098 //===----------------------------------------------------------------------=== 1099 // strncasecmp() 1100 //===----------------------------------------------------------------------=== 1101 1102 #define strncasecmp BUILTIN(strncasecmp) 1103 int strncasecmp(const char *s1, const char *s2, size_t n); 1104 1105 void strncasecmp_check_modelling() { 1106 char *x = "aa"; 1107 char *y = "a"; 1108 clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}} 1109 clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 1110 clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 1111 1112 clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}} 1113 clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 1114 clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 1115 } 1116 1117 void strncasecmp_constant0() { 1118 clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}} 1119 } 1120 1121 void strncasecmp_constant_and_var_0() { 1122 char *x = "abc"; 1123 clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}} 1124 } 1125 1126 void strncasecmp_constant_and_var_1() { 1127 char *x = "abc"; 1128 clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}} 1129 } 1130 1131 void strncasecmp_0() { 1132 char *x = "abc"; 1133 char *y = "Abc"; 1134 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1135 } 1136 1137 void strncasecmp_1() { 1138 char *x = "Bcd"; 1139 char *y = "abc"; 1140 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1141 } 1142 1143 void strncasecmp_2() { 1144 char *x = "abc"; 1145 char *y = "Bcd"; 1146 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1147 } 1148 1149 void strncasecmp_null_0() { 1150 char *x = NULL; 1151 char *y = "123"; 1152 strncasecmp(x, y, 3); // expected-warning{{Null pointer passed as 1st argument to string comparison function}} 1153 } 1154 1155 void strncasecmp_null_1() { 1156 char *x = "123"; 1157 char *y = NULL; 1158 strncasecmp(x, y, 3); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1159 } 1160 1161 void strncasecmp_diff_length_0() { 1162 char *x = "abcde"; 1163 char *y = "aBd"; 1164 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1165 } 1166 1167 void strncasecmp_diff_length_1() { 1168 char *x = "abc"; 1169 char *y = "aBdef"; 1170 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1171 } 1172 1173 void strncasecmp_diff_length_2() { 1174 char *x = "aBcDe"; 1175 char *y = "abc"; 1176 clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}} 1177 } 1178 1179 void strncasecmp_diff_length_3() { 1180 char *x = "aBc"; 1181 char *y = "abcde"; 1182 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1183 } 1184 1185 void strncasecmp_diff_length_4() { 1186 char *x = "abcde"; 1187 char *y = "aBc"; 1188 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1189 } 1190 1191 void strncasecmp_diff_length_5() { 1192 char *x = "abcde"; 1193 char *y = "aBd"; 1194 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1195 } 1196 1197 void strncasecmp_diff_length_6() { 1198 char *x = "aBDe"; 1199 char *y = "abc"; 1200 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1201 } 1202 1203 void strncasecmp_embedded_null () { 1204 clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 1205 } 1206 1207 int strncasecmp_null_argument(char *a, size_t n) { 1208 char *b = 0; 1209 // Do not warn about the first argument! 1210 return strncasecmp(a, b, n); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}} 1211 } 1212 1213 //===----------------------------------------------------------------------=== 1214 // strsep() 1215 //===----------------------------------------------------------------------=== 1216 1217 char *strsep(char **stringp, const char *delim); 1218 1219 void strsep_null_delim(char *s) { 1220 strsep(&s, NULL); // expected-warning{{Null pointer passed as 2nd argument to strsep()}} 1221 } 1222 1223 void strsep_null_search() { 1224 strsep(NULL, ""); // expected-warning{{Null pointer passed as 1st argument to strsep()}} 1225 } 1226 1227 void strsep_return_original_pointer(char *s) { 1228 char *original = s; 1229 char *result = strsep(&s, ""); // no-warning 1230 clang_analyzer_eval(original == result); // expected-warning{{TRUE}} 1231 } 1232 1233 void strsep_null_string() { 1234 char *s = NULL; 1235 char *result = strsep(&s, ""); // no-warning 1236 clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}} 1237 } 1238 1239 void strsep_changes_input_pointer(char *s) { 1240 char *original = s; 1241 strsep(&s, ""); // no-warning 1242 clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}} 1243 clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}} 1244 1245 // Check that the value is symbolic. 1246 if (s == NULL) { 1247 clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}} 1248 } 1249 } 1250 1251 void strsep_changes_input_string() { 1252 char str[] = "abc"; 1253 1254 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}} 1255 1256 char *s = str; 1257 strsep(&s, "b"); // no-warning 1258 1259 // The real strsep will change the first delimiter it finds into a NUL 1260 // character. For now, we just model the invalidation. 1261 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} 1262 } 1263 1264 //===----------------------------------------------------------------------=== 1265 // memset() / explicit_bzero() / bzero() 1266 //===----------------------------------------------------------------------=== 1267 1268 void *memset(void *dest, int ch, size_t count); 1269 1270 void bzero(void *dst, size_t count); 1271 void explicit_bzero(void *dest, size_t count); 1272 1273 void *malloc(size_t size); 1274 void free(void *); 1275 1276 void memset1_char_array_null() { 1277 char str[] = "abcd"; 1278 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1279 memset(str, '\0', 2); 1280 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1281 } 1282 1283 void memset2_char_array_null() { 1284 char str[] = "abcd"; 1285 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1286 memset(str, '\0', strlen(str) + 1); 1287 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1288 clang_analyzer_eval(str[2] == 0); // expected-warning{{TRUE}} 1289 } 1290 1291 void memset3_char_malloc_null() { 1292 char *str = (char *)malloc(10 * sizeof(char)); 1293 memset(str + 1, '\0', 8); 1294 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1295 free(str); 1296 } 1297 1298 void memset4_char_malloc_null() { 1299 char *str = (char *)malloc(10 * sizeof(char)); 1300 //void *str = malloc(10 * sizeof(char)); 1301 memset(str, '\0', 10); 1302 clang_analyzer_eval(str[1] == 0); // expected-warning{{TRUE}} 1303 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1304 free(str); 1305 } 1306 1307 #ifdef SUPPRESS_OUT_OF_BOUND 1308 void memset5_char_malloc_overflow_null() { 1309 char *str = (char *)malloc(10 * sizeof(char)); 1310 memset(str, '\0', 12); 1311 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1312 free(str); 1313 } 1314 #endif 1315 1316 void memset6_char_array_nonnull() { 1317 char str[] = "abcd"; 1318 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1319 memset(str, '0', 2); 1320 clang_analyzer_eval(str[0] == 'a'); // expected-warning{{UNKNOWN}} 1321 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{UNKNOWN}} 1322 } 1323 1324 #ifdef SUPPRESS_OUT_OF_BOUND 1325 void memset8_char_array_nonnull() { 1326 char str[5] = "abcd"; 1327 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1328 memset(str, '0', 10); // expected-warning{{'memset' will always overflow; destination buffer has size 5, but size argument is 10}} 1329 clang_analyzer_eval(str[0] != '0'); // expected-warning{{UNKNOWN}} 1330 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1331 clang_analyzer_eval(strlen(str) < 10); // expected-warning{{FALSE}} 1332 } 1333 #endif 1334 1335 struct POD_memset { 1336 int num; 1337 char c; 1338 }; 1339 1340 void memset10_struct() { 1341 struct POD_memset pod; 1342 char *str = (char *)&pod; 1343 pod.num = 1; 1344 pod.c = 1; 1345 clang_analyzer_eval(pod.num == 0); // expected-warning{{FALSE}} 1346 memset(str, 0, sizeof(struct POD_memset)); 1347 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1348 } 1349 1350 #ifdef SUPPRESS_OUT_OF_BOUND 1351 void memset11_struct_field() { 1352 struct POD_memset pod; 1353 pod.num = 1; 1354 pod.c = '1'; 1355 memset(&pod.num, 0, sizeof(struct POD_memset)); 1356 1357 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1358 clang_analyzer_eval(pod.c == '\0'); // expected-warning{{TRUE}} 1359 } 1360 1361 void memset12_struct_field() { 1362 struct POD_memset pod; 1363 pod.num = 1; 1364 pod.c = '1'; 1365 memset(&pod.c, 0, sizeof(struct POD_memset)); // expected-warning {{'memset' will always overflow; destination buffer has size 4, but size argument is 8}} 1366 clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}} 1367 clang_analyzer_eval(pod.c == 0); // expected-warning{{UNKNOWN}} 1368 } 1369 1370 union U_memset { 1371 int i; 1372 double d; 1373 char c; 1374 }; 1375 1376 void memset13_union_field() { 1377 union U_memset u; 1378 u.i = 5; 1379 memset(&u.i, '\0', sizeof(union U_memset)); 1380 // Note: This should be TRUE, analyzer can't handle union perfectly now. 1381 clang_analyzer_eval(u.d == 0); // expected-warning{{UNKNOWN}} 1382 } 1383 #endif 1384 1385 void memset14_region_cast() { 1386 char *str = (char *)malloc(10 * sizeof(int)); 1387 int *array = (int *)str; 1388 memset(array, 0, 10 * sizeof(int)); 1389 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{TRUE}} 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 void memset15_region_cast() { 1396 char *str = (char *)malloc(10 * sizeof(int)); 1397 int *array = (int *)str; 1398 memset(array, 0, 5 * sizeof(int)); 1399 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{UNKNOWN}} 1400 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1401 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1402 free(str); 1403 } 1404 1405 int memset20_scalar() { 1406 int *x = malloc(sizeof(int)); 1407 *x = 10; 1408 memset(x, 0, sizeof(int)); 1409 int num = 1 / *x; // expected-warning{{Division by zero}} 1410 free(x); 1411 return num; 1412 } 1413 1414 int memset21_scalar() { 1415 int *x = malloc(sizeof(int)); 1416 memset(x, 0, 1); 1417 int num = 1 / *x; 1418 free(x); 1419 return num; 1420 } 1421 1422 void memset22_array() { 1423 int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 1424 clang_analyzer_eval(array[1] == 2); // expected-warning{{TRUE}} 1425 memset(array, 0, sizeof(array)); 1426 clang_analyzer_eval(array[1] == 0); // expected-warning{{TRUE}} 1427 } 1428 1429 void memset23_array_pod_object() { 1430 struct POD_memset array[10]; 1431 array[1].num = 10; 1432 array[1].c = 'c'; 1433 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1434 memset(&array[1], 0, sizeof(struct POD_memset)); 1435 clang_analyzer_eval(array[1].num == 0); // expected-warning{{UNKNOWN}} 1436 } 1437 1438 void memset24_array_pod_object() { 1439 struct POD_memset array[10]; 1440 array[1].num = 10; 1441 array[1].c = 'c'; 1442 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1443 memset(array, 0, sizeof(array)); 1444 clang_analyzer_eval(array[1].num == 0); // expected-warning{{TRUE}} 1445 } 1446 1447 void memset25_symbol(char c) { 1448 char array[10] = {1}; 1449 if (c != 0) 1450 return; 1451 1452 memset(array, c, 10); 1453 1454 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1455 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1456 } 1457 1458 void memset26_upper_UCHAR_MAX() { 1459 char array[10] = {1}; 1460 1461 memset(array, 1024, 10); 1462 1463 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1464 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1465 } 1466 1467 void bzero1_null() { 1468 char *a = NULL; 1469 1470 bzero(a, 10); // expected-warning{{Null pointer passed as 1st argument to memory clearance function}} 1471 } 1472 1473 void bzero2_char_array_null() { 1474 char str[] = "abcd"; 1475 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1476 bzero(str, 2); 1477 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1478 } 1479 1480 void bzero3_char_ptr_null() { 1481 char *str = "abcd"; 1482 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1483 bzero(str + 2, 2); 1484 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{FALSE}} 1485 } 1486 1487 void explicit_bzero1_null() { 1488 char *a = NULL; 1489 1490 explicit_bzero(a, 10); // expected-warning{{Null pointer passed as 1st argument to memory clearance function}} 1491 } 1492 1493 void explicit_bzero2_clear_mypassword() { 1494 char passwd[7] = "passwd"; 1495 1496 explicit_bzero(passwd, sizeof(passwd)); // no-warning 1497 1498 clang_analyzer_eval(strlen(passwd) == 0); // expected-warning{{TRUE}} 1499 clang_analyzer_eval(passwd[0] == '\0'); // expected-warning{{TRUE}} 1500 } 1501 1502 void explicit_bzero3_out_ofbound() { 1503 char *privkey = (char *)malloc(7); 1504 const char newprivkey[10] = "mysafekey"; 1505 1506 strcpy(privkey, "random"); 1507 explicit_bzero(privkey, sizeof(newprivkey)); 1508 #ifndef SUPPRESS_OUT_OF_BOUND 1509 // expected-warning@-2 {{Memory clearance function overflows the destination buffer}} 1510 #endif 1511 clang_analyzer_eval(privkey[0] == '\0'); 1512 #ifdef SUPPRESS_OUT_OF_BOUND 1513 // expected-warning@-2 {{UNKNOWN}} 1514 #endif 1515 free(privkey); 1516 } 1517 1518 //===----------------------------------------------------------------------=== 1519 // FIXMEs 1520 //===----------------------------------------------------------------------=== 1521 1522 // The analyzer_eval call below should evaluate to true. We are being too 1523 // aggressive in marking the (length of) src symbol dead. The length of dst 1524 // depends on src. This could be explicitly specified in the checker or the 1525 // logic for handling MetadataSymbol in SymbolManager needs to change. 1526 void strcat_symbolic_src_length(char *src) { 1527 char dst[8] = "1234"; 1528 strcat(dst, src); 1529 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}} 1530 } 1531 1532 1533 // The analyzer_eval call below should evaluate to true. Most likely the same 1534 // issue as the test above. 1535 void strncpy_exactly_matching_buffer2(char *y) { 1536 if (strlen(y) >= 4) 1537 return; 1538 1539 char x[4]; 1540 strncpy(x, y, 4); // no-warning 1541 1542 // This time, we know that y fits in x anyway. 1543 clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}} 1544 } 1545 1546 void memset7_char_array_nonnull() { 1547 char str[5] = "abcd"; 1548 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1549 memset(str, '0', 5); 1550 // FIXME: This should be TRUE. 1551 clang_analyzer_eval(str[0] == '0'); // expected-warning{{UNKNOWN}} 1552 clang_analyzer_eval(strlen(str) >= 5); // expected-warning{{TRUE}} 1553 } 1554 1555 void memset16_region_cast() { 1556 char *str = (char *)malloc(10 * sizeof(int)); 1557 int *array = (int *)str; 1558 memset(array, '0', 10 * sizeof(int)); 1559 // FIXME: This should be TRUE. 1560 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1561 clang_analyzer_eval(strlen((char *)array) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1562 clang_analyzer_eval(strlen(str) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1563 free(str); 1564 } 1565 1566 #ifdef SUPPRESS_OUT_OF_BOUND 1567 void memset17_region_cast() { 1568 char *str = (char *)malloc(10 * sizeof(int)); 1569 int *array = (int *)str; 1570 memset(array, '0', 12 * sizeof(int)); 1571 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1572 clang_analyzer_eval(strlen((char *)array) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1573 clang_analyzer_eval(strlen(str) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1574 free(str); 1575 } 1576 1577 void memset18_memset_multiple_times() { 1578 char *str = (char *)malloc(10 * sizeof(char)); 1579 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1580 1581 memset(str + 2, '\0', 10 * sizeof(char)); 1582 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1583 clang_analyzer_eval(str[1] == '\0'); // expected-warning{{UNKNOWN}} 1584 1585 memset(str, '0', 10 * sizeof(char)); 1586 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1587 // FIXME: This should be TRUE. 1588 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1589 1590 free(str); 1591 } 1592 1593 void memset19_memset_multiple_times() { 1594 char *str = (char *)malloc(10 * sizeof(char)); 1595 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1596 1597 memset(str, '0', 10 * sizeof(char)); 1598 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1599 // FIXME: This should be TRUE. 1600 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1601 1602 memset(str + 2, '\0', 10 * sizeof(char)); 1603 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{UNKNOWN}} 1604 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1605 1606 free(str); 1607 } 1608 #endif 1609 1610 // The analyzer does not support binding a symbol with default binding. 1611 void memset27_symbol(char c) { 1612 char array[10] = {0}; 1613 if (c < 10) 1614 return; 1615 1616 memset(array, c, 10); 1617 1618 clang_analyzer_eval(strlen(array) >= 10); // expected-warning{{TRUE}} 1619 // FIXME: This should be TRUE. 1620 clang_analyzer_eval(array[4] >= 10); // expected-warning{{UNKNOWN}} 1621 } 1622 1623 void memset28() { 1624 short x; 1625 memset(&x, 1, sizeof(short)); 1626 // This should be true. 1627 clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}} 1628 } 1629 1630 void memset29_plain_int_zero() { 1631 short x; 1632 memset(&x, 0, sizeof(short)); 1633 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} 1634 } 1635 1636 void test_memset_chk() { 1637 int x; 1638 __builtin___memset_chk(&x, 0, sizeof(x), __builtin_object_size(&x, 0)); 1639 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} 1640 } 1641