1 //= CStringChecker.cpp - Checks calls to C string functions --------*- C++ -*-// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This defines CStringChecker, which is an assortment of checks on calls 11 // to functions in <string.h>. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "ClangSACheckers.h" 16 #include "clang/StaticAnalyzer/Core/Checker.h" 17 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 18 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 19 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 21 #include "llvm/ADT/SmallString.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/ADT/StringSwitch.h" 24 25 using namespace clang; 26 using namespace ento; 27 28 namespace { 29 class CStringChecker : public Checker< eval::Call, 30 check::PreStmt<DeclStmt>, 31 check::LiveSymbols, 32 check::DeadSymbols, 33 check::RegionChanges 34 > { 35 mutable llvm::OwningPtr<BugType> BT_Null, BT_Bounds, 36 BT_Overlap, BT_NotCString, 37 BT_AdditionOverflow; 38 mutable const char *CurrentFunctionDescription; 39 40 public: 41 static void *getTag() { static int tag; return &tag; } 42 43 bool evalCall(const CallExpr *CE, CheckerContext &C) const; 44 void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const; 45 void checkLiveSymbols(ProgramStateRef state, SymbolReaper &SR) const; 46 void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; 47 bool wantsRegionChangeUpdate(ProgramStateRef state) const; 48 49 ProgramStateRef 50 checkRegionChanges(ProgramStateRef state, 51 const StoreManager::InvalidatedSymbols *, 52 ArrayRef<const MemRegion *> ExplicitRegions, 53 ArrayRef<const MemRegion *> Regions) const; 54 55 typedef void (CStringChecker::*FnCheck)(CheckerContext &, 56 const CallExpr *) const; 57 58 void evalMemcpy(CheckerContext &C, const CallExpr *CE) const; 59 void evalMempcpy(CheckerContext &C, const CallExpr *CE) const; 60 void evalMemmove(CheckerContext &C, const CallExpr *CE) const; 61 void evalBcopy(CheckerContext &C, const CallExpr *CE) const; 62 void evalCopyCommon(CheckerContext &C, const CallExpr *CE, 63 ProgramStateRef state, 64 const Expr *Size, 65 const Expr *Source, 66 const Expr *Dest, 67 bool Restricted = false, 68 bool IsMempcpy = false) const; 69 70 void evalMemcmp(CheckerContext &C, const CallExpr *CE) const; 71 72 void evalstrLength(CheckerContext &C, const CallExpr *CE) const; 73 void evalstrnLength(CheckerContext &C, const CallExpr *CE) const; 74 void evalstrLengthCommon(CheckerContext &C, 75 const CallExpr *CE, 76 bool IsStrnlen = false) const; 77 78 void evalStrcpy(CheckerContext &C, const CallExpr *CE) const; 79 void evalStrncpy(CheckerContext &C, const CallExpr *CE) const; 80 void evalStpcpy(CheckerContext &C, const CallExpr *CE) const; 81 void evalStrcpyCommon(CheckerContext &C, 82 const CallExpr *CE, 83 bool returnEnd, 84 bool isBounded, 85 bool isAppending) const; 86 87 void evalStrcat(CheckerContext &C, const CallExpr *CE) const; 88 void evalStrncat(CheckerContext &C, const CallExpr *CE) const; 89 90 void evalStrcmp(CheckerContext &C, const CallExpr *CE) const; 91 void evalStrncmp(CheckerContext &C, const CallExpr *CE) const; 92 void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const; 93 void evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const; 94 void evalStrcmpCommon(CheckerContext &C, 95 const CallExpr *CE, 96 bool isBounded = false, 97 bool ignoreCase = false) const; 98 99 // Utility methods 100 std::pair<ProgramStateRef , ProgramStateRef > 101 static assumeZero(CheckerContext &C, 102 ProgramStateRef state, SVal V, QualType Ty); 103 104 static ProgramStateRef setCStringLength(ProgramStateRef state, 105 const MemRegion *MR, 106 SVal strLength); 107 static SVal getCStringLengthForRegion(CheckerContext &C, 108 ProgramStateRef &state, 109 const Expr *Ex, 110 const MemRegion *MR, 111 bool hypothetical); 112 SVal getCStringLength(CheckerContext &C, 113 ProgramStateRef &state, 114 const Expr *Ex, 115 SVal Buf, 116 bool hypothetical = false) const; 117 118 const StringLiteral *getCStringLiteral(CheckerContext &C, 119 ProgramStateRef &state, 120 const Expr *expr, 121 SVal val) const; 122 123 static ProgramStateRef InvalidateBuffer(CheckerContext &C, 124 ProgramStateRef state, 125 const Expr *Ex, SVal V); 126 127 static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx, 128 const MemRegion *MR); 129 130 // Re-usable checks 131 ProgramStateRef checkNonNull(CheckerContext &C, 132 ProgramStateRef state, 133 const Expr *S, 134 SVal l) const; 135 ProgramStateRef CheckLocation(CheckerContext &C, 136 ProgramStateRef state, 137 const Expr *S, 138 SVal l, 139 const char *message = NULL) const; 140 ProgramStateRef CheckBufferAccess(CheckerContext &C, 141 ProgramStateRef state, 142 const Expr *Size, 143 const Expr *FirstBuf, 144 const Expr *SecondBuf, 145 const char *firstMessage = NULL, 146 const char *secondMessage = NULL, 147 bool WarnAboutSize = false) const; 148 149 ProgramStateRef CheckBufferAccess(CheckerContext &C, 150 ProgramStateRef state, 151 const Expr *Size, 152 const Expr *Buf, 153 const char *message = NULL, 154 bool WarnAboutSize = false) const { 155 // This is a convenience override. 156 return CheckBufferAccess(C, state, Size, Buf, NULL, message, NULL, 157 WarnAboutSize); 158 } 159 ProgramStateRef CheckOverlap(CheckerContext &C, 160 ProgramStateRef state, 161 const Expr *Size, 162 const Expr *First, 163 const Expr *Second) const; 164 void emitOverlapBug(CheckerContext &C, 165 ProgramStateRef state, 166 const Stmt *First, 167 const Stmt *Second) const; 168 169 ProgramStateRef checkAdditionOverflow(CheckerContext &C, 170 ProgramStateRef state, 171 NonLoc left, 172 NonLoc right) const; 173 }; 174 175 class CStringLength { 176 public: 177 typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap; 178 }; 179 } //end anonymous namespace 180 181 namespace clang { 182 namespace ento { 183 template <> 184 struct ProgramStateTrait<CStringLength> 185 : public ProgramStatePartialTrait<CStringLength::EntryMap> { 186 static void *GDMIndex() { return CStringChecker::getTag(); } 187 }; 188 } 189 } 190 191 //===----------------------------------------------------------------------===// 192 // Individual checks and utility methods. 193 //===----------------------------------------------------------------------===// 194 195 std::pair<ProgramStateRef , ProgramStateRef > 196 CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V, 197 QualType Ty) { 198 DefinedSVal *val = dyn_cast<DefinedSVal>(&V); 199 if (!val) 200 return std::pair<ProgramStateRef , ProgramStateRef >(state, state); 201 202 SValBuilder &svalBuilder = C.getSValBuilder(); 203 DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); 204 return state->assume(svalBuilder.evalEQ(state, *val, zero)); 205 } 206 207 ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C, 208 ProgramStateRef state, 209 const Expr *S, SVal l) const { 210 // If a previous check has failed, propagate the failure. 211 if (!state) 212 return NULL; 213 214 ProgramStateRef stateNull, stateNonNull; 215 llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType()); 216 217 if (stateNull && !stateNonNull) { 218 ExplodedNode *N = C.generateSink(stateNull); 219 if (!N) 220 return NULL; 221 222 if (!BT_Null) 223 BT_Null.reset(new BuiltinBug("API", 224 "Null pointer argument in call to byte string function")); 225 226 llvm::SmallString<80> buf; 227 llvm::raw_svector_ostream os(buf); 228 assert(CurrentFunctionDescription); 229 os << "Null pointer argument in call to " << CurrentFunctionDescription; 230 231 // Generate a report for this bug. 232 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null.get()); 233 BugReport *report = new BugReport(*BT, os.str(), N); 234 235 report->addRange(S->getSourceRange()); 236 report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S)); 237 C.EmitReport(report); 238 return NULL; 239 } 240 241 // From here on, assume that the value is non-null. 242 assert(stateNonNull); 243 return stateNonNull; 244 } 245 246 // FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor? 247 ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C, 248 ProgramStateRef state, 249 const Expr *S, SVal l, 250 const char *warningMsg) const { 251 // If a previous check has failed, propagate the failure. 252 if (!state) 253 return NULL; 254 255 // Check for out of bound array element access. 256 const MemRegion *R = l.getAsRegion(); 257 if (!R) 258 return state; 259 260 const ElementRegion *ER = dyn_cast<ElementRegion>(R); 261 if (!ER) 262 return state; 263 264 assert(ER->getValueType() == C.getASTContext().CharTy && 265 "CheckLocation should only be called with char* ElementRegions"); 266 267 // Get the size of the array. 268 const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion()); 269 SValBuilder &svalBuilder = C.getSValBuilder(); 270 SVal Extent = 271 svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder)); 272 DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent); 273 274 // Get the index of the accessed element. 275 DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex()); 276 277 ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true); 278 ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false); 279 if (StOutBound && !StInBound) { 280 ExplodedNode *N = C.generateSink(StOutBound); 281 if (!N) 282 return NULL; 283 284 if (!BT_Bounds) { 285 BT_Bounds.reset(new BuiltinBug("Out-of-bound array access", 286 "Byte string function accesses out-of-bound array element")); 287 } 288 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds.get()); 289 290 // Generate a report for this bug. 291 BugReport *report; 292 if (warningMsg) { 293 report = new BugReport(*BT, warningMsg, N); 294 } else { 295 assert(CurrentFunctionDescription); 296 assert(CurrentFunctionDescription[0] != '\0'); 297 298 llvm::SmallString<80> buf; 299 llvm::raw_svector_ostream os(buf); 300 os << (char)toupper(CurrentFunctionDescription[0]) 301 << &CurrentFunctionDescription[1] 302 << " accesses out-of-bound array element"; 303 report = new BugReport(*BT, os.str(), N); 304 } 305 306 // FIXME: It would be nice to eventually make this diagnostic more clear, 307 // e.g., by referencing the original declaration or by saying *why* this 308 // reference is outside the range. 309 310 report->addRange(S->getSourceRange()); 311 C.EmitReport(report); 312 return NULL; 313 } 314 315 // Array bound check succeeded. From this point forward the array bound 316 // should always succeed. 317 return StInBound; 318 } 319 320 ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C, 321 ProgramStateRef state, 322 const Expr *Size, 323 const Expr *FirstBuf, 324 const Expr *SecondBuf, 325 const char *firstMessage, 326 const char *secondMessage, 327 bool WarnAboutSize) const { 328 // If a previous check has failed, propagate the failure. 329 if (!state) 330 return NULL; 331 332 SValBuilder &svalBuilder = C.getSValBuilder(); 333 ASTContext &Ctx = svalBuilder.getContext(); 334 const LocationContext *LCtx = C.getLocationContext(); 335 336 QualType sizeTy = Size->getType(); 337 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy); 338 339 // Check that the first buffer is non-null. 340 SVal BufVal = state->getSVal(FirstBuf, LCtx); 341 state = checkNonNull(C, state, FirstBuf, BufVal); 342 if (!state) 343 return NULL; 344 345 // Get the access length and make sure it is known. 346 // FIXME: This assumes the caller has already checked that the access length 347 // is positive. And that it's unsigned. 348 SVal LengthVal = state->getSVal(Size, LCtx); 349 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal); 350 if (!Length) 351 return state; 352 353 // Compute the offset of the last element to be accessed: size-1. 354 NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy)); 355 NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub, 356 *Length, One, sizeTy)); 357 358 // Check that the first buffer is sufficiently long. 359 SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType()); 360 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) { 361 const Expr *warningExpr = (WarnAboutSize ? Size : FirstBuf); 362 363 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc, 364 LastOffset, PtrTy); 365 state = CheckLocation(C, state, warningExpr, BufEnd, firstMessage); 366 367 // If the buffer isn't large enough, abort. 368 if (!state) 369 return NULL; 370 } 371 372 // If there's a second buffer, check it as well. 373 if (SecondBuf) { 374 BufVal = state->getSVal(SecondBuf, LCtx); 375 state = checkNonNull(C, state, SecondBuf, BufVal); 376 if (!state) 377 return NULL; 378 379 BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType()); 380 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) { 381 const Expr *warningExpr = (WarnAboutSize ? Size : SecondBuf); 382 383 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc, 384 LastOffset, PtrTy); 385 state = CheckLocation(C, state, warningExpr, BufEnd, secondMessage); 386 } 387 } 388 389 // Large enough or not, return this state! 390 return state; 391 } 392 393 ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C, 394 ProgramStateRef state, 395 const Expr *Size, 396 const Expr *First, 397 const Expr *Second) const { 398 // Do a simple check for overlap: if the two arguments are from the same 399 // buffer, see if the end of the first is greater than the start of the second 400 // or vice versa. 401 402 // If a previous check has failed, propagate the failure. 403 if (!state) 404 return NULL; 405 406 ProgramStateRef stateTrue, stateFalse; 407 408 // Get the buffer values and make sure they're known locations. 409 const LocationContext *LCtx = C.getLocationContext(); 410 SVal firstVal = state->getSVal(First, LCtx); 411 SVal secondVal = state->getSVal(Second, LCtx); 412 413 Loc *firstLoc = dyn_cast<Loc>(&firstVal); 414 if (!firstLoc) 415 return state; 416 417 Loc *secondLoc = dyn_cast<Loc>(&secondVal); 418 if (!secondLoc) 419 return state; 420 421 // Are the two values the same? 422 SValBuilder &svalBuilder = C.getSValBuilder(); 423 llvm::tie(stateTrue, stateFalse) = 424 state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc)); 425 426 if (stateTrue && !stateFalse) { 427 // If the values are known to be equal, that's automatically an overlap. 428 emitOverlapBug(C, stateTrue, First, Second); 429 return NULL; 430 } 431 432 // assume the two expressions are not equal. 433 assert(stateFalse); 434 state = stateFalse; 435 436 // Which value comes first? 437 QualType cmpTy = svalBuilder.getConditionType(); 438 SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT, 439 *firstLoc, *secondLoc, cmpTy); 440 DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse); 441 if (!reverseTest) 442 return state; 443 444 llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest); 445 if (stateTrue) { 446 if (stateFalse) { 447 // If we don't know which one comes first, we can't perform this test. 448 return state; 449 } else { 450 // Switch the values so that firstVal is before secondVal. 451 Loc *tmpLoc = firstLoc; 452 firstLoc = secondLoc; 453 secondLoc = tmpLoc; 454 455 // Switch the Exprs as well, so that they still correspond. 456 const Expr *tmpExpr = First; 457 First = Second; 458 Second = tmpExpr; 459 } 460 } 461 462 // Get the length, and make sure it too is known. 463 SVal LengthVal = state->getSVal(Size, LCtx); 464 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal); 465 if (!Length) 466 return state; 467 468 // Convert the first buffer's start address to char*. 469 // Bail out if the cast fails. 470 ASTContext &Ctx = svalBuilder.getContext(); 471 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy); 472 SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy, 473 First->getType()); 474 Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart); 475 if (!FirstStartLoc) 476 return state; 477 478 // Compute the end of the first buffer. Bail out if THAT fails. 479 SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add, 480 *FirstStartLoc, *Length, CharPtrTy); 481 Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd); 482 if (!FirstEndLoc) 483 return state; 484 485 // Is the end of the first buffer past the start of the second buffer? 486 SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT, 487 *FirstEndLoc, *secondLoc, cmpTy); 488 DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap); 489 if (!OverlapTest) 490 return state; 491 492 llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest); 493 494 if (stateTrue && !stateFalse) { 495 // Overlap! 496 emitOverlapBug(C, stateTrue, First, Second); 497 return NULL; 498 } 499 500 // assume the two expressions don't overlap. 501 assert(stateFalse); 502 return stateFalse; 503 } 504 505 void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state, 506 const Stmt *First, const Stmt *Second) const { 507 ExplodedNode *N = C.generateSink(state); 508 if (!N) 509 return; 510 511 if (!BT_Overlap) 512 BT_Overlap.reset(new BugType("Unix API", "Improper arguments")); 513 514 // Generate a report for this bug. 515 BugReport *report = 516 new BugReport(*BT_Overlap, 517 "Arguments must not be overlapping buffers", N); 518 report->addRange(First->getSourceRange()); 519 report->addRange(Second->getSourceRange()); 520 521 C.EmitReport(report); 522 } 523 524 ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C, 525 ProgramStateRef state, 526 NonLoc left, 527 NonLoc right) const { 528 // If a previous check has failed, propagate the failure. 529 if (!state) 530 return NULL; 531 532 SValBuilder &svalBuilder = C.getSValBuilder(); 533 BasicValueFactory &BVF = svalBuilder.getBasicValueFactory(); 534 535 QualType sizeTy = svalBuilder.getContext().getSizeType(); 536 const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy); 537 NonLoc maxVal = svalBuilder.makeIntVal(maxValInt); 538 539 SVal maxMinusRight; 540 if (isa<nonloc::ConcreteInt>(right)) { 541 maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right, 542 sizeTy); 543 } else { 544 // Try switching the operands. (The order of these two assignments is 545 // important!) 546 maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left, 547 sizeTy); 548 left = right; 549 } 550 551 if (NonLoc *maxMinusRightNL = dyn_cast<NonLoc>(&maxMinusRight)) { 552 QualType cmpTy = svalBuilder.getConditionType(); 553 // If left > max - right, we have an overflow. 554 SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left, 555 *maxMinusRightNL, cmpTy); 556 557 ProgramStateRef stateOverflow, stateOkay; 558 llvm::tie(stateOverflow, stateOkay) = 559 state->assume(cast<DefinedOrUnknownSVal>(willOverflow)); 560 561 if (stateOverflow && !stateOkay) { 562 // We have an overflow. Emit a bug report. 563 ExplodedNode *N = C.generateSink(stateOverflow); 564 if (!N) 565 return NULL; 566 567 if (!BT_AdditionOverflow) 568 BT_AdditionOverflow.reset(new BuiltinBug("API", 569 "Sum of expressions causes overflow")); 570 571 // This isn't a great error message, but this should never occur in real 572 // code anyway -- you'd have to create a buffer longer than a size_t can 573 // represent, which is sort of a contradiction. 574 const char *warning = 575 "This expression will create a string whose length is too big to " 576 "be represented as a size_t"; 577 578 // Generate a report for this bug. 579 BugReport *report = new BugReport(*BT_AdditionOverflow, warning, N); 580 C.EmitReport(report); 581 582 return NULL; 583 } 584 585 // From now on, assume an overflow didn't occur. 586 assert(stateOkay); 587 state = stateOkay; 588 } 589 590 return state; 591 } 592 593 ProgramStateRef CStringChecker::setCStringLength(ProgramStateRef state, 594 const MemRegion *MR, 595 SVal strLength) { 596 assert(!strLength.isUndef() && "Attempt to set an undefined string length"); 597 598 MR = MR->StripCasts(); 599 600 switch (MR->getKind()) { 601 case MemRegion::StringRegionKind: 602 // FIXME: This can happen if we strcpy() into a string region. This is 603 // undefined [C99 6.4.5p6], but we should still warn about it. 604 return state; 605 606 case MemRegion::SymbolicRegionKind: 607 case MemRegion::AllocaRegionKind: 608 case MemRegion::VarRegionKind: 609 case MemRegion::FieldRegionKind: 610 case MemRegion::ObjCIvarRegionKind: 611 // These are the types we can currently track string lengths for. 612 break; 613 614 case MemRegion::ElementRegionKind: 615 // FIXME: Handle element regions by upper-bounding the parent region's 616 // string length. 617 return state; 618 619 default: 620 // Other regions (mostly non-data) can't have a reliable C string length. 621 // For now, just ignore the change. 622 // FIXME: These are rare but not impossible. We should output some kind of 623 // warning for things like strcpy((char[]){'a', 0}, "b"); 624 return state; 625 } 626 627 if (strLength.isUnknown()) 628 return state->remove<CStringLength>(MR); 629 630 return state->set<CStringLength>(MR, strLength); 631 } 632 633 SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C, 634 ProgramStateRef &state, 635 const Expr *Ex, 636 const MemRegion *MR, 637 bool hypothetical) { 638 if (!hypothetical) { 639 // If there's a recorded length, go ahead and return it. 640 const SVal *Recorded = state->get<CStringLength>(MR); 641 if (Recorded) 642 return *Recorded; 643 } 644 645 // Otherwise, get a new symbol and update the state. 646 unsigned Count = C.getCurrentBlockCount(); 647 SValBuilder &svalBuilder = C.getSValBuilder(); 648 QualType sizeTy = svalBuilder.getContext().getSizeType(); 649 SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(), 650 MR, Ex, sizeTy, Count); 651 652 if (!hypothetical) 653 state = state->set<CStringLength>(MR, strLength); 654 655 return strLength; 656 } 657 658 SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state, 659 const Expr *Ex, SVal Buf, 660 bool hypothetical) const { 661 const MemRegion *MR = Buf.getAsRegion(); 662 if (!MR) { 663 // If we can't get a region, see if it's something we /know/ isn't a 664 // C string. In the context of locations, the only time we can issue such 665 // a warning is for labels. 666 if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) { 667 if (ExplodedNode *N = C.addTransition(state)) { 668 if (!BT_NotCString) 669 BT_NotCString.reset(new BuiltinBug("API", 670 "Argument is not a null-terminated string.")); 671 672 llvm::SmallString<120> buf; 673 llvm::raw_svector_ostream os(buf); 674 assert(CurrentFunctionDescription); 675 os << "Argument to " << CurrentFunctionDescription 676 << " is the address of the label '" << Label->getLabel()->getName() 677 << "', which is not a null-terminated string"; 678 679 // Generate a report for this bug. 680 BugReport *report = new BugReport(*BT_NotCString, 681 os.str(), N); 682 683 report->addRange(Ex->getSourceRange()); 684 C.EmitReport(report); 685 } 686 687 return UndefinedVal(); 688 } 689 690 // If it's not a region and not a label, give up. 691 return UnknownVal(); 692 } 693 694 // If we have a region, strip casts from it and see if we can figure out 695 // its length. For anything we can't figure out, just return UnknownVal. 696 MR = MR->StripCasts(); 697 698 switch (MR->getKind()) { 699 case MemRegion::StringRegionKind: { 700 // Modifying the contents of string regions is undefined [C99 6.4.5p6], 701 // so we can assume that the byte length is the correct C string length. 702 SValBuilder &svalBuilder = C.getSValBuilder(); 703 QualType sizeTy = svalBuilder.getContext().getSizeType(); 704 const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral(); 705 return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy); 706 } 707 case MemRegion::SymbolicRegionKind: 708 case MemRegion::AllocaRegionKind: 709 case MemRegion::VarRegionKind: 710 case MemRegion::FieldRegionKind: 711 case MemRegion::ObjCIvarRegionKind: 712 return getCStringLengthForRegion(C, state, Ex, MR, hypothetical); 713 case MemRegion::CompoundLiteralRegionKind: 714 // FIXME: Can we track this? Is it necessary? 715 return UnknownVal(); 716 case MemRegion::ElementRegionKind: 717 // FIXME: How can we handle this? It's not good enough to subtract the 718 // offset from the base string length; consider "123\x00567" and &a[5]. 719 return UnknownVal(); 720 default: 721 // Other regions (mostly non-data) can't have a reliable C string length. 722 // In this case, an error is emitted and UndefinedVal is returned. 723 // The caller should always be prepared to handle this case. 724 if (ExplodedNode *N = C.addTransition(state)) { 725 if (!BT_NotCString) 726 BT_NotCString.reset(new BuiltinBug("API", 727 "Argument is not a null-terminated string.")); 728 729 llvm::SmallString<120> buf; 730 llvm::raw_svector_ostream os(buf); 731 732 assert(CurrentFunctionDescription); 733 os << "Argument to " << CurrentFunctionDescription << " is "; 734 735 if (SummarizeRegion(os, C.getASTContext(), MR)) 736 os << ", which is not a null-terminated string"; 737 else 738 os << "not a null-terminated string"; 739 740 // Generate a report for this bug. 741 BugReport *report = new BugReport(*BT_NotCString, 742 os.str(), N); 743 744 report->addRange(Ex->getSourceRange()); 745 C.EmitReport(report); 746 } 747 748 return UndefinedVal(); 749 } 750 } 751 752 const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C, 753 ProgramStateRef &state, const Expr *expr, SVal val) const { 754 755 // Get the memory region pointed to by the val. 756 const MemRegion *bufRegion = val.getAsRegion(); 757 if (!bufRegion) 758 return NULL; 759 760 // Strip casts off the memory region. 761 bufRegion = bufRegion->StripCasts(); 762 763 // Cast the memory region to a string region. 764 const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion); 765 if (!strRegion) 766 return NULL; 767 768 // Return the actual string in the string region. 769 return strRegion->getStringLiteral(); 770 } 771 772 ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C, 773 ProgramStateRef state, 774 const Expr *E, SVal V) { 775 Loc *L = dyn_cast<Loc>(&V); 776 if (!L) 777 return state; 778 779 // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes 780 // some assumptions about the value that CFRefCount can't. Even so, it should 781 // probably be refactored. 782 if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) { 783 const MemRegion *R = MR->getRegion()->StripCasts(); 784 785 // Are we dealing with an ElementRegion? If so, we should be invalidating 786 // the super-region. 787 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { 788 R = ER->getSuperRegion(); 789 // FIXME: What about layers of ElementRegions? 790 } 791 792 // Invalidate this region. 793 unsigned Count = C.getCurrentBlockCount(); 794 return state->invalidateRegions(R, E, Count); 795 } 796 797 // If we have a non-region value by chance, just remove the binding. 798 // FIXME: is this necessary or correct? This handles the non-Region 799 // cases. Is it ever valid to store to these? 800 return state->unbindLoc(*L); 801 } 802 803 bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx, 804 const MemRegion *MR) { 805 const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR); 806 807 switch (MR->getKind()) { 808 case MemRegion::FunctionTextRegionKind: { 809 const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); 810 if (FD) 811 os << "the address of the function '" << *FD << '\''; 812 else 813 os << "the address of a function"; 814 return true; 815 } 816 case MemRegion::BlockTextRegionKind: 817 os << "block text"; 818 return true; 819 case MemRegion::BlockDataRegionKind: 820 os << "a block"; 821 return true; 822 case MemRegion::CXXThisRegionKind: 823 case MemRegion::CXXTempObjectRegionKind: 824 os << "a C++ temp object of type " << TVR->getValueType().getAsString(); 825 return true; 826 case MemRegion::VarRegionKind: 827 os << "a variable of type" << TVR->getValueType().getAsString(); 828 return true; 829 case MemRegion::FieldRegionKind: 830 os << "a field of type " << TVR->getValueType().getAsString(); 831 return true; 832 case MemRegion::ObjCIvarRegionKind: 833 os << "an instance variable of type " << TVR->getValueType().getAsString(); 834 return true; 835 default: 836 return false; 837 } 838 } 839 840 //===----------------------------------------------------------------------===// 841 // evaluation of individual function calls. 842 //===----------------------------------------------------------------------===// 843 844 void CStringChecker::evalCopyCommon(CheckerContext &C, 845 const CallExpr *CE, 846 ProgramStateRef state, 847 const Expr *Size, const Expr *Dest, 848 const Expr *Source, bool Restricted, 849 bool IsMempcpy) const { 850 CurrentFunctionDescription = "memory copy function"; 851 852 // See if the size argument is zero. 853 const LocationContext *LCtx = C.getLocationContext(); 854 SVal sizeVal = state->getSVal(Size, LCtx); 855 QualType sizeTy = Size->getType(); 856 857 ProgramStateRef stateZeroSize, stateNonZeroSize; 858 llvm::tie(stateZeroSize, stateNonZeroSize) = 859 assumeZero(C, state, sizeVal, sizeTy); 860 861 // Get the value of the Dest. 862 SVal destVal = state->getSVal(Dest, LCtx); 863 864 // If the size is zero, there won't be any actual memory access, so 865 // just bind the return value to the destination buffer and return. 866 if (stateZeroSize) { 867 stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, destVal); 868 C.addTransition(stateZeroSize); 869 } 870 871 // If the size can be nonzero, we have to check the other arguments. 872 if (stateNonZeroSize) { 873 state = stateNonZeroSize; 874 875 // Ensure the destination is not null. If it is NULL there will be a 876 // NULL pointer dereference. 877 state = checkNonNull(C, state, Dest, destVal); 878 if (!state) 879 return; 880 881 // Get the value of the Src. 882 SVal srcVal = state->getSVal(Source, LCtx); 883 884 // Ensure the source is not null. If it is NULL there will be a 885 // NULL pointer dereference. 886 state = checkNonNull(C, state, Source, srcVal); 887 if (!state) 888 return; 889 890 // Ensure the accesses are valid and that the buffers do not overlap. 891 const char * const writeWarning = 892 "Memory copy function overflows destination buffer"; 893 state = CheckBufferAccess(C, state, Size, Dest, Source, 894 writeWarning, /* sourceWarning = */ NULL); 895 if (Restricted) 896 state = CheckOverlap(C, state, Size, Dest, Source); 897 898 if (!state) 899 return; 900 901 // If this is mempcpy, get the byte after the last byte copied and 902 // bind the expr. 903 if (IsMempcpy) { 904 loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal); 905 assert(destRegVal && "Destination should be a known MemRegionVal here"); 906 907 // Get the length to copy. 908 NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&sizeVal); 909 910 if (lenValNonLoc) { 911 // Get the byte after the last byte copied. 912 SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add, 913 *destRegVal, 914 *lenValNonLoc, 915 Dest->getType()); 916 917 // The byte after the last byte copied is the return value. 918 state = state->BindExpr(CE, LCtx, lastElement); 919 } else { 920 // If we don't know how much we copied, we can at least 921 // conjure a return value for later. 922 unsigned Count = C.getCurrentBlockCount(); 923 SVal result = 924 C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); 925 state = state->BindExpr(CE, LCtx, result); 926 } 927 928 } else { 929 // All other copies return the destination buffer. 930 // (Well, bcopy() has a void return type, but this won't hurt.) 931 state = state->BindExpr(CE, LCtx, destVal); 932 } 933 934 // Invalidate the destination. 935 // FIXME: Even if we can't perfectly model the copy, we should see if we 936 // can use LazyCompoundVals to copy the source values into the destination. 937 // This would probably remove any existing bindings past the end of the 938 // copied region, but that's still an improvement over blank invalidation. 939 state = InvalidateBuffer(C, state, Dest, 940 state->getSVal(Dest, C.getLocationContext())); 941 C.addTransition(state); 942 } 943 } 944 945 946 void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const { 947 // void *memcpy(void *restrict dst, const void *restrict src, size_t n); 948 // The return value is the address of the destination buffer. 949 const Expr *Dest = CE->getArg(0); 950 ProgramStateRef state = C.getState(); 951 952 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true); 953 } 954 955 void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const { 956 // void *mempcpy(void *restrict dst, const void *restrict src, size_t n); 957 // The return value is a pointer to the byte following the last written byte. 958 const Expr *Dest = CE->getArg(0); 959 ProgramStateRef state = C.getState(); 960 961 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true); 962 } 963 964 void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const { 965 // void *memmove(void *dst, const void *src, size_t n); 966 // The return value is the address of the destination buffer. 967 const Expr *Dest = CE->getArg(0); 968 ProgramStateRef state = C.getState(); 969 970 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1)); 971 } 972 973 void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const { 974 // void bcopy(const void *src, void *dst, size_t n); 975 evalCopyCommon(C, CE, C.getState(), 976 CE->getArg(2), CE->getArg(1), CE->getArg(0)); 977 } 978 979 void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const { 980 // int memcmp(const void *s1, const void *s2, size_t n); 981 CurrentFunctionDescription = "memory comparison function"; 982 983 const Expr *Left = CE->getArg(0); 984 const Expr *Right = CE->getArg(1); 985 const Expr *Size = CE->getArg(2); 986 987 ProgramStateRef state = C.getState(); 988 SValBuilder &svalBuilder = C.getSValBuilder(); 989 990 // See if the size argument is zero. 991 const LocationContext *LCtx = C.getLocationContext(); 992 SVal sizeVal = state->getSVal(Size, LCtx); 993 QualType sizeTy = Size->getType(); 994 995 ProgramStateRef stateZeroSize, stateNonZeroSize; 996 llvm::tie(stateZeroSize, stateNonZeroSize) = 997 assumeZero(C, state, sizeVal, sizeTy); 998 999 // If the size can be zero, the result will be 0 in that case, and we don't 1000 // have to check either of the buffers. 1001 if (stateZeroSize) { 1002 state = stateZeroSize; 1003 state = state->BindExpr(CE, LCtx, 1004 svalBuilder.makeZeroVal(CE->getType())); 1005 C.addTransition(state); 1006 } 1007 1008 // If the size can be nonzero, we have to check the other arguments. 1009 if (stateNonZeroSize) { 1010 state = stateNonZeroSize; 1011 // If we know the two buffers are the same, we know the result is 0. 1012 // First, get the two buffers' addresses. Another checker will have already 1013 // made sure they're not undefined. 1014 DefinedOrUnknownSVal LV = 1015 cast<DefinedOrUnknownSVal>(state->getSVal(Left, LCtx)); 1016 DefinedOrUnknownSVal RV = 1017 cast<DefinedOrUnknownSVal>(state->getSVal(Right, LCtx)); 1018 1019 // See if they are the same. 1020 DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV); 1021 ProgramStateRef StSameBuf, StNotSameBuf; 1022 llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf); 1023 1024 // If the two arguments might be the same buffer, we know the result is 0, 1025 // and we only need to check one size. 1026 if (StSameBuf) { 1027 state = StSameBuf; 1028 state = CheckBufferAccess(C, state, Size, Left); 1029 if (state) { 1030 state = StSameBuf->BindExpr(CE, LCtx, 1031 svalBuilder.makeZeroVal(CE->getType())); 1032 C.addTransition(state); 1033 } 1034 } 1035 1036 // If the two arguments might be different buffers, we have to check the 1037 // size of both of them. 1038 if (StNotSameBuf) { 1039 state = StNotSameBuf; 1040 state = CheckBufferAccess(C, state, Size, Left, Right); 1041 if (state) { 1042 // The return value is the comparison result, which we don't know. 1043 unsigned Count = C.getCurrentBlockCount(); 1044 SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count); 1045 state = state->BindExpr(CE, LCtx, CmpV); 1046 C.addTransition(state); 1047 } 1048 } 1049 } 1050 } 1051 1052 void CStringChecker::evalstrLength(CheckerContext &C, 1053 const CallExpr *CE) const { 1054 // size_t strlen(const char *s); 1055 evalstrLengthCommon(C, CE, /* IsStrnlen = */ false); 1056 } 1057 1058 void CStringChecker::evalstrnLength(CheckerContext &C, 1059 const CallExpr *CE) const { 1060 // size_t strnlen(const char *s, size_t maxlen); 1061 evalstrLengthCommon(C, CE, /* IsStrnlen = */ true); 1062 } 1063 1064 void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, 1065 bool IsStrnlen) const { 1066 CurrentFunctionDescription = "string length function"; 1067 ProgramStateRef state = C.getState(); 1068 const LocationContext *LCtx = C.getLocationContext(); 1069 1070 if (IsStrnlen) { 1071 const Expr *maxlenExpr = CE->getArg(1); 1072 SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); 1073 1074 ProgramStateRef stateZeroSize, stateNonZeroSize; 1075 llvm::tie(stateZeroSize, stateNonZeroSize) = 1076 assumeZero(C, state, maxlenVal, maxlenExpr->getType()); 1077 1078 // If the size can be zero, the result will be 0 in that case, and we don't 1079 // have to check the string itself. 1080 if (stateZeroSize) { 1081 SVal zero = C.getSValBuilder().makeZeroVal(CE->getType()); 1082 stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, zero); 1083 C.addTransition(stateZeroSize); 1084 } 1085 1086 // If the size is GUARANTEED to be zero, we're done! 1087 if (!stateNonZeroSize) 1088 return; 1089 1090 // Otherwise, record the assumption that the size is nonzero. 1091 state = stateNonZeroSize; 1092 } 1093 1094 // Check that the string argument is non-null. 1095 const Expr *Arg = CE->getArg(0); 1096 SVal ArgVal = state->getSVal(Arg, LCtx); 1097 1098 state = checkNonNull(C, state, Arg, ArgVal); 1099 1100 if (!state) 1101 return; 1102 1103 SVal strLength = getCStringLength(C, state, Arg, ArgVal); 1104 1105 // If the argument isn't a valid C string, there's no valid state to 1106 // transition to. 1107 if (strLength.isUndef()) 1108 return; 1109 1110 DefinedOrUnknownSVal result = UnknownVal(); 1111 1112 // If the check is for strnlen() then bind the return value to no more than 1113 // the maxlen value. 1114 if (IsStrnlen) { 1115 QualType cmpTy = C.getSValBuilder().getConditionType(); 1116 1117 // It's a little unfortunate to be getting this again, 1118 // but it's not that expensive... 1119 const Expr *maxlenExpr = CE->getArg(1); 1120 SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); 1121 1122 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength); 1123 NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal); 1124 1125 if (strLengthNL && maxlenValNL) { 1126 ProgramStateRef stateStringTooLong, stateStringNotTooLong; 1127 1128 // Check if the strLength is greater than the maxlen. 1129 llvm::tie(stateStringTooLong, stateStringNotTooLong) = 1130 state->assume(cast<DefinedOrUnknownSVal> 1131 (C.getSValBuilder().evalBinOpNN(state, BO_GT, 1132 *strLengthNL, 1133 *maxlenValNL, 1134 cmpTy))); 1135 1136 if (stateStringTooLong && !stateStringNotTooLong) { 1137 // If the string is longer than maxlen, return maxlen. 1138 result = *maxlenValNL; 1139 } else if (stateStringNotTooLong && !stateStringTooLong) { 1140 // If the string is shorter than maxlen, return its length. 1141 result = *strLengthNL; 1142 } 1143 } 1144 1145 if (result.isUnknown()) { 1146 // If we don't have enough information for a comparison, there's 1147 // no guarantee the full string length will actually be returned. 1148 // All we know is the return value is the min of the string length 1149 // and the limit. This is better than nothing. 1150 unsigned Count = C.getCurrentBlockCount(); 1151 result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); 1152 NonLoc *resultNL = cast<NonLoc>(&result); 1153 1154 if (strLengthNL) { 1155 state = state->assume(cast<DefinedOrUnknownSVal> 1156 (C.getSValBuilder().evalBinOpNN(state, BO_LE, 1157 *resultNL, 1158 *strLengthNL, 1159 cmpTy)), true); 1160 } 1161 1162 if (maxlenValNL) { 1163 state = state->assume(cast<DefinedOrUnknownSVal> 1164 (C.getSValBuilder().evalBinOpNN(state, BO_LE, 1165 *resultNL, 1166 *maxlenValNL, 1167 cmpTy)), true); 1168 } 1169 } 1170 1171 } else { 1172 // This is a plain strlen(), not strnlen(). 1173 result = cast<DefinedOrUnknownSVal>(strLength); 1174 1175 // If we don't know the length of the string, conjure a return 1176 // value, so it can be used in constraints, at least. 1177 if (result.isUnknown()) { 1178 unsigned Count = C.getCurrentBlockCount(); 1179 result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); 1180 } 1181 } 1182 1183 // Bind the return value. 1184 assert(!result.isUnknown() && "Should have conjured a value by now"); 1185 state = state->BindExpr(CE, LCtx, result); 1186 C.addTransition(state); 1187 } 1188 1189 void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const { 1190 // char *strcpy(char *restrict dst, const char *restrict src); 1191 evalStrcpyCommon(C, CE, 1192 /* returnEnd = */ false, 1193 /* isBounded = */ false, 1194 /* isAppending = */ false); 1195 } 1196 1197 void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const { 1198 // char *strncpy(char *restrict dst, const char *restrict src, size_t n); 1199 evalStrcpyCommon(C, CE, 1200 /* returnEnd = */ false, 1201 /* isBounded = */ true, 1202 /* isAppending = */ false); 1203 } 1204 1205 void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const { 1206 // char *stpcpy(char *restrict dst, const char *restrict src); 1207 evalStrcpyCommon(C, CE, 1208 /* returnEnd = */ true, 1209 /* isBounded = */ false, 1210 /* isAppending = */ false); 1211 } 1212 1213 void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const { 1214 //char *strcat(char *restrict s1, const char *restrict s2); 1215 evalStrcpyCommon(C, CE, 1216 /* returnEnd = */ false, 1217 /* isBounded = */ false, 1218 /* isAppending = */ true); 1219 } 1220 1221 void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const { 1222 //char *strncat(char *restrict s1, const char *restrict s2, size_t n); 1223 evalStrcpyCommon(C, CE, 1224 /* returnEnd = */ false, 1225 /* isBounded = */ true, 1226 /* isAppending = */ true); 1227 } 1228 1229 void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, 1230 bool returnEnd, bool isBounded, 1231 bool isAppending) const { 1232 CurrentFunctionDescription = "string copy function"; 1233 ProgramStateRef state = C.getState(); 1234 const LocationContext *LCtx = C.getLocationContext(); 1235 1236 // Check that the destination is non-null. 1237 const Expr *Dst = CE->getArg(0); 1238 SVal DstVal = state->getSVal(Dst, LCtx); 1239 1240 state = checkNonNull(C, state, Dst, DstVal); 1241 if (!state) 1242 return; 1243 1244 // Check that the source is non-null. 1245 const Expr *srcExpr = CE->getArg(1); 1246 SVal srcVal = state->getSVal(srcExpr, LCtx); 1247 state = checkNonNull(C, state, srcExpr, srcVal); 1248 if (!state) 1249 return; 1250 1251 // Get the string length of the source. 1252 SVal strLength = getCStringLength(C, state, srcExpr, srcVal); 1253 1254 // If the source isn't a valid C string, give up. 1255 if (strLength.isUndef()) 1256 return; 1257 1258 SValBuilder &svalBuilder = C.getSValBuilder(); 1259 QualType cmpTy = svalBuilder.getConditionType(); 1260 QualType sizeTy = svalBuilder.getContext().getSizeType(); 1261 1262 // These two values allow checking two kinds of errors: 1263 // - actual overflows caused by a source that doesn't fit in the destination 1264 // - potential overflows caused by a bound that could exceed the destination 1265 SVal amountCopied = UnknownVal(); 1266 SVal maxLastElementIndex = UnknownVal(); 1267 const char *boundWarning = NULL; 1268 1269 // If the function is strncpy, strncat, etc... it is bounded. 1270 if (isBounded) { 1271 // Get the max number of characters to copy. 1272 const Expr *lenExpr = CE->getArg(2); 1273 SVal lenVal = state->getSVal(lenExpr, LCtx); 1274 1275 // Protect against misdeclared strncpy(). 1276 lenVal = svalBuilder.evalCast(lenVal, sizeTy, lenExpr->getType()); 1277 1278 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength); 1279 NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal); 1280 1281 // If we know both values, we might be able to figure out how much 1282 // we're copying. 1283 if (strLengthNL && lenValNL) { 1284 ProgramStateRef stateSourceTooLong, stateSourceNotTooLong; 1285 1286 // Check if the max number to copy is less than the length of the src. 1287 // If the bound is equal to the source length, strncpy won't null- 1288 // terminate the result! 1289 llvm::tie(stateSourceTooLong, stateSourceNotTooLong) = 1290 state->assume(cast<DefinedOrUnknownSVal> 1291 (svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL, 1292 *lenValNL, cmpTy))); 1293 1294 if (stateSourceTooLong && !stateSourceNotTooLong) { 1295 // Max number to copy is less than the length of the src, so the actual 1296 // strLength copied is the max number arg. 1297 state = stateSourceTooLong; 1298 amountCopied = lenVal; 1299 1300 } else if (!stateSourceTooLong && stateSourceNotTooLong) { 1301 // The source buffer entirely fits in the bound. 1302 state = stateSourceNotTooLong; 1303 amountCopied = strLength; 1304 } 1305 } 1306 1307 // We still want to know if the bound is known to be too large. 1308 if (lenValNL) { 1309 if (isAppending) { 1310 // For strncat, the check is strlen(dst) + lenVal < sizeof(dst) 1311 1312 // Get the string length of the destination. If the destination is 1313 // memory that can't have a string length, we shouldn't be copying 1314 // into it anyway. 1315 SVal dstStrLength = getCStringLength(C, state, Dst, DstVal); 1316 if (dstStrLength.isUndef()) 1317 return; 1318 1319 if (NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength)) { 1320 maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Add, 1321 *lenValNL, 1322 *dstStrLengthNL, 1323 sizeTy); 1324 boundWarning = "Size argument is greater than the free space in the " 1325 "destination buffer"; 1326 } 1327 1328 } else { 1329 // For strncpy, this is just checking that lenVal <= sizeof(dst) 1330 // (Yes, strncpy and strncat differ in how they treat termination. 1331 // strncat ALWAYS terminates, but strncpy doesn't.) 1332 NonLoc one = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy)); 1333 maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL, 1334 one, sizeTy); 1335 boundWarning = "Size argument is greater than the length of the " 1336 "destination buffer"; 1337 } 1338 } 1339 1340 // If we couldn't pin down the copy length, at least bound it. 1341 // FIXME: We should actually run this code path for append as well, but 1342 // right now it creates problems with constraints (since we can end up 1343 // trying to pass constraints from symbol to symbol). 1344 if (amountCopied.isUnknown() && !isAppending) { 1345 // Try to get a "hypothetical" string length symbol, which we can later 1346 // set as a real value if that turns out to be the case. 1347 amountCopied = getCStringLength(C, state, lenExpr, srcVal, true); 1348 assert(!amountCopied.isUndef()); 1349 1350 if (NonLoc *amountCopiedNL = dyn_cast<NonLoc>(&amountCopied)) { 1351 if (lenValNL) { 1352 // amountCopied <= lenVal 1353 SVal copiedLessThanBound = svalBuilder.evalBinOpNN(state, BO_LE, 1354 *amountCopiedNL, 1355 *lenValNL, 1356 cmpTy); 1357 state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanBound), 1358 true); 1359 if (!state) 1360 return; 1361 } 1362 1363 if (strLengthNL) { 1364 // amountCopied <= strlen(source) 1365 SVal copiedLessThanSrc = svalBuilder.evalBinOpNN(state, BO_LE, 1366 *amountCopiedNL, 1367 *strLengthNL, 1368 cmpTy); 1369 state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanSrc), 1370 true); 1371 if (!state) 1372 return; 1373 } 1374 } 1375 } 1376 1377 } else { 1378 // The function isn't bounded. The amount copied should match the length 1379 // of the source buffer. 1380 amountCopied = strLength; 1381 } 1382 1383 assert(state); 1384 1385 // This represents the number of characters copied into the destination 1386 // buffer. (It may not actually be the strlen if the destination buffer 1387 // is not terminated.) 1388 SVal finalStrLength = UnknownVal(); 1389 1390 // If this is an appending function (strcat, strncat...) then set the 1391 // string length to strlen(src) + strlen(dst) since the buffer will 1392 // ultimately contain both. 1393 if (isAppending) { 1394 // Get the string length of the destination. If the destination is memory 1395 // that can't have a string length, we shouldn't be copying into it anyway. 1396 SVal dstStrLength = getCStringLength(C, state, Dst, DstVal); 1397 if (dstStrLength.isUndef()) 1398 return; 1399 1400 NonLoc *srcStrLengthNL = dyn_cast<NonLoc>(&amountCopied); 1401 NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength); 1402 1403 // If we know both string lengths, we might know the final string length. 1404 if (srcStrLengthNL && dstStrLengthNL) { 1405 // Make sure the two lengths together don't overflow a size_t. 1406 state = checkAdditionOverflow(C, state, *srcStrLengthNL, *dstStrLengthNL); 1407 if (!state) 1408 return; 1409 1410 finalStrLength = svalBuilder.evalBinOpNN(state, BO_Add, *srcStrLengthNL, 1411 *dstStrLengthNL, sizeTy); 1412 } 1413 1414 // If we couldn't get a single value for the final string length, 1415 // we can at least bound it by the individual lengths. 1416 if (finalStrLength.isUnknown()) { 1417 // Try to get a "hypothetical" string length symbol, which we can later 1418 // set as a real value if that turns out to be the case. 1419 finalStrLength = getCStringLength(C, state, CE, DstVal, true); 1420 assert(!finalStrLength.isUndef()); 1421 1422 if (NonLoc *finalStrLengthNL = dyn_cast<NonLoc>(&finalStrLength)) { 1423 if (srcStrLengthNL) { 1424 // finalStrLength >= srcStrLength 1425 SVal sourceInResult = svalBuilder.evalBinOpNN(state, BO_GE, 1426 *finalStrLengthNL, 1427 *srcStrLengthNL, 1428 cmpTy); 1429 state = state->assume(cast<DefinedOrUnknownSVal>(sourceInResult), 1430 true); 1431 if (!state) 1432 return; 1433 } 1434 1435 if (dstStrLengthNL) { 1436 // finalStrLength >= dstStrLength 1437 SVal destInResult = svalBuilder.evalBinOpNN(state, BO_GE, 1438 *finalStrLengthNL, 1439 *dstStrLengthNL, 1440 cmpTy); 1441 state = state->assume(cast<DefinedOrUnknownSVal>(destInResult), 1442 true); 1443 if (!state) 1444 return; 1445 } 1446 } 1447 } 1448 1449 } else { 1450 // Otherwise, this is a copy-over function (strcpy, strncpy, ...), and 1451 // the final string length will match the input string length. 1452 finalStrLength = amountCopied; 1453 } 1454 1455 // The final result of the function will either be a pointer past the last 1456 // copied element, or a pointer to the start of the destination buffer. 1457 SVal Result = (returnEnd ? UnknownVal() : DstVal); 1458 1459 assert(state); 1460 1461 // If the destination is a MemRegion, try to check for a buffer overflow and 1462 // record the new string length. 1463 if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) { 1464 QualType ptrTy = Dst->getType(); 1465 1466 // If we have an exact value on a bounded copy, use that to check for 1467 // overflows, rather than our estimate about how much is actually copied. 1468 if (boundWarning) { 1469 if (NonLoc *maxLastNL = dyn_cast<NonLoc>(&maxLastElementIndex)) { 1470 SVal maxLastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal, 1471 *maxLastNL, ptrTy); 1472 state = CheckLocation(C, state, CE->getArg(2), maxLastElement, 1473 boundWarning); 1474 if (!state) 1475 return; 1476 } 1477 } 1478 1479 // Then, if the final length is known... 1480 if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&finalStrLength)) { 1481 SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal, 1482 *knownStrLength, ptrTy); 1483 1484 // ...and we haven't checked the bound, we'll check the actual copy. 1485 if (!boundWarning) { 1486 const char * const warningMsg = 1487 "String copy function overflows destination buffer"; 1488 state = CheckLocation(C, state, Dst, lastElement, warningMsg); 1489 if (!state) 1490 return; 1491 } 1492 1493 // If this is a stpcpy-style copy, the last element is the return value. 1494 if (returnEnd) 1495 Result = lastElement; 1496 } 1497 1498 // Invalidate the destination. This must happen before we set the C string 1499 // length because invalidation will clear the length. 1500 // FIXME: Even if we can't perfectly model the copy, we should see if we 1501 // can use LazyCompoundVals to copy the source values into the destination. 1502 // This would probably remove any existing bindings past the end of the 1503 // string, but that's still an improvement over blank invalidation. 1504 state = InvalidateBuffer(C, state, Dst, *dstRegVal); 1505 1506 // Set the C string length of the destination, if we know it. 1507 if (isBounded && !isAppending) { 1508 // strncpy is annoying in that it doesn't guarantee to null-terminate 1509 // the result string. If the original string didn't fit entirely inside 1510 // the bound (including the null-terminator), we don't know how long the 1511 // result is. 1512 if (amountCopied != strLength) 1513 finalStrLength = UnknownVal(); 1514 } 1515 state = setCStringLength(state, dstRegVal->getRegion(), finalStrLength); 1516 } 1517 1518 assert(state); 1519 1520 // If this is a stpcpy-style copy, but we were unable to check for a buffer 1521 // overflow, we still need a result. Conjure a return value. 1522 if (returnEnd && Result.isUnknown()) { 1523 unsigned Count = C.getCurrentBlockCount(); 1524 Result = svalBuilder.getConjuredSymbolVal(NULL, CE, Count); 1525 } 1526 1527 // Set the return value. 1528 state = state->BindExpr(CE, LCtx, Result); 1529 C.addTransition(state); 1530 } 1531 1532 void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const { 1533 //int strcmp(const char *s1, const char *s2); 1534 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ false); 1535 } 1536 1537 void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const { 1538 //int strncmp(const char *s1, const char *s2, size_t n); 1539 evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false); 1540 } 1541 1542 void CStringChecker::evalStrcasecmp(CheckerContext &C, 1543 const CallExpr *CE) const { 1544 //int strcasecmp(const char *s1, const char *s2); 1545 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true); 1546 } 1547 1548 void CStringChecker::evalStrncasecmp(CheckerContext &C, 1549 const CallExpr *CE) const { 1550 //int strncasecmp(const char *s1, const char *s2, size_t n); 1551 evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ true); 1552 } 1553 1554 void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, 1555 bool isBounded, bool ignoreCase) const { 1556 CurrentFunctionDescription = "string comparison function"; 1557 ProgramStateRef state = C.getState(); 1558 const LocationContext *LCtx = C.getLocationContext(); 1559 1560 // Check that the first string is non-null 1561 const Expr *s1 = CE->getArg(0); 1562 SVal s1Val = state->getSVal(s1, LCtx); 1563 state = checkNonNull(C, state, s1, s1Val); 1564 if (!state) 1565 return; 1566 1567 // Check that the second string is non-null. 1568 const Expr *s2 = CE->getArg(1); 1569 SVal s2Val = state->getSVal(s2, LCtx); 1570 state = checkNonNull(C, state, s2, s2Val); 1571 if (!state) 1572 return; 1573 1574 // Get the string length of the first string or give up. 1575 SVal s1Length = getCStringLength(C, state, s1, s1Val); 1576 if (s1Length.isUndef()) 1577 return; 1578 1579 // Get the string length of the second string or give up. 1580 SVal s2Length = getCStringLength(C, state, s2, s2Val); 1581 if (s2Length.isUndef()) 1582 return; 1583 1584 // If we know the two buffers are the same, we know the result is 0. 1585 // First, get the two buffers' addresses. Another checker will have already 1586 // made sure they're not undefined. 1587 DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(s1Val); 1588 DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(s2Val); 1589 1590 // See if they are the same. 1591 SValBuilder &svalBuilder = C.getSValBuilder(); 1592 DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV); 1593 ProgramStateRef StSameBuf, StNotSameBuf; 1594 llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf); 1595 1596 // If the two arguments might be the same buffer, we know the result is 0, 1597 // and we only need to check one size. 1598 if (StSameBuf) { 1599 StSameBuf = StSameBuf->BindExpr(CE, LCtx, 1600 svalBuilder.makeZeroVal(CE->getType())); 1601 C.addTransition(StSameBuf); 1602 1603 // If the two arguments are GUARANTEED to be the same, we're done! 1604 if (!StNotSameBuf) 1605 return; 1606 } 1607 1608 assert(StNotSameBuf); 1609 state = StNotSameBuf; 1610 1611 // At this point we can go about comparing the two buffers. 1612 // For now, we only do this if they're both known string literals. 1613 1614 // Attempt to extract string literals from both expressions. 1615 const StringLiteral *s1StrLiteral = getCStringLiteral(C, state, s1, s1Val); 1616 const StringLiteral *s2StrLiteral = getCStringLiteral(C, state, s2, s2Val); 1617 bool canComputeResult = false; 1618 1619 if (s1StrLiteral && s2StrLiteral) { 1620 StringRef s1StrRef = s1StrLiteral->getString(); 1621 StringRef s2StrRef = s2StrLiteral->getString(); 1622 1623 if (isBounded) { 1624 // Get the max number of characters to compare. 1625 const Expr *lenExpr = CE->getArg(2); 1626 SVal lenVal = state->getSVal(lenExpr, LCtx); 1627 1628 // If the length is known, we can get the right substrings. 1629 if (const llvm::APSInt *len = svalBuilder.getKnownValue(state, lenVal)) { 1630 // Create substrings of each to compare the prefix. 1631 s1StrRef = s1StrRef.substr(0, (size_t)len->getZExtValue()); 1632 s2StrRef = s2StrRef.substr(0, (size_t)len->getZExtValue()); 1633 canComputeResult = true; 1634 } 1635 } else { 1636 // This is a normal, unbounded strcmp. 1637 canComputeResult = true; 1638 } 1639 1640 if (canComputeResult) { 1641 // Real strcmp stops at null characters. 1642 size_t s1Term = s1StrRef.find('\0'); 1643 if (s1Term != StringRef::npos) 1644 s1StrRef = s1StrRef.substr(0, s1Term); 1645 1646 size_t s2Term = s2StrRef.find('\0'); 1647 if (s2Term != StringRef::npos) 1648 s2StrRef = s2StrRef.substr(0, s2Term); 1649 1650 // Use StringRef's comparison methods to compute the actual result. 1651 int result; 1652 1653 if (ignoreCase) { 1654 // Compare string 1 to string 2 the same way strcasecmp() does. 1655 result = s1StrRef.compare_lower(s2StrRef); 1656 } else { 1657 // Compare string 1 to string 2 the same way strcmp() does. 1658 result = s1StrRef.compare(s2StrRef); 1659 } 1660 1661 // Build the SVal of the comparison and bind the return value. 1662 SVal resultVal = svalBuilder.makeIntVal(result, CE->getType()); 1663 state = state->BindExpr(CE, LCtx, resultVal); 1664 } 1665 } 1666 1667 if (!canComputeResult) { 1668 // Conjure a symbolic value. It's the best we can do. 1669 unsigned Count = C.getCurrentBlockCount(); 1670 SVal resultVal = svalBuilder.getConjuredSymbolVal(NULL, CE, Count); 1671 state = state->BindExpr(CE, LCtx, resultVal); 1672 } 1673 1674 // Record this as a possible path. 1675 C.addTransition(state); 1676 } 1677 1678 //===----------------------------------------------------------------------===// 1679 // The driver method, and other Checker callbacks. 1680 //===----------------------------------------------------------------------===// 1681 1682 bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { 1683 StringRef Name = C.getCalleeName(CE); 1684 if (Name.empty()) 1685 return false; 1686 if (Name.startswith("__builtin_")) 1687 Name = Name.substr(10); 1688 1689 FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name) 1690 .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy) 1691 .Cases("mempcpy", "__mempcpy_chk", &CStringChecker::evalMempcpy) 1692 .Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp) 1693 .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove) 1694 .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy) 1695 .Cases("strncpy", "__strncpy_chk", &CStringChecker::evalStrncpy) 1696 .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy) 1697 .Cases("strcat", "__strcat_chk", &CStringChecker::evalStrcat) 1698 .Cases("strncat", "__strncat_chk", &CStringChecker::evalStrncat) 1699 .Case("strlen", &CStringChecker::evalstrLength) 1700 .Case("strnlen", &CStringChecker::evalstrnLength) 1701 .Case("strcmp", &CStringChecker::evalStrcmp) 1702 .Case("strncmp", &CStringChecker::evalStrncmp) 1703 .Case("strcasecmp", &CStringChecker::evalStrcasecmp) 1704 .Case("strncasecmp", &CStringChecker::evalStrncasecmp) 1705 .Case("bcopy", &CStringChecker::evalBcopy) 1706 .Default(NULL); 1707 1708 // If the callee isn't a string function, let another checker handle it. 1709 if (!evalFunction) 1710 return false; 1711 1712 // Make sure each function sets its own description. 1713 // (But don't bother in a release build.) 1714 assert(!(CurrentFunctionDescription = NULL)); 1715 1716 // Check and evaluate the call. 1717 (this->*evalFunction)(C, CE); 1718 return true; 1719 } 1720 1721 void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const { 1722 // Record string length for char a[] = "abc"; 1723 ProgramStateRef state = C.getState(); 1724 1725 for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 1726 I != E; ++I) { 1727 const VarDecl *D = dyn_cast<VarDecl>(*I); 1728 if (!D) 1729 continue; 1730 1731 // FIXME: Handle array fields of structs. 1732 if (!D->getType()->isArrayType()) 1733 continue; 1734 1735 const Expr *Init = D->getInit(); 1736 if (!Init) 1737 continue; 1738 if (!isa<StringLiteral>(Init)) 1739 continue; 1740 1741 Loc VarLoc = state->getLValue(D, C.getLocationContext()); 1742 const MemRegion *MR = VarLoc.getAsRegion(); 1743 if (!MR) 1744 continue; 1745 1746 SVal StrVal = state->getSVal(Init, C.getLocationContext()); 1747 assert(StrVal.isValid() && "Initializer string is unknown or undefined"); 1748 DefinedOrUnknownSVal strLength 1749 = cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal)); 1750 1751 state = state->set<CStringLength>(MR, strLength); 1752 } 1753 1754 C.addTransition(state); 1755 } 1756 1757 bool CStringChecker::wantsRegionChangeUpdate(ProgramStateRef state) const { 1758 CStringLength::EntryMap Entries = state->get<CStringLength>(); 1759 return !Entries.isEmpty(); 1760 } 1761 1762 ProgramStateRef 1763 CStringChecker::checkRegionChanges(ProgramStateRef state, 1764 const StoreManager::InvalidatedSymbols *, 1765 ArrayRef<const MemRegion *> ExplicitRegions, 1766 ArrayRef<const MemRegion *> Regions) const { 1767 CStringLength::EntryMap Entries = state->get<CStringLength>(); 1768 if (Entries.isEmpty()) 1769 return state; 1770 1771 llvm::SmallPtrSet<const MemRegion *, 8> Invalidated; 1772 llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions; 1773 1774 // First build sets for the changed regions and their super-regions. 1775 for (ArrayRef<const MemRegion *>::iterator 1776 I = Regions.begin(), E = Regions.end(); I != E; ++I) { 1777 const MemRegion *MR = *I; 1778 Invalidated.insert(MR); 1779 1780 SuperRegions.insert(MR); 1781 while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) { 1782 MR = SR->getSuperRegion(); 1783 SuperRegions.insert(MR); 1784 } 1785 } 1786 1787 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>(); 1788 1789 // Then loop over the entries in the current state. 1790 for (CStringLength::EntryMap::iterator I = Entries.begin(), 1791 E = Entries.end(); I != E; ++I) { 1792 const MemRegion *MR = I.getKey(); 1793 1794 // Is this entry for a super-region of a changed region? 1795 if (SuperRegions.count(MR)) { 1796 Entries = F.remove(Entries, MR); 1797 continue; 1798 } 1799 1800 // Is this entry for a sub-region of a changed region? 1801 const MemRegion *Super = MR; 1802 while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) { 1803 Super = SR->getSuperRegion(); 1804 if (Invalidated.count(Super)) { 1805 Entries = F.remove(Entries, MR); 1806 break; 1807 } 1808 } 1809 } 1810 1811 return state->set<CStringLength>(Entries); 1812 } 1813 1814 void CStringChecker::checkLiveSymbols(ProgramStateRef state, 1815 SymbolReaper &SR) const { 1816 // Mark all symbols in our string length map as valid. 1817 CStringLength::EntryMap Entries = state->get<CStringLength>(); 1818 1819 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end(); 1820 I != E; ++I) { 1821 SVal Len = I.getData(); 1822 1823 for (SymExpr::symbol_iterator si = Len.symbol_begin(), 1824 se = Len.symbol_end(); si != se; ++si) 1825 SR.markInUse(*si); 1826 } 1827 } 1828 1829 void CStringChecker::checkDeadSymbols(SymbolReaper &SR, 1830 CheckerContext &C) const { 1831 if (!SR.hasDeadSymbols()) 1832 return; 1833 1834 ProgramStateRef state = C.getState(); 1835 CStringLength::EntryMap Entries = state->get<CStringLength>(); 1836 if (Entries.isEmpty()) 1837 return; 1838 1839 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>(); 1840 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end(); 1841 I != E; ++I) { 1842 SVal Len = I.getData(); 1843 if (SymbolRef Sym = Len.getAsSymbol()) { 1844 if (SR.isDead(Sym)) 1845 Entries = F.remove(Entries, I.getKey()); 1846 } 1847 } 1848 1849 state = state->set<CStringLength>(Entries); 1850 C.addTransition(state); 1851 } 1852 1853 void ento::registerCStringChecker(CheckerManager &mgr) { 1854 mgr.registerChecker<CStringChecker>(); 1855 } 1856