1 //===--- CloexecCheck.h - clang-tidy-----------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file contains the declaration of the CloexecCheck class, which is the 11 /// base class for all of the close-on-exec checks in Android module. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H 16 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H 17 18 #include "../ClangTidyCheck.h" 19 20 namespace clang::tidy::android { 21 22 /// The base class for all close-on-exec checks in Android module. 23 /// To be specific, there are some functions that need the close-on-exec flag to 24 /// prevent the file descriptor leakage on fork+exec and this class provides 25 /// utilities to identify and fix these C functions. 26 class CloexecCheck : public ClangTidyCheck { 27 public: CloexecCheck(StringRef Name,ClangTidyContext * Context)28 CloexecCheck(StringRef Name, ClangTidyContext *Context) 29 : ClangTidyCheck(Name, Context) {} 30 31 protected: 32 void 33 registerMatchersImpl(ast_matchers::MatchFinder *Finder, 34 ast_matchers::internal::Matcher<FunctionDecl> Function); 35 36 /// Currently, we have three types of fixes. 37 /// 38 /// Type1 is to insert the necessary macro flag in the flag argument. For 39 /// example, 'O_CLOEXEC' is required in function 'open()', so 40 /// \code 41 /// open(file, O_RDONLY); 42 /// \endcode 43 /// should be 44 /// \code 45 /// open(file, O_RDONLY | O_CLOEXE); 46 /// \endcode 47 /// 48 /// \param [out] Result MatchResult from AST matcher. 49 /// \param MacroFlag The macro name of the flag. 50 /// \param ArgPos The 0-based position of the flag argument. 51 void insertMacroFlag(const ast_matchers::MatchFinder::MatchResult &Result, 52 StringRef MacroFlag, int ArgPos); 53 54 /// Type2 is to replace the API to another function that has required the 55 /// ability. For example: 56 /// \code 57 /// creat(path, mode); 58 /// \endcode 59 /// should be 60 /// \code 61 /// open(path, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, mode) 62 /// \endcode 63 /// 64 /// \param [out] Result MatchResult from AST matcher. 65 /// \param WarningMsg The warning message. 66 /// \param FixMsg The fix message. 67 void replaceFunc(const ast_matchers::MatchFinder::MatchResult &Result, 68 StringRef WarningMsg, StringRef FixMsg); 69 70 /// Type3 is also to add a flag to the corresponding argument, but this time, 71 /// the flag is some string and each char represents a mode rather than a 72 /// macro. For example, 'fopen' needs char 'e' in its mode argument string, so 73 /// \code 74 /// fopen(in_file, "r"); 75 /// \endcode 76 /// should be 77 /// \code 78 /// fopen(in_file, "re"); 79 /// \endcode 80 /// 81 /// \param [out] Result MatchResult from AST matcher. 82 /// \param Mode The required mode char. 83 /// \param ArgPos The 0-based position of the flag argument. 84 void insertStringFlag(const ast_matchers::MatchFinder::MatchResult &Result, 85 const char Mode, const int ArgPos); 86 87 /// Helper function to get the spelling of a particular argument. 88 StringRef getSpellingArg(const ast_matchers::MatchFinder::MatchResult &Result, 89 int N) const; 90 91 /// Binding name of the FuncDecl of a function call. 92 static const char *FuncDeclBindingStr; 93 94 /// Binding name of the function call expression. 95 static const char *FuncBindingStr; 96 }; 97 98 } // namespace clang::tidy::android 99 100 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H 101