Yes. Sorry for the broken. But it works well in my Linux machine. Maybe I should revert it first.
Thanks, Yan Wang On Thu, Aug 10, 2017 at 12:07 PM, Nico Weber <tha...@chromium.org> wrote: > 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@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/CloexecMemfdCreat >> eCheck.cpp >> clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h >> clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloex >> ec-memfd-create.rst >> clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memf >> d-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-cl >> oexec-creat"); >> CheckFactories.registerCheck<CloexecFopenCheck>("android-cl >> oexec-fopen"); >> + CheckFactories.registerCheck<CloexecMemfdCreateCheck>( >> + "android-cloexec-memfd-create"); >> CheckFactories.registerCheck<CloexecOpenCheck>("android-clo >> exec-open"); >> CheckFactories.registerCheck<CloexecSocketCheck>("android-c >> loexec-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->Ignor >> eParenCasts())->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<CallExp >> r>(FuncBindingStr); >> + const auto *FlagArg = MatchedCall->getArg(ArgPos); >> + const auto *FD = Result.Nodes.getNodeAs<Functio >> nDecl>(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<CallExp >> r>(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<CallExp >> r>(FuncBindingStr); >> + const auto *FD = Result.Nodes.getNodeAs<Functio >> nDecl>(FuncDeclBindingStr); >> + const auto *ModeArg = MatchedCall->getArg(ArgPos); >> + >> + // Check if the <Mode> may be in the mode string. >> + const auto *ModeStr = dyn_cast<StringLiteral>(ModeAr >> g->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/CloexecMemfdCreat >> eCheck.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(is >> AnyCharacter()))); >> + 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/CloexecMemfdCreat >> eCheck.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-cloexe >> c-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_CREA >> TE_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-cloex >> ec-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-int >> eger-division.html>`_ check >> >> >> Added: clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloex >> ec-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-memf >> d-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@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits