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