r216078 - [analyzer] UnixAPI: Check when open(2) is called with more than three arguments.

Jordan Rose jordan_rose at apple.com
Wed Aug 20 09:58:03 PDT 2014


Author: jrose
Date: Wed Aug 20 11:58:03 2014
New Revision: 216078

URL: http://llvm.org/viewvc/llvm-project?rev=216078&view=rev
Log:
[analyzer] UnixAPI: Check when open(2) is called with more than three arguments.

Patch by Daniel Fahlgren.

Added:
    cfe/trunk/test/Analysis/unix-api.c
Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp?rev=216078&r1=216077&r2=216078&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp Wed Aug 20 11:58:03 2014
@@ -62,6 +62,10 @@ private:
       return;
     BT.reset(new BugType(this, name, categories::UnixAPI));
   }
+  void ReportOpenBug(CheckerContext &C,
+                     ProgramStateRef State,
+                     const char *Msg,
+                     SourceRange SR) const;
 };
 } //end anonymous namespace
 
@@ -69,7 +73,35 @@ private:
 // "open" (man 2 open)
 //===----------------------------------------------------------------------===//
 
+void UnixAPIChecker::ReportOpenBug(CheckerContext &C,
+                                   ProgramStateRef State,
+                                   const char *Msg,
+                                   SourceRange SR) const {
+  ExplodedNode *N = C.generateSink(State);
+  if (!N)
+    return;
+
+  LazyInitialize(BT_open, "Improper use of 'open'");
+
+  BugReport *Report = new BugReport(*BT_open, Msg, N);
+  Report->addRange(SR);
+  C.emitReport(Report);
+}
+
 void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
+  ProgramStateRef state = C.getState();
+
+  if (CE->getNumArgs() < 2) {
+    // The frontend should issue a warning for this case, so this is a sanity
+    // check.
+    return;
+  } else if (CE->getNumArgs() > 3) {
+    ReportOpenBug(C, state,
+                  "Call to 'open' with more than three arguments",
+                  CE->getArg(3)->getSourceRange());
+    return;
+  }
+
   // The definition of O_CREAT is platform specific.  We need a better way
   // of querying this information from the checking environment.
   if (!Val_O_CREAT.hasValue()) {
@@ -85,15 +117,6 @@ void UnixAPIChecker::CheckOpen(CheckerCo
     }
   }
 
-  // Look at the 'oflags' argument for the O_CREAT flag.
-  ProgramStateRef state = C.getState();
-
-  if (CE->getNumArgs() < 2) {
-    // The frontend should issue a warning for this case, so this is a sanity
-    // check.
-    return;
-  }
-
   // Now check if oflags has O_CREAT set.
   const Expr *oflagsEx = CE->getArg(1);
   const SVal V = state->getSVal(oflagsEx, C.getLocationContext());
@@ -122,18 +145,10 @@ void UnixAPIChecker::CheckOpen(CheckerCo
     return;
 
   if (CE->getNumArgs() < 3) {
-    ExplodedNode *N = C.generateSink(trueState);
-    if (!N)
-      return;
-
-    LazyInitialize(BT_open, "Improper use of 'open'");
-
-    BugReport *report =
-      new BugReport(*BT_open,
-                            "Call to 'open' requires a third argument when "
-                            "the 'O_CREAT' flag is set", N);
-    report->addRange(oflagsEx->getSourceRange());
-    C.emitReport(report);
+    ReportOpenBug(C, trueState,
+                  "Call to 'open' requires a third argument when "
+                  "the 'O_CREAT' flag is set",
+                  oflagsEx->getSourceRange());
   }
 }
 

Added: cfe/trunk/test/Analysis/unix-api.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unix-api.c?rev=216078&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/unix-api.c (added)
+++ cfe/trunk/test/Analysis/unix-api.c Wed Aug 20 11:58:03 2014
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -verify %s
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+int open(const char *, int, ...);
+int close(int fildes);
+
+void open_1(const char *path) {
+  int fd;
+  fd = open(path, O_RDONLY); // no-warning
+  if (fd > -1)
+    close(fd);
+}
+
+void open_2(const char *path) {
+  int fd;
+  int mode = 0x0;
+  fd = open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than three arguments}}
+  if (fd > -1)
+    close(fd);
+}





More information about the cfe-commits mailing list