Skip to content

Commit 8573dcd

Browse files
committed
enumerate the checkers
1 parent 171617a commit 8573dcd

File tree

7 files changed

+78
-41
lines changed

7 files changed

+78
-41
lines changed

plugin/CMakeLists.txt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,3 @@ project(${PROJECTID})
55
set(EXECUTABLE_NAME "${PROJECTID}")
66
add_library(${EXECUTABLE_NAME} SHARED MyCheckers.cc)
77
target_link_libraries(${EXECUTABLE_NAME} ${FULL_LLVM_LIBS})
8-
9-
# set(LLVM_ROOT_DIRECTORY "/home/hongxu/marple-llvm/llvm/cmake")
10-
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LLVM_ROOT_DIRECTORY}")
11-
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LLVM_ROOT_DIRECTORY}/modules")
12-
# find_package(LLVM)
13-
# include(AddLLVM)
14-
# add_definitions(${LLVM_DEFINITIONS})
15-
# include_directories(${LLVM_INCLUDE_DIRS})
16-
# link_directories(${LLVM_LIBRARY_DIRS})
17-
# add_llvm_loadable_module(${EXECUTABLE_NAME} SHARED MyCheckers.cc)

plugin/DBZ.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
using namespace clang;
1010
using namespace ento;
1111

12-
namespace {
12+
namespace chx {
1313
class MyDZChecker
1414
: public Checker<check::PreStmt<BinaryOperator>, check::PostCall> {
1515
mutable std::unique_ptr<BugType> BT;
@@ -23,7 +23,6 @@ class MyDZChecker
2323
categories::LogicError)) {}
2424
void checkPostCall(CallEvent const &, CheckerContext &) const;
2525
};
26-
} // end anonymous namespace
2726

2827
void MyDZChecker::reportBug(const char *Msg, ProgramStateRef StateZero,
2928
CheckerContext &C) const {
@@ -93,3 +92,5 @@ void MyDZChecker::checkPostCall(CallEvent const &call,
9392
}
9493
}
9594
}
95+
96+
} // end namespace

plugin/MyCheckers.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
#include "heartbleed.cc"
33

44
extern "C" void clang_registerCheckers(CheckerRegistry &registry) {
5-
registry.addChecker<MyDZChecker>("chx.DZChecker", "DZChecker");
6-
registry.addChecker<NetworkTaintChecker>("chx.NetChecker", "NetChecker");
5+
registry.addChecker<chx::MyDZChecker>("chx.DZChecker", "DZChecker");
6+
registry.addChecker<chx::NetworkTaintChecker>("chx.NetChecker", "NetChecker");
77
}
88

99
extern "C" const char clang_analyzerAPIVersionString[] =

plugin/heartbleed.cc

Lines changed: 64 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,73 @@
77

88
#include "llvm/Support/raw_ostream.h"
99

10+
#include <iostream>
11+
1012
/// http://blog.trailofbits.com/2014/04/27/using-static-analysis-and-clang-to-find-heartbleed/
1113

1214
using namespace clang;
1315
using namespace ento;
1416

15-
namespace {
17+
namespace chx {
1618

19+
// check::ASTDecl,check::PreStmt, check::PostStmt, check::Event,
1720
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+
> {
1929
mutable std::unique_ptr<BugType> BT;
2030

21-
bool isArgUnConstrained(Optional<NonLoc>, SValBuilder &,
31+
bool isArgUnConstrained(llvm::Optional<NonLoc>, SValBuilder &,
2232
ProgramStateRef) const;
2333

2434
public:
2535
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")) {}
2838

2939
void checkPreCall(const CallEvent &, CheckerContext &) const;
3040
void checkPostCall(const CallEvent &, CheckerContext &) const;
3141
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+
// }
3276
};
33-
}
3477

3578
// checker logic
3679
bool NetworkTaintChecker::isArgUnConstrained(Optional<NonLoc> Arg,
@@ -40,29 +83,24 @@ bool NetworkTaintChecker::isArgUnConstrained(Optional<NonLoc> Arg,
4083

4184
if (Arg) {
4285
// 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
5795
llvm::APInt V(32, 5000);
5896
SVal Val = builder.makeIntVal(V, false);
5997

6098
Optional<NonLoc> NLVal = Val.getAs<NonLoc>();
6199

62100
if (NLVal.hasValue() == false) return result;
63101

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());
66104

67105
Optional<NonLoc> NLcmprLT = cmprLT.getAs<NonLoc>();
68106

@@ -81,8 +119,9 @@ bool NetworkTaintChecker::isArgUnConstrained(Optional<NonLoc> Arg,
81119
// check memcpy / memset calls
82120
void NetworkTaintChecker::checkPreCall(const CallEvent &call,
83121
CheckerContext &C) const {
84-
ProgramStateRef state = C.getState();
122+
// ProgramStateRef state = C.getState();
85123
const IdentifierInfo *ID = call.getCalleeIdentifier();
124+
std::cerr << " [checkPreCall]: " << ID->getName().data() << "\n";
86125

87126
if (ID == nullptr) {
88127
return;
@@ -150,15 +189,13 @@ void NetworkTaintChecker::checkLocation(SVal l, bool isLoad, const Stmt *LoadS,
150189
// check for htonl/htons
151190
void NetworkTaintChecker::checkPostCall(const CallEvent &Call,
152191
CheckerContext &C) const {
153-
// is htons or htonl?
154192
const IdentifierInfo *ID = Call.getCalleeIdentifier();
155193

156194
if (ID == nullptr) {
157195
return;
158196
}
159197

160-
if (ID->getName() == "ntohl" || ID->getName() == "xyzzy" ||
161-
ID->getName() == "ntohs") {
198+
if (ID->getName() == "ntohl" || ID->getName() == "ntohs") {
162199
ProgramStateRef State = C.getState();
163200
// taint the value written to by this call
164201
SymbolRef Sym = Call.getReturnValue().getAsSymbol();
@@ -171,3 +208,4 @@ void NetworkTaintChecker::checkPostCall(const CallEvent &Call,
171208

172209
return;
173210
}
211+
} // end namespace

tests/plugin/e1/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
all: demo1.out
22

33
demo1.out: demo1.c
4-
$(CC) -o demo1.out demo1.c
4+
$(CC) -o demo1.out demo1.c -g
55

66
clean:
77
rm -f demo1.out

tests/plugin/e2/demo2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ int main(int argc, char *argv[]) {
2424
size = ntohl(size);
2525

2626
if (size < sizeof(data_array)) {
27+
// limited to size, no bug
2728
memcpy(buf, data_array, size);
2829
}
2930

tests/plugin/e3/dbz.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include <stdio.h>
2+
3+
int a = 0;
4+
5+
int main(void){
6+
return 3 / a;
7+
}

0 commit comments

Comments
 (0)