blob: 3c20baa93cf77943aecac1639fafdcd909257662 [file] [log] [blame]
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001//= CStringChecker.h - Checks calls to C string functions ----------*- C++ -*-//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This defines CStringChecker, which is an assortment of checks on calls
11// to functions in <string.h>.
12//
13//===----------------------------------------------------------------------===//
14
15#include "GRExprEngineExperimentalChecks.h"
16#include "clang/Checker/BugReporter/BugType.h"
17#include "clang/Checker/PathSensitive/CheckerVisitor.h"
18#include "llvm/ADT/StringSwitch.h"
19
20using namespace clang;
21
22namespace {
23class CStringChecker : public CheckerVisitor<CStringChecker> {
24 BugType *BT_Bounds;
25 BugType *BT_Overlap;
26public:
27 CStringChecker()
28 : BT_Bounds(0), BT_Overlap(0) {}
29 static void *getTag() { static int tag; return &tag; }
30
31 bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
32
33 typedef const GRState *(CStringChecker::*FnCheck)(CheckerContext &,
34 const CallExpr *);
35
36 const GRState *EvalMemcpy(CheckerContext &C, const CallExpr *CE);
37 const GRState *EvalMemmove(CheckerContext &C, const CallExpr *CE);
Jordy Rosebc56d1f2010-07-07 08:15:01 +000038 const GRState *EvalMemcmp(CheckerContext &C, const CallExpr *CE);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000039 const GRState *EvalBcopy(CheckerContext &C, const CallExpr *CE);
40
41 // Utility methods
Jordy Rosea6b808c2010-07-07 07:48:06 +000042 const GRState *CheckNonNull(CheckerContext &C, const GRState *state,
43 const Stmt *S, SVal l);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000044 const GRState *CheckLocation(CheckerContext &C, const GRState *state,
45 const Stmt *S, SVal l);
46 const GRState *CheckBufferAccess(CheckerContext &C, const GRState *state,
47 const Expr *Size,
48 const Expr *FirstBuf,
49 const Expr *SecondBuf = NULL);
50 const GRState *CheckOverlap(CheckerContext &C, const GRState *state,
51 const Expr *First, const Expr *Second,
52 const Expr *Size);
53 void EmitOverlapBug(CheckerContext &C, const GRState *state,
54 const Stmt *First, const Stmt *Second);
55};
56} //end anonymous namespace
57
58void clang::RegisterCStringChecker(GRExprEngine &Eng) {
59 Eng.registerCheck(new CStringChecker());
60}
61
Jordy Rosea6b808c2010-07-07 07:48:06 +000062const GRState *CStringChecker::CheckNonNull(CheckerContext &C,
63 const GRState *state,
64 const Stmt *S, SVal l) {
65 // FIXME: This method just checks, of course, that the value is non-null.
66 // It should maybe be refactored and combined with AttrNonNullChecker.
67 if (l.isUnknownOrUndef())
68 return state;
69
70 ValueManager &ValMgr = C.getValueManager();
71 SValuator &SV = ValMgr.getSValuator();
72
73 Loc Null = ValMgr.makeNull();
74 DefinedOrUnknownSVal LocIsNull = SV.EvalEQ(state, cast<Loc>(l), Null);
75
76 const GRState *stateIsNull, *stateIsNonNull;
77 llvm::tie(stateIsNull, stateIsNonNull) = state->Assume(LocIsNull);
78
79 if (stateIsNull && !stateIsNonNull) {
80 ExplodedNode *N = C.GenerateSink(stateIsNull);
81 if (!N)
82 return NULL;
83
84 if (!BT_Bounds)
85 BT_Bounds = new BuiltinBug("API",
86 "Null pointer argument in call to byte string function");
87
88 // Generate a report for this bug.
89 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds);
90 EnhancedBugReport *report = new EnhancedBugReport(*BT,
91 BT->getDescription(), N);
92
93 report->addRange(S->getSourceRange());
94 report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, S);
95 C.EmitReport(report);
96 return NULL;
97 }
98
99 // From here on, assume that the value is non-null.
100 assert(stateIsNonNull);
101 return stateIsNonNull;
102}
103
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000104// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
105const GRState *CStringChecker::CheckLocation(CheckerContext &C,
106 const GRState *state,
107 const Stmt *S, SVal l) {
108 // Check for out of bound array element access.
109 const MemRegion *R = l.getAsRegion();
110 if (!R)
111 return state;
112
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000113 const ElementRegion *ER = dyn_cast<ElementRegion>(R);
114 if (!ER)
115 return state;
116
117 assert(ER->getValueType(C.getASTContext()) == C.getASTContext().CharTy &&
118 "CheckLocation should only be called with char* ElementRegions");
119
120 // Get the size of the array.
121 const SubRegion *Super = cast<SubRegion>(ER->getSuperRegion());
122 ValueManager &ValMgr = C.getValueManager();
123 SVal Extent = ValMgr.convertToArrayIndex(Super->getExtent(ValMgr));
124 DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
125
126 // Get the index of the accessed element.
127 DefinedOrUnknownSVal &Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
128
129 const GRState *StInBound = state->AssumeInBound(Idx, Size, true);
130 const GRState *StOutBound = state->AssumeInBound(Idx, Size, false);
131 if (StOutBound && !StInBound) {
132 ExplodedNode *N = C.GenerateSink(StOutBound);
133 if (!N)
134 return NULL;
135
136 if (!BT_Bounds)
137 BT_Bounds = new BuiltinBug("Out-of-bound array access",
138 "Byte string function accesses out-of-bound array element "
139 "(buffer overflow)");
140
141 // FIXME: It would be nice to eventually make this diagnostic more clear,
142 // e.g., by referencing the original declaration or by saying *why* this
143 // reference is outside the range.
144
145 // Generate a report for this bug.
146 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds);
147 RangedBugReport *report = new RangedBugReport(*BT, BT->getDescription(), N);
148
149 report->addRange(S->getSourceRange());
150 C.EmitReport(report);
151 return NULL;
152 }
153
154 // Array bound check succeeded. From this point forward the array bound
155 // should always succeed.
156 return StInBound;
157}
158
159const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
160 const GRState *state,
161 const Expr *Size,
162 const Expr *FirstBuf,
163 const Expr *SecondBuf) {
164 ValueManager &VM = C.getValueManager();
165 SValuator &SV = VM.getSValuator();
166 ASTContext &Ctx = C.getASTContext();
167
168 QualType SizeTy = Ctx.getSizeType();
169 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
170
171 // Get the access length and make sure it is known.
172 SVal LengthVal = state->getSVal(Size);
173 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
174 if (!Length)
175 return state;
176
Jordy Rosea6b808c2010-07-07 07:48:06 +0000177 // If the length is zero, it doesn't matter what the two buffers are.
178 DefinedOrUnknownSVal Zero = VM.makeZeroVal(SizeTy);
179 DefinedOrUnknownSVal LengthIsZero = SV.EvalEQ(state, *Length, Zero);
180
181 const GRState *stateZeroLength, *stateNonZeroLength;
182 llvm::tie(stateZeroLength, stateNonZeroLength) = state->Assume(LengthIsZero);
183 if (stateZeroLength && !stateNonZeroLength)
184 return stateZeroLength;
185
186 // FIXME: At this point all we know is it's *possible* for the length to be
187 // nonzero; we don't know it for sure. Unfortunately, that means the next few
188 // tests are incorrect for the edge cases in which a buffer is null or invalid
189 // but the size argument was set to zero in some way that we couldn't track.
190 // What we should really do is bifurcate the state here, but that doesn't
191 // match the way CheckBufferAccess is being used.
192
193 // From here on, we're going to pretend that even if the length is zero, the
194 // buffer access rules still apply. That means the buffer must be non-NULL,
195 // and the value at buffer[size-1] must be valid.
196
197 // Check that the first buffer is non-null.
198 SVal BufVal = state->getSVal(FirstBuf);
199 state = CheckNonNull(C, state, FirstBuf, BufVal);
200 if (!state)
201 return NULL;
202
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000203 // Compute the offset of the last element to be accessed: size-1.
204 NonLoc One = cast<NonLoc>(VM.makeIntVal(1, SizeTy));
205 NonLoc LastOffset = cast<NonLoc>(SV.EvalBinOpNN(state, BinaryOperator::Sub,
206 *Length, One, SizeTy));
207
Jordy Rosea6b808c2010-07-07 07:48:06 +0000208 // Check that the first buffer is sufficently long.
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000209 Loc BufStart = cast<Loc>(SV.EvalCast(BufVal, PtrTy, FirstBuf->getType()));
210 SVal BufEnd
211 = SV.EvalBinOpLN(state, BinaryOperator::Add, BufStart, LastOffset, PtrTy);
212 state = CheckLocation(C, state, FirstBuf, BufEnd);
213
214 // If the buffer isn't large enough, abort.
215 if (!state)
216 return NULL;
217
218 // If there's a second buffer, check it as well.
219 if (SecondBuf) {
220 BufVal = state->getSVal(SecondBuf);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000221 state = CheckNonNull(C, state, SecondBuf, BufVal);
222 if (!state)
223 return NULL;
224
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000225 BufStart = cast<Loc>(SV.EvalCast(BufVal, PtrTy, SecondBuf->getType()));
226 BufEnd
227 = SV.EvalBinOpLN(state, BinaryOperator::Add, BufStart, LastOffset, PtrTy);
228 state = CheckLocation(C, state, SecondBuf, BufEnd);
229 }
230
231 // Large enough or not, return this state!
232 return state;
233}
234
235const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
236 const GRState *state,
237 const Expr *First,
238 const Expr *Second,
239 const Expr *Size) {
240 // Do a simple check for overlap: if the two arguments are from the same
241 // buffer, see if the end of the first is greater than the start of the second
242 // or vice versa.
243
244 ValueManager &VM = state->getStateManager().getValueManager();
245 SValuator &SV = VM.getSValuator();
246 ASTContext &Ctx = VM.getContext();
247 const GRState *stateTrue, *stateFalse;
248
249 // Get the buffer values and make sure they're known locations.
250 SVal FirstVal = state->getSVal(First);
251 SVal SecondVal = state->getSVal(Second);
252
253 Loc *FirstLoc = dyn_cast<Loc>(&FirstVal);
254 if (!FirstLoc)
255 return state;
256
257 Loc *SecondLoc = dyn_cast<Loc>(&SecondVal);
258 if (!SecondLoc)
259 return state;
260
261 // Are the two values the same?
262 DefinedOrUnknownSVal EqualTest = SV.EvalEQ(state, *FirstLoc, *SecondLoc);
263 llvm::tie(stateTrue, stateFalse) = state->Assume(EqualTest);
264
265 if (stateTrue && !stateFalse) {
266 // If the values are known to be equal, that's automatically an overlap.
267 EmitOverlapBug(C, stateTrue, First, Second);
268 return NULL;
269 }
270
271 // Assume the two expressions are not equal.
272 assert(stateFalse);
273 state = stateFalse;
274
275 // Which value comes first?
276 QualType CmpTy = Ctx.IntTy;
277 SVal Reverse = SV.EvalBinOpLL(state, BinaryOperator::GT,
278 *FirstLoc, *SecondLoc, CmpTy);
279 DefinedOrUnknownSVal *ReverseTest = dyn_cast<DefinedOrUnknownSVal>(&Reverse);
280 if (!ReverseTest)
281 return state;
282
283 llvm::tie(stateTrue, stateFalse) = state->Assume(*ReverseTest);
284
285 if (stateTrue) {
286 if (stateFalse) {
287 // If we don't know which one comes first, we can't perform this test.
288 return state;
289 } else {
290 // Switch the values so that FirstVal is before SecondVal.
291 Loc *tmpLoc = FirstLoc;
292 FirstLoc = SecondLoc;
293 SecondLoc = tmpLoc;
294
295 // Switch the Exprs as well, so that they still correspond.
296 const Expr *tmpExpr = First;
297 First = Second;
298 Second = tmpExpr;
299 }
300 }
301
302 // Get the length, and make sure it too is known.
303 SVal LengthVal = state->getSVal(Size);
304 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
305 if (!Length)
306 return state;
307
308 // Convert the first buffer's start address to char*.
309 // Bail out if the cast fails.
310 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
311 SVal FirstStart = SV.EvalCast(*FirstLoc, CharPtrTy, First->getType());
312 Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
313 if (!FirstStartLoc)
314 return state;
315
316 // Compute the end of the first buffer. Bail out if THAT fails.
317 SVal FirstEnd = SV.EvalBinOpLN(state, BinaryOperator::Add,
318 *FirstStartLoc, *Length, CharPtrTy);
319 Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
320 if (!FirstEndLoc)
321 return state;
322
323 // Is the end of the first buffer past the start of the second buffer?
324 SVal Overlap = SV.EvalBinOpLL(state, BinaryOperator::GT,
325 *FirstEndLoc, *SecondLoc, CmpTy);
326 DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
327 if (!OverlapTest)
328 return state;
329
330 llvm::tie(stateTrue, stateFalse) = state->Assume(*OverlapTest);
331
332 if (stateTrue && !stateFalse) {
333 // Overlap!
334 EmitOverlapBug(C, stateTrue, First, Second);
335 return NULL;
336 }
337
338 // Assume the two expressions don't overlap.
339 assert(stateFalse);
340 return stateFalse;
341}
342
343void CStringChecker::EmitOverlapBug(CheckerContext &C, const GRState *state,
344 const Stmt *First, const Stmt *Second) {
345 ExplodedNode *N = C.GenerateSink(state);
346 if (!N)
347 return;
348
349 if (!BT_Overlap)
350 BT_Overlap = new BugType("Unix API", "Improper arguments");
351
352 // Generate a report for this bug.
353 RangedBugReport *report =
354 new RangedBugReport(*BT_Overlap,
355 "Arguments must not be overlapping buffers", N);
356 report->addRange(First->getSourceRange());
357 report->addRange(Second->getSourceRange());
358
359 C.EmitReport(report);
360}
361
362const GRState *
363CStringChecker::EvalMemcpy(CheckerContext &C, const CallExpr *CE) {
364 // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
365 // memcpy() is like memmove(), but with the extra requirement that the buffers
366 // not overlap.
367 const GRState *state = EvalMemmove(C, CE);
368 if (!state)
369 return NULL;
370
371 return CheckOverlap(C, state, CE->getArg(0), CE->getArg(1), CE->getArg(2));
372}
373
374const GRState *
375CStringChecker::EvalMemmove(CheckerContext &C, const CallExpr *CE) {
376 // void *memmove(void *dst, const void *src, size_t n);
377 const Expr *Dest = CE->getArg(0);
378 const Expr *Source = CE->getArg(1);
379 const Expr *Size = CE->getArg(2);
380
381 // Check that the accesses will stay in bounds.
382 const GRState *state = C.getState();
383 state = CheckBufferAccess(C, state, Size, Dest, Source);
384 if (!state)
385 return NULL;
386
387 // The return value is the address of the destination buffer.
388 return state->BindExpr(CE, state->getSVal(Dest));
389}
390
391const GRState *
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000392CStringChecker::EvalMemcmp(CheckerContext &C, const CallExpr *CE) {
393 // int memcmp(const void *s1, const void *s2, size_t n);
394 const Expr *Left = CE->getArg(0);
395 const Expr *Right = CE->getArg(1);
396 const Expr *Size = CE->getArg(2);
397
398 const GRState *state = C.getState();
399 ValueManager &ValMgr = C.getValueManager();
400 SValuator &SV = ValMgr.getSValuator();
401 const GRState *stateTrue, *stateFalse;
402
403 // If we know the size argument is 0, we know the result is 0, and we don't
404 // have to check either of the buffers. (Another checker will have already
405 // made sure the size isn't undefined, so we can cast it safely.)
406 DefinedOrUnknownSVal SizeV = cast<DefinedOrUnknownSVal>(state->getSVal(Size));
407 DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Size->getType());
408
409 DefinedOrUnknownSVal SizeIsZero = SV.EvalEQ(state, SizeV, Zero);
410 llvm::tie(stateTrue, stateFalse) = state->Assume(SizeIsZero);
411
412 // FIXME: This should really cause a bifurcation of the state, but that would
413 // require changing the contract to allow the various Eval* methods to add
414 // transitions themselves. Currently that isn't the case because some of these
415 // functions are "basically" like another function, but with one or two
416 // additional restrictions (like memcpy and memmove).
417
418 if (stateTrue && !stateFalse)
419 return stateTrue->BindExpr(CE, ValMgr.makeZeroVal(CE->getType()));
420
421 // At this point, we still don't know that the size is nonzero, only that it
422 // might be.
423
424 // If we know the two buffers are the same, we know the result is 0.
425 // First, get the two buffers' addresses. Another checker will have already
426 // made sure they're not undefined.
427 DefinedOrUnknownSVal LBuf = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
428 DefinedOrUnknownSVal RBuf = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
429
430 // See if they are the same.
431 DefinedOrUnknownSVal SameBuf = SV.EvalEQ(state, LBuf, RBuf);
432 llvm::tie(stateTrue, stateFalse) = state->Assume(SameBuf);
433
434 // FIXME: This should also bifurcate the state (as above).
435
436 // If the two arguments are known to be the same buffer, we know the result is
437 // zero, and we only need to check one size.
438 if (stateTrue && !stateFalse) {
439 state = CheckBufferAccess(C, stateTrue, Size, Left);
440 return state->BindExpr(CE, ValMgr.makeZeroVal(CE->getType()));
441 }
442
443 // At this point, we don't know if the arguments are the same or not -- we
444 // only know that they *might* be different. We can't make any assumptions.
445
446 // The return value is the comparison result, which we don't know.
447 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
448 SVal RetVal = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
449 state = state->BindExpr(CE, RetVal);
450
451 // Check that the accesses will stay in bounds.
452 return CheckBufferAccess(C, state, Size, Left, Right);
453}
454
455const GRState *
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000456CStringChecker::EvalBcopy(CheckerContext &C, const CallExpr *CE) {
457 // void bcopy(const void *src, void *dst, size_t n);
458 return CheckBufferAccess(C, C.getState(),
459 CE->getArg(2), CE->getArg(0), CE->getArg(1));
460}
461
462bool CStringChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
463 // Get the callee. All the functions we care about are C functions
464 // with simple identifiers.
465 const GRState *state = C.getState();
466 const Expr *Callee = CE->getCallee();
467 const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
468
469 if (!FD)
470 return false;
471
472 // Get the name of the callee. If it's a builtin, strip off the prefix.
473 llvm::StringRef Name = FD->getName();
474 if (Name.startswith("__builtin_"))
475 Name = Name.substr(10);
476
477 FnCheck EvalFunction = llvm::StringSwitch<FnCheck>(Name)
Jordy Rosea6b808c2010-07-07 07:48:06 +0000478 .Cases("memcpy", "__memcpy_chk", &CStringChecker::EvalMemcpy)
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000479 .Cases("memcmp", "bcmp", &CStringChecker::EvalMemcmp)
Jordy Rosea6b808c2010-07-07 07:48:06 +0000480 .Cases("memmove", "__memmove_chk", &CStringChecker::EvalMemmove)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000481 .Case("bcopy", &CStringChecker::EvalBcopy)
482 .Default(NULL);
483
484 if (!EvalFunction)
485 // The callee isn't a string function. Let another checker handle it.
486 return false;
487
488 const GRState *NewState = (this->*EvalFunction)(C, CE);
489
490 if (NewState)
491 C.addTransition(NewState);
492 return true;
493}