//== MIGChecker.cpp - MIG calling convention checker ------------*- C++ -*--==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines MIGChecker, a Mach Interface Generator calling convention // checker. Namely, in MIG callback implementation the following rules apply: // - When a server routine returns an error code that represents success, it // must take ownership of resources passed to it (and eventually release // them). // - Additionally, when returning success, all out-parameters must be // initialized. // - When it returns any other error code, it must not take ownership, // because the message and its out-of-line parameters will be destroyed // by the client that called the function. // For now we only check the last rule, as its violations lead to dangerous // use-after-free exploits. // //===----------------------------------------------------------------------===// #include "clang/AST/Attr.h" #include "clang/Analysis/AnyCall.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include <optional> usingnamespaceclang; usingnamespaceento; namespace { class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>, check::EndFunction> { … }; } // end anonymous namespace // A flag that says that the programmer has called a MIG destructor // for at least one parameter. REGISTER_TRAIT_WITH_PROGRAMSTATE(…) … // A set of parameters for which the check is suppressed because // reference counting is being performed. REGISTER_SET_WITH_PROGRAMSTATE(…) … static const ParmVarDecl *getOriginParam(SVal V, CheckerContext &C, bool IncludeBaseRegions = false) { … } static bool isInMIGCall(CheckerContext &C) { … } void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { … } // Returns true if V can potentially represent a "successful" kern_return_t. static bool mayBeSuccess(SVal V, CheckerContext &C) { … } void MIGChecker::checkReturnAux(const ReturnStmt *RS, CheckerContext &C) const { … } void ento::registerMIGChecker(CheckerManager &Mgr) { … } bool ento::shouldRegisterMIGChecker(const CheckerManager &mgr) { … }