1 // RUN: %clang_analyze_cc1 -verify %s \ 2 // RUN: -analyzer-checker=core \ 3 // RUN: -analyzer-checker=unix.cstring \ 4 // RUN: -analyzer-checker=alpha.unix.cstring \ 5 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \ 6 // RUN: -analyzer-checker=debug.ExprInspection \ 7 // RUN: -analyzer-config eagerly-assume=false 8 // 9 // RUN: %clang_analyze_cc1 -verify %s -DUSE_BUILTINS \ 10 // RUN: -analyzer-checker=core \ 11 // RUN: -analyzer-checker=unix.cstring \ 12 // RUN: -analyzer-checker=alpha.unix.cstring \ 13 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \ 14 // RUN: -analyzer-checker=debug.ExprInspection \ 15 // RUN: -analyzer-config eagerly-assume=false 16 // 17 // RUN: %clang_analyze_cc1 -verify %s -DVARIANT \ 18 // RUN: -analyzer-checker=core \ 19 // RUN: -analyzer-checker=unix.cstring \ 20 // RUN: -analyzer-checker=alpha.unix.cstring \ 21 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \ 22 // RUN: -analyzer-checker=debug.ExprInspection \ 23 // RUN: -analyzer-config eagerly-assume=false 24 // 25 // RUN: %clang_analyze_cc1 -verify %s -DUSE_BUILTINS -DVARIANT \ 26 // RUN: -analyzer-checker=core \ 27 // RUN: -analyzer-checker=unix.cstring \ 28 // RUN: -analyzer-checker=alpha.unix.cstring \ 29 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \ 30 // RUN: -analyzer-checker=debug.ExprInspection \ 31 // RUN: -analyzer-config eagerly-assume=false 32 33 //===----------------------------------------------------------------------=== 34 // Declarations 35 //===----------------------------------------------------------------------=== 36 37 // Some functions are so similar to each other that they follow the same code 38 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is 39 // defined, make sure to use the variants instead to make sure they are still 40 // checked by the analyzer. 41 42 // Some functions are implemented as builtins. These should be #defined as 43 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined. 44 45 // Functions that have variants and are also available as builtins should be 46 // declared carefully! See memcpy() for an example. 47 48 #ifdef USE_BUILTINS 49 # define BUILTIN(f) __builtin_ ## f 50 #else /* USE_BUILTINS */ 51 # define BUILTIN(f) f 52 #endif /* USE_BUILTINS */ 53 54 typedef typeof(sizeof(int)) size_t; 55 56 void clang_analyzer_eval(int); 57 58 //===----------------------------------------------------------------------=== 59 // memcpy() 60 //===----------------------------------------------------------------------=== 61 62 #ifdef VARIANT 63 64 #define __memcpy_chk BUILTIN(__memcpy_chk) 65 void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n, 66 size_t destlen); 67 68 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1) 69 70 #else /* VARIANT */ 71 72 #define memcpy BUILTIN(memcpy) 73 void *memcpy(void *restrict s1, const void *restrict s2, size_t n); 74 75 #endif /* VARIANT */ 76 77 78 void memcpy0 (void) { 79 char src[] = {1, 2, 3, 4}; 80 char dst[4] = {0}; 81 82 memcpy(dst, src, 4); // no-warning 83 84 clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}} 85 86 // If we actually model the copy, we can make this known. 87 // The important thing for now is that the old value has been invalidated. 88 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 89 } 90 91 void memcpy1 (void) { 92 char src[] = {1, 2, 3, 4}; 93 char dst[10]; 94 95 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 96 } 97 98 void memcpy2 (void) { 99 char src[] = {1, 2, 3, 4}; 100 char dst[1]; 101 102 memcpy(dst, src, 4); // expected-warning {{Memory copy function overflows the destination buffer}} 103 #ifndef VARIANT 104 // expected-warning@-2 {{memcpy' will always overflow; destination buffer has size 1, but size argument is 4}} 105 #endif 106 } 107 108 void memcpy3 (void) { 109 char src[] = {1, 2, 3, 4}; 110 char dst[3]; 111 112 memcpy(dst+1, src+2, 2); // no-warning 113 } 114 115 void memcpy4 (void) { 116 char src[] = {1, 2, 3, 4}; 117 char dst[10]; 118 119 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 120 } 121 122 void memcpy5(void) { 123 char src[] = {1, 2, 3, 4}; 124 char dst[3]; 125 126 memcpy(dst + 2, src + 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}} 127 #ifndef VARIANT 128 // expected-warning@-2{{memcpy' will always overflow; destination buffer has size 1, but size argument is 2}} 129 #endif 130 } 131 132 void memcpy6(void) { 133 int a[4] = {0}; 134 memcpy(a, a, 8); // expected-warning{{overlapping}} 135 } 136 137 void memcpy7(void) { 138 int a[4] = {0}; 139 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 140 } 141 142 void memcpy8(void) { 143 int a[4] = {0}; 144 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 145 } 146 147 void memcpy9(void) { 148 int a[4] = {0}; 149 memcpy(a+2, a+1, 4); // no-warning 150 memcpy(a+1, a+2, 4); // no-warning 151 } 152 153 void memcpy10(void) { 154 char a[4] = {0}; 155 memcpy(0, a, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}} 156 } 157 158 void memcpy11(void) { 159 char a[4] = {0}; 160 memcpy(a, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}} 161 } 162 163 void memcpy12(void) { 164 char a[4] = {0}; 165 memcpy(0, a, 0); // no-warning 166 } 167 168 void memcpy13(void) { 169 char a[4] = {0}; 170 memcpy(a, 0, 0); // no-warning 171 } 172 173 void memcpy_unknown_size (size_t n) { 174 char a[4], b[4] = {1}; 175 clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}} 176 } 177 178 void memcpy_unknown_size_warn (size_t n) { 179 char a[4]; 180 void *result = memcpy(a, 0, n); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}} 181 clang_analyzer_eval(result == a); // no-warning (above is fatal) 182 } 183 184 //===----------------------------------------------------------------------=== 185 // mempcpy() 186 //===----------------------------------------------------------------------=== 187 188 #ifdef VARIANT 189 190 #define __mempcpy_chk BUILTIN(__mempcpy_chk) 191 void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n, 192 size_t destlen); 193 194 #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1) 195 196 #else /* VARIANT */ 197 198 #define mempcpy BUILTIN(mempcpy) 199 void *mempcpy(void *restrict s1, const void *restrict s2, size_t n); 200 201 #endif /* VARIANT */ 202 203 204 void mempcpy0 (void) { 205 char src[] = {1, 2, 3, 4}; 206 char dst[5] = {0}; 207 208 mempcpy(dst, src, 4); // no-warning 209 210 clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}} 211 212 // If we actually model the copy, we can make this known. 213 // The important thing for now is that the old value has been invalidated. 214 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 215 } 216 217 void mempcpy1 (void) { 218 char src[] = {1, 2, 3, 4}; 219 char dst[10]; 220 221 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 222 } 223 224 void mempcpy2 (void) { 225 char src[] = {1, 2, 3, 4}; 226 char dst[1]; 227 228 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows the destination buffer}} 229 #ifndef VARIANT 230 // expected-warning@-2{{'mempcpy' will always overflow; destination buffer has size 1, but size argument is 4}} 231 #endif 232 } 233 234 void mempcpy3 (void) { 235 char src[] = {1, 2, 3, 4}; 236 char dst[3]; 237 238 mempcpy(dst+1, src+2, 2); // no-warning 239 } 240 241 void mempcpy4 (void) { 242 char src[] = {1, 2, 3, 4}; 243 char dst[10]; 244 245 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 246 } 247 248 void mempcpy5(void) { 249 char src[] = {1, 2, 3, 4}; 250 char dst[3]; 251 252 mempcpy(dst + 2, src + 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}} 253 #ifndef VARIANT 254 // expected-warning@-2{{'mempcpy' will always overflow; destination buffer has size 1, but size argument is 2}} 255 #endif 256 } 257 258 void mempcpy6(void) { 259 int a[4] = {0}; 260 mempcpy(a, a, 8); // expected-warning{{overlapping}} 261 } 262 263 void mempcpy7(void) { 264 int a[4] = {0}; 265 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 266 } 267 268 void mempcpy8(void) { 269 int a[4] = {0}; 270 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 271 } 272 273 void mempcpy9(void) { 274 int a[4] = {0}; 275 mempcpy(a+2, a+1, 4); // no-warning 276 mempcpy(a+1, a+2, 4); // no-warning 277 } 278 279 void mempcpy10(void) { 280 char a[4] = {0}; 281 mempcpy(0, a, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}} 282 } 283 284 void mempcpy11(void) { 285 char a[4] = {0}; 286 mempcpy(a, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}} 287 } 288 289 void mempcpy12(void) { 290 char a[4] = {0}; 291 mempcpy(0, a, 0); // no-warning 292 } 293 294 void mempcpy13(void) { 295 char a[4] = {0}; 296 mempcpy(a, 0, 0); // no-warning 297 } 298 299 void mempcpy14(void) { 300 int src[] = {1, 2, 3, 4}; 301 int dst[5] = {0}; 302 int *p; 303 304 p = mempcpy(dst, src, 4 * sizeof(int)); 305 306 clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}} 307 } 308 309 struct st { 310 int i; 311 int j; 312 }; 313 314 void mempcpy15(void) { 315 struct st s1 = {0}; 316 struct st s2; 317 struct st *p1; 318 struct st *p2; 319 320 p1 = (&s2) + 1; 321 p2 = mempcpy(&s2, &s1, sizeof(struct st)); 322 323 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}} 324 } 325 326 void mempcpy16(void) { 327 struct st s1[10] = {{0}}; 328 struct st s2[10]; 329 struct st *p1; 330 struct st *p2; 331 332 p1 = (&s2[0]) + 5; 333 p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st)); 334 335 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}} 336 } 337 338 void mempcpy_unknown_size_warn (size_t n) { 339 char a[4]; 340 void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}} 341 clang_analyzer_eval(result == a); // no-warning (above is fatal) 342 } 343 344 void mempcpy_unknownable_size (char *src, float n) { 345 char a[4]; 346 // This used to crash because we don't model floats. 347 mempcpy(a, src, (size_t)n); 348 } 349 350 //===----------------------------------------------------------------------=== 351 // memmove() 352 //===----------------------------------------------------------------------=== 353 354 #ifdef VARIANT 355 356 #define __memmove_chk BUILTIN(__memmove_chk) 357 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 358 359 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 360 361 #else /* VARIANT */ 362 363 #define memmove BUILTIN(memmove) 364 void *memmove(void *s1, const void *s2, size_t n); 365 366 #endif /* VARIANT */ 367 368 369 void memmove0 (void) { 370 char src[] = {1, 2, 3, 4}; 371 char dst[4] = {0}; 372 373 memmove(dst, src, 4); // no-warning 374 375 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}} 376 377 // If we actually model the copy, we can make this known. 378 // The important thing for now is that the old value has been invalidated. 379 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 380 } 381 382 void memmove1 (void) { 383 char src[] = {1, 2, 3, 4}; 384 char dst[10]; 385 386 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 387 } 388 389 void memmove2 (void) { 390 char src[] = {1, 2, 3, 4}; 391 char dst[1]; 392 393 memmove(dst, src, 4); // expected-warning{{Memory copy function overflows the destination buffer}} 394 #ifndef VARIANT 395 // expected-warning@-2{{memmove' will always overflow; destination buffer has size 1, but size argument is 4}} 396 #endif 397 } 398 399 //===----------------------------------------------------------------------=== 400 // memcmp() 401 //===----------------------------------------------------------------------=== 402 403 #ifdef VARIANT 404 405 #define bcmp BUILTIN(bcmp) 406 int bcmp(const void *s1, const void *s2, size_t n); 407 #define memcmp bcmp 408 // 409 #else /* VARIANT */ 410 411 #define memcmp BUILTIN(memcmp) 412 int memcmp(const void *s1, const void *s2, size_t n); 413 414 #endif /* VARIANT */ 415 416 417 void memcmp0 (void) { 418 char a[] = {1, 2, 3, 4}; 419 char b[4] = { 0 }; 420 421 memcmp(a, b, 4); // no-warning 422 } 423 424 void memcmp1 (void) { 425 char a[] = {1, 2, 3, 4}; 426 char b[10] = { 0 }; 427 428 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 429 } 430 431 void memcmp2 (void) { 432 char a[] = {1, 2, 3, 4}; 433 char b[1] = { 0 }; 434 435 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 436 } 437 438 void memcmp3 (void) { 439 char a[] = {1, 2, 3, 4}; 440 441 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}} 442 } 443 444 void memcmp4 (char *input) { 445 char a[] = {1, 2, 3, 4}; 446 447 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}} 448 } 449 450 void memcmp5 (char *input) { 451 char a[] = {1, 2, 3, 4}; 452 453 clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}} 454 clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}} 455 clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}} 456 } 457 458 void memcmp6 (char *a, char *b, size_t n) { 459 int result = memcmp(a, b, n); 460 if (result != 0) 461 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}} 462 // else 463 // analyzer_assert_unknown(n == 0); 464 465 // We can't do the above comparison because n has already been constrained. 466 // On one path n == 0, on the other n != 0. 467 } 468 469 int memcmp7 (char *a, size_t x, size_t y, size_t n) { 470 // We used to crash when either of the arguments was unknown. 471 return memcmp(a, &a[x*y], n) + 472 memcmp(&a[x*y], a, n); 473 } 474 475 int memcmp8(char *a, size_t n) { 476 char *b = 0; 477 // Do not warn about the first argument! 478 return memcmp(a, b, n); // expected-warning{{Null pointer passed as 2nd argument to memory comparison function}} 479 } 480 481 //===----------------------------------------------------------------------=== 482 // bcopy() 483 //===----------------------------------------------------------------------=== 484 485 #define bcopy BUILTIN(bcopy) 486 // __builtin_bcopy is not defined with const in Builtins.def. 487 void bcopy(/*const*/ void *s1, void *s2, size_t n); 488 489 490 void bcopy0 (void) { 491 char src[] = {1, 2, 3, 4}; 492 char dst[4] = {0}; 493 494 bcopy(src, dst, 4); // no-warning 495 496 // If we actually model the copy, we can make this known. 497 // The important thing for now is that the old value has been invalidated. 498 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 499 } 500 501 void bcopy1 (void) { 502 char src[] = {1, 2, 3, 4}; 503 char dst[10]; 504 505 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 506 } 507 508 void bcopy2 (void) { 509 char src[] = {1, 2, 3, 4}; 510 char dst[1]; 511 512 bcopy(src, dst, 4); // expected-warning{{overflow}} 513 } 514 515 void *malloc(size_t); 516 void free(void *); 517 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) { 518 char *bytes = malloc(sizeof(char) * (length + 1)); 519 memcpy(bytes, input, length); 520 char x = bytes[0]; // no warning 521 free(bytes); 522 return x; 523 } 524 525 struct S { 526 char f; 527 }; 528 529 void nocrash_on_locint_offset(void *addr, void* from, struct S s) { 530 size_t iAdd = (size_t) addr; 531 memcpy(((void *) &(s.f)), from, iAdd); 532 } 533