7
7
8
8
#include " llvm/Support/raw_ostream.h"
9
9
10
+ #include < iostream>
11
+
10
12
// / http://blog.trailofbits.com/2014/04/27/using-static-analysis-and-clang-to-find-heartbleed/
11
13
12
14
using namespace clang ;
13
15
using namespace ento ;
14
16
15
- namespace {
17
+ namespace chx {
16
18
19
+ // check::ASTDecl,check::PreStmt, check::PostStmt, check::Event,
17
20
class NetworkTaintChecker
18
- : public Checker<check::PreCall, check::PostCall, check::Location> {
21
+ : public Checker<check::PreCall, check::PostCall, check::Location,
22
+ check::ASTCodeBody, check::EndOfTranslationUnit,
23
+ check::Bind, check::EndAnalysis, check::EndFunction,
24
+ check::BranchCondition, check::DeadSymbols
25
+ // check::RegionChanges,
26
+ // check::PointerEscape,
27
+ // check::ConstPointerEscape
28
+ > {
19
29
mutable std::unique_ptr<BugType> BT;
20
30
21
- bool isArgUnConstrained (Optional<NonLoc>, SValBuilder &,
31
+ bool isArgUnConstrained (llvm:: Optional<NonLoc>, SValBuilder &,
22
32
ProgramStateRef) const ;
23
33
24
34
public:
25
35
NetworkTaintChecker (void )
26
- : BT(std::make_unique<BugType>(this , " Tainted dereference" ,
27
- " AWR Custom Analyzer" )) {}
36
+ : BT(std::make_unique<BugType>(this , " My Tainted dereference" ,
37
+ " MY Custom Analyzer" )) {}
28
38
29
39
void checkPreCall (const CallEvent &, CheckerContext &) const ;
30
40
void checkPostCall (const CallEvent &, CheckerContext &) const ;
31
41
void checkLocation (SVal, bool , const Stmt *, CheckerContext &) const ;
42
+ // unimplemented
43
+ void checkASTCodeBody (const Decl *D, AnalysisManager &mgr,
44
+ BugReporter &BR) const {}
45
+
46
+ void checkEndOfTranslationUnit (const TranslationUnitDecl *TU,
47
+ AnalysisManager &mgr, BugReporter &BR) const {}
48
+ void checkBind (const SVal &location, const SVal &val, const Stmt *S,
49
+ CheckerContext &C) const {}
50
+ void checkEndAnalysis (ExplodedGraph &G, BugReporter &BR,
51
+ ExprEngine &Eng) const {}
52
+ void checkEndFunction (CheckerContext &C) const {}
53
+ void checkBranchCondition (const Stmt *Condition, CheckerContext &C) const {}
54
+ void checkDeadSymbols (SymbolReaper &SR, CheckerContext &C) const {}
55
+
56
+ // bool wantsRegionChangeUpdate(ProgramStateRef state) const { return false; }
57
+ // ProgramStateRef checkRegionChanges(ProgramStateRef state,
58
+ // const InvalidatedSymbols *invalidated,
59
+ // ArrayRef<const MemRegion *> Explicits,
60
+ // ArrayRef<const MemRegion *> Regions,
61
+ // const CallEvent *Call) const {
62
+ // return nullptr;
63
+ // }
64
+ // ProgramStateRef checkPointerEscape(
65
+ // ProgramStateRef State, const InvalidatedSymbols &Escaped,
66
+ // const CallEvent *Call, PointerEscapeKind Kind,
67
+ // RegionAndSymbolInvalidationTraits *ETraits) const {
68
+ // return nullptr;
69
+ // }
70
+ // ProgramStateRef checkConstPointerEscape(
71
+ // ProgramStateRef State, const InvalidatedSymbols &Escaped,
72
+ // const CallEvent *Call, PointerEscapeKind Kind,
73
+ // RegionAndSymbolInvalidationTraits *ETraits) const {
74
+ // return nullptr;
75
+ // }
32
76
};
33
- }
34
77
35
78
// checker logic
36
79
bool NetworkTaintChecker::isArgUnConstrained (Optional<NonLoc> Arg,
@@ -40,29 +83,24 @@ bool NetworkTaintChecker::isArgUnConstrained(Optional<NonLoc> Arg,
40
83
41
84
if (Arg) {
42
85
// so 5000 is chosen as an arbitrary value. reall what we should do is
43
- // compare
44
- // the range on the value with the range of the memory object pointed to by
45
- // either the base pointer, in an array dereference, or the first and second
46
- // parameters to memcpy, in a call to memcpy. however, frequently this
47
- // information
48
- // is opaque to the analyzer. what I mostly wanted to answer was, show me
49
- // locations
50
- // in the code where NO constraints, practically, had been applied to the
51
- // size.
52
- // this would still permit technically incorrect constraints to be passed,
53
- // so
54
- // there is room for improvement, but I think that generally, something
55
- // sound is
56
- // unattainable here so we just do what we can in the time allotted
86
+ // compare the range on the value with the range of the memory object
87
+ // pointed to by either the base pointer, in an array dereference, or the
88
+ // first and second parameters to memcpy, in a call to memcpy. however,
89
+ // frequently this information is opaque to the analyzer. what I mostly
90
+ // wanted to answer was, show me locations in the code where NO constraints,
91
+ // practically, had been applied to the size. this would still permit
92
+ // technically incorrect constraints to be passed, so there is room for
93
+ // improvement, but I think that generally, something sound is unattainable
94
+ // here so we just do what we can in the time allotted
57
95
llvm::APInt V (32 , 5000 );
58
96
SVal Val = builder.makeIntVal (V, false );
59
97
60
98
Optional<NonLoc> NLVal = Val.getAs <NonLoc>();
61
99
62
100
if (NLVal.hasValue () == false ) return result;
63
101
64
- SVal cmprLT = builder.evalBinOpNN (state, BO_GT, *Arg, *NLVal ,
65
- builder.getConditionType ());
102
+ SVal cmprLT = builder.evalBinOpNN (state, BinaryOperatorKind:: BO_GT, *Arg,
103
+ *NLVal, builder.getConditionType ());
66
104
67
105
Optional<NonLoc> NLcmprLT = cmprLT.getAs <NonLoc>();
68
106
@@ -81,8 +119,9 @@ bool NetworkTaintChecker::isArgUnConstrained(Optional<NonLoc> Arg,
81
119
// check memcpy / memset calls
82
120
void NetworkTaintChecker::checkPreCall (const CallEvent &call,
83
121
CheckerContext &C) const {
84
- ProgramStateRef state = C.getState ();
122
+ // ProgramStateRef state = C.getState();
85
123
const IdentifierInfo *ID = call.getCalleeIdentifier ();
124
+ std::cerr << " [checkPreCall]: " << ID->getName ().data () << " \n " ;
86
125
87
126
if (ID == nullptr ) {
88
127
return ;
@@ -150,15 +189,13 @@ void NetworkTaintChecker::checkLocation(SVal l, bool isLoad, const Stmt *LoadS,
150
189
// check for htonl/htons
151
190
void NetworkTaintChecker::checkPostCall (const CallEvent &Call,
152
191
CheckerContext &C) const {
153
- // is htons or htonl?
154
192
const IdentifierInfo *ID = Call.getCalleeIdentifier ();
155
193
156
194
if (ID == nullptr ) {
157
195
return ;
158
196
}
159
197
160
- if (ID->getName () == " ntohl" || ID->getName () == " xyzzy" ||
161
- ID->getName () == " ntohs" ) {
198
+ if (ID->getName () == " ntohl" || ID->getName () == " ntohs" ) {
162
199
ProgramStateRef State = C.getState ();
163
200
// taint the value written to by this call
164
201
SymbolRef Sym = Call.getReturnValue ().getAsSymbol ();
@@ -171,3 +208,4 @@ void NetworkTaintChecker::checkPostCall(const CallEvent &Call,
171
208
172
209
return ;
173
210
}
211
+ } // end namespace
0 commit comments