1 //= CStringChecker.cpp - Checks calls to C string functions --------*- C++ -*-// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This defines CStringChecker, which is an assortment of checks on calls 10 // to functions in <string.h>. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "InterCheckerAPI.h" 15 #include "clang/Basic/CharInfo.h" 16 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" 17 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 18 #include "clang/StaticAnalyzer/Core/Checker.h" 19 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" 21 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 22 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 23 #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" 24 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 25 #include "llvm/ADT/STLExtras.h" 26 #include "llvm/ADT/SmallString.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/Support/raw_ostream.h" 29 30 using namespace clang; 31 using namespace ento; 32 33 namespace { 34 struct AnyArgExpr { 35 // FIXME: Remove constructor in C++17 to turn it into an aggregate. 36 AnyArgExpr(const Expr *Expression, unsigned ArgumentIndex) 37 : Expression{Expression}, ArgumentIndex{ArgumentIndex} {} 38 const Expr *Expression; 39 unsigned ArgumentIndex; 40 }; 41 42 struct SourceArgExpr : AnyArgExpr { 43 using AnyArgExpr::AnyArgExpr; // FIXME: Remove using in C++17. 44 }; 45 46 struct DestinationArgExpr : AnyArgExpr { 47 using AnyArgExpr::AnyArgExpr; // FIXME: Same. 48 }; 49 50 struct SizeArgExpr : AnyArgExpr { 51 using AnyArgExpr::AnyArgExpr; // FIXME: Same. 52 }; 53 54 using ErrorMessage = SmallString<128>; 55 enum class AccessKind { write, read }; 56 57 static ErrorMessage createOutOfBoundErrorMsg(StringRef FunctionDescription, 58 AccessKind Access) { 59 ErrorMessage Message; 60 llvm::raw_svector_ostream Os(Message); 61 62 // Function classification like: Memory copy function 63 Os << toUppercase(FunctionDescription.front()) 64 << &FunctionDescription.data()[1]; 65 66 if (Access == AccessKind::write) { 67 Os << " overflows the destination buffer"; 68 } else { // read access 69 Os << " accesses out-of-bound array element"; 70 } 71 72 return Message; 73 } 74 75 enum class ConcatFnKind { none = 0, strcat = 1, strlcat = 2 }; 76 class CStringChecker : public Checker< eval::Call, 77 check::PreStmt<DeclStmt>, 78 check::LiveSymbols, 79 check::DeadSymbols, 80 check::RegionChanges 81 > { 82 mutable std::unique_ptr<BugType> BT_Null, BT_Bounds, BT_Overlap, 83 BT_NotCString, BT_AdditionOverflow, BT_UninitRead; 84 85 mutable const char *CurrentFunctionDescription; 86 87 public: 88 /// The filter is used to filter out the diagnostics which are not enabled by 89 /// the user. 90 struct CStringChecksFilter { 91 DefaultBool CheckCStringNullArg; 92 DefaultBool CheckCStringOutOfBounds; 93 DefaultBool CheckCStringBufferOverlap; 94 DefaultBool CheckCStringNotNullTerm; 95 DefaultBool CheckCStringUninitializedRead; 96 97 CheckerNameRef CheckNameCStringNullArg; 98 CheckerNameRef CheckNameCStringOutOfBounds; 99 CheckerNameRef CheckNameCStringBufferOverlap; 100 CheckerNameRef CheckNameCStringNotNullTerm; 101 CheckerNameRef CheckNameCStringUninitializedRead; 102 }; 103 104 CStringChecksFilter Filter; 105 106 static void *getTag() { static int tag; return &tag; } 107 108 bool evalCall(const CallEvent &Call, CheckerContext &C) const; 109 void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const; 110 void checkLiveSymbols(ProgramStateRef state, SymbolReaper &SR) const; 111 void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; 112 113 ProgramStateRef 114 checkRegionChanges(ProgramStateRef state, 115 const InvalidatedSymbols *, 116 ArrayRef<const MemRegion *> ExplicitRegions, 117 ArrayRef<const MemRegion *> Regions, 118 const LocationContext *LCtx, 119 const CallEvent *Call) const; 120 121 typedef void (CStringChecker::*FnCheck)(CheckerContext &, 122 const CallExpr *) const; 123 CallDescriptionMap<FnCheck> Callbacks = { 124 {{CDF_MaybeBuiltin, "memcpy", 3}, &CStringChecker::evalMemcpy}, 125 {{CDF_MaybeBuiltin, "mempcpy", 3}, &CStringChecker::evalMempcpy}, 126 {{CDF_MaybeBuiltin, "memcmp", 3}, &CStringChecker::evalMemcmp}, 127 {{CDF_MaybeBuiltin, "memmove", 3}, &CStringChecker::evalMemmove}, 128 {{CDF_MaybeBuiltin, "memset", 3}, &CStringChecker::evalMemset}, 129 {{CDF_MaybeBuiltin, "explicit_memset", 3}, &CStringChecker::evalMemset}, 130 {{CDF_MaybeBuiltin, "strcpy", 2}, &CStringChecker::evalStrcpy}, 131 {{CDF_MaybeBuiltin, "strncpy", 3}, &CStringChecker::evalStrncpy}, 132 {{CDF_MaybeBuiltin, "stpcpy", 2}, &CStringChecker::evalStpcpy}, 133 {{CDF_MaybeBuiltin, "strlcpy", 3}, &CStringChecker::evalStrlcpy}, 134 {{CDF_MaybeBuiltin, "strcat", 2}, &CStringChecker::evalStrcat}, 135 {{CDF_MaybeBuiltin, "strncat", 3}, &CStringChecker::evalStrncat}, 136 {{CDF_MaybeBuiltin, "strlcat", 3}, &CStringChecker::evalStrlcat}, 137 {{CDF_MaybeBuiltin, "strlen", 1}, &CStringChecker::evalstrLength}, 138 {{CDF_MaybeBuiltin, "strnlen", 2}, &CStringChecker::evalstrnLength}, 139 {{CDF_MaybeBuiltin, "strcmp", 2}, &CStringChecker::evalStrcmp}, 140 {{CDF_MaybeBuiltin, "strncmp", 3}, &CStringChecker::evalStrncmp}, 141 {{CDF_MaybeBuiltin, "strcasecmp", 2}, &CStringChecker::evalStrcasecmp}, 142 {{CDF_MaybeBuiltin, "strncasecmp", 3}, &CStringChecker::evalStrncasecmp}, 143 {{CDF_MaybeBuiltin, "strsep", 2}, &CStringChecker::evalStrsep}, 144 {{CDF_MaybeBuiltin, "bcopy", 3}, &CStringChecker::evalBcopy}, 145 {{CDF_MaybeBuiltin, "bcmp", 3}, &CStringChecker::evalMemcmp}, 146 {{CDF_MaybeBuiltin, "bzero", 2}, &CStringChecker::evalBzero}, 147 {{CDF_MaybeBuiltin, "explicit_bzero", 2}, &CStringChecker::evalBzero}, 148 }; 149 150 // These require a bit of special handling. 151 CallDescription StdCopy{{"std", "copy"}, 3}, 152 StdCopyBackward{{"std", "copy_backward"}, 3}; 153 154 FnCheck identifyCall(const CallEvent &Call, CheckerContext &C) const; 155 void evalMemcpy(CheckerContext &C, const CallExpr *CE) const; 156 void evalMempcpy(CheckerContext &C, const CallExpr *CE) const; 157 void evalMemmove(CheckerContext &C, const CallExpr *CE) const; 158 void evalBcopy(CheckerContext &C, const CallExpr *CE) const; 159 void evalCopyCommon(CheckerContext &C, const CallExpr *CE, 160 ProgramStateRef state, SizeArgExpr Size, 161 DestinationArgExpr Dest, SourceArgExpr Source, 162 bool Restricted, bool IsMempcpy) const; 163 164 void evalMemcmp(CheckerContext &C, const CallExpr *CE) const; 165 166 void evalstrLength(CheckerContext &C, const CallExpr *CE) const; 167 void evalstrnLength(CheckerContext &C, const CallExpr *CE) const; 168 void evalstrLengthCommon(CheckerContext &C, 169 const CallExpr *CE, 170 bool IsStrnlen = false) const; 171 172 void evalStrcpy(CheckerContext &C, const CallExpr *CE) const; 173 void evalStrncpy(CheckerContext &C, const CallExpr *CE) const; 174 void evalStpcpy(CheckerContext &C, const CallExpr *CE) const; 175 void evalStrlcpy(CheckerContext &C, const CallExpr *CE) const; 176 void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd, 177 bool IsBounded, ConcatFnKind appendK, 178 bool returnPtr = true) const; 179 180 void evalStrcat(CheckerContext &C, const CallExpr *CE) const; 181 void evalStrncat(CheckerContext &C, const CallExpr *CE) const; 182 void evalStrlcat(CheckerContext &C, const CallExpr *CE) const; 183 184 void evalStrcmp(CheckerContext &C, const CallExpr *CE) const; 185 void evalStrncmp(CheckerContext &C, const CallExpr *CE) const; 186 void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const; 187 void evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const; 188 void evalStrcmpCommon(CheckerContext &C, 189 const CallExpr *CE, 190 bool IsBounded = false, 191 bool IgnoreCase = false) const; 192 193 void evalStrsep(CheckerContext &C, const CallExpr *CE) const; 194 195 void evalStdCopy(CheckerContext &C, const CallExpr *CE) const; 196 void evalStdCopyBackward(CheckerContext &C, const CallExpr *CE) const; 197 void evalStdCopyCommon(CheckerContext &C, const CallExpr *CE) const; 198 void evalMemset(CheckerContext &C, const CallExpr *CE) const; 199 void evalBzero(CheckerContext &C, const CallExpr *CE) const; 200 201 // Utility methods 202 std::pair<ProgramStateRef , ProgramStateRef > 203 static assumeZero(CheckerContext &C, 204 ProgramStateRef state, SVal V, QualType Ty); 205 206 static ProgramStateRef setCStringLength(ProgramStateRef state, 207 const MemRegion *MR, 208 SVal strLength); 209 static SVal getCStringLengthForRegion(CheckerContext &C, 210 ProgramStateRef &state, 211 const Expr *Ex, 212 const MemRegion *MR, 213 bool hypothetical); 214 SVal getCStringLength(CheckerContext &C, 215 ProgramStateRef &state, 216 const Expr *Ex, 217 SVal Buf, 218 bool hypothetical = false) const; 219 220 const StringLiteral *getCStringLiteral(CheckerContext &C, 221 ProgramStateRef &state, 222 const Expr *expr, 223 SVal val) const; 224 225 static ProgramStateRef InvalidateBuffer(CheckerContext &C, 226 ProgramStateRef state, 227 const Expr *Ex, SVal V, 228 bool IsSourceBuffer, 229 const Expr *Size); 230 231 static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx, 232 const MemRegion *MR); 233 234 static bool memsetAux(const Expr *DstBuffer, SVal CharE, 235 const Expr *Size, CheckerContext &C, 236 ProgramStateRef &State); 237 238 // Re-usable checks 239 ProgramStateRef checkNonNull(CheckerContext &C, ProgramStateRef State, 240 AnyArgExpr Arg, SVal l) const; 241 ProgramStateRef CheckLocation(CheckerContext &C, ProgramStateRef state, 242 AnyArgExpr Buffer, SVal Element, 243 AccessKind Access) const; 244 ProgramStateRef CheckBufferAccess(CheckerContext &C, ProgramStateRef State, 245 AnyArgExpr Buffer, SizeArgExpr Size, 246 AccessKind Access) const; 247 ProgramStateRef CheckOverlap(CheckerContext &C, ProgramStateRef state, 248 SizeArgExpr Size, AnyArgExpr First, 249 AnyArgExpr Second) const; 250 void emitOverlapBug(CheckerContext &C, 251 ProgramStateRef state, 252 const Stmt *First, 253 const Stmt *Second) const; 254 255 void emitNullArgBug(CheckerContext &C, ProgramStateRef State, const Stmt *S, 256 StringRef WarningMsg) const; 257 void emitOutOfBoundsBug(CheckerContext &C, ProgramStateRef State, 258 const Stmt *S, StringRef WarningMsg) const; 259 void emitNotCStringBug(CheckerContext &C, ProgramStateRef State, 260 const Stmt *S, StringRef WarningMsg) const; 261 void emitAdditionOverflowBug(CheckerContext &C, ProgramStateRef State) const; 262 void emitUninitializedReadBug(CheckerContext &C, ProgramStateRef State, 263 const Expr *E) const; 264 ProgramStateRef checkAdditionOverflow(CheckerContext &C, 265 ProgramStateRef state, 266 NonLoc left, 267 NonLoc right) const; 268 269 // Return true if the destination buffer of the copy function may be in bound. 270 // Expects SVal of Size to be positive and unsigned. 271 // Expects SVal of FirstBuf to be a FieldRegion. 272 static bool IsFirstBufInBound(CheckerContext &C, 273 ProgramStateRef state, 274 const Expr *FirstBuf, 275 const Expr *Size); 276 }; 277 278 } //end anonymous namespace 279 280 REGISTER_MAP_WITH_PROGRAMSTATE(CStringLength, const MemRegion *, SVal) 281 282 //===----------------------------------------------------------------------===// 283 // Individual checks and utility methods. 284 //===----------------------------------------------------------------------===// 285 286 std::pair<ProgramStateRef , ProgramStateRef > 287 CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V, 288 QualType Ty) { 289 Optional<DefinedSVal> val = V.getAs<DefinedSVal>(); 290 if (!val) 291 return std::pair<ProgramStateRef , ProgramStateRef >(state, state); 292 293 SValBuilder &svalBuilder = C.getSValBuilder(); 294 DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); 295 return state->assume(svalBuilder.evalEQ(state, *val, zero)); 296 } 297 298 ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C, 299 ProgramStateRef State, 300 AnyArgExpr Arg, SVal l) const { 301 // If a previous check has failed, propagate the failure. 302 if (!State) 303 return nullptr; 304 305 ProgramStateRef stateNull, stateNonNull; 306 std::tie(stateNull, stateNonNull) = 307 assumeZero(C, State, l, Arg.Expression->getType()); 308 309 if (stateNull && !stateNonNull) { 310 if (Filter.CheckCStringNullArg) { 311 SmallString<80> buf; 312 llvm::raw_svector_ostream OS(buf); 313 assert(CurrentFunctionDescription); 314 OS << "Null pointer passed as " << (Arg.ArgumentIndex + 1) 315 << llvm::getOrdinalSuffix(Arg.ArgumentIndex + 1) << " argument to " 316 << CurrentFunctionDescription; 317 318 emitNullArgBug(C, stateNull, Arg.Expression, OS.str()); 319 } 320 return nullptr; 321 } 322 323 // From here on, assume that the value is non-null. 324 assert(stateNonNull); 325 return stateNonNull; 326 } 327 328 // FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor? 329 ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C, 330 ProgramStateRef state, 331 AnyArgExpr Buffer, SVal Element, 332 AccessKind Access) const { 333 334 // If a previous check has failed, propagate the failure. 335 if (!state) 336 return nullptr; 337 338 // Check for out of bound array element access. 339 const MemRegion *R = Element.getAsRegion(); 340 if (!R) 341 return state; 342 343 const auto *ER = dyn_cast<ElementRegion>(R); 344 if (!ER) 345 return state; 346 347 if (ER->getValueType() != C.getASTContext().CharTy) 348 return state; 349 350 // Get the size of the array. 351 const auto *superReg = cast<SubRegion>(ER->getSuperRegion()); 352 DefinedOrUnknownSVal Size = 353 getDynamicExtent(state, superReg, C.getSValBuilder()); 354 355 // Get the index of the accessed element. 356 DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>(); 357 358 ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true); 359 ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false); 360 if (StOutBound && !StInBound) { 361 // These checks are either enabled by the CString out-of-bounds checker 362 // explicitly or implicitly by the Malloc checker. 363 // In the latter case we only do modeling but do not emit warning. 364 if (!Filter.CheckCStringOutOfBounds) 365 return nullptr; 366 367 // Emit a bug report. 368 ErrorMessage Message = 369 createOutOfBoundErrorMsg(CurrentFunctionDescription, Access); 370 emitOutOfBoundsBug(C, StOutBound, Buffer.Expression, Message); 371 return nullptr; 372 } 373 374 // Ensure that we wouldn't read uninitialized value. 375 if (Access == AccessKind::read) { 376 if (Filter.CheckCStringUninitializedRead && 377 StInBound->getSVal(ER).isUndef()) { 378 emitUninitializedReadBug(C, StInBound, Buffer.Expression); 379 return nullptr; 380 } 381 } 382 383 // Array bound check succeeded. From this point forward the array bound 384 // should always succeed. 385 return StInBound; 386 } 387 388 ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C, 389 ProgramStateRef State, 390 AnyArgExpr Buffer, 391 SizeArgExpr Size, 392 AccessKind Access) const { 393 // If a previous check has failed, propagate the failure. 394 if (!State) 395 return nullptr; 396 397 SValBuilder &svalBuilder = C.getSValBuilder(); 398 ASTContext &Ctx = svalBuilder.getContext(); 399 400 QualType SizeTy = Size.Expression->getType(); 401 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy); 402 403 // Check that the first buffer is non-null. 404 SVal BufVal = C.getSVal(Buffer.Expression); 405 State = checkNonNull(C, State, Buffer, BufVal); 406 if (!State) 407 return nullptr; 408 409 // If out-of-bounds checking is turned off, skip the rest. 410 if (!Filter.CheckCStringOutOfBounds) 411 return State; 412 413 // Get the access length and make sure it is known. 414 // FIXME: This assumes the caller has already checked that the access length 415 // is positive. And that it's unsigned. 416 SVal LengthVal = C.getSVal(Size.Expression); 417 Optional<NonLoc> Length = LengthVal.getAs<NonLoc>(); 418 if (!Length) 419 return State; 420 421 // Compute the offset of the last element to be accessed: size-1. 422 NonLoc One = svalBuilder.makeIntVal(1, SizeTy).castAs<NonLoc>(); 423 SVal Offset = svalBuilder.evalBinOpNN(State, BO_Sub, *Length, One, SizeTy); 424 if (Offset.isUnknown()) 425 return nullptr; 426 NonLoc LastOffset = Offset.castAs<NonLoc>(); 427 428 // Check that the first buffer is sufficiently long. 429 SVal BufStart = 430 svalBuilder.evalCast(BufVal, PtrTy, Buffer.Expression->getType()); 431 if (Optional<Loc> BufLoc = BufStart.getAs<Loc>()) { 432 433 SVal BufEnd = 434 svalBuilder.evalBinOpLN(State, BO_Add, *BufLoc, LastOffset, PtrTy); 435 State = CheckLocation(C, State, Buffer, BufEnd, Access); 436 437 // If the buffer isn't large enough, abort. 438 if (!State) 439 return nullptr; 440 } 441 442 // Large enough or not, return this state! 443 return State; 444 } 445 446 ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C, 447 ProgramStateRef state, 448 SizeArgExpr Size, AnyArgExpr First, 449 AnyArgExpr Second) const { 450 if (!Filter.CheckCStringBufferOverlap) 451 return state; 452 453 // Do a simple check for overlap: if the two arguments are from the same 454 // buffer, see if the end of the first is greater than the start of the second 455 // or vice versa. 456 457 // If a previous check has failed, propagate the failure. 458 if (!state) 459 return nullptr; 460 461 ProgramStateRef stateTrue, stateFalse; 462 463 // Get the buffer values and make sure they're known locations. 464 const LocationContext *LCtx = C.getLocationContext(); 465 SVal firstVal = state->getSVal(First.Expression, LCtx); 466 SVal secondVal = state->getSVal(Second.Expression, LCtx); 467 468 Optional<Loc> firstLoc = firstVal.getAs<Loc>(); 469 if (!firstLoc) 470 return state; 471 472 Optional<Loc> secondLoc = secondVal.getAs<Loc>(); 473 if (!secondLoc) 474 return state; 475 476 // Are the two values the same? 477 SValBuilder &svalBuilder = C.getSValBuilder(); 478 std::tie(stateTrue, stateFalse) = 479 state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc)); 480 481 if (stateTrue && !stateFalse) { 482 // If the values are known to be equal, that's automatically an overlap. 483 emitOverlapBug(C, stateTrue, First.Expression, Second.Expression); 484 return nullptr; 485 } 486 487 // assume the two expressions are not equal. 488 assert(stateFalse); 489 state = stateFalse; 490 491 // Which value comes first? 492 QualType cmpTy = svalBuilder.getConditionType(); 493 SVal reverse = 494 svalBuilder.evalBinOpLL(state, BO_GT, *firstLoc, *secondLoc, cmpTy); 495 Optional<DefinedOrUnknownSVal> reverseTest = 496 reverse.getAs<DefinedOrUnknownSVal>(); 497 if (!reverseTest) 498 return state; 499 500 std::tie(stateTrue, stateFalse) = state->assume(*reverseTest); 501 if (stateTrue) { 502 if (stateFalse) { 503 // If we don't know which one comes first, we can't perform this test. 504 return state; 505 } else { 506 // Switch the values so that firstVal is before secondVal. 507 std::swap(firstLoc, secondLoc); 508 509 // Switch the Exprs as well, so that they still correspond. 510 std::swap(First, Second); 511 } 512 } 513 514 // Get the length, and make sure it too is known. 515 SVal LengthVal = state->getSVal(Size.Expression, LCtx); 516 Optional<NonLoc> Length = LengthVal.getAs<NonLoc>(); 517 if (!Length) 518 return state; 519 520 // Convert the first buffer's start address to char*. 521 // Bail out if the cast fails. 522 ASTContext &Ctx = svalBuilder.getContext(); 523 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy); 524 SVal FirstStart = 525 svalBuilder.evalCast(*firstLoc, CharPtrTy, First.Expression->getType()); 526 Optional<Loc> FirstStartLoc = FirstStart.getAs<Loc>(); 527 if (!FirstStartLoc) 528 return state; 529 530 // Compute the end of the first buffer. Bail out if THAT fails. 531 SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add, *FirstStartLoc, 532 *Length, CharPtrTy); 533 Optional<Loc> FirstEndLoc = FirstEnd.getAs<Loc>(); 534 if (!FirstEndLoc) 535 return state; 536 537 // Is the end of the first buffer past the start of the second buffer? 538 SVal Overlap = 539 svalBuilder.evalBinOpLL(state, BO_GT, *FirstEndLoc, *secondLoc, cmpTy); 540 Optional<DefinedOrUnknownSVal> OverlapTest = 541 Overlap.getAs<DefinedOrUnknownSVal>(); 542 if (!OverlapTest) 543 return state; 544 545 std::tie(stateTrue, stateFalse) = state->assume(*OverlapTest); 546 547 if (stateTrue && !stateFalse) { 548 // Overlap! 549 emitOverlapBug(C, stateTrue, First.Expression, Second.Expression); 550 return nullptr; 551 } 552 553 // assume the two expressions don't overlap. 554 assert(stateFalse); 555 return stateFalse; 556 } 557 558 void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state, 559 const Stmt *First, const Stmt *Second) const { 560 ExplodedNode *N = C.generateErrorNode(state); 561 if (!N) 562 return; 563 564 if (!BT_Overlap) 565 BT_Overlap.reset(new BugType(Filter.CheckNameCStringBufferOverlap, 566 categories::UnixAPI, "Improper arguments")); 567 568 // Generate a report for this bug. 569 auto report = std::make_unique<PathSensitiveBugReport>( 570 *BT_Overlap, "Arguments must not be overlapping buffers", N); 571 report->addRange(First->getSourceRange()); 572 report->addRange(Second->getSourceRange()); 573 574 C.emitReport(std::move(report)); 575 } 576 577 void CStringChecker::emitNullArgBug(CheckerContext &C, ProgramStateRef State, 578 const Stmt *S, StringRef WarningMsg) const { 579 if (ExplodedNode *N = C.generateErrorNode(State)) { 580 if (!BT_Null) 581 BT_Null.reset(new BuiltinBug( 582 Filter.CheckNameCStringNullArg, categories::UnixAPI, 583 "Null pointer argument in call to byte string function")); 584 585 BuiltinBug *BT = static_cast<BuiltinBug *>(BT_Null.get()); 586 auto Report = std::make_unique<PathSensitiveBugReport>(*BT, WarningMsg, N); 587 Report->addRange(S->getSourceRange()); 588 if (const auto *Ex = dyn_cast<Expr>(S)) 589 bugreporter::trackExpressionValue(N, Ex, *Report); 590 C.emitReport(std::move(Report)); 591 } 592 } 593 594 void CStringChecker::emitUninitializedReadBug(CheckerContext &C, 595 ProgramStateRef State, 596 const Expr *E) const { 597 if (ExplodedNode *N = C.generateErrorNode(State)) { 598 const char *Msg = 599 "Bytes string function accesses uninitialized/garbage values"; 600 if (!BT_UninitRead) 601 BT_UninitRead.reset( 602 new BuiltinBug(Filter.CheckNameCStringUninitializedRead, 603 "Accessing unitialized/garbage values", Msg)); 604 605 BuiltinBug *BT = static_cast<BuiltinBug *>(BT_UninitRead.get()); 606 607 auto Report = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N); 608 Report->addRange(E->getSourceRange()); 609 bugreporter::trackExpressionValue(N, E, *Report); 610 C.emitReport(std::move(Report)); 611 } 612 } 613 614 void CStringChecker::emitOutOfBoundsBug(CheckerContext &C, 615 ProgramStateRef State, const Stmt *S, 616 StringRef WarningMsg) const { 617 if (ExplodedNode *N = C.generateErrorNode(State)) { 618 if (!BT_Bounds) 619 BT_Bounds.reset(new BuiltinBug( 620 Filter.CheckCStringOutOfBounds ? Filter.CheckNameCStringOutOfBounds 621 : Filter.CheckNameCStringNullArg, 622 "Out-of-bound array access", 623 "Byte string function accesses out-of-bound array element")); 624 625 BuiltinBug *BT = static_cast<BuiltinBug *>(BT_Bounds.get()); 626 627 // FIXME: It would be nice to eventually make this diagnostic more clear, 628 // e.g., by referencing the original declaration or by saying *why* this 629 // reference is outside the range. 630 auto Report = std::make_unique<PathSensitiveBugReport>(*BT, WarningMsg, N); 631 Report->addRange(S->getSourceRange()); 632 C.emitReport(std::move(Report)); 633 } 634 } 635 636 void CStringChecker::emitNotCStringBug(CheckerContext &C, ProgramStateRef State, 637 const Stmt *S, 638 StringRef WarningMsg) const { 639 if (ExplodedNode *N = C.generateNonFatalErrorNode(State)) { 640 if (!BT_NotCString) 641 BT_NotCString.reset(new BuiltinBug( 642 Filter.CheckNameCStringNotNullTerm, categories::UnixAPI, 643 "Argument is not a null-terminated string.")); 644 645 auto Report = 646 std::make_unique<PathSensitiveBugReport>(*BT_NotCString, WarningMsg, N); 647 648 Report->addRange(S->getSourceRange()); 649 C.emitReport(std::move(Report)); 650 } 651 } 652 653 void CStringChecker::emitAdditionOverflowBug(CheckerContext &C, 654 ProgramStateRef State) const { 655 if (ExplodedNode *N = C.generateErrorNode(State)) { 656 if (!BT_AdditionOverflow) 657 BT_AdditionOverflow.reset( 658 new BuiltinBug(Filter.CheckNameCStringOutOfBounds, "API", 659 "Sum of expressions causes overflow.")); 660 661 // This isn't a great error message, but this should never occur in real 662 // code anyway -- you'd have to create a buffer longer than a size_t can 663 // represent, which is sort of a contradiction. 664 const char *WarningMsg = 665 "This expression will create a string whose length is too big to " 666 "be represented as a size_t"; 667 668 auto Report = std::make_unique<PathSensitiveBugReport>(*BT_AdditionOverflow, 669 WarningMsg, N); 670 C.emitReport(std::move(Report)); 671 } 672 } 673 674 ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C, 675 ProgramStateRef state, 676 NonLoc left, 677 NonLoc right) const { 678 // If out-of-bounds checking is turned off, skip the rest. 679 if (!Filter.CheckCStringOutOfBounds) 680 return state; 681 682 // If a previous check has failed, propagate the failure. 683 if (!state) 684 return nullptr; 685 686 SValBuilder &svalBuilder = C.getSValBuilder(); 687 BasicValueFactory &BVF = svalBuilder.getBasicValueFactory(); 688 689 QualType sizeTy = svalBuilder.getContext().getSizeType(); 690 const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy); 691 NonLoc maxVal = svalBuilder.makeIntVal(maxValInt); 692 693 SVal maxMinusRight; 694 if (right.getAs<nonloc::ConcreteInt>()) { 695 maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right, 696 sizeTy); 697 } else { 698 // Try switching the operands. (The order of these two assignments is 699 // important!) 700 maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left, 701 sizeTy); 702 left = right; 703 } 704 705 if (Optional<NonLoc> maxMinusRightNL = maxMinusRight.getAs<NonLoc>()) { 706 QualType cmpTy = svalBuilder.getConditionType(); 707 // If left > max - right, we have an overflow. 708 SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left, 709 *maxMinusRightNL, cmpTy); 710 711 ProgramStateRef stateOverflow, stateOkay; 712 std::tie(stateOverflow, stateOkay) = 713 state->assume(willOverflow.castAs<DefinedOrUnknownSVal>()); 714 715 if (stateOverflow && !stateOkay) { 716 // We have an overflow. Emit a bug report. 717 emitAdditionOverflowBug(C, stateOverflow); 718 return nullptr; 719 } 720 721 // From now on, assume an overflow didn't occur. 722 assert(stateOkay); 723 state = stateOkay; 724 } 725 726 return state; 727 } 728 729 ProgramStateRef CStringChecker::setCStringLength(ProgramStateRef state, 730 const MemRegion *MR, 731 SVal strLength) { 732 assert(!strLength.isUndef() && "Attempt to set an undefined string length"); 733 734 MR = MR->StripCasts(); 735 736 switch (MR->getKind()) { 737 case MemRegion::StringRegionKind: 738 // FIXME: This can happen if we strcpy() into a string region. This is 739 // undefined [C99 6.4.5p6], but we should still warn about it. 740 return state; 741 742 case MemRegion::SymbolicRegionKind: 743 case MemRegion::AllocaRegionKind: 744 case MemRegion::NonParamVarRegionKind: 745 case MemRegion::ParamVarRegionKind: 746 case MemRegion::FieldRegionKind: 747 case MemRegion::ObjCIvarRegionKind: 748 // These are the types we can currently track string lengths for. 749 break; 750 751 case MemRegion::ElementRegionKind: 752 // FIXME: Handle element regions by upper-bounding the parent region's 753 // string length. 754 return state; 755 756 default: 757 // Other regions (mostly non-data) can't have a reliable C string length. 758 // For now, just ignore the change. 759 // FIXME: These are rare but not impossible. We should output some kind of 760 // warning for things like strcpy((char[]){'a', 0}, "b"); 761 return state; 762 } 763 764 if (strLength.isUnknown()) 765 return state->remove<CStringLength>(MR); 766 767 return state->set<CStringLength>(MR, strLength); 768 } 769 770 SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C, 771 ProgramStateRef &state, 772 const Expr *Ex, 773 const MemRegion *MR, 774 bool hypothetical) { 775 if (!hypothetical) { 776 // If there's a recorded length, go ahead and return it. 777 const SVal *Recorded = state->get<CStringLength>(MR); 778 if (Recorded) 779 return *Recorded; 780 } 781 782 // Otherwise, get a new symbol and update the state. 783 SValBuilder &svalBuilder = C.getSValBuilder(); 784 QualType sizeTy = svalBuilder.getContext().getSizeType(); 785 SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(), 786 MR, Ex, sizeTy, 787 C.getLocationContext(), 788 C.blockCount()); 789 790 if (!hypothetical) { 791 if (Optional<NonLoc> strLn = strLength.getAs<NonLoc>()) { 792 // In case of unbounded calls strlen etc bound the range to SIZE_MAX/4 793 BasicValueFactory &BVF = svalBuilder.getBasicValueFactory(); 794 const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy); 795 llvm::APSInt fourInt = APSIntType(maxValInt).getValue(4); 796 const llvm::APSInt *maxLengthInt = BVF.evalAPSInt(BO_Div, maxValInt, 797 fourInt); 798 NonLoc maxLength = svalBuilder.makeIntVal(*maxLengthInt); 799 SVal evalLength = svalBuilder.evalBinOpNN(state, BO_LE, *strLn, 800 maxLength, sizeTy); 801 state = state->assume(evalLength.castAs<DefinedOrUnknownSVal>(), true); 802 } 803 state = state->set<CStringLength>(MR, strLength); 804 } 805 806 return strLength; 807 } 808 809 SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state, 810 const Expr *Ex, SVal Buf, 811 bool hypothetical) const { 812 const MemRegion *MR = Buf.getAsRegion(); 813 if (!MR) { 814 // If we can't get a region, see if it's something we /know/ isn't a 815 // C string. In the context of locations, the only time we can issue such 816 // a warning is for labels. 817 if (Optional<loc::GotoLabel> Label = Buf.getAs<loc::GotoLabel>()) { 818 if (Filter.CheckCStringNotNullTerm) { 819 SmallString<120> buf; 820 llvm::raw_svector_ostream os(buf); 821 assert(CurrentFunctionDescription); 822 os << "Argument to " << CurrentFunctionDescription 823 << " is the address of the label '" << Label->getLabel()->getName() 824 << "', which is not a null-terminated string"; 825 826 emitNotCStringBug(C, state, Ex, os.str()); 827 } 828 return UndefinedVal(); 829 } 830 831 // If it's not a region and not a label, give up. 832 return UnknownVal(); 833 } 834 835 // If we have a region, strip casts from it and see if we can figure out 836 // its length. For anything we can't figure out, just return UnknownVal. 837 MR = MR->StripCasts(); 838 839 switch (MR->getKind()) { 840 case MemRegion::StringRegionKind: { 841 // Modifying the contents of string regions is undefined [C99 6.4.5p6], 842 // so we can assume that the byte length is the correct C string length. 843 SValBuilder &svalBuilder = C.getSValBuilder(); 844 QualType sizeTy = svalBuilder.getContext().getSizeType(); 845 const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral(); 846 return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy); 847 } 848 case MemRegion::SymbolicRegionKind: 849 case MemRegion::AllocaRegionKind: 850 case MemRegion::NonParamVarRegionKind: 851 case MemRegion::ParamVarRegionKind: 852 case MemRegion::FieldRegionKind: 853 case MemRegion::ObjCIvarRegionKind: 854 return getCStringLengthForRegion(C, state, Ex, MR, hypothetical); 855 case MemRegion::CompoundLiteralRegionKind: 856 // FIXME: Can we track this? Is it necessary? 857 return UnknownVal(); 858 case MemRegion::ElementRegionKind: 859 // FIXME: How can we handle this? It's not good enough to subtract the 860 // offset from the base string length; consider "123\x00567" and &a[5]. 861 return UnknownVal(); 862 default: 863 // Other regions (mostly non-data) can't have a reliable C string length. 864 // In this case, an error is emitted and UndefinedVal is returned. 865 // The caller should always be prepared to handle this case. 866 if (Filter.CheckCStringNotNullTerm) { 867 SmallString<120> buf; 868 llvm::raw_svector_ostream os(buf); 869 870 assert(CurrentFunctionDescription); 871 os << "Argument to " << CurrentFunctionDescription << " is "; 872 873 if (SummarizeRegion(os, C.getASTContext(), MR)) 874 os << ", which is not a null-terminated string"; 875 else 876 os << "not a null-terminated string"; 877 878 emitNotCStringBug(C, state, Ex, os.str()); 879 } 880 return UndefinedVal(); 881 } 882 } 883 884 const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C, 885 ProgramStateRef &state, const Expr *expr, SVal val) const { 886 887 // Get the memory region pointed to by the val. 888 const MemRegion *bufRegion = val.getAsRegion(); 889 if (!bufRegion) 890 return nullptr; 891 892 // Strip casts off the memory region. 893 bufRegion = bufRegion->StripCasts(); 894 895 // Cast the memory region to a string region. 896 const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion); 897 if (!strRegion) 898 return nullptr; 899 900 // Return the actual string in the string region. 901 return strRegion->getStringLiteral(); 902 } 903 904 bool CStringChecker::IsFirstBufInBound(CheckerContext &C, 905 ProgramStateRef state, 906 const Expr *FirstBuf, 907 const Expr *Size) { 908 // If we do not know that the buffer is long enough we return 'true'. 909 // Otherwise the parent region of this field region would also get 910 // invalidated, which would lead to warnings based on an unknown state. 911 912 // Originally copied from CheckBufferAccess and CheckLocation. 913 SValBuilder &svalBuilder = C.getSValBuilder(); 914 ASTContext &Ctx = svalBuilder.getContext(); 915 const LocationContext *LCtx = C.getLocationContext(); 916 917 QualType sizeTy = Size->getType(); 918 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy); 919 SVal BufVal = state->getSVal(FirstBuf, LCtx); 920 921 SVal LengthVal = state->getSVal(Size, LCtx); 922 Optional<NonLoc> Length = LengthVal.getAs<NonLoc>(); 923 if (!Length) 924 return true; // cf top comment. 925 926 // Compute the offset of the last element to be accessed: size-1. 927 NonLoc One = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>(); 928 SVal Offset = svalBuilder.evalBinOpNN(state, BO_Sub, *Length, One, sizeTy); 929 if (Offset.isUnknown()) 930 return true; // cf top comment 931 NonLoc LastOffset = Offset.castAs<NonLoc>(); 932 933 // Check that the first buffer is sufficiently long. 934 SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType()); 935 Optional<Loc> BufLoc = BufStart.getAs<Loc>(); 936 if (!BufLoc) 937 return true; // cf top comment. 938 939 SVal BufEnd = 940 svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc, LastOffset, PtrTy); 941 942 // Check for out of bound array element access. 943 const MemRegion *R = BufEnd.getAsRegion(); 944 if (!R) 945 return true; // cf top comment. 946 947 const ElementRegion *ER = dyn_cast<ElementRegion>(R); 948 if (!ER) 949 return true; // cf top comment. 950 951 // FIXME: Does this crash when a non-standard definition 952 // of a library function is encountered? 953 assert(ER->getValueType() == C.getASTContext().CharTy && 954 "IsFirstBufInBound should only be called with char* ElementRegions"); 955 956 // Get the size of the array. 957 const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion()); 958 DefinedOrUnknownSVal SizeDV = getDynamicExtent(state, superReg, svalBuilder); 959 960 // Get the index of the accessed element. 961 DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>(); 962 963 ProgramStateRef StInBound = state->assumeInBound(Idx, SizeDV, true); 964 965 return static_cast<bool>(StInBound); 966 } 967 968 ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C, 969 ProgramStateRef state, 970 const Expr *E, SVal V, 971 bool IsSourceBuffer, 972 const Expr *Size) { 973 Optional<Loc> L = V.getAs<Loc>(); 974 if (!L) 975 return state; 976 977 // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes 978 // some assumptions about the value that CFRefCount can't. Even so, it should 979 // probably be refactored. 980 if (Optional<loc::MemRegionVal> MR = L->getAs<loc::MemRegionVal>()) { 981 const MemRegion *R = MR->getRegion()->StripCasts(); 982 983 // Are we dealing with an ElementRegion? If so, we should be invalidating 984 // the super-region. 985 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { 986 R = ER->getSuperRegion(); 987 // FIXME: What about layers of ElementRegions? 988 } 989 990 // Invalidate this region. 991 const LocationContext *LCtx = C.getPredecessor()->getLocationContext(); 992 993 bool CausesPointerEscape = false; 994 RegionAndSymbolInvalidationTraits ITraits; 995 // Invalidate and escape only indirect regions accessible through the source 996 // buffer. 997 if (IsSourceBuffer) { 998 ITraits.setTrait(R->getBaseRegion(), 999 RegionAndSymbolInvalidationTraits::TK_PreserveContents); 1000 ITraits.setTrait(R, RegionAndSymbolInvalidationTraits::TK_SuppressEscape); 1001 CausesPointerEscape = true; 1002 } else { 1003 const MemRegion::Kind& K = R->getKind(); 1004 if (K == MemRegion::FieldRegionKind) 1005 if (Size && IsFirstBufInBound(C, state, E, Size)) { 1006 // If destination buffer is a field region and access is in bound, 1007 // do not invalidate its super region. 1008 ITraits.setTrait( 1009 R, 1010 RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); 1011 } 1012 } 1013 1014 return state->invalidateRegions(R, E, C.blockCount(), LCtx, 1015 CausesPointerEscape, nullptr, nullptr, 1016 &ITraits); 1017 } 1018 1019 // If we have a non-region value by chance, just remove the binding. 1020 // FIXME: is this necessary or correct? This handles the non-Region 1021 // cases. Is it ever valid to store to these? 1022 return state->killBinding(*L); 1023 } 1024 1025 bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx, 1026 const MemRegion *MR) { 1027 switch (MR->getKind()) { 1028 case MemRegion::FunctionCodeRegionKind: { 1029 if (const auto *FD = cast<FunctionCodeRegion>(MR)->getDecl()) 1030 os << "the address of the function '" << *FD << '\''; 1031 else 1032 os << "the address of a function"; 1033 return true; 1034 } 1035 case MemRegion::BlockCodeRegionKind: 1036 os << "block text"; 1037 return true; 1038 case MemRegion::BlockDataRegionKind: 1039 os << "a block"; 1040 return true; 1041 case MemRegion::CXXThisRegionKind: 1042 case MemRegion::CXXTempObjectRegionKind: 1043 os << "a C++ temp object of type " 1044 << cast<TypedValueRegion>(MR)->getValueType().getAsString(); 1045 return true; 1046 case MemRegion::NonParamVarRegionKind: 1047 os << "a variable of type" 1048 << cast<TypedValueRegion>(MR)->getValueType().getAsString(); 1049 return true; 1050 case MemRegion::ParamVarRegionKind: 1051 os << "a parameter of type" 1052 << cast<TypedValueRegion>(MR)->getValueType().getAsString(); 1053 return true; 1054 case MemRegion::FieldRegionKind: 1055 os << "a field of type " 1056 << cast<TypedValueRegion>(MR)->getValueType().getAsString(); 1057 return true; 1058 case MemRegion::ObjCIvarRegionKind: 1059 os << "an instance variable of type " 1060 << cast<TypedValueRegion>(MR)->getValueType().getAsString(); 1061 return true; 1062 default: 1063 return false; 1064 } 1065 } 1066 1067 bool CStringChecker::memsetAux(const Expr *DstBuffer, SVal CharVal, 1068 const Expr *Size, CheckerContext &C, 1069 ProgramStateRef &State) { 1070 SVal MemVal = C.getSVal(DstBuffer); 1071 SVal SizeVal = C.getSVal(Size); 1072 const MemRegion *MR = MemVal.getAsRegion(); 1073 if (!MR) 1074 return false; 1075 1076 // We're about to model memset by producing a "default binding" in the Store. 1077 // Our current implementation - RegionStore - doesn't support default bindings 1078 // that don't cover the whole base region. So we should first get the offset 1079 // and the base region to figure out whether the offset of buffer is 0. 1080 RegionOffset Offset = MR->getAsOffset(); 1081 const MemRegion *BR = Offset.getRegion(); 1082 1083 Optional<NonLoc> SizeNL = SizeVal.getAs<NonLoc>(); 1084 if (!SizeNL) 1085 return false; 1086 1087 SValBuilder &svalBuilder = C.getSValBuilder(); 1088 ASTContext &Ctx = C.getASTContext(); 1089 1090 // void *memset(void *dest, int ch, size_t count); 1091 // For now we can only handle the case of offset is 0 and concrete char value. 1092 if (Offset.isValid() && !Offset.hasSymbolicOffset() && 1093 Offset.getOffset() == 0) { 1094 // Get the base region's size. 1095 DefinedOrUnknownSVal SizeDV = getDynamicExtent(State, BR, svalBuilder); 1096 1097 ProgramStateRef StateWholeReg, StateNotWholeReg; 1098 std::tie(StateWholeReg, StateNotWholeReg) = 1099 State->assume(svalBuilder.evalEQ(State, SizeDV, *SizeNL)); 1100 1101 // With the semantic of 'memset()', we should convert the CharVal to 1102 // unsigned char. 1103 CharVal = svalBuilder.evalCast(CharVal, Ctx.UnsignedCharTy, Ctx.IntTy); 1104 1105 ProgramStateRef StateNullChar, StateNonNullChar; 1106 std::tie(StateNullChar, StateNonNullChar) = 1107 assumeZero(C, State, CharVal, Ctx.UnsignedCharTy); 1108 1109 if (StateWholeReg && !StateNotWholeReg && StateNullChar && 1110 !StateNonNullChar) { 1111 // If the 'memset()' acts on the whole region of destination buffer and 1112 // the value of the second argument of 'memset()' is zero, bind the second 1113 // argument's value to the destination buffer with 'default binding'. 1114 // FIXME: Since there is no perfect way to bind the non-zero character, we 1115 // can only deal with zero value here. In the future, we need to deal with 1116 // the binding of non-zero value in the case of whole region. 1117 State = State->bindDefaultZero(svalBuilder.makeLoc(BR), 1118 C.getLocationContext()); 1119 } else { 1120 // If the destination buffer's extent is not equal to the value of 1121 // third argument, just invalidate buffer. 1122 State = InvalidateBuffer(C, State, DstBuffer, MemVal, 1123 /*IsSourceBuffer*/ false, Size); 1124 } 1125 1126 if (StateNullChar && !StateNonNullChar) { 1127 // If the value of the second argument of 'memset()' is zero, set the 1128 // string length of destination buffer to 0 directly. 1129 State = setCStringLength(State, MR, 1130 svalBuilder.makeZeroVal(Ctx.getSizeType())); 1131 } else if (!StateNullChar && StateNonNullChar) { 1132 SVal NewStrLen = svalBuilder.getMetadataSymbolVal( 1133 CStringChecker::getTag(), MR, DstBuffer, Ctx.getSizeType(), 1134 C.getLocationContext(), C.blockCount()); 1135 1136 // If the value of second argument is not zero, then the string length 1137 // is at least the size argument. 1138 SVal NewStrLenGESize = svalBuilder.evalBinOp( 1139 State, BO_GE, NewStrLen, SizeVal, svalBuilder.getConditionType()); 1140 1141 State = setCStringLength( 1142 State->assume(NewStrLenGESize.castAs<DefinedOrUnknownSVal>(), true), 1143 MR, NewStrLen); 1144 } 1145 } else { 1146 // If the offset is not zero and char value is not concrete, we can do 1147 // nothing but invalidate the buffer. 1148 State = InvalidateBuffer(C, State, DstBuffer, MemVal, 1149 /*IsSourceBuffer*/ false, Size); 1150 } 1151 return true; 1152 } 1153 1154 //===----------------------------------------------------------------------===// 1155 // evaluation of individual function calls. 1156 //===----------------------------------------------------------------------===// 1157 1158 void CStringChecker::evalCopyCommon(CheckerContext &C, const CallExpr *CE, 1159 ProgramStateRef state, SizeArgExpr Size, 1160 DestinationArgExpr Dest, 1161 SourceArgExpr Source, bool Restricted, 1162 bool IsMempcpy) const { 1163 CurrentFunctionDescription = "memory copy function"; 1164 1165 // See if the size argument is zero. 1166 const LocationContext *LCtx = C.getLocationContext(); 1167 SVal sizeVal = state->getSVal(Size.Expression, LCtx); 1168 QualType sizeTy = Size.Expression->getType(); 1169 1170 ProgramStateRef stateZeroSize, stateNonZeroSize; 1171 std::tie(stateZeroSize, stateNonZeroSize) = 1172 assumeZero(C, state, sizeVal, sizeTy); 1173 1174 // Get the value of the Dest. 1175 SVal destVal = state->getSVal(Dest.Expression, LCtx); 1176 1177 // If the size is zero, there won't be any actual memory access, so 1178 // just bind the return value to the destination buffer and return. 1179 if (stateZeroSize && !stateNonZeroSize) { 1180 stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, destVal); 1181 C.addTransition(stateZeroSize); 1182 return; 1183 } 1184 1185 // If the size can be nonzero, we have to check the other arguments. 1186 if (stateNonZeroSize) { 1187 state = stateNonZeroSize; 1188 1189 // Ensure the destination is not null. If it is NULL there will be a 1190 // NULL pointer dereference. 1191 state = checkNonNull(C, state, Dest, destVal); 1192 if (!state) 1193 return; 1194 1195 // Get the value of the Src. 1196 SVal srcVal = state->getSVal(Source.Expression, LCtx); 1197 1198 // Ensure the source is not null. If it is NULL there will be a 1199 // NULL pointer dereference. 1200 state = checkNonNull(C, state, Source, srcVal); 1201 if (!state) 1202 return; 1203 1204 // Ensure the accesses are valid and that the buffers do not overlap. 1205 state = CheckBufferAccess(C, state, Dest, Size, AccessKind::write); 1206 state = CheckBufferAccess(C, state, Source, Size, AccessKind::read); 1207 1208 if (Restricted) 1209 state = CheckOverlap(C, state, Size, Dest, Source); 1210 1211 if (!state) 1212 return; 1213 1214 // If this is mempcpy, get the byte after the last byte copied and 1215 // bind the expr. 1216 if (IsMempcpy) { 1217 // Get the byte after the last byte copied. 1218 SValBuilder &SvalBuilder = C.getSValBuilder(); 1219 ASTContext &Ctx = SvalBuilder.getContext(); 1220 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy); 1221 SVal DestRegCharVal = 1222 SvalBuilder.evalCast(destVal, CharPtrTy, Dest.Expression->getType()); 1223 SVal lastElement = C.getSValBuilder().evalBinOp( 1224 state, BO_Add, DestRegCharVal, sizeVal, Dest.Expression->getType()); 1225 // If we don't know how much we copied, we can at least 1226 // conjure a return value for later. 1227 if (lastElement.isUnknown()) 1228 lastElement = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, 1229 C.blockCount()); 1230 1231 // The byte after the last byte copied is the return value. 1232 state = state->BindExpr(CE, LCtx, lastElement); 1233 } else { 1234 // All other copies return the destination buffer. 1235 // (Well, bcopy() has a void return type, but this won't hurt.) 1236 state = state->BindExpr(CE, LCtx, destVal); 1237 } 1238 1239 // Invalidate the destination (regular invalidation without pointer-escaping 1240 // the address of the top-level region). 1241 // FIXME: Even if we can't perfectly model the copy, we should see if we 1242 // can use LazyCompoundVals to copy the source values into the destination. 1243 // This would probably remove any existing bindings past the end of the 1244 // copied region, but that's still an improvement over blank invalidation. 1245 state = 1246 InvalidateBuffer(C, state, Dest.Expression, C.getSVal(Dest.Expression), 1247 /*IsSourceBuffer*/ false, Size.Expression); 1248 1249 // Invalidate the source (const-invalidation without const-pointer-escaping 1250 // the address of the top-level region). 1251 state = InvalidateBuffer(C, state, Source.Expression, 1252 C.getSVal(Source.Expression), 1253 /*IsSourceBuffer*/ true, nullptr); 1254 1255 C.addTransition(state); 1256 } 1257 } 1258 1259 void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const { 1260 // void *memcpy(void *restrict dst, const void *restrict src, size_t n); 1261 // The return value is the address of the destination buffer. 1262 DestinationArgExpr Dest = {CE->getArg(0), 0}; 1263 SourceArgExpr Src = {CE->getArg(1), 1}; 1264 SizeArgExpr Size = {CE->getArg(2), 2}; 1265 1266 ProgramStateRef State = C.getState(); 1267 1268 constexpr bool IsRestricted = true; 1269 constexpr bool IsMempcpy = false; 1270 evalCopyCommon(C, CE, State, Size, Dest, Src, IsRestricted, IsMempcpy); 1271 } 1272 1273 void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const { 1274 // void *mempcpy(void *restrict dst, const void *restrict src, size_t n); 1275 // The return value is a pointer to the byte following the last written byte. 1276 DestinationArgExpr Dest = {CE->getArg(0), 0}; 1277 SourceArgExpr Src = {CE->getArg(1), 1}; 1278 SizeArgExpr Size = {CE->getArg(2), 2}; 1279 1280 constexpr bool IsRestricted = true; 1281 constexpr bool IsMempcpy = true; 1282 evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy); 1283 } 1284 1285 void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const { 1286 // void *memmove(void *dst, const void *src, size_t n); 1287 // The return value is the address of the destination buffer. 1288 DestinationArgExpr Dest = {CE->getArg(0), 0}; 1289 SourceArgExpr Src = {CE->getArg(1), 1}; 1290 SizeArgExpr Size = {CE->getArg(2), 2}; 1291 1292 constexpr bool IsRestricted = false; 1293 constexpr bool IsMempcpy = false; 1294 evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy); 1295 } 1296 1297 void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const { 1298 // void bcopy(const void *src, void *dst, size_t n); 1299 SourceArgExpr Src(CE->getArg(0), 0); 1300 DestinationArgExpr Dest = {CE->getArg(1), 1}; 1301 SizeArgExpr Size = {CE->getArg(2), 2}; 1302 1303 constexpr bool IsRestricted = false; 1304 constexpr bool IsMempcpy = false; 1305 evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy); 1306 } 1307 1308 void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const { 1309 // int memcmp(const void *s1, const void *s2, size_t n); 1310 CurrentFunctionDescription = "memory comparison function"; 1311 1312 AnyArgExpr Left = {CE->getArg(0), 0}; 1313 AnyArgExpr Right = {CE->getArg(1), 1}; 1314 SizeArgExpr Size = {CE->getArg(2), 2}; 1315 1316 ProgramStateRef State = C.getState(); 1317 SValBuilder &Builder = C.getSValBuilder(); 1318 const LocationContext *LCtx = C.getLocationContext(); 1319 1320 // See if the size argument is zero. 1321 SVal sizeVal = State->getSVal(Size.Expression, LCtx); 1322 QualType sizeTy = Size.Expression->getType(); 1323 1324 ProgramStateRef stateZeroSize, stateNonZeroSize; 1325 std::tie(stateZeroSize, stateNonZeroSize) = 1326 assumeZero(C, State, sizeVal, sizeTy); 1327 1328 // If the size can be zero, the result will be 0 in that case, and we don't 1329 // have to check either of the buffers. 1330 if (stateZeroSize) { 1331 State = stateZeroSize; 1332 State = State->BindExpr(CE, LCtx, Builder.makeZeroVal(CE->getType())); 1333 C.addTransition(State); 1334 } 1335 1336 // If the size can be nonzero, we have to check the other arguments. 1337 if (stateNonZeroSize) { 1338 State = stateNonZeroSize; 1339 // If we know the two buffers are the same, we know the result is 0. 1340 // First, get the two buffers' addresses. Another checker will have already 1341 // made sure they're not undefined. 1342 DefinedOrUnknownSVal LV = 1343 State->getSVal(Left.Expression, LCtx).castAs<DefinedOrUnknownSVal>(); 1344 DefinedOrUnknownSVal RV = 1345 State->getSVal(Right.Expression, LCtx).castAs<DefinedOrUnknownSVal>(); 1346 1347 // See if they are the same. 1348 ProgramStateRef SameBuffer, NotSameBuffer; 1349 std::tie(SameBuffer, NotSameBuffer) = 1350 State->assume(Builder.evalEQ(State, LV, RV)); 1351 1352 // If the two arguments are the same buffer, we know the result is 0, 1353 // and we only need to check one size. 1354 if (SameBuffer && !NotSameBuffer) { 1355 State = SameBuffer; 1356 State = CheckBufferAccess(C, State, Left, Size, AccessKind::read); 1357 if (State) { 1358 State = 1359 SameBuffer->BindExpr(CE, LCtx, Builder.makeZeroVal(CE->getType())); 1360 C.addTransition(State); 1361 } 1362 return; 1363 } 1364 1365 // If the two arguments might be different buffers, we have to check 1366 // the size of both of them. 1367 assert(NotSameBuffer); 1368 State = CheckBufferAccess(C, State, Right, Size, AccessKind::read); 1369 State = CheckBufferAccess(C, State, Left, Size, AccessKind::read); 1370 if (State) { 1371 // The return value is the comparison result, which we don't know. 1372 SVal CmpV = Builder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); 1373 State = State->BindExpr(CE, LCtx, CmpV); 1374 C.addTransition(State); 1375 } 1376 } 1377 } 1378 1379 void CStringChecker::evalstrLength(CheckerContext &C, 1380 const CallExpr *CE) const { 1381 // size_t strlen(const char *s); 1382 evalstrLengthCommon(C, CE, /* IsStrnlen = */ false); 1383 } 1384 1385 void CStringChecker::evalstrnLength(CheckerContext &C, 1386 const CallExpr *CE) const { 1387 // size_t strnlen(const char *s, size_t maxlen); 1388 evalstrLengthCommon(C, CE, /* IsStrnlen = */ true); 1389 } 1390 1391 void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, 1392 bool IsStrnlen) const { 1393 CurrentFunctionDescription = "string length function"; 1394 ProgramStateRef state = C.getState(); 1395 const LocationContext *LCtx = C.getLocationContext(); 1396 1397 if (IsStrnlen) { 1398 const Expr *maxlenExpr = CE->getArg(1); 1399 SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); 1400 1401 ProgramStateRef stateZeroSize, stateNonZeroSize; 1402 std::tie(stateZeroSize, stateNonZeroSize) = 1403 assumeZero(C, state, maxlenVal, maxlenExpr->getType()); 1404 1405 // If the size can be zero, the result will be 0 in that case, and we don't 1406 // have to check the string itself. 1407 if (stateZeroSize) { 1408 SVal zero = C.getSValBuilder().makeZeroVal(CE->getType()); 1409 stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, zero); 1410 C.addTransition(stateZeroSize); 1411 } 1412 1413 // If the size is GUARANTEED to be zero, we're done! 1414 if (!stateNonZeroSize) 1415 return; 1416 1417 // Otherwise, record the assumption that the size is nonzero. 1418 state = stateNonZeroSize; 1419 } 1420 1421 // Check that the string argument is non-null. 1422 AnyArgExpr Arg = {CE->getArg(0), 0}; 1423 SVal ArgVal = state->getSVal(Arg.Expression, LCtx); 1424 state = checkNonNull(C, state, Arg, ArgVal); 1425 1426 if (!state) 1427 return; 1428 1429 SVal strLength = getCStringLength(C, state, Arg.Expression, ArgVal); 1430 1431 // If the argument isn't a valid C string, there's no valid state to 1432 // transition to. 1433 if (strLength.isUndef()) 1434 return; 1435 1436 DefinedOrUnknownSVal result = UnknownVal(); 1437 1438 // If the check is for strnlen() then bind the return value to no more than 1439 // the maxlen value. 1440 if (IsStrnlen) { 1441 QualType cmpTy = C.getSValBuilder().getConditionType(); 1442 1443 // It's a little unfortunate to be getting this again, 1444 // but it's not that expensive... 1445 const Expr *maxlenExpr = CE->getArg(1); 1446 SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); 1447 1448 Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>(); 1449 Optional<NonLoc> maxlenValNL = maxlenVal.getAs<NonLoc>(); 1450 1451 if (strLengthNL && maxlenValNL) { 1452 ProgramStateRef stateStringTooLong, stateStringNotTooLong; 1453 1454 // Check if the strLength is greater than the maxlen. 1455 std::tie(stateStringTooLong, stateStringNotTooLong) = state->assume( 1456 C.getSValBuilder() 1457 .evalBinOpNN(state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy) 1458 .castAs<DefinedOrUnknownSVal>()); 1459 1460 if (stateStringTooLong && !stateStringNotTooLong) { 1461 // If the string is longer than maxlen, return maxlen. 1462 result = *maxlenValNL; 1463 } else if (stateStringNotTooLong && !stateStringTooLong) { 1464 // If the string is shorter than maxlen, return its length. 1465 result = *strLengthNL; 1466 } 1467 } 1468 1469 if (result.isUnknown()) { 1470 // If we don't have enough information for a comparison, there's 1471 // no guarantee the full string length will actually be returned. 1472 // All we know is the return value is the min of the string length 1473 // and the limit. This is better than nothing. 1474 result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, 1475 C.blockCount()); 1476 NonLoc resultNL = result.castAs<NonLoc>(); 1477 1478 if (strLengthNL) { 1479 state = state->assume(C.getSValBuilder().evalBinOpNN( 1480 state, BO_LE, resultNL, *strLengthNL, cmpTy) 1481 .castAs<DefinedOrUnknownSVal>(), true); 1482 } 1483 1484 if (maxlenValNL) { 1485 state = state->assume(C.getSValBuilder().evalBinOpNN( 1486 state, BO_LE, resultNL, *maxlenValNL, cmpTy) 1487 .castAs<DefinedOrUnknownSVal>(), true); 1488 } 1489 } 1490 1491 } else { 1492 // This is a plain strlen(), not strnlen(). 1493 result = strLength.castAs<DefinedOrUnknownSVal>(); 1494 1495 // If we don't know the length of the string, conjure a return 1496 // value, so it can be used in constraints, at least. 1497 if (result.isUnknown()) { 1498 result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, 1499 C.blockCount()); 1500 } 1501 } 1502 1503 // Bind the return value. 1504 assert(!result.isUnknown() && "Should have conjured a value by now"); 1505 state = state->BindExpr(CE, LCtx, result); 1506 C.addTransition(state); 1507 } 1508 1509 void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const { 1510 // char *strcpy(char *restrict dst, const char *restrict src); 1511 evalStrcpyCommon(C, CE, 1512 /* ReturnEnd = */ false, 1513 /* IsBounded = */ false, 1514 /* appendK = */ ConcatFnKind::none); 1515 } 1516 1517 void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const { 1518 // char *strncpy(char *restrict dst, const char *restrict src, size_t n); 1519 evalStrcpyCommon(C, CE, 1520 /* ReturnEnd = */ false, 1521 /* IsBounded = */ true, 1522 /* appendK = */ ConcatFnKind::none); 1523 } 1524 1525 void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const { 1526 // char *stpcpy(char *restrict dst, const char *restrict src); 1527 evalStrcpyCommon(C, CE, 1528 /* ReturnEnd = */ true, 1529 /* IsBounded = */ false, 1530 /* appendK = */ ConcatFnKind::none); 1531 } 1532 1533 void CStringChecker::evalStrlcpy(CheckerContext &C, const CallExpr *CE) const { 1534 // size_t strlcpy(char *dest, const char *src, size_t size); 1535 evalStrcpyCommon(C, CE, 1536 /* ReturnEnd = */ true, 1537 /* IsBounded = */ true, 1538 /* appendK = */ ConcatFnKind::none, 1539 /* returnPtr = */ false); 1540 } 1541 1542 void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const { 1543 // char *strcat(char *restrict s1, const char *restrict s2); 1544 evalStrcpyCommon(C, CE, 1545 /* ReturnEnd = */ false, 1546 /* IsBounded = */ false, 1547 /* appendK = */ ConcatFnKind::strcat); 1548 } 1549 1550 void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const { 1551 // char *strncat(char *restrict s1, const char *restrict s2, size_t n); 1552 evalStrcpyCommon(C, CE, 1553 /* ReturnEnd = */ false, 1554 /* IsBounded = */ true, 1555 /* appendK = */ ConcatFnKind::strcat); 1556 } 1557 1558 void CStringChecker::evalStrlcat(CheckerContext &C, const CallExpr *CE) const { 1559 // size_t strlcat(char *dst, const char *src, size_t size); 1560 // It will append at most size - strlen(dst) - 1 bytes, 1561 // NULL-terminating the result. 1562 evalStrcpyCommon(C, CE, 1563 /* ReturnEnd = */ false, 1564 /* IsBounded = */ true, 1565 /* appendK = */ ConcatFnKind::strlcat, 1566 /* returnPtr = */ false); 1567 } 1568 1569 void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, 1570 bool ReturnEnd, bool IsBounded, 1571 ConcatFnKind appendK, 1572 bool returnPtr) const { 1573 if (appendK == ConcatFnKind::none) 1574 CurrentFunctionDescription = "string copy function"; 1575 else 1576 CurrentFunctionDescription = "string concatenation function"; 1577 1578 ProgramStateRef state = C.getState(); 1579 const LocationContext *LCtx = C.getLocationContext(); 1580 1581 // Check that the destination is non-null. 1582 DestinationArgExpr Dst = {CE->getArg(0), 0}; 1583 SVal DstVal = state->getSVal(Dst.Expression, LCtx); 1584 state = checkNonNull(C, state, Dst, DstVal); 1585 if (!state) 1586 return; 1587 1588 // Check that the source is non-null. 1589 SourceArgExpr srcExpr = {CE->getArg(1), 1}; 1590 SVal srcVal = state->getSVal(srcExpr.Expression, LCtx); 1591 state = checkNonNull(C, state, srcExpr, srcVal); 1592 if (!state) 1593 return; 1594 1595 // Get the string length of the source. 1596 SVal strLength = getCStringLength(C, state, srcExpr.Expression, srcVal); 1597 Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>(); 1598 1599 // Get the string length of the destination buffer. 1600 SVal dstStrLength = getCStringLength(C, state, Dst.Expression, DstVal); 1601 Optional<NonLoc> dstStrLengthNL = dstStrLength.getAs<NonLoc>(); 1602 1603 // If the source isn't a valid C string, give up. 1604 if (strLength.isUndef()) 1605 return; 1606 1607 SValBuilder &svalBuilder = C.getSValBuilder(); 1608 QualType cmpTy = svalBuilder.getConditionType(); 1609 QualType sizeTy = svalBuilder.getContext().getSizeType(); 1610 1611 // These two values allow checking two kinds of errors: 1612 // - actual overflows caused by a source that doesn't fit in the destination 1613 // - potential overflows caused by a bound that could exceed the destination 1614 SVal amountCopied = UnknownVal(); 1615 SVal maxLastElementIndex = UnknownVal(); 1616 const char *boundWarning = nullptr; 1617 1618 // FIXME: Why do we choose the srcExpr if the access has no size? 1619 // Note that the 3rd argument of the call would be the size parameter. 1620 SizeArgExpr SrcExprAsSizeDummy = {srcExpr.Expression, srcExpr.ArgumentIndex}; 1621 state = CheckOverlap( 1622 C, state, 1623 (IsBounded ? SizeArgExpr{CE->getArg(2), 2} : SrcExprAsSizeDummy), Dst, 1624 srcExpr); 1625 1626 if (!state) 1627 return; 1628 1629 // If the function is strncpy, strncat, etc... it is bounded. 1630 if (IsBounded) { 1631 // Get the max number of characters to copy. 1632 SizeArgExpr lenExpr = {CE->getArg(2), 2}; 1633 SVal lenVal = state->getSVal(lenExpr.Expression, LCtx); 1634 1635 // Protect against misdeclared strncpy(). 1636 lenVal = 1637 svalBuilder.evalCast(lenVal, sizeTy, lenExpr.Expression->getType()); 1638 1639 Optional<NonLoc> lenValNL = lenVal.getAs<NonLoc>(); 1640 1641 // If we know both values, we might be able to figure out how much 1642 // we're copying. 1643 if (strLengthNL && lenValNL) { 1644 switch (appendK) { 1645 case ConcatFnKind::none: 1646 case ConcatFnKind::strcat: { 1647 ProgramStateRef stateSourceTooLong, stateSourceNotTooLong; 1648 // Check if the max number to copy is less than the length of the src. 1649 // If the bound is equal to the source length, strncpy won't null- 1650 // terminate the result! 1651 std::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume( 1652 svalBuilder 1653 .evalBinOpNN(state, BO_GE, *strLengthNL, *lenValNL, cmpTy) 1654 .castAs<DefinedOrUnknownSVal>()); 1655 1656 if (stateSourceTooLong && !stateSourceNotTooLong) { 1657 // Max number to copy is less than the length of the src, so the 1658 // actual strLength copied is the max number arg. 1659 state = stateSourceTooLong; 1660 amountCopied = lenVal; 1661 1662 } else if (!stateSourceTooLong && stateSourceNotTooLong) { 1663 // The source buffer entirely fits in the bound. 1664 state = stateSourceNotTooLong; 1665 amountCopied = strLength; 1666 } 1667 break; 1668 } 1669 case ConcatFnKind::strlcat: 1670 if (!dstStrLengthNL) 1671 return; 1672 1673 // amountCopied = min (size - dstLen - 1 , srcLen) 1674 SVal freeSpace = svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL, 1675 *dstStrLengthNL, sizeTy); 1676 if (!freeSpace.getAs<NonLoc>()) 1677 return; 1678 freeSpace = 1679 svalBuilder.evalBinOp(state, BO_Sub, freeSpace, 1680 svalBuilder.makeIntVal(1, sizeTy), sizeTy); 1681 Optional<NonLoc> freeSpaceNL = freeSpace.getAs<NonLoc>(); 1682 1683 // While unlikely, it is possible that the subtraction is 1684 // too complex to compute, let's check whether it succeeded. 1685 if (!freeSpaceNL) 1686 return; 1687 SVal hasEnoughSpace = svalBuilder.evalBinOpNN( 1688 state, BO_LE, *strLengthNL, *freeSpaceNL, cmpTy); 1689 1690 ProgramStateRef TrueState, FalseState; 1691 std::tie(TrueState, FalseState) = 1692 state->assume(hasEnoughSpace.castAs<DefinedOrUnknownSVal>()); 1693 1694 // srcStrLength <= size - dstStrLength -1 1695 if (TrueState && !FalseState) { 1696 amountCopied = strLength; 1697 } 1698 1699 // srcStrLength > size - dstStrLength -1 1700 if (!TrueState && FalseState) { 1701 amountCopied = freeSpace; 1702 } 1703 1704 if (TrueState && FalseState) 1705 amountCopied = UnknownVal(); 1706 break; 1707 } 1708 } 1709 // We still want to know if the bound is known to be too large. 1710 if (lenValNL) { 1711 switch (appendK) { 1712 case ConcatFnKind::strcat: 1713 // For strncat, the check is strlen(dst) + lenVal < sizeof(dst) 1714 1715 // Get the string length of the destination. If the destination is 1716 // memory that can't have a string length, we shouldn't be copying 1717 // into it anyway. 1718 if (dstStrLength.isUndef()) 1719 return; 1720 1721 if (dstStrLengthNL) { 1722 maxLastElementIndex = svalBuilder.evalBinOpNN( 1723 state, BO_Add, *lenValNL, *dstStrLengthNL, sizeTy); 1724 1725 boundWarning = "Size argument is greater than the free space in the " 1726 "destination buffer"; 1727 } 1728 break; 1729 case ConcatFnKind::none: 1730 case ConcatFnKind::strlcat: 1731 // For strncpy and strlcat, this is just checking 1732 // that lenVal <= sizeof(dst). 1733 // (Yes, strncpy and strncat differ in how they treat termination. 1734 // strncat ALWAYS terminates, but strncpy doesn't.) 1735 1736 // We need a special case for when the copy size is zero, in which 1737 // case strncpy will do no work at all. Our bounds check uses n-1 1738 // as the last element accessed, so n == 0 is problematic. 1739 ProgramStateRef StateZeroSize, StateNonZeroSize; 1740 std::tie(StateZeroSize, StateNonZeroSize) = 1741 assumeZero(C, state, *lenValNL, sizeTy); 1742 1743 // If the size is known to be zero, we're done. 1744 if (StateZeroSize && !StateNonZeroSize) { 1745 if (returnPtr) { 1746 StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, DstVal); 1747 } else { 1748 if (appendK == ConcatFnKind::none) { 1749 // strlcpy returns strlen(src) 1750 StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, strLength); 1751 } else { 1752 // strlcat returns strlen(src) + strlen(dst) 1753 SVal retSize = svalBuilder.evalBinOp( 1754 state, BO_Add, strLength, dstStrLength, sizeTy); 1755 StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, retSize); 1756 } 1757 } 1758 C.addTransition(StateZeroSize); 1759 return; 1760 } 1761 1762 // Otherwise, go ahead and figure out the last element we'll touch. 1763 // We don't record the non-zero assumption here because we can't 1764 // be sure. We won't warn on a possible zero. 1765 NonLoc one = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>(); 1766 maxLastElementIndex = 1767 svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL, one, sizeTy); 1768 boundWarning = "Size argument is greater than the length of the " 1769 "destination buffer"; 1770 break; 1771 } 1772 } 1773 } else { 1774 // The function isn't bounded. The amount copied should match the length 1775 // of the source buffer. 1776 amountCopied = strLength; 1777 } 1778 1779 assert(state); 1780 1781 // This represents the number of characters copied into the destination 1782 // buffer. (It may not actually be the strlen if the destination buffer 1783 // is not terminated.) 1784 SVal finalStrLength = UnknownVal(); 1785 SVal strlRetVal = UnknownVal(); 1786 1787 if (appendK == ConcatFnKind::none && !returnPtr) { 1788 // strlcpy returns the sizeof(src) 1789 strlRetVal = strLength; 1790 } 1791 1792 // If this is an appending function (strcat, strncat...) then set the 1793 // string length to strlen(src) + strlen(dst) since the buffer will 1794 // ultimately contain both. 1795 if (appendK != ConcatFnKind::none) { 1796 // Get the string length of the destination. If the destination is memory 1797 // that can't have a string length, we shouldn't be copying into it anyway. 1798 if (dstStrLength.isUndef()) 1799 return; 1800 1801 if (appendK == ConcatFnKind::strlcat && dstStrLengthNL && strLengthNL) { 1802 strlRetVal = svalBuilder.evalBinOpNN(state, BO_Add, *strLengthNL, 1803 *dstStrLengthNL, sizeTy); 1804 } 1805 1806 Optional<NonLoc> amountCopiedNL = amountCopied.getAs<NonLoc>(); 1807 1808 // If we know both string lengths, we might know the final string length. 1809 if (amountCopiedNL && dstStrLengthNL) { 1810 // Make sure the two lengths together don't overflow a size_t. 1811 state = checkAdditionOverflow(C, state, *amountCopiedNL, *dstStrLengthNL); 1812 if (!state) 1813 return; 1814 1815 finalStrLength = svalBuilder.evalBinOpNN(state, BO_Add, *amountCopiedNL, 1816 *dstStrLengthNL, sizeTy); 1817 } 1818 1819 // If we couldn't get a single value for the final string length, 1820 // we can at least bound it by the individual lengths. 1821 if (finalStrLength.isUnknown()) { 1822 // Try to get a "hypothetical" string length symbol, which we can later 1823 // set as a real value if that turns out to be the case. 1824 finalStrLength = getCStringLength(C, state, CE, DstVal, true); 1825 assert(!finalStrLength.isUndef()); 1826 1827 if (Optional<NonLoc> finalStrLengthNL = finalStrLength.getAs<NonLoc>()) { 1828 if (amountCopiedNL && appendK == ConcatFnKind::none) { 1829 // we overwrite dst string with the src 1830 // finalStrLength >= srcStrLength 1831 SVal sourceInResult = svalBuilder.evalBinOpNN( 1832 state, BO_GE, *finalStrLengthNL, *amountCopiedNL, cmpTy); 1833 state = state->assume(sourceInResult.castAs<DefinedOrUnknownSVal>(), 1834 true); 1835 if (!state) 1836 return; 1837 } 1838 1839 if (dstStrLengthNL && appendK != ConcatFnKind::none) { 1840 // we extend the dst string with the src 1841 // finalStrLength >= dstStrLength 1842 SVal destInResult = svalBuilder.evalBinOpNN(state, BO_GE, 1843 *finalStrLengthNL, 1844 *dstStrLengthNL, 1845 cmpTy); 1846 state = 1847 state->assume(destInResult.castAs<DefinedOrUnknownSVal>(), true); 1848 if (!state) 1849 return; 1850 } 1851 } 1852 } 1853 1854 } else { 1855 // Otherwise, this is a copy-over function (strcpy, strncpy, ...), and 1856 // the final string length will match the input string length. 1857 finalStrLength = amountCopied; 1858 } 1859 1860 SVal Result; 1861 1862 if (returnPtr) { 1863 // The final result of the function will either be a pointer past the last 1864 // copied element, or a pointer to the start of the destination buffer. 1865 Result = (ReturnEnd ? UnknownVal() : DstVal); 1866 } else { 1867 if (appendK == ConcatFnKind::strlcat || appendK == ConcatFnKind::none) 1868 //strlcpy, strlcat 1869 Result = strlRetVal; 1870 else 1871 Result = finalStrLength; 1872 } 1873 1874 assert(state); 1875 1876 // If the destination is a MemRegion, try to check for a buffer overflow and 1877 // record the new string length. 1878 if (Optional<loc::MemRegionVal> dstRegVal = 1879 DstVal.getAs<loc::MemRegionVal>()) { 1880 QualType ptrTy = Dst.Expression->getType(); 1881 1882 // If we have an exact value on a bounded copy, use that to check for 1883 // overflows, rather than our estimate about how much is actually copied. 1884 if (Optional<NonLoc> maxLastNL = maxLastElementIndex.getAs<NonLoc>()) { 1885 SVal maxLastElement = 1886 svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal, *maxLastNL, ptrTy); 1887 1888 state = CheckLocation(C, state, Dst, maxLastElement, AccessKind::write); 1889 if (!state) 1890 return; 1891 } 1892 1893 // Then, if the final length is known... 1894 if (Optional<NonLoc> knownStrLength = finalStrLength.getAs<NonLoc>()) { 1895 SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal, 1896 *knownStrLength, ptrTy); 1897 1898 // ...and we haven't checked the bound, we'll check the actual copy. 1899 if (!boundWarning) { 1900 state = CheckLocation(C, state, Dst, lastElement, AccessKind::write); 1901 if (!state) 1902 return; 1903 } 1904 1905 // If this is a stpcpy-style copy, the last element is the return value. 1906 if (returnPtr && ReturnEnd) 1907 Result = lastElement; 1908 } 1909 1910 // Invalidate the destination (regular invalidation without pointer-escaping 1911 // the address of the top-level region). This must happen before we set the 1912 // C string length because invalidation will clear the length. 1913 // FIXME: Even if we can't perfectly model the copy, we should see if we 1914 // can use LazyCompoundVals to copy the source values into the destination. 1915 // This would probably remove any existing bindings past the end of the 1916 // string, but that's still an improvement over blank invalidation. 1917 state = InvalidateBuffer(C, state, Dst.Expression, *dstRegVal, 1918 /*IsSourceBuffer*/ false, nullptr); 1919 1920 // Invalidate the source (const-invalidation without const-pointer-escaping 1921 // the address of the top-level region). 1922 state = InvalidateBuffer(C, state, srcExpr.Expression, srcVal, 1923 /*IsSourceBuffer*/ true, nullptr); 1924 1925 // Set the C string length of the destination, if we know it. 1926 if (IsBounded && (appendK == ConcatFnKind::none)) { 1927 // strncpy is annoying in that it doesn't guarantee to null-terminate 1928 // the result string. If the original string didn't fit entirely inside 1929 // the bound (including the null-terminator), we don't know how long the 1930 // result is. 1931 if (amountCopied != strLength) 1932 finalStrLength = UnknownVal(); 1933 } 1934 state = setCStringLength(state, dstRegVal->getRegion(), finalStrLength); 1935 } 1936 1937 assert(state); 1938 1939 if (returnPtr) { 1940 // If this is a stpcpy-style copy, but we were unable to check for a buffer 1941 // overflow, we still need a result. Conjure a return value. 1942 if (ReturnEnd && Result.isUnknown()) { 1943 Result = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); 1944 } 1945 } 1946 // Set the return value. 1947 state = state->BindExpr(CE, LCtx, Result); 1948 C.addTransition(state); 1949 } 1950 1951 void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const { 1952 //int strcmp(const char *s1, const char *s2); 1953 evalStrcmpCommon(C, CE, /* IsBounded = */ false, /* IgnoreCase = */ false); 1954 } 1955 1956 void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const { 1957 //int strncmp(const char *s1, const char *s2, size_t n); 1958 evalStrcmpCommon(C, CE, /* IsBounded = */ true, /* IgnoreCase = */ false); 1959 } 1960 1961 void CStringChecker::evalStrcasecmp(CheckerContext &C, 1962 const CallExpr *CE) const { 1963 //int strcasecmp(const char *s1, const char *s2); 1964 evalStrcmpCommon(C, CE, /* IsBounded = */ false, /* IgnoreCase = */ true); 1965 } 1966 1967 void CStringChecker::evalStrncasecmp(CheckerContext &C, 1968 const CallExpr *CE) const { 1969 //int strncasecmp(const char *s1, const char *s2, size_t n); 1970 evalStrcmpCommon(C, CE, /* IsBounded = */ true, /* IgnoreCase = */ true); 1971 } 1972 1973 void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, 1974 bool IsBounded, bool IgnoreCase) const { 1975 CurrentFunctionDescription = "string comparison function"; 1976 ProgramStateRef state = C.getState(); 1977 const LocationContext *LCtx = C.getLocationContext(); 1978 1979 // Check that the first string is non-null 1980 AnyArgExpr Left = {CE->getArg(0), 0}; 1981 SVal LeftVal = state->getSVal(Left.Expression, LCtx); 1982 state = checkNonNull(C, state, Left, LeftVal); 1983 if (!state) 1984 return; 1985 1986 // Check that the second string is non-null. 1987 AnyArgExpr Right = {CE->getArg(1), 1}; 1988 SVal RightVal = state->getSVal(Right.Expression, LCtx); 1989 state = checkNonNull(C, state, Right, RightVal); 1990 if (!state) 1991 return; 1992 1993 // Get the string length of the first string or give up. 1994 SVal LeftLength = getCStringLength(C, state, Left.Expression, LeftVal); 1995 if (LeftLength.isUndef()) 1996 return; 1997 1998 // Get the string length of the second string or give up. 1999 SVal RightLength = getCStringLength(C, state, Right.Expression, RightVal); 2000 if (RightLength.isUndef()) 2001 return; 2002 2003 // If we know the two buffers are the same, we know the result is 0. 2004 // First, get the two buffers' addresses. Another checker will have already 2005 // made sure they're not undefined. 2006 DefinedOrUnknownSVal LV = LeftVal.castAs<DefinedOrUnknownSVal>(); 2007 DefinedOrUnknownSVal RV = RightVal.castAs<DefinedOrUnknownSVal>(); 2008 2009 // See if they are the same. 2010 SValBuilder &svalBuilder = C.getSValBuilder(); 2011 DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV); 2012 ProgramStateRef StSameBuf, StNotSameBuf; 2013 std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf); 2014 2015 // If the two arguments might be the same buffer, we know the result is 0, 2016 // and we only need to check one size. 2017 if (StSameBuf) { 2018 StSameBuf = StSameBuf->BindExpr(CE, LCtx, 2019 svalBuilder.makeZeroVal(CE->getType())); 2020 C.addTransition(StSameBuf); 2021 2022 // If the two arguments are GUARANTEED to be the same, we're done! 2023 if (!StNotSameBuf) 2024 return; 2025 } 2026 2027 assert(StNotSameBuf); 2028 state = StNotSameBuf; 2029 2030 // At this point we can go about comparing the two buffers. 2031 // For now, we only do this if they're both known string literals. 2032 2033 // Attempt to extract string literals from both expressions. 2034 const StringLiteral *LeftStrLiteral = 2035 getCStringLiteral(C, state, Left.Expression, LeftVal); 2036 const StringLiteral *RightStrLiteral = 2037 getCStringLiteral(C, state, Right.Expression, RightVal); 2038 bool canComputeResult = false; 2039 SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, 2040 C.blockCount()); 2041 2042 if (LeftStrLiteral && RightStrLiteral) { 2043 StringRef LeftStrRef = LeftStrLiteral->getString(); 2044 StringRef RightStrRef = RightStrLiteral->getString(); 2045 2046 if (IsBounded) { 2047 // Get the max number of characters to compare. 2048 const Expr *lenExpr = CE->getArg(2); 2049 SVal lenVal = state->getSVal(lenExpr, LCtx); 2050 2051 // If the length is known, we can get the right substrings. 2052 if (const llvm::APSInt *len = svalBuilder.getKnownValue(state, lenVal)) { 2053 // Create substrings of each to compare the prefix. 2054 LeftStrRef = LeftStrRef.substr(0, (size_t)len->getZExtValue()); 2055 RightStrRef = RightStrRef.substr(0, (size_t)len->getZExtValue()); 2056 canComputeResult = true; 2057 } 2058 } else { 2059 // This is a normal, unbounded strcmp. 2060 canComputeResult = true; 2061 } 2062 2063 if (canComputeResult) { 2064 // Real strcmp stops at null characters. 2065 size_t s1Term = LeftStrRef.find('\0'); 2066 if (s1Term != StringRef::npos) 2067 LeftStrRef = LeftStrRef.substr(0, s1Term); 2068 2069 size_t s2Term = RightStrRef.find('\0'); 2070 if (s2Term != StringRef::npos) 2071 RightStrRef = RightStrRef.substr(0, s2Term); 2072 2073 // Use StringRef's comparison methods to compute the actual result. 2074 int compareRes = IgnoreCase ? LeftStrRef.compare_insensitive(RightStrRef) 2075 : LeftStrRef.compare(RightStrRef); 2076 2077 // The strcmp function returns an integer greater than, equal to, or less 2078 // than zero, [c11, p7.24.4.2]. 2079 if (compareRes == 0) { 2080 resultVal = svalBuilder.makeIntVal(compareRes, CE->getType()); 2081 } 2082 else { 2083 DefinedSVal zeroVal = svalBuilder.makeIntVal(0, CE->getType()); 2084 // Constrain strcmp's result range based on the result of StringRef's 2085 // comparison methods. 2086 BinaryOperatorKind op = (compareRes == 1) ? BO_GT : BO_LT; 2087 SVal compareWithZero = 2088 svalBuilder.evalBinOp(state, op, resultVal, zeroVal, 2089 svalBuilder.getConditionType()); 2090 DefinedSVal compareWithZeroVal = compareWithZero.castAs<DefinedSVal>(); 2091 state = state->assume(compareWithZeroVal, true); 2092 } 2093 } 2094 } 2095 2096 state = state->BindExpr(CE, LCtx, resultVal); 2097 2098 // Record this as a possible path. 2099 C.addTransition(state); 2100 } 2101 2102 void CStringChecker::evalStrsep(CheckerContext &C, const CallExpr *CE) const { 2103 // char *strsep(char **stringp, const char *delim); 2104 // Verify whether the search string parameter matches the return type. 2105 SourceArgExpr SearchStrPtr = {CE->getArg(0), 0}; 2106 2107 QualType CharPtrTy = SearchStrPtr.Expression->getType()->getPointeeType(); 2108 if (CharPtrTy.isNull() || 2109 CE->getType().getUnqualifiedType() != CharPtrTy.getUnqualifiedType()) 2110 return; 2111 2112 CurrentFunctionDescription = "strsep()"; 2113 ProgramStateRef State = C.getState(); 2114 const LocationContext *LCtx = C.getLocationContext(); 2115 2116 // Check that the search string pointer is non-null (though it may point to 2117 // a null string). 2118 SVal SearchStrVal = State->getSVal(SearchStrPtr.Expression, LCtx); 2119 State = checkNonNull(C, State, SearchStrPtr, SearchStrVal); 2120 if (!State) 2121 return; 2122 2123 // Check that the delimiter string is non-null. 2124 AnyArgExpr DelimStr = {CE->getArg(1), 1}; 2125 SVal DelimStrVal = State->getSVal(DelimStr.Expression, LCtx); 2126 State = checkNonNull(C, State, DelimStr, DelimStrVal); 2127 if (!State) 2128 return; 2129 2130 SValBuilder &SVB = C.getSValBuilder(); 2131 SVal Result; 2132 if (Optional<Loc> SearchStrLoc = SearchStrVal.getAs<Loc>()) { 2133 // Get the current value of the search string pointer, as a char*. 2134 Result = State->getSVal(*SearchStrLoc, CharPtrTy); 2135 2136 // Invalidate the search string, representing the change of one delimiter 2137 // character to NUL. 2138 State = InvalidateBuffer(C, State, SearchStrPtr.Expression, Result, 2139 /*IsSourceBuffer*/ false, nullptr); 2140 2141 // Overwrite the search string pointer. The new value is either an address 2142 // further along in the same string, or NULL if there are no more tokens. 2143 State = State->bindLoc(*SearchStrLoc, 2144 SVB.conjureSymbolVal(getTag(), 2145 CE, 2146 LCtx, 2147 CharPtrTy, 2148 C.blockCount()), 2149 LCtx); 2150 } else { 2151 assert(SearchStrVal.isUnknown()); 2152 // Conjure a symbolic value. It's the best we can do. 2153 Result = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); 2154 } 2155 2156 // Set the return value, and finish. 2157 State = State->BindExpr(CE, LCtx, Result); 2158 C.addTransition(State); 2159 } 2160 2161 // These should probably be moved into a C++ standard library checker. 2162 void CStringChecker::evalStdCopy(CheckerContext &C, const CallExpr *CE) const { 2163 evalStdCopyCommon(C, CE); 2164 } 2165 2166 void CStringChecker::evalStdCopyBackward(CheckerContext &C, 2167 const CallExpr *CE) const { 2168 evalStdCopyCommon(C, CE); 2169 } 2170 2171 void CStringChecker::evalStdCopyCommon(CheckerContext &C, 2172 const CallExpr *CE) const { 2173 if (!CE->getArg(2)->getType()->isPointerType()) 2174 return; 2175 2176 ProgramStateRef State = C.getState(); 2177 2178 const LocationContext *LCtx = C.getLocationContext(); 2179 2180 // template <class _InputIterator, class _OutputIterator> 2181 // _OutputIterator 2182 // copy(_InputIterator __first, _InputIterator __last, 2183 // _OutputIterator __result) 2184 2185 // Invalidate the destination buffer 2186 const Expr *Dst = CE->getArg(2); 2187 SVal DstVal = State->getSVal(Dst, LCtx); 2188 State = InvalidateBuffer(C, State, Dst, DstVal, /*IsSource=*/false, 2189 /*Size=*/nullptr); 2190 2191 SValBuilder &SVB = C.getSValBuilder(); 2192 2193 SVal ResultVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); 2194 State = State->BindExpr(CE, LCtx, ResultVal); 2195 2196 C.addTransition(State); 2197 } 2198 2199 void CStringChecker::evalMemset(CheckerContext &C, const CallExpr *CE) const { 2200 // void *memset(void *s, int c, size_t n); 2201 CurrentFunctionDescription = "memory set function"; 2202 2203 DestinationArgExpr Buffer = {CE->getArg(0), 0}; 2204 AnyArgExpr CharE = {CE->getArg(1), 1}; 2205 SizeArgExpr Size = {CE->getArg(2), 2}; 2206 2207 ProgramStateRef State = C.getState(); 2208 2209 // See if the size argument is zero. 2210 const LocationContext *LCtx = C.getLocationContext(); 2211 SVal SizeVal = C.getSVal(Size.Expression); 2212 QualType SizeTy = Size.Expression->getType(); 2213 2214 ProgramStateRef ZeroSize, NonZeroSize; 2215 std::tie(ZeroSize, NonZeroSize) = assumeZero(C, State, SizeVal, SizeTy); 2216 2217 // Get the value of the memory area. 2218 SVal BufferPtrVal = C.getSVal(Buffer.Expression); 2219 2220 // If the size is zero, there won't be any actual memory access, so 2221 // just bind the return value to the buffer and return. 2222 if (ZeroSize && !NonZeroSize) { 2223 ZeroSize = ZeroSize->BindExpr(CE, LCtx, BufferPtrVal); 2224 C.addTransition(ZeroSize); 2225 return; 2226 } 2227 2228 // Ensure the memory area is not null. 2229 // If it is NULL there will be a NULL pointer dereference. 2230 State = checkNonNull(C, NonZeroSize, Buffer, BufferPtrVal); 2231 if (!State) 2232 return; 2233 2234 State = CheckBufferAccess(C, State, Buffer, Size, AccessKind::write); 2235 if (!State) 2236 return; 2237 2238 // According to the values of the arguments, bind the value of the second 2239 // argument to the destination buffer and set string length, or just 2240 // invalidate the destination buffer. 2241 if (!memsetAux(Buffer.Expression, C.getSVal(CharE.Expression), 2242 Size.Expression, C, State)) 2243 return; 2244 2245 State = State->BindExpr(CE, LCtx, BufferPtrVal); 2246 C.addTransition(State); 2247 } 2248 2249 void CStringChecker::evalBzero(CheckerContext &C, const CallExpr *CE) const { 2250 CurrentFunctionDescription = "memory clearance function"; 2251 2252 DestinationArgExpr Buffer = {CE->getArg(0), 0}; 2253 SizeArgExpr Size = {CE->getArg(1), 1}; 2254 SVal Zero = C.getSValBuilder().makeZeroVal(C.getASTContext().IntTy); 2255 2256 ProgramStateRef State = C.getState(); 2257 2258 // See if the size argument is zero. 2259 SVal SizeVal = C.getSVal(Size.Expression); 2260 QualType SizeTy = Size.Expression->getType(); 2261 2262 ProgramStateRef StateZeroSize, StateNonZeroSize; 2263 std::tie(StateZeroSize, StateNonZeroSize) = 2264 assumeZero(C, State, SizeVal, SizeTy); 2265 2266 // If the size is zero, there won't be any actual memory access, 2267 // In this case we just return. 2268 if (StateZeroSize && !StateNonZeroSize) { 2269 C.addTransition(StateZeroSize); 2270 return; 2271 } 2272 2273 // Get the value of the memory area. 2274 SVal MemVal = C.getSVal(Buffer.Expression); 2275 2276 // Ensure the memory area is not null. 2277 // If it is NULL there will be a NULL pointer dereference. 2278 State = checkNonNull(C, StateNonZeroSize, Buffer, MemVal); 2279 if (!State) 2280 return; 2281 2282 State = CheckBufferAccess(C, State, Buffer, Size, AccessKind::write); 2283 if (!State) 2284 return; 2285 2286 if (!memsetAux(Buffer.Expression, Zero, Size.Expression, C, State)) 2287 return; 2288 2289 C.addTransition(State); 2290 } 2291 2292 //===----------------------------------------------------------------------===// 2293 // The driver method, and other Checker callbacks. 2294 //===----------------------------------------------------------------------===// 2295 2296 CStringChecker::FnCheck CStringChecker::identifyCall(const CallEvent &Call, 2297 CheckerContext &C) const { 2298 const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr()); 2299 if (!CE) 2300 return nullptr; 2301 2302 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl()); 2303 if (!FD) 2304 return nullptr; 2305 2306 if (StdCopy.matches(Call)) 2307 return &CStringChecker::evalStdCopy; 2308 if (StdCopyBackward.matches(Call)) 2309 return &CStringChecker::evalStdCopyBackward; 2310 2311 // Pro-actively check that argument types are safe to do arithmetic upon. 2312 // We do not want to crash if someone accidentally passes a structure 2313 // into, say, a C++ overload of any of these functions. We could not check 2314 // that for std::copy because they may have arguments of other types. 2315 for (auto I : CE->arguments()) { 2316 QualType T = I->getType(); 2317 if (!T->isIntegralOrEnumerationType() && !T->isPointerType()) 2318 return nullptr; 2319 } 2320 2321 const FnCheck *Callback = Callbacks.lookup(Call); 2322 if (Callback) 2323 return *Callback; 2324 2325 return nullptr; 2326 } 2327 2328 bool CStringChecker::evalCall(const CallEvent &Call, CheckerContext &C) const { 2329 FnCheck Callback = identifyCall(Call, C); 2330 2331 // If the callee isn't a string function, let another checker handle it. 2332 if (!Callback) 2333 return false; 2334 2335 // Check and evaluate the call. 2336 const auto *CE = cast<CallExpr>(Call.getOriginExpr()); 2337 (this->*Callback)(C, CE); 2338 2339 // If the evaluate call resulted in no change, chain to the next eval call 2340 // handler. 2341 // Note, the custom CString evaluation calls assume that basic safety 2342 // properties are held. However, if the user chooses to turn off some of these 2343 // checks, we ignore the issues and leave the call evaluation to a generic 2344 // handler. 2345 return C.isDifferent(); 2346 } 2347 2348 void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const { 2349 // Record string length for char a[] = "abc"; 2350 ProgramStateRef state = C.getState(); 2351 2352 for (const auto *I : DS->decls()) { 2353 const VarDecl *D = dyn_cast<VarDecl>(I); 2354 if (!D) 2355 continue; 2356 2357 // FIXME: Handle array fields of structs. 2358 if (!D->getType()->isArrayType()) 2359 continue; 2360 2361 const Expr *Init = D->getInit(); 2362 if (!Init) 2363 continue; 2364 if (!isa<StringLiteral>(Init)) 2365 continue; 2366 2367 Loc VarLoc = state->getLValue(D, C.getLocationContext()); 2368 const MemRegion *MR = VarLoc.getAsRegion(); 2369 if (!MR) 2370 continue; 2371 2372 SVal StrVal = C.getSVal(Init); 2373 assert(StrVal.isValid() && "Initializer string is unknown or undefined"); 2374 DefinedOrUnknownSVal strLength = 2375 getCStringLength(C, state, Init, StrVal).castAs<DefinedOrUnknownSVal>(); 2376 2377 state = state->set<CStringLength>(MR, strLength); 2378 } 2379 2380 C.addTransition(state); 2381 } 2382 2383 ProgramStateRef 2384 CStringChecker::checkRegionChanges(ProgramStateRef state, 2385 const InvalidatedSymbols *, 2386 ArrayRef<const MemRegion *> ExplicitRegions, 2387 ArrayRef<const MemRegion *> Regions, 2388 const LocationContext *LCtx, 2389 const CallEvent *Call) const { 2390 CStringLengthTy Entries = state->get<CStringLength>(); 2391 if (Entries.isEmpty()) 2392 return state; 2393 2394 llvm::SmallPtrSet<const MemRegion *, 8> Invalidated; 2395 llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions; 2396 2397 // First build sets for the changed regions and their super-regions. 2398 for (ArrayRef<const MemRegion *>::iterator 2399 I = Regions.begin(), E = Regions.end(); I != E; ++I) { 2400 const MemRegion *MR = *I; 2401 Invalidated.insert(MR); 2402 2403 SuperRegions.insert(MR); 2404 while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) { 2405 MR = SR->getSuperRegion(); 2406 SuperRegions.insert(MR); 2407 } 2408 } 2409 2410 CStringLengthTy::Factory &F = state->get_context<CStringLength>(); 2411 2412 // Then loop over the entries in the current state. 2413 for (CStringLengthTy::iterator I = Entries.begin(), 2414 E = Entries.end(); I != E; ++I) { 2415 const MemRegion *MR = I.getKey(); 2416 2417 // Is this entry for a super-region of a changed region? 2418 if (SuperRegions.count(MR)) { 2419 Entries = F.remove(Entries, MR); 2420 continue; 2421 } 2422 2423 // Is this entry for a sub-region of a changed region? 2424 const MemRegion *Super = MR; 2425 while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) { 2426 Super = SR->getSuperRegion(); 2427 if (Invalidated.count(Super)) { 2428 Entries = F.remove(Entries, MR); 2429 break; 2430 } 2431 } 2432 } 2433 2434 return state->set<CStringLength>(Entries); 2435 } 2436 2437 void CStringChecker::checkLiveSymbols(ProgramStateRef state, 2438 SymbolReaper &SR) const { 2439 // Mark all symbols in our string length map as valid. 2440 CStringLengthTy Entries = state->get<CStringLength>(); 2441 2442 for (CStringLengthTy::iterator I = Entries.begin(), E = Entries.end(); 2443 I != E; ++I) { 2444 SVal Len = I.getData(); 2445 2446 for (SymExpr::symbol_iterator si = Len.symbol_begin(), 2447 se = Len.symbol_end(); si != se; ++si) 2448 SR.markInUse(*si); 2449 } 2450 } 2451 2452 void CStringChecker::checkDeadSymbols(SymbolReaper &SR, 2453 CheckerContext &C) const { 2454 ProgramStateRef state = C.getState(); 2455 CStringLengthTy Entries = state->get<CStringLength>(); 2456 if (Entries.isEmpty()) 2457 return; 2458 2459 CStringLengthTy::Factory &F = state->get_context<CStringLength>(); 2460 for (CStringLengthTy::iterator I = Entries.begin(), E = Entries.end(); 2461 I != E; ++I) { 2462 SVal Len = I.getData(); 2463 if (SymbolRef Sym = Len.getAsSymbol()) { 2464 if (SR.isDead(Sym)) 2465 Entries = F.remove(Entries, I.getKey()); 2466 } 2467 } 2468 2469 state = state->set<CStringLength>(Entries); 2470 C.addTransition(state); 2471 } 2472 2473 void ento::registerCStringModeling(CheckerManager &Mgr) { 2474 Mgr.registerChecker<CStringChecker>(); 2475 } 2476 2477 bool ento::shouldRegisterCStringModeling(const CheckerManager &mgr) { 2478 return true; 2479 } 2480 2481 #define REGISTER_CHECKER(name) \ 2482 void ento::register##name(CheckerManager &mgr) { \ 2483 CStringChecker *checker = mgr.getChecker<CStringChecker>(); \ 2484 checker->Filter.Check##name = true; \ 2485 checker->Filter.CheckName##name = mgr.getCurrentCheckerName(); \ 2486 } \ 2487 \ 2488 bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; } 2489 2490 REGISTER_CHECKER(CStringNullArg) 2491 REGISTER_CHECKER(CStringOutOfBounds) 2492 REGISTER_CHECKER(CStringBufferOverlap) 2493 REGISTER_CHECKER(CStringNotNullTerm) 2494 REGISTER_CHECKER(CStringUninitializedRead)