xref: /llvm-project/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp (revision 527a4205505155503de1fb1daecea472ba95358b)
1 //===--- Env33CCheck.cpp - clang-tidy--------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CommandProcessorCheck.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 
14 using namespace clang::ast_matchers;
15 
16 namespace clang {
17 namespace tidy {
18 namespace cert {
19 
20 void CommandProcessorCheck::registerMatchers(MatchFinder *Finder) {
21   Finder->addMatcher(
22       callExpr(
23           callee(functionDecl(anyOf(hasName("::system"), hasName("::popen"),
24                                     hasName("::_popen")))
25                      .bind("func")),
26           // Do not diagnose when the call expression passes a null pointer
27           // constant to system(); that only checks for the presence of a
28           // command processor, which is not a security risk by itself.
29           unless(callExpr(callee(functionDecl(hasName("::system"))),
30                           argumentCountIs(1),
31                           hasArgument(0, nullPointerConstant()))))
32           .bind("expr"),
33       this);
34 }
35 
36 void CommandProcessorCheck::check(const MatchFinder::MatchResult &Result) {
37   const auto *Fn = Result.Nodes.getNodeAs<FunctionDecl>("func");
38   const auto *E = Result.Nodes.getNodeAs<CallExpr>("expr");
39 
40   diag(E->getExprLoc(), "calling %0 uses a command processor") << Fn;
41 }
42 
43 } // namespace cert
44 } // namespace tidy
45 } // namespace clang
46