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