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 +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits