Coverage Report

Created: 2023-09-30 09:22

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