14
14
#include " clang/StaticAnalyzer/Core/BugReporter/BugType.h"
15
15
#include " clang/StaticAnalyzer/Core/Checker.h"
16
16
#include " clang/StaticAnalyzer/Core/CheckerManager.h"
17
+ #include " clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
17
18
#include " clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
18
19
#include " clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
19
20
#include " clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
@@ -37,53 +38,44 @@ bool isRootChanged(intptr_t k) { return k == ROOT_CHANGED; }
37
38
// ROOT_CHANGED<--chdir(..)-- JAIL_ENTERED<--chdir(..)--
38
39
// | |
39
40
// bug<--foo()-- JAIL_ENTERED<--foo()--
40
- class ChrootChecker : public Checker <eval::Call, check::PreStmt<CallExpr> > {
41
- mutable IdentifierInfo *II_chroot, *II_chdir;
41
+ class ChrootChecker : public Checker <eval::Call, check::PreCall> {
42
42
// This bug refers to possibly break out of a chroot() jail.
43
43
mutable std::unique_ptr<BuiltinBug> BT_BreakJail;
44
44
45
+ const CallDescription Chroot{" chroot" , 1 }, Chdir{" chdir" , 1 };
46
+
45
47
public:
46
- ChrootChecker () : II_chroot( nullptr ), II_chdir( nullptr ) {}
48
+ ChrootChecker () {}
47
49
48
50
static void *getTag () {
49
51
static int x;
50
52
return &x;
51
53
}
52
54
53
- bool evalCall (const CallExpr *CE , CheckerContext &C) const ;
54
- void checkPreStmt (const CallExpr *CE , CheckerContext &C) const ;
55
+ bool evalCall (const CallEvent &Call , CheckerContext &C) const ;
56
+ void checkPreCall (const CallEvent &Call , CheckerContext &C) const ;
55
57
56
58
private:
57
- void Chroot (CheckerContext &C, const CallExpr *CE ) const ;
58
- void Chdir (CheckerContext &C, const CallExpr *CE ) const ;
59
+ void evalChroot ( const CallEvent &Call, CheckerContext &C ) const ;
60
+ void evalChdir ( const CallEvent &Call, CheckerContext &C ) const ;
59
61
};
60
62
61
63
} // end anonymous namespace
62
64
63
- bool ChrootChecker::evalCall (const CallExpr *CE, CheckerContext &C) const {
64
- const FunctionDecl *FD = C.getCalleeDecl (CE);
65
- if (!FD)
66
- return false ;
67
-
68
- ASTContext &Ctx = C.getASTContext ();
69
- if (!II_chroot)
70
- II_chroot = &Ctx.Idents .get (" chroot" );
71
- if (!II_chdir)
72
- II_chdir = &Ctx.Idents .get (" chdir" );
73
-
74
- if (FD->getIdentifier () == II_chroot) {
75
- Chroot (C, CE);
65
+ bool ChrootChecker::evalCall (const CallEvent &Call, CheckerContext &C) const {
66
+ if (Call.isCalled (Chroot)) {
67
+ evalChroot (Call, C);
76
68
return true ;
77
69
}
78
- if (FD-> getIdentifier () == II_chdir ) {
79
- Chdir (C, CE );
70
+ if (Call. isCalled (Chdir) ) {
71
+ evalChdir (Call, C );
80
72
return true ;
81
73
}
82
74
83
75
return false ;
84
76
}
85
77
86
- void ChrootChecker::Chroot (CheckerContext &C, const CallExpr *CE ) const {
78
+ void ChrootChecker::evalChroot ( const CallEvent &Call, CheckerContext &C ) const {
87
79
ProgramStateRef state = C.getState ();
88
80
ProgramStateManager &Mgr = state->getStateManager ();
89
81
@@ -93,7 +85,7 @@ void ChrootChecker::Chroot(CheckerContext &C, const CallExpr *CE) const {
93
85
C.addTransition (state);
94
86
}
95
87
96
- void ChrootChecker::Chdir (CheckerContext &C, const CallExpr *CE ) const {
88
+ void ChrootChecker::evalChdir ( const CallEvent &Call, CheckerContext &C ) const {
97
89
ProgramStateRef state = C.getState ();
98
90
ProgramStateManager &Mgr = state->getStateManager ();
99
91
@@ -103,7 +95,7 @@ void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
103
95
return ;
104
96
105
97
// After chdir("/"), enter the jail, set the enum value JAIL_ENTERED.
106
- const Expr *ArgExpr = CE-> getArg (0 );
98
+ const Expr *ArgExpr = Call. getArgExpr (0 );
107
99
SVal ArgVal = C.getSVal (ArgExpr);
108
100
109
101
if (const MemRegion *R = ArgVal.getAsRegion ()) {
@@ -120,19 +112,10 @@ void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
120
112
}
121
113
122
114
// Check the jail state before any function call except chroot and chdir().
123
- void ChrootChecker::checkPreStmt (const CallExpr *CE, CheckerContext &C) const {
124
- const FunctionDecl *FD = C.getCalleeDecl (CE);
125
- if (!FD)
126
- return ;
127
-
128
- ASTContext &Ctx = C.getASTContext ();
129
- if (!II_chroot)
130
- II_chroot = &Ctx.Idents .get (" chroot" );
131
- if (!II_chdir)
132
- II_chdir = &Ctx.Idents .get (" chdir" );
133
-
115
+ void ChrootChecker::checkPreCall (const CallEvent &Call,
116
+ CheckerContext &C) const {
134
117
// Ignore chroot and chdir.
135
- if (FD-> getIdentifier () == II_chroot || FD-> getIdentifier () == II_chdir )
118
+ if (Call. isCalled (Chroot) || Call. isCalled (Chdir) )
136
119
return ;
137
120
138
121
// If jail state is ROOT_CHANGED, generate BugReport.
0 commit comments