[clang-tools-extra] r310630 - [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 10 12:07:41 PDT 2017


Not sure if you've seen it, this broke the Windows build:
http://lab.llvm.org:8011/builders/clang-x64-ninja-win7/builds/5880/steps/build%20stage%201/logs/stdio

FAILED: C:\PROGRA~2\MICROS~3.0\VC\bin\amd64\cl.exe   /nologo /TP
-DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE
-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE
-D_CRT_SECURE_NO_WARNINGS -D_GNU_SOURCE -D_HAS_EXCEPTIONS=0
-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-Itools\clang\tools\extra\clang-tidy\android
-ID:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android
-ID:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include
-Itools\clang\include -Iinclude
-ID:\buildslave\clang-x64-ninja-win7\llvm\include /DWIN32 /D_WINDOWS
/Zc:inline /Zc:strictStrings /Oi /Zc:rvalueCast /W4 -wd4141 -wd4146 -wd4180
-wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457
-wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512
-wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703
-wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324
-w14062 -we4238 /MD /O2 /Ob2   -UNDEBUG  /EHs-c- /GR- /showIncludes
/Fotools\clang\tools\extra\clang-tidy\android\CMakeFiles\clangTidyAndroidModule.dir\CloexecCheck.cpp.obj
/Fdtools\clang\tools\extra\clang-tidy\android\CMakeFiles\clangTidyAndroidModule.dir\
/FS -c
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android\CloexecCheck.cpp
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android\CloexecCheck.cpp(99):
error C2666: 'clang::operator <<': 4 overloads have similar conversions
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclObjC.h(2612):
note: could be 'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,const clang::ObjCImplementationDecl &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclObjC.h(2429):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,const clang::ObjCCategoryImplDecl &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclCXX.h(3698):
note: or       'const clang::PartialDiagnostic &clang::operator <<(const
clang::PartialDiagnostic &,clang::AccessSpecifier)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclCXX.h(3695):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::AccessSpecifier)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Attr.h(202):
note: or       'const clang::PartialDiagnostic &clang::operator <<(const
clang::PartialDiagnostic &,const clang::Attr *)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Attr.h(195):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::Attr *)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Sema/CodeCompleteConsumer.h(802):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,const clang::CodeCompletionString &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/CanonicalType.h(204):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::CanQualType)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/TemplateBase.h(646):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::TemplateArgument &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Decl.h(3961):
note: or       'const clang::PartialDiagnostic &clang::operator <<(const
clang::PartialDiagnostic &,const clang::NamedDecl *)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Decl.h(3955):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::NamedDecl *)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Decl.h(404):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,const clang::NamedDecl &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Type.h(6024):
note: or       'const clang::PartialDiagnostic &clang::operator <<(const
clang::PartialDiagnostic &,clang::QualType)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Type.h(6015):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::QualType)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/TemplateName.h(309):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::TemplateName)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/NestedNameSpecifier.h(507):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::NestedNameSpecifier *)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(570):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,clang::DeclarationNameInfo)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(563):
note: or       'const clang::PartialDiagnostic &clang::operator <<(const
clang::PartialDiagnostic &,clang::DeclarationName)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(554):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::DeclarationName)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(313):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,clang::DeclarationName)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/PartialDiagnostic.h(408):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::PartialDiagnostic &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/ObjCRuntime.h(361):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,const clang::ObjCRuntime &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/VersionTuple.h(165):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,const clang::VersionTuple &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1202):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::DiagNullabilityKind)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1191):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,llvm::ArrayRef<clang::FixItHint>)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1185):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::FixItHint &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1179):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::CharSourceRange &)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1172):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,llvm::ArrayRef<clang::SourceRange>)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1166):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::SourceRange)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1145):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::IdentifierInfo *)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1139):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,clang::tok::TokenKind)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1133):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,unsigned int)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1117):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,int)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1110):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const char *)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1104):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,llvm::StringRef)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1098):
note: or       'const clang::DiagnosticBuilder &clang::operator <<(const
clang::DiagnosticBuilder &,const clang::AddFlagValue)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/DiagnosticOptions.h(58):
note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream
&,clang::DiagnosticLevelMask)'
D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android\CloexecCheck.cpp(99):
note: while trying to match the argument list '(const
clang::DiagnosticBuilder, const char)'
ninja: build stopped: subcommand failed.

On Thu, Aug 10, 2017 at 1:18 PM, Yan Wang via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: yawanng
> Date: Thu Aug 10 10:18:10 2017
> New Revision: 310630
>
> URL: http://llvm.org/viewvc/llvm-project?rev=310630&view=rev
> Log:
> [clang-tidy] Refactor the code and add a close-on-exec check on
> memfd_create() in Android module.
>
> Summary:
> 1. Refactor the structure of the code by adding a base class for all
> close-on-exec checks, which implements most of the needed functions.
> 2. memfd_create() is better to set MFD_CLOEXEC flag to avoid file
> descriptor leakage.
>
> Reviewers: alexfh, aaron.ballman, hokein
>
> Reviewed By: alexfh, hokein
>
> Subscribers: Eugene.Zelenko, chh, cfe-commits, srhines, mgorny,
> JDevlieghere, xazax.hun
>
> Tags: #clang-tools-extra
>
> Differential Revision: https://reviews.llvm.org/D35372
>
> Added:
>     clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp
>     clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h
>     clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.cpp
>     clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h
>     clang-tools-extra/trunk/docs/clang-tidy/checks/android-
> cloexec-memfd-create.rst
>     clang-tools-extra/trunk/test/clang-tidy/android-cloexec-
> memfd-create.cpp
> Modified:
>     clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp
>     clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt
>     clang-tools-extra/trunk/docs/ReleaseNotes.rst
>     clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
>
> Modified: clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/clang-tidy/android/AndroidTidyModule.cpp?rev=
> 310630&r1=310629&r2=310630&view=diff
> ============================================================
> ==================
> --- clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp
> (original)
> +++ clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp Thu
> Aug 10 10:18:10 2017
> @@ -12,6 +12,7 @@
>  #include "../ClangTidyModuleRegistry.h"
>  #include "CloexecCreatCheck.h"
>  #include "CloexecFopenCheck.h"
> +#include "CloexecMemfdCreateCheck.h"
>  #include "CloexecOpenCheck.h"
>  #include "CloexecSocketCheck.h"
>
> @@ -27,6 +28,8 @@ public:
>    void addCheckFactories(ClangTidyCheckFactories &CheckFactories)
> override {
>      CheckFactories.registerCheck<CloexecCreatCheck>("android-
> cloexec-creat");
>      CheckFactories.registerCheck<CloexecFopenCheck>("android-
> cloexec-fopen");
> +    CheckFactories.registerCheck<CloexecMemfdCreateCheck>(
> +        "android-cloexec-memfd-create");
>      CheckFactories.registerCheck<CloexecOpenCheck>("android-
> cloexec-open");
>      CheckFactories.registerCheck<CloexecSocketCheck>("android-
> cloexec-socket");
>    }
>
> Modified: clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/clang-tidy/android/CMakeLists.txt?rev=310630&r1=
> 310629&r2=310630&view=diff
> ============================================================
> ==================
> --- clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt Thu Aug 10
> 10:18:10 2017
> @@ -2,8 +2,10 @@ set(LLVM_LINK_COMPONENTS support)
>
>  add_clang_library(clangTidyAndroidModule
>    AndroidTidyModule.cpp
> +  CloexecCheck.cpp
>    CloexecCreatCheck.cpp
>    CloexecFopenCheck.cpp
> +  CloexecMemfdCreateCheck.cpp
>    CloexecOpenCheck.cpp
>    CloexecSocketCheck.cpp
>
>
> Added: clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/clang-tidy/android/CloexecCheck.cpp?rev=310630&view=auto
> ============================================================
> ==================
> --- clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp (added)
> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp Thu Aug
> 10 10:18:10 2017
> @@ -0,0 +1,105 @@
> +//===--- CloexecCheck.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 "CloexecCheck.h"
> +#include "../utils/ASTUtils.h"
> +#include "clang/AST/ASTContext.h"
> +#include "clang/ASTMatchers/ASTMatchFinder.h"
> +#include "clang/Lex/Lexer.h"
> +
> +using namespace clang::ast_matchers;
> +
> +namespace clang {
> +namespace tidy {
> +namespace android {
> +
> +namespace {
> +
> +const char *const FuncDeclBindingStr = "funcDecl";
> +const char *const FuncBindingStr = "func";
> +
> +// Helper function to form the correct string mode for Type3.
> +// Build the replace text. If it's string constant, add <Mode> directly
> in the
> +// end of the string. Else, add <Mode>.
> +std::string buildFixMsgForStringFlag(const Expr *Arg, const SourceManager
> &SM,
> +                                     const LangOptions &LangOpts, char
> Mode) {
> +  if (Arg->getLocStart().isMacroID())
> +    return (Lexer::getSourceText(
> +                CharSourceRange::getTokenRange(Arg->getSourceRange()),
> SM,
> +                LangOpts) +
> +            " \"" + Twine(Mode) + "\"")
> +        .str();
> +
> +  StringRef SR = cast<StringLiteral>(Arg->IgnoreParenCasts())->
> getString();
> +  return ("\"" + SR + Twine(Mode) + "\"").str();
> +}
> +} // namespace
> +
> +void CloexecCheck::registerMatchersImpl(
> +    MatchFinder *Finder, internal::Matcher<FunctionDecl> Function) {
> +  // We assume all the checked APIs are C functions.
> +  Finder->addMatcher(
> +      callExpr(
> +          callee(functionDecl(isExternC(), Function).bind(
> FuncDeclBindingStr)))
> +          .bind(FuncBindingStr),
> +      this);
> +}
> +
> +void CloexecCheck::insertMacroFlag(const MatchFinder::MatchResult
> &Result,
> +                                   StringRef MacroFlag, int ArgPos) {
> +  const auto *MatchedCall = Result.Nodes.getNodeAs<
> CallExpr>(FuncBindingStr);
> +  const auto *FlagArg = MatchedCall->getArg(ArgPos);
> +  const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>(
> FuncDeclBindingStr);
> +  SourceManager &SM = *Result.SourceManager;
> +
> +  if (utils::exprHasBitFlagWithSpelling(FlagArg->IgnoreParenCasts(), SM,
> +                                        Result.Context->getLangOpts(),
> +                                        MacroFlag))
> +    return;
> +
> +  SourceLocation EndLoc =
> +      Lexer::getLocForEndOfToken(SM.getFileLoc(FlagArg->getLocEnd()), 0,
> SM,
> +                                 Result.Context->getLangOpts());
> +
> +  diag(EndLoc, "%0 should use %1 where possible")
> +      << FD << MacroFlag
> +      << FixItHint::CreateInsertion(EndLoc, (Twine(" | ") +
> MacroFlag).str());
> +}
> +
> +void CloexecCheck::replaceFunc(const MatchFinder::MatchResult &Result,
> +                               StringRef WarningMsg, StringRef FixMsg) {
> +  const auto *MatchedCall = Result.Nodes.getNodeAs<
> CallExpr>(FuncBindingStr);
> +  diag(MatchedCall->getLocStart(), WarningMsg)
> +      << FixItHint::CreateReplacement(MatchedCall->getSourceRange(),
> FixMsg);
> +}
> +
> +void CloexecCheck::insertStringFlag(
> +    const ast_matchers::MatchFinder::MatchResult &Result, const char
> Mode,
> +    const int ArgPos) {
> +  const auto *MatchedCall = Result.Nodes.getNodeAs<
> CallExpr>(FuncBindingStr);
> +  const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>(
> FuncDeclBindingStr);
> +  const auto *ModeArg = MatchedCall->getArg(ArgPos);
> +
> +  // Check if the <Mode> may be in the mode string.
> +  const auto *ModeStr = dyn_cast<StringLiteral>(
> ModeArg->IgnoreParenCasts());
> +  if (!ModeStr || (ModeStr->getString().find(Mode) != StringRef::npos))
> +    return;
> +
> +  const std::string &ReplacementText = buildFixMsgForStringFlag(
> +      ModeArg, *Result.SourceManager, Result.Context->getLangOpts(),
> Mode);
> +
> +  diag(ModeArg->getLocStart(), "use %0 mode '%1' to set O_CLOEXEC")
> +      << FD << Mode
> +      << FixItHint::CreateReplacement(ModeArg->getSourceRange(),
> +                                      ReplacementText);
> +}
> +
> +} // namespace android
> +} // namespace tidy
> +} // namespace clang
>
> Added: clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/clang-tidy/android/CloexecCheck.h?rev=310630&view=auto
> ============================================================
> ==================
> --- clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h (added)
> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h Thu Aug 10
> 10:18:10 2017
> @@ -0,0 +1,95 @@
> +//===--- CloexecCheck.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.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +///
> +/// \file
> +/// This file contains the declaration of the CloexecCheck class, which
> is the
> +/// base class for all of the close-on-exec checks in Android module.
> +///
> +//===------------------------------------------------------
> ----------------===//
> +
> +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H
> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H
> +
> +#include "../ClangTidy.h"
> +
> +namespace clang {
> +namespace tidy {
> +namespace android {
> +
> +/// \brief The base class for all close-on-exec checks in Android module.
> +/// To be specific, there are some functions that need the close-on-exec
> flag to
> +/// prevent the file descriptor leakage on fork+exec and this class
> provides
> +/// utilities to identify and fix these C functions.
> +class CloexecCheck : public ClangTidyCheck {
> +public:
> +  CloexecCheck(StringRef Name, ClangTidyContext *Context)
> +      : ClangTidyCheck(Name, Context) {}
> +
> +protected:
> +  void
> +  registerMatchersImpl(ast_matchers::MatchFinder *Finder,
> +                       ast_matchers::internal::Matcher<FunctionDecl>
> Function);
> +
> +  /// Currently, we have three types of fixes.
> +  ///
> +  /// Type1 is to insert the necessary macro flag in the flag argument.
> For
> +  /// example, 'O_CLOEXEC' is required in function 'open()', so
> +  /// \code
> +  ///   open(file, O_RDONLY);
> +  /// \endcode
> +  /// should be
> +  /// \code
> +  ///   open(file, O_RDONLY | O_CLOEXE);
> +  /// \endcode
> +  ///
> +  /// \param [out] Result MatchResult from AST matcher.
> +  /// \param MacroFlag The macro name of the flag.
> +  /// \param ArgPos The 0-based position of the flag argument.
> +  void insertMacroFlag(const ast_matchers::MatchFinder::MatchResult
> &Result,
> +                       StringRef MarcoFlag, int ArgPos);
> +
> +  /// Type2 is to replace the API to another function that has required
> the
> +  /// ability. For example:
> +  /// \code
> +  ///   creat(path, mode);
> +  /// \endcode
> +  /// should be
> +  /// \code
> +  ///   open(path, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, mode)
> +  /// \endcode
> +  ///
> +  /// \param [out] Result MatchResult from AST matcher.
> +  /// \param WarningMsg The warning message.
> +  /// \param FixMsg The fix message.
> +  void replaceFunc(const ast_matchers::MatchFinder::MatchResult &Result,
> +                   StringRef WarningMsg, StringRef FixMsg);
> +
> +  /// Type3 is also to add a flag to the corresponding argument, but this
> time,
> +  /// the flag is some string and each char represents a mode rather than
> a
> +  /// macro. For example, 'fopen' needs char 'e' in its mode argument
> string, so
> +  /// \code
> +  ///   fopen(in_file, "r");
> +  /// \endcode
> +  /// should be
> +  /// \code
> +  ///   fopen(in_file, "re");
> +  /// \endcode
> +  ///
> +  /// \param [out] Result MatchResult from AST matcher.
> +  /// \param Mode The required mode char.
> +  /// \param ArgPos The 0-based position of the flag argument.
> +  void insertStringFlag(const ast_matchers::MatchFinder::MatchResult
> &Result,
> +                        char Mode, const int ArgPos);
> +};
> +
> +} // namespace android
> +} // namespace tidy
> +} // namespace clang
> +
> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H
>
> Added: clang-tools-extra/trunk/clang-tidy/android/
> CloexecMemfdCreateCheck.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/clang-tidy/android/CloexecMemfdCreateCheck.cpp?rev=310630&view=auto
> ============================================================
> ==================
> --- clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.cpp
> (added)
> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.cpp
> Thu Aug 10 10:18:10 2017
> @@ -0,0 +1,32 @@
> +//===--- CloexecMemfdCreateCheck.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 "CloexecMemfdCreateCheck.h"
> +
> +using namespace clang::ast_matchers;
> +
> +namespace clang {
> +namespace tidy {
> +namespace android {
> +
> +void CloexecMemfdCreateCheck::registerMatchers(MatchFinder *Finder) {
> +  auto CharPointerType = hasType(pointerType(pointee(isAnyCharacter())));
> +  registerMatchersImpl(
> +      Finder, functionDecl(returns(isInteger()), hasName("memfd_create"),
> +                           hasParameter(0, CharPointerType),
> +                           hasParameter(1, hasType(isInteger()))));
> +}
> +
> +void CloexecMemfdCreateCheck::check(const MatchFinder::MatchResult
> &Result) {
> +  insertMacroFlag(Result, "MFD_CLOEXEC", /*ArgPos=*/1);
> +}
> +
> +} // namespace android
> +} // namespace tidy
> +} // namespace clang
>
> Added: clang-tools-extra/trunk/clang-tidy/android/
> CloexecMemfdCreateCheck.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/clang-tidy/android/CloexecMemfdCreateCheck.h?rev=310630&view=auto
> ============================================================
> ==================
> --- clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h
> (added)
> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h
> Thu Aug 10 10:18:10 2017
> @@ -0,0 +1,35 @@
> +//===--- CloexecMemfdCreateCheck.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_ANDROID_CLOEXEC_MEMFD_CREATE_H
> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_MEMFD_CREATE_H
> +
> +#include "CloexecCheck.h"
> +
> +namespace clang {
> +namespace tidy {
> +namespace android {
> +
> +/// Finds code that uses memfd_create() without using the MFD_CLOEXEC
> flag.
> +///
> +/// For the user-facing documentation see:
> +/// http://clang.llvm.org/extra/clang-tidy/checks/android-
> cloexec-memfd-create.html
> +class CloexecMemfdCreateCheck : public CloexecCheck {
> +public:
> +  CloexecMemfdCreateCheck(StringRef Name, ClangTidyContext *Context)
> +      : CloexecCheck(Name, Context) {}
> +  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
> +  void check(const ast_matchers::MatchFinder::MatchResult &Result)
> override;
> +};
> +
> +} // namespace android
> +} // namespace tidy
> +} // namespace clang
> +
> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_MEMFD_
> CREATE_H
>
> Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/docs/ReleaseNotes.rst?rev=310630&r1=310629&r2=310630&view=diff
> ============================================================
> ==================
> --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
> +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Thu Aug 10 10:18:10 2017
> @@ -70,6 +70,12 @@ Improvements to clang-tidy
>        ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
>        ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
>
> +- New `android-cloexec-memfd_create
> +    <http://clang.llvm.org/extra/clang-tidy/checks/android-
> cloexec-memfd_create.html>`_ check
> +
> +    Checks if the required file flag ``MFD_CLOEXEC`` is present in the
> argument of
> +      ``memfd_create()``.
> +
>  - New `bugprone-integer-division
>    <http://clang.llvm.org/extra/clang-tidy/checks/bugprone-
> integer-division.html>`_ check
>
>
> Added: clang-tools-extra/trunk/docs/clang-tidy/checks/android-
> cloexec-memfd-create.rst
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/docs/clang-tidy/checks/android-cloexec-memfd-create.
> rst?rev=310630&view=auto
> ============================================================
> ==================
> --- clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloexec-memfd-create.rst
> (added)
> +++ clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloexec-memfd-create.rst
> Thu Aug 10 10:18:10 2017
> @@ -0,0 +1,18 @@
> +.. title:: clang-tidy - android-cloexec-memfd-create
> +
> +android-cloexec-memfd-create
> +============================
> +
> +``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to
> avoid
> +the file descriptor leakage. Without this flag, an opened sensitive file
> would
> +remain open across a fork+exec to a lower-privileged SELinux domain.
> +
> +Examples:
> +
> +.. code-block:: c++
> +
> +  memfd_create(name, MFD_ALLOW_SEALING);
> +
> +  // becomes
> +
> +  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
>
> 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=310630&r1=310629&
> r2=310630&view=diff
> ============================================================
> ==================
> --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
> +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Thu Aug 10
> 10:18:10 2017
> @@ -6,6 +6,7 @@ Clang-Tidy Checks
>  .. toctree::
>     android-cloexec-creat
>     android-cloexec-fopen
> +   android-cloexec-memfd-create
>     android-cloexec-open
>     android-cloexec-socket
>     boost-use-to-string
>
> Added: clang-tools-extra/trunk/test/clang-tidy/android-cloexec-
> memfd-create.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/test/clang-tidy/android-cloexec-memfd-create.cpp?rev=
> 310630&view=auto
> ============================================================
> ==================
> --- clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memfd-create.cpp
> (added)
> +++ clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memfd-create.cpp
> Thu Aug 10 10:18:10 2017
> @@ -0,0 +1,63 @@
> +// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
> +
> +#define MFD_ALLOW_SEALING 1
> +#define __O_CLOEXEC 3
> +#define MFD_CLOEXEC __O_CLOEXEC
> +#define TEMP_FAILURE_RETRY(exp) \
> +  ({                            \
> +    int _rc;                    \
> +    do {                        \
> +      _rc = (exp);              \
> +    } while (_rc == -1);        \
> +  })
> +#define NULL 0
> +
> +extern "C" int memfd_create(const char *name, unsigned int flags);
> +
> +void a() {
> +  memfd_create(NULL, MFD_ALLOW_SEALING);
> +  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use
> MFD_CLOEXEC where possible [android-cloexec-memfd-create]
> +  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
> +  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
> +  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
> +  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL,
> MFD_ALLOW_SEALING | MFD_CLOEXEC))
> +}
> +
> +void f() {
> +  memfd_create(NULL, 3);
> +  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
> +  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
> +  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
> +  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
> +  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
> +
> +  int flag = 3;
> +  memfd_create(NULL, flag);
> +  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
> +}
> +
> +namespace i {
> +int memfd_create(const char *name, unsigned int flags);
> +
> +void d() {
> +  memfd_create(NULL, MFD_ALLOW_SEALING);
> +  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
> +}
> +
> +} // namespace i
> +
> +void e() {
> +  memfd_create(NULL, MFD_CLOEXEC);
> +  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
> +  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
> +  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING |
> MFD_CLOEXEC));
> +}
> +
> +class G {
> +public:
> +  int memfd_create(const char *name, unsigned int flags);
> +  void d() {
> +    memfd_create(NULL, MFD_ALLOW_SEALING);
> +    TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
> +  }
> +};
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170810/1beab5e7/attachment-0001.html>


More information about the cfe-commits mailing list