[clang-tools-extra] r249727 - Adding a checker (cert-err52-cpp) that detects use of setjmp or longjmp in C++ code. Corresponds to the CERT C++ secure coding rule: https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=1834

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 8 12:54:44 PDT 2015


Author: aaronballman
Date: Thu Oct  8 14:54:43 2015
New Revision: 249727

URL: http://llvm.org/viewvc/llvm-project?rev=249727&view=rev
Log:
Adding a checker (cert-err52-cpp) that detects use of setjmp or longjmp in C++ code. Corresponds to the CERT C++ secure coding rule: https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=1834

Added:
    clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.cpp
    clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/cert-setlongjmp.rst
    clang-tools-extra/trunk/test/clang-tidy/cert-setlongjmp.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp
    clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp?rev=249727&r1=249726&r2=249727&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp Thu Oct  8 14:54:43 2015
@@ -15,6 +15,7 @@
 #include "../misc/NewDeleteOverloadsCheck.h"
 #include "../misc/NonCopyableObjects.h"
 #include "../misc/StaticAssertCheck.h"
+#include "SetLongJmpCheck.h"
 #include "VariadicFunctionDefCheck.h"
 
 namespace clang {
@@ -35,6 +36,9 @@ public:
     // OOP
     CheckFactories.registerCheck<MoveConstructorInitCheck>(
         "cert-oop11-cpp");
+    // ERR
+    CheckFactories.registerCheck<SetLongJmpCheck>(
+        "cert-err52-cpp");
 
     // C checkers
     // DCL

Modified: clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt?rev=249727&r1=249726&r2=249727&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt Thu Oct  8 14:54:43 2015
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
 
 add_clang_library(clangTidyCERTModule
   CERTTidyModule.cpp
+  SetLongJmpCheck.cpp
   VariadicFunctionDefCheck.cpp
 
   LINK_LIBS

Added: clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.cpp?rev=249727&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.cpp Thu Oct  8 14:54:43 2015
@@ -0,0 +1,77 @@
+//===--- SetLongJmpCheck.cpp - clang-tidy----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SetLongJmpCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+const char SetLongJmpCheck::DiagWording[] =
+    "do not call %0; consider using exception handling instead";
+
+namespace {
+class SetJmpMacroCallbacks : public PPCallbacks {
+  SetLongJmpCheck &Check;
+
+public:
+  explicit SetJmpMacroCallbacks(SetLongJmpCheck &Check) : Check(Check) {}
+
+  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
+                    SourceRange Range, const MacroArgs *Args) override {
+    const auto *II = MacroNameTok.getIdentifierInfo();
+    if (!II)
+      return;
+
+    if (II->getName() == "setjmp")
+      Check.diag(Range.getBegin(), Check.DiagWording) << II;
+  }
+};
+} // namespace
+
+void SetLongJmpCheck::registerPPCallbacks(CompilerInstance &Compiler) {
+  // This checker only applies to C++, where exception handling is a superior
+  // solution to setjmp/longjmp calls.
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  // Per [headers]p5, setjmp must be exposed as a macro instead of a function,
+  // despite the allowance in C for setjmp to also be an extern function.
+  Compiler.getPreprocessor().addPPCallbacks(
+      llvm::make_unique<SetJmpMacroCallbacks>(*this));
+}
+
+void SetLongJmpCheck::registerMatchers(MatchFinder *Finder) {
+  // This checker only applies to C++, where exception handling is a superior
+  // solution to setjmp/longjmp calls.
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  // In case there is an implementation that happens to define setjmp as a
+  // function instead of a macro, this will also catch use of it. However, we
+  // are primarily searching for uses of longjmp.
+  Finder->addMatcher(callExpr(callee(functionDecl(anyOf(hasName("setjmp"),
+                                                        hasName("longjmp")))))
+                         .bind("expr"),
+                     this);
+}
+
+void SetLongJmpCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *E = Result.Nodes.getNodeAs<CallExpr>("expr");
+  diag(E->getExprLoc(), DiagWording) << cast<NamedDecl>(E->getCalleeDecl());
+}
+
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.h?rev=249727&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/cert/SetLongJmpCheck.h Thu Oct  8 14:54:43 2015
@@ -0,0 +1,37 @@
+//===--- SetLongJmpCheck.h - clang-tidy--------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// Guards against use of setjmp/longjmp in C++ code
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-setlongjmp.html
+class SetLongJmpCheck : public ClangTidyCheck {
+public:
+  SetLongJmpCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void registerPPCallbacks(CompilerInstance &Compiler) override;
+
+  static const char DiagWording[];
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
+

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/cert-setlongjmp.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/cert-setlongjmp.rst?rev=249727&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/cert-setlongjmp.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/cert-setlongjmp.rst Thu Oct  8 14:54:43 2015
@@ -0,0 +1,11 @@
+cert-err52-cpp
+==============
+
+The C standard library facilities setjmp() and longjmp() can be used to
+simulate throwing and catching exceptions. However, these facilities bypass
+automatic resource management and can result in undefined behavior, commonly
+including resource leaks, and denial-of-service attacks.
+
+This check corresponds to the CERT C++ Coding Standard rule
+`ERR52-CPP. Do not use setjmp() or longjmp()
+<https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=1834>`_.

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=249727&r1=249726&r2=249727&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Thu Oct  8 14:54:43 2015
@@ -2,6 +2,7 @@ List of clang-tidy Checks
 =========================
 
 .. toctree::
+   cert-setlongjmp
    cert-variadic-function-def
    cppcoreguidelines-pro-type-const-cast
    cppcoreguidelines-pro-type-reinterpret-cast

Added: clang-tools-extra/trunk/test/clang-tidy/cert-setlongjmp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cert-setlongjmp.cpp?rev=249727&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cert-setlongjmp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cert-setlongjmp.cpp Thu Oct  8 14:54:43 2015
@@ -0,0 +1,26 @@
+// RUN: %python %S/check_clang_tidy.py %s cert-err52-cpp %t -- -std=c++11
+
+typedef void *jmp_buf;
+extern int __setjmpimpl(jmp_buf);
+#define setjmp(x) __setjmpimpl(x)
+[[noreturn]] extern void longjmp(jmp_buf, int);
+
+namespace std {
+using ::jmp_buf;
+using ::longjmp;
+}
+
+static jmp_buf env;
+void g() {
+  std::longjmp(env, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead [cert-err52-cpp]
+  ::longjmp(env, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead
+  longjmp(env, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead
+}
+
+void f() {
+  (void)setjmp(env);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not call 'setjmp'; consider using exception handling instead
+}




More information about the cfe-commits mailing list