================
@@ -827,8 +829,96 @@ void GenericTaintChecker::initTaintRules(CheckerContext 
&C) const {
                             std::make_move_iterator(Rules.end()));
 }
 
+bool isPointerToCharArray(const QualType &QT) {
+  if (!QT->isPointerType())
+    return false;
+  QualType PointeeType = QT->getPointeeType();
+  if (!PointeeType->isPointerType() ||
+      !PointeeType->getPointeeType()->isCharType())
+    return false;
+  return true;
+}
+
+// The incoming parameters of the main function get tainted
+// if the program called in an untrusted environment.
+void GenericTaintChecker::checkBeginFunction(CheckerContext &C) const {
+  if (!C.inTopFrame() || C.getAnalysisManager()
+                             .getAnalyzerOptions()
+                             .ShouldAssumeControlledEnvironment)
+    return;
+
+  const auto *FD = dyn_cast<FunctionDecl>(C.getLocationContext()->getDecl());
+  if (!FD || !FD->isMain() || FD->param_size() < 2)
+    return;
+
+  if (!FD->parameters()[0]->getType()->isIntegerType())
+    return;
+
+  if (!isPointerToCharArray(FD->parameters()[1]->getType()))
+    return;
+  ProgramStateRef State = C.getState();
+
+  const MemRegion *ArgcReg =
+      State->getRegion(FD->parameters()[0], C.getLocationContext());
+  SVal ArgcSVal = State->getSVal(ArgcReg);
+  State = addTaint(State, ArgcSVal);
+  StringRef ArgcName = FD->parameters()[0]->getName();
+  if (auto N = ArgcSVal.getAs<NonLoc>()) {
+    ConstraintManager &CM = C.getConstraintManager();
+    // The upper bound is the ARG_MAX on an arbitrary Linux
+    // to model that is is typically smaller than INT_MAX.
+    State = CM.assumeInclusiveRange(State, *N, llvm::APSInt::getUnsigned(1),
+                                    llvm::APSInt::getUnsigned(2097152), true);
+  }
+
+  const MemRegion *ArgvReg =
+      State->getRegion(FD->parameters()[1], C.getLocationContext());
+  SVal ArgvSVal = State->getSVal(ArgvReg);
+  State = addTaint(State, ArgvSVal);
+  StringRef ArgvName = FD->parameters()[1]->getName();
+
+  bool HaveEnvp = FD->param_size() > 2;
+  SVal EnvpSVal;
+  StringRef EnvpName;
+  if (HaveEnvp && !isPointerToCharArray(FD->parameters()[2]->getType()))
+    return;
+  if (HaveEnvp) {
+    const MemRegion *EnvPReg =
+        State->getRegion(FD->parameters()[2], C.getLocationContext());
+    EnvpSVal = State->getSVal(EnvPReg);
+    EnvpName = FD->parameters()[2]->getName();
+    State = addTaint(State, EnvpSVal);
+  }
+
+  const NoteTag *OriginatingTag =
+      C.getNoteTag([ArgvSVal, ArgcSVal, ArgcName, ArgvName, EnvpSVal,
+                    EnvpName](PathSensitiveBugReport &BR) -> std::string {
+        // We give diagnostics only for taint related reports
+        if ((!BR.isInteresting(ArgcSVal) && !BR.isInteresting(ArgvSVal) &&
+             !BR.isInteresting(EnvpSVal)) ||
+            BR.getBugType().getCategory() != categories::TaintedData)
+          return "";
+        std::string Message = "";
+        if (BR.isInteresting(ArgvSVal))
+          Message += "'" + ArgvName.str() + "'";
+        if (BR.isInteresting(ArgcSVal)) {
+          if (Message.size() > 0)
+            Message += ", ";
+          Message += "'" + ArgcName.str() + "'";
+        }
+        if (BR.isInteresting(EnvpSVal)) {
+          if (Message.size() > 0)
+            Message += ", ";
+          Message += "'" + EnvpName.str() + "'";
+        }
+        return "Taint originated in " + Message;
+      });
----------------
dkrupp wrote:

This alternative solution looks nice, however to me it feels too abstract and 
more difficult to read for concatenating 3 strings and some commas. At least 
too abstract to be used only at a single place in this function.

So, if you don't mind, I would like to stay with the original implementation as 
it would be more straightforward to read and is just as efficent.

https://github.com/llvm/llvm-project/pull/178054
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to