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