diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp | |
parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) |
Notes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp | 141 |
1 files changed, 0 insertions, 141 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp deleted file mode 100644 index 9fffedfccd87..000000000000 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp +++ /dev/null @@ -1,141 +0,0 @@ -//===-- ChrootChecker.cpp - chroot usage checks ---------------------------===// -// -// 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 chroot checker, which checks improper use of chroot. -// -//===----------------------------------------------------------------------===// - -#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/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" - -using namespace clang; -using namespace ento; - -namespace { - -// enum value that represent the jail state -enum Kind { NO_CHROOT, ROOT_CHANGED, JAIL_ENTERED }; - -bool isRootChanged(intptr_t k) { return k == ROOT_CHANGED; } -//bool isJailEntered(intptr_t k) { return k == JAIL_ENTERED; } - -// This checker checks improper use of chroot. -// The state transition: -// NO_CHROOT ---chroot(path)--> ROOT_CHANGED ---chdir(/) --> JAIL_ENTERED -// | | -// ROOT_CHANGED<--chdir(..)-- JAIL_ENTERED<--chdir(..)-- -// | | -// bug<--foo()-- JAIL_ENTERED<--foo()-- -class ChrootChecker : public Checker<eval::Call, check::PreCall> { - // This bug refers to possibly break out of a chroot() jail. - mutable std::unique_ptr<BuiltinBug> BT_BreakJail; - - const CallDescription Chroot{"chroot", 1}, Chdir{"chdir", 1}; - -public: - ChrootChecker() {} - - static void *getTag() { - static int x; - return &x; - } - - bool evalCall(const CallEvent &Call, CheckerContext &C) const; - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; - -private: - void evalChroot(const CallEvent &Call, CheckerContext &C) const; - void evalChdir(const CallEvent &Call, CheckerContext &C) const; -}; - -} // end anonymous namespace - -bool ChrootChecker::evalCall(const CallEvent &Call, CheckerContext &C) const { - if (Call.isCalled(Chroot)) { - evalChroot(Call, C); - return true; - } - if (Call.isCalled(Chdir)) { - evalChdir(Call, C); - return true; - } - - return false; -} - -void ChrootChecker::evalChroot(const CallEvent &Call, CheckerContext &C) const { - ProgramStateRef state = C.getState(); - ProgramStateManager &Mgr = state->getStateManager(); - - // Once encouter a chroot(), set the enum value ROOT_CHANGED directly in - // the GDM. - state = Mgr.addGDM(state, ChrootChecker::getTag(), (void*) ROOT_CHANGED); - C.addTransition(state); -} - -void ChrootChecker::evalChdir(const CallEvent &Call, CheckerContext &C) const { - ProgramStateRef state = C.getState(); - ProgramStateManager &Mgr = state->getStateManager(); - - // If there are no jail state in the GDM, just return. - const void *k = state->FindGDM(ChrootChecker::getTag()); - if (!k) - return; - - // After chdir("/"), enter the jail, set the enum value JAIL_ENTERED. - const Expr *ArgExpr = Call.getArgExpr(0); - SVal ArgVal = C.getSVal(ArgExpr); - - if (const MemRegion *R = ArgVal.getAsRegion()) { - R = R->StripCasts(); - if (const StringRegion* StrRegion= dyn_cast<StringRegion>(R)) { - const StringLiteral* Str = StrRegion->getStringLiteral(); - if (Str->getString() == "/") - state = Mgr.addGDM(state, ChrootChecker::getTag(), - (void*) JAIL_ENTERED); - } - } - - C.addTransition(state); -} - -// Check the jail state before any function call except chroot and chdir(). -void ChrootChecker::checkPreCall(const CallEvent &Call, - CheckerContext &C) const { - // Ignore chroot and chdir. - if (Call.isCalled(Chroot) || Call.isCalled(Chdir)) - return; - - // If jail state is ROOT_CHANGED, generate BugReport. - void *const* k = C.getState()->FindGDM(ChrootChecker::getTag()); - if (k) - if (isRootChanged((intptr_t) *k)) - if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - if (!BT_BreakJail) - BT_BreakJail.reset(new BuiltinBug( - this, "Break out of jail", "No call of chdir(\"/\") immediately " - "after chroot")); - C.emitReport(llvm::make_unique<BugReport>( - *BT_BreakJail, BT_BreakJail->getDescription(), N)); - } -} - -void ento::registerChrootChecker(CheckerManager &mgr) { - mgr.registerChecker<ChrootChecker>(); -} - -bool ento::shouldRegisterChrootChecker(const LangOptions &LO) { - return true; -} |