23 using namespace clang;
29 enum Kind { NO_CHROOT, ROOT_CHANGED, JAIL_ENTERED };
31 bool isRootChanged(
intptr_t k) {
return k == ROOT_CHANGED; }
41 class ChrootChecker :
public Checker<eval::Call, check::PreStmt<CallExpr> > {
44 mutable std::unique_ptr<BuiltinBug> BT_BreakJail;
47 ChrootChecker() : II_chroot(
nullptr), II_chdir(
nullptr) {}
49 static void *getTag() {
54 bool evalCall(
const CallExpr *CE, CheckerContext &C)
const;
55 void checkPreStmt(
const CallExpr *CE, CheckerContext &C)
const;
58 void Chroot(CheckerContext &C,
const CallExpr *CE)
const;
59 void Chdir(CheckerContext &C,
const CallExpr *CE)
const;
64 bool ChrootChecker::evalCall(
const CallExpr *CE, CheckerContext &C)
const {
87 void ChrootChecker::Chroot(CheckerContext &C,
const CallExpr *CE)
const {
89 ProgramStateManager &Mgr = state->getStateManager();
93 state = Mgr.addGDM(state, ChrootChecker::getTag(), (
void*) ROOT_CHANGED);
94 C.addTransition(state);
97 void ChrootChecker::Chdir(CheckerContext &C,
const CallExpr *CE)
const {
99 ProgramStateManager &Mgr = state->getStateManager();
102 const void *k = state->FindGDM(ChrootChecker::getTag());
108 SVal ArgVal = C.getSVal(ArgExpr);
110 if (
const MemRegion *R = ArgVal.getAsRegion()) {
112 if (
const StringRegion* StrRegion= dyn_cast<StringRegion>(R)) {
115 state = Mgr.addGDM(state, ChrootChecker::getTag(),
116 (
void*) JAIL_ENTERED);
120 C.addTransition(state);
124 void ChrootChecker::checkPreStmt(
const CallExpr *CE, CheckerContext &C)
const {
140 void *
const* k = C.getState()->FindGDM(ChrootChecker::getTag());
143 if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
145 BT_BreakJail.reset(
new BuiltinBug(
146 this,
"Break out of jail",
"No call of chdir(\"/\") immediately " 148 C.emitReport(llvm::make_unique<BugReport>(
149 *BT_BreakJail, BT_BreakJail->getDescription(), N));
153 void ento::registerChrootChecker(CheckerManager &mgr) {
154 mgr.registerChecker<ChrootChecker>();
Represents a function declaration or definition.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
__INTPTR_TYPE__ intptr_t
A signed integer type with the property that any valid pointer to void can be converted to this type...
StringRef getString() const
This represents one expression.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Dataflow Directional Tag Classes.
StringLiteral - This represents a string literal expression, e.g.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).