40 using namespace clang;
45 class VforkChecker :
public Checker<check::PreCall, check::PostCall,
46 check::Bind, check::PreStmt<ReturnStmt>> {
47 mutable std::unique_ptr<BuiltinBug> BT;
48 mutable llvm::SmallSet<const IdentifierInfo *, 10> VforkWhitelist;
57 const char *Details =
nullptr)
const;
60 VforkChecker() : II_vfork(nullptr) {}
76 #define VFORK_RESULT_INVALID 0 77 #define VFORK_RESULT_NONE ((void *)(uintptr_t)1) 84 auto FD = dyn_cast_or_null<FunctionDecl>(D);
93 return FD->getIdentifier() == II_vfork;
99 if (VforkWhitelist.empty()) {
101 const char *ids[] = {
114 for (
const char **
id = ids; *
id; ++
id)
115 VforkWhitelist.insert(&AC.
Idents.
get(*
id));
118 return VforkWhitelist.count(II);
122 const char *Details)
const {
126 "Dangerous construct in a vforked process"));
129 llvm::raw_svector_ostream os(buf);
131 os << What <<
" is prohibited after a successful vfork";
134 os <<
"; " << Details;
136 auto Report = llvm::make_unique<BugReport>(*BT, os.str(), N);
143 void VforkChecker::checkPostCall(
const CallEvent &Call,
148 if (isChildProcess(State))
151 if (!isVforkCall(Call.
getDecl(), C))
176 std::tie(ParentState, ChildState) = C.
getState()->assume(*DVal);
178 ChildState = ChildState->set<VforkResultRegion>(LhsDeclReg);
183 void VforkChecker::checkPreCall(
const CallEvent &Call,
186 if (isChildProcess(State)
188 reportBug(
"This function call", C);
192 void VforkChecker::checkBind(
SVal L,
SVal V,
const Stmt *S,
195 if (!isChildProcess(State))
199 static_cast<const MemRegion *
>(State->get<VforkResultRegion>());
203 if (!MR || MR == VforkLhs)
206 reportBug(
"This assignment", C);
212 if (isChildProcess(State))
213 reportBug(
"Return", C,
"call _exit() instead");
MemRegion - The root abstract class for all memory regions.
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
Stmt - This represents one statement.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Decl - This represents one declaration (or definition), e.g.
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Represents a variable declaration or definition.
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 ...
SVal getReturnValue() const
Returns the return value of the call.
std::pair< const clang::VarDecl *, const clang::Expr * > parseAssignment(const Stmt *S)
static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name=StringRef())
Returns true if the callee is an externally-visible function in the top-level namespace, such as malloc.
const IdentifierInfo * getCalleeIdentifier() const
Returns the name of the callee, if its name is a simple identifier.
internal::Matcher< T > id(StringRef ID, const internal::BindableMatcher< T > &InnerMatcher)
If the provided matcher matches a node, binds the node to ID.
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
#define VFORK_RESULT_INVALID
ParentMap & getParentMap() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
CHECKER * registerChecker(AT... Args)
Used to register checkers.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy...
StoreManager & getStoreManager()
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
const MemRegion * getAsRegion() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
#define VFORK_RESULT_NONE
Dataflow Directional Tag Classes.
ASTContext & getASTContext()
const VarRegion * getVarRegion(const VarDecl *D, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
Represents an abstract call to a function or method along a particular path.
MemRegionManager & getRegionManager()
getRegionManager - Returns the internal RegionManager object that is used to query and manipulate Mem...
const ProgramStateRef & getState() const
Stmt * getParentIgnoreParenCasts(Stmt *) const
const LocationContext * getLocationContext() const