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