steakhal created this revision.
steakhal added reviewers: NoQ, Szelethus.
steakhal added a project: clang.
Herald added subscribers: cfe-commits, Charusso, donat.nagy, mikhail.ramalho, 
a.sidorin, szepet, baloghadamsoftware, xazax.hun, whisperity.

This patch introduces the `clang_analyzer_isTainted` expression inspection 
check for checking taint.

Using this we could query the analyzer whether the expression used as the 
argument is tainted or not.
This would be useful in tests, where we don't want to issue warning for all 
tainted expressions in a given file (like the `debug.TaintTest` would do) but 
only for certain expressions.

Example usage:

  int read_integer() {
    int n;
    clang_analyzer_isTainted(n);     // expected-warning{{NO}}
    scanf("%d", &n);
    clang_analyzer_isTainted(n);     // expected-warning{{YES}}
    clang_analyzer_isTainted(n + 2); // expected-warning{{YES}}
    clang_analyzer_isTainted(n > 0); // expected-warning{{YES}}
    return n;
  }


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74131

Files:
  clang/docs/analyzer/developer-docs/DebugChecks.rst
  clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp


Index: clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -6,6 +6,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "Taint.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -46,6 +47,7 @@
   void analyzerHashDump(const CallExpr *CE, CheckerContext &C) const;
   void analyzerDenote(const CallExpr *CE, CheckerContext &C) const;
   void analyzerExpress(const CallExpr *CE, CheckerContext &C) const;
+  void analyzerIsTainted(const CallExpr *CE, CheckerContext &C) const;
 
   typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
                                                  CheckerContext &C) const;
@@ -92,6 +94,7 @@
     .Case("clang_analyzer_hashDump", &ExprInspectionChecker::analyzerHashDump)
     .Case("clang_analyzer_denote", &ExprInspectionChecker::analyzerDenote)
     .Case("clang_analyzer_express", &ExprInspectionChecker::analyzerExpress)
+    .StartsWith("clang_analyzer_isTainted", 
&ExprInspectionChecker::analyzerIsTainted)
     .Default(nullptr);
 
   if (!Handler)
@@ -412,6 +415,17 @@
   reportBug(*Str, C);
 }
 
+void ExprInspectionChecker::analyzerIsTainted(const CallExpr *CE,
+                                              CheckerContext &C) const {
+  if (CE->getNumArgs() != 1) {
+    reportBug("clang_analyzer_isTainted() requires exactly one argument", C);
+    return;
+  }
+  const bool IsTainted =
+      taint::isTainted(C.getState(), CE->getArg(0), C.getLocationContext());
+  reportBug(IsTainted ? "YES" : "NO", C);
+}
+
 void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
   Mgr.registerChecker<ExprInspectionChecker>();
 }
Index: clang/docs/analyzer/developer-docs/DebugChecks.rst
===================================================================
--- clang/docs/analyzer/developer-docs/DebugChecks.rst
+++ clang/docs/analyzer/developer-docs/DebugChecks.rst
@@ -275,6 +275,24 @@
 
   See clang_analyzer_denote().
 
+- ``void clang_analyzer_isTainted(a single argument of any type);``
+
+  Queries the analyzer whether the expression used as argument is tainted or 
not.
+  This is useful in tests, where we don't want to issue warning for all tainted
+  expressions but only check for certain expressions.
+
+  Example usage::
+
+    int read_integer() {
+      int n;
+      clang_analyzer_isTainted(n);     // expected-warning{{NO}}
+      scanf("%d", &n);
+      clang_analyzer_isTainted(n);     // expected-warning{{YES}}
+      clang_analyzer_isTainted(n + 2); // expected-warning{{YES}}
+      clang_analyzer_isTainted(n > 0); // expected-warning{{YES}}
+      return n;
+    }
+
 Statistics
 ==========
 


Index: clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Taint.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -46,6 +47,7 @@
   void analyzerHashDump(const CallExpr *CE, CheckerContext &C) const;
   void analyzerDenote(const CallExpr *CE, CheckerContext &C) const;
   void analyzerExpress(const CallExpr *CE, CheckerContext &C) const;
+  void analyzerIsTainted(const CallExpr *CE, CheckerContext &C) const;
 
   typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
                                                  CheckerContext &C) const;
@@ -92,6 +94,7 @@
     .Case("clang_analyzer_hashDump", &ExprInspectionChecker::analyzerHashDump)
     .Case("clang_analyzer_denote", &ExprInspectionChecker::analyzerDenote)
     .Case("clang_analyzer_express", &ExprInspectionChecker::analyzerExpress)
+    .StartsWith("clang_analyzer_isTainted", &ExprInspectionChecker::analyzerIsTainted)
     .Default(nullptr);
 
   if (!Handler)
@@ -412,6 +415,17 @@
   reportBug(*Str, C);
 }
 
+void ExprInspectionChecker::analyzerIsTainted(const CallExpr *CE,
+                                              CheckerContext &C) const {
+  if (CE->getNumArgs() != 1) {
+    reportBug("clang_analyzer_isTainted() requires exactly one argument", C);
+    return;
+  }
+  const bool IsTainted =
+      taint::isTainted(C.getState(), CE->getArg(0), C.getLocationContext());
+  reportBug(IsTainted ? "YES" : "NO", C);
+}
+
 void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
   Mgr.registerChecker<ExprInspectionChecker>();
 }
Index: clang/docs/analyzer/developer-docs/DebugChecks.rst
===================================================================
--- clang/docs/analyzer/developer-docs/DebugChecks.rst
+++ clang/docs/analyzer/developer-docs/DebugChecks.rst
@@ -275,6 +275,24 @@
 
   See clang_analyzer_denote().
 
+- ``void clang_analyzer_isTainted(a single argument of any type);``
+
+  Queries the analyzer whether the expression used as argument is tainted or not.
+  This is useful in tests, where we don't want to issue warning for all tainted
+  expressions but only check for certain expressions.
+
+  Example usage::
+
+    int read_integer() {
+      int n;
+      clang_analyzer_isTainted(n);     // expected-warning{{NO}}
+      scanf("%d", &n);
+      clang_analyzer_isTainted(n);     // expected-warning{{YES}}
+      clang_analyzer_isTainted(n + 2); // expected-warning{{YES}}
+      clang_analyzer_isTainted(n > 0); // expected-warning{{YES}}
+      return n;
+    }
+
 Statistics
 ==========
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to