Files
clang-p2996/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp
NagyDonat e2f1cbae45 [analyzer] Use explicit call description mode (easy cases) (#88879)
This commit explicitly specifies the matching mode (C library function,
any non-method function, or C++ method) for the `CallDescription`s
constructed in various checkers where this transition was easy and
straightforward.

This change won't cause major functional changes, but isn't NFC because
it ensures that e.g. call descriptions for a non-method function won't
accidentally match a method that has the same name.

Separate commits will perform (or have already performed) this change in
other checkers. My goal is to ensure that the call description mode is
always explicitly specified and eliminate (or strongly restrict) the
vague "may be either a method or a simple function" mode that's the
current default.
2024-04-19 14:22:51 +02:00

68 lines
2.5 KiB
C++

//== PutenvWithAutoChecker.cpp --------------------------------- -*- 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 PutenvWithAutoChecker which finds calls of ``putenv``
// function with automatic variable as the argument.
// https://wiki.sei.cmu.edu/confluence/x/6NYxBQ
//
//===----------------------------------------------------------------------===//
#include "../AllocationState.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 "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
using namespace clang;
using namespace ento;
namespace {
class PutenvWithAutoChecker : public Checker<check::PostCall> {
private:
BugType BT{this, "'putenv' function should not be called with auto variables",
categories::SecurityError};
const CallDescription Putenv{CDM::CLibrary, {"putenv"}, 1};
public:
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
};
} // namespace
void PutenvWithAutoChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
if (!Putenv.matches(Call))
return;
SVal ArgV = Call.getArgSVal(0);
const Expr *ArgExpr = Call.getArgExpr(0);
const MemSpaceRegion *MSR = ArgV.getAsRegion()->getMemorySpace();
if (!isa<StackSpaceRegion>(MSR))
return;
StringRef ErrorMsg = "The 'putenv' function should not be called with "
"arguments that have automatic storage";
ExplodedNode *N = C.generateErrorNode();
auto Report = std::make_unique<PathSensitiveBugReport>(BT, ErrorMsg, N);
// Track the argument.
bugreporter::trackExpressionValue(Report->getErrorNode(), ArgExpr, *Report);
C.emitReport(std::move(Report));
}
void ento::registerPutenvWithAuto(CheckerManager &Mgr) {
Mgr.registerChecker<PutenvWithAutoChecker>();
}
bool ento::shouldRegisterPutenvWithAuto(const CheckerManager &) { return true; }