32enum ChrootKind { NO_CHROOT, ROOT_CHANGED, ROOT_CHANGE_FAILED, JAIL_ENTERED };
51class ChrootChecker final :
public Checker<eval::Call, check::PreCall> {
60 const BugType BreakJailBug{
this,
"Break out of jail"};
66 if (Chroot.matches(
Call))
67 return evalChroot(
Call,
C);
69 if (Chdir.matches(
Call))
70 return evalChdir(
Call,
C);
79 const auto *CE = cast<CallExpr>(
Call.getOriginExpr());
81 const QualType IntTy =
C.getASTContext().IntTy;
86 C.addTransition(ChrootFailed->set<ChrootState>(ROOT_CHANGE_FAILED));
89 C.addTransition(ChrootSucceeded->set<ChrootState>(ROOT_CHANGED));
97 if (State->get<ChrootState>() == NO_CHROOT)
105 if (
const auto *StrRegion = dyn_cast<StringRegion>(R)) {
106 if (StrRegion->getStringLiteral()->getString() ==
"/") {
107 C.addTransition(State->set<ChrootState>(JAIL_ENTERED));
134 if (!Chroot.matchesAsWritten(*
Call))
140 return std::make_shared<PathDiagnosticEventPiece>(Pos,
"chroot called here",
144 void Profile(llvm::FoldingSetNodeID &ID)
const override {
151 bool Satisfied =
false;
158 if (matchesAny(
Call, Chroot, Chdir))
162 if (
C.getState()->get<ChrootState>() != ROOT_CHANGED)
167 C.generateNonFatalErrorNode(
C.getState(),
C.getPredecessor());
171 auto R = std::make_unique<PathSensitiveBugReport>(
172 BreakJailBug, R
"(No call of chdir("/") immediately after chroot)", Err);
173 R->addVisitor<ChrootInvocationVisitor>(Chroot);
174 C.emitReport(std::move(R));
183bool ento::shouldRegisterChrootChecker(
const CheckerManager &) {
return true; }
Defines the clang::ASTContext interface.
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
const SourceManager & getSourceManager() const
BugReporterVisitors are used to add custom diagnostics along a path.
virtual void Profile(llvm::FoldingSetNodeID &ID) const =0
virtual PathDiagnosticPieceRef VisitNode(const ExplodedNode *Succ, BugReporterContext &BRC, PathSensitiveBugReport &BR)=0
Return a diagnostic piece which should be associated with the given node.
A CallDescription is a pattern that can be used to match calls based on the qualified name and the ar...
Represents an abstract call to a function or method along a particular path.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
const LocationContext * getLocationContext() const
MemRegion - The root abstract class for all memory regions.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
const MemRegion * getAsRegion() const
Value representing integer constant.
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.