Lines Matching +full:auto +full:- +full:string +full:- +full:detection

1 //== GenericTaintChecker.cpp ----------------------------------- -*- C++ -*--=//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
39 #define DEBUG_TYPE "taint-checker"
51 /// Check for CWE-134: Uncontrolled Format String.
53 "Untrusted data is used as a format string "
54 "(CWE-134: Uncontrolled Format String)";
57 /// CERT/STR02-C. "Sanitize data passed to complex subsystems"
58 /// CWE-78, "Failure to Sanitize Data into an OS Command"
61 "(CERT/STR02-C. Sanitize data passed to complex subsystems)";
65 "Untrusted data is passed to a user-defined sink";
71 constexpr ArgIdxTy ReturnValueIndex{-1};
87 const auto *SymReg = dyn_cast_or_null<SymbolicRegion>(Val.getAsRegion());
92 const auto *DeclReg =
93 dyn_cast_or_null<DeclRegion>(SymReg->getSymbol()->getOriginRegion());
99 if (const auto *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) {
100 D = D->getCanonicalDecl();
101 if (D->getName() == "stdin" && D->hasExternalStorage() && D->isExternC()) {
103 const QualType Ty = D->getType().getCanonicalType();
105 if (Ty->isPointerType())
106 return Ty->getPointeeType() == FILETy;
113 const QualType ArgTy = LValue.getType(State->getStateManager().getContext());
114 if (!ArgTy->isPointerType() || !ArgTy->getPointeeType()->isVoidType())
115 return State->getSVal(LValue);
119 return State->getSVal(LValue, State->getStateManager().getContext().CharTy);
124 if (auto LValue = Arg.getAs<Loc>())
134 if (auto Pointee = getPointeeOf(State, Arg))
156 PathSensitiveBugReport &BR) -> std::string {
166 for (auto Sym : TaintedSymbols) {
169 LLVM_DEBUG(for (auto Arg
186 PathSensitiveBugReport &BR) -> std::string {
195 for (auto [Idx, Sym] : llvm::enumerate(TaintedSymbols)) {
214 return std::string(Out.str());
218 /// ArgSet is used to describe arguments relevant for taint detection or
300 /// Handles the resolution of indexes of type ArgIdxTy to Expr*-s.
314 using NameScopeArgs = std::tuple<std::string, std::string, ArgVecTy>;
318 std::string Name;
319 std::string Scope;
354 RulesContTy parseConfiguration(const std::string &Option,
362 void validateArgVector(const std::string &Option, const ArgVecTy &Args) const;
372 void parseConfig(const std::string &Option, TaintConfiguration::Sink &&P,
374 void parseConfig(const std::string &Option, TaintConfiguration::Filter &&P,
376 void parseConfig(const std::string &Option,
406 /// access user-provided configuration.
470 /// A set which is used to pass information from call pre-visit instruction
471 /// to the call post-visit. The values are signed integers, which are either
478 void GenericTaintRuleParser::validateArgVector(const std::string &Option,
484 "an argument number for propagation rules greater or equal to -1");
496 StringRef{C.Scope}.split(NameParts, "::", /*MaxSplit*/ -1,
512 void GenericTaintRuleParser::parseConfig(const std::string &Option,
520 void GenericTaintRuleParser::parseConfig(const std::string &Option,
528 void GenericTaintRuleParser::parseConfig(const std::string &Option,
547 GenericTaintRuleParser::parseConfiguration(const std::string &Option,
552 for (auto &F : Config.Filters)
555 for (auto &S : Config.Sinks)
558 for (auto &P : Config.Propagations)
710 // See the details here: https://github.com/llvm/llvm-project/pull/66086
810 // User-provided taint configuration.
814 std::string Option{"Config"};
816 Mgr->getAnalyzerOptions().getCheckerStringOption(this, Option);
837 if (const auto *Rule =
838 Call.isGlobalCFunction() ? StaticTaintRules->lookup(Call) : nullptr)
839 Rule->process(*this, Call, C);
840 else if (const auto *Rule = DynamicTaintRules->lookup(Call))
841 Rule->process(*this, Call, C);
846 // TODO: Make CallDescription be able to match attributes such as printf-like
862 // Depending on what was tainted at pre-visit, we determined a set of
865 TaintArgsOnPostVisitTy TaintArgsMap = State->get<TaintArgsOnPostVisit>();
870 assert(!TaintArgs->isEmpty());
896 if (auto V = getPointeeOf(State, Call.getArgSVal(ArgNum))) {
910 State = State->remove<TaintArgsOnPostVisit>(CurrentFrame);
925 const auto ForEachCallArg = [&C, &Call, CallNumArgs](auto &&Fun) {
946 if (auto P = getPointeeOf(State, S))
982 const auto WouldEscape = [](SVal V, QualType Ty) -> bool {
986 const bool IsNonConstRef = Ty->isReferenceType() && !Ty.isConstQualified();
988 Ty->isPointerType() && !Ty->getPointeeType().isConstQualified();
994 auto &F = State->getStateManager().get_context<ArgIdxFactory>();
1006 // non-const pointer or reference to a function which is
1011 if (WouldEscape(V, E->getType()) && getTaintedPointeeOrPointer(State, V)) {
1022 State = State->set<TaintArgsOnPostVisit>(C.getStackFrame(), Result);
1048 static CheckerProgramPointTag Tag(BT->getCheckerName(), Msg);
1050 auto report = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
1051 report->addRange(E->getSourceRange());
1052 for (auto TaintedSym : getTaintedSymbols(C.getState(), *TaintedSVal)) {
1053 report->markInteresting(TaintedSym);
1070 // Find if the function contains a format string argument.
1076 const FunctionDecl *FDecl = CallDecl->getAsFunction();
1082 for (const auto *Format : FDecl->specific_attrs<FormatAttr>()) {
1083 ArgNum = Format->getFormatIdx() - 1;
1084 if ((Format->getType()->getName() == "printf") && CallNumArgs > ArgNum)
1093 // Check if the function contains a format string argument.
1098 // If either the format string content or the pointer itself are tainted,
1111 if (ID->getName() != "socket")
1114 SourceLocation DomLoc = Call.getArgExpr(0)->getExprLoc();
1123 auto &F = State->getStateManager().get_context<ArgIdxFactory>();
1125 State = State->set<TaintArgsOnPostVisit>(C.getStackFrame(), Result);
1140 checker->isTaintReporterCheckerEnabled = true;
1141 checker->BT.emplace(Mgr.getCurrentCheckerName(), "Use of Untrusted Data",