//===-- 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.
//  This is described by the SEI Cert C rule POS05-C.
//  The checker is a warning not a hard failure since it only checks for a
//  recommended rule.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.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/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"

using namespace clang;
using namespace ento;

namespace {
enum ChrootKind { NO_CHROOT, ROOT_CHANGED, ROOT_CHANGE_FAILED, JAIL_ENTERED };
} // namespace

// Track chroot state changes for success, failure, state change
// and "jail"
REGISTER_TRAIT_WITH_PROGRAMSTATE(ChrootState, ChrootKind)
namespace {

// This checker checks improper use of chroot.
// The state transitions
//
//                          -> ROOT_CHANGE_FAILED
//                          |
// NO_CHROOT ---chroot(path)--> ROOT_CHANGED ---chdir(/) --> JAIL_ENTERED
//                                  |                               |
//         ROOT_CHANGED<--chdir(..)--      JAIL_ENTERED<--chdir(..)--
//                                  |                               |
//                      bug<--foo()--          JAIL_ENTERED<--foo()--
//
class ChrootChecker final : public Checker<eval::Call, check::PreCall> {
public:
  bool evalCall(const CallEvent &Call, CheckerContext &C) const;
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;

private:
  bool evalChroot(const CallEvent &Call, CheckerContext &C) const;
  bool evalChdir(const CallEvent &Call, CheckerContext &C) const;

  const BugType BreakJailBug{this, "Break out of jail"};
  const CallDescription Chroot{CDM::CLibrary, {"chroot"}, 1};
  const CallDescription Chdir{CDM::CLibrary, {"chdir"}, 1};
};

bool ChrootChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
  if (Chroot.matches(Call))
    return evalChroot(Call, C);

  if (Chdir.matches(Call))
    return evalChdir(Call, C);

  return false;
}

bool ChrootChecker::evalChroot(const CallEvent &Call, CheckerContext &C) const {
  BasicValueFactory &BVF = C.getSValBuilder().getBasicValueFactory();
  const StackFrame *SF = C.getStackFrame();
  ProgramStateRef State = C.getState();
  const auto *CE = cast<CallExpr>(Call.getOriginExpr());

  const QualType IntTy = C.getASTContext().IntTy;
  SVal Zero = nonloc::ConcreteInt{BVF.getValue(0, IntTy)};
  SVal Minus1 = nonloc::ConcreteInt{BVF.getValue(-1, IntTy)};

  ProgramStateRef ChrootFailed = State->BindExpr(CE, SF, Minus1);
  C.addTransition(ChrootFailed->set<ChrootState>(ROOT_CHANGE_FAILED));

  ProgramStateRef ChrootSucceeded = State->BindExpr(CE, SF, Zero);
  C.addTransition(ChrootSucceeded->set<ChrootState>(ROOT_CHANGED));
  return true;
}

bool ChrootChecker::evalChdir(const CallEvent &Call, CheckerContext &C) const {
  ProgramStateRef State = C.getState();

  // If there are no jail state, just return.
  if (State->get<ChrootState>() == NO_CHROOT)
    return false;

  // After chdir("/"), enter the jail, set the enum value JAIL_ENTERED.
  SVal ArgVal = Call.getArgSVal(0);

  if (const MemRegion *R = ArgVal.getAsRegion()) {
    R = R->StripCasts();
    if (const auto *StrRegion = dyn_cast<StringRegion>(R)) {
      if (StrRegion->getStringLiteral()->getString() == "/") {
        C.addTransition(State->set<ChrootState>(JAIL_ENTERED));
        return true;
      }
    }
  }
  return false;
}

class ChrootInvocationVisitor final : public BugReporterVisitor {
public:
  explicit ChrootInvocationVisitor(const CallDescription &Chroot)
      : Chroot{Chroot} {}

  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
                                   BugReporterContext &BRC,
                                   PathSensitiveBugReport &BR) override {
    if (Satisfied)
      return nullptr;

    auto StmtP = N->getLocation().getAs<StmtPoint>();
    if (!StmtP)
      return nullptr;

    const CallExpr *Call = StmtP->getStmtAs<CallExpr>();
    if (!Call)
      return nullptr;

    if (!Chroot.matchesAsWritten(*Call))
      return nullptr;

    Satisfied = true;
    PathDiagnosticLocation Pos(Call, BRC.getSourceManager(),
                               N->getStackFrame());
    return std::make_shared<PathDiagnosticEventPiece>(Pos, "chroot called here",
                                                      /*addPosRange=*/true);
  }

  void Profile(llvm::FoldingSetNodeID &ID) const override {
    static bool Tag;
    ID.AddPointer(&Tag);
  }

private:
  const CallDescription &Chroot;
  bool Satisfied = false;
};

// 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 (matchesAny(Call, Chroot, Chdir))
    return;

  // If jail state is not ROOT_CHANGED just return.
  if (C.getState()->get<ChrootState>() != ROOT_CHANGED)
    return;

  // Generate bug report.
  ExplodedNode *Err =
      C.generateNonFatalErrorNode(C.getState(), C.getPredecessor());
  if (!Err)
    return;

  auto R = std::make_unique<PathSensitiveBugReport>(
      BreakJailBug, R"(No call of chdir("/") immediately after chroot)", Err);
  R->addVisitor<ChrootInvocationVisitor>(Chroot);
  C.emitReport(std::move(R));
}

} // namespace

void ento::registerChrootChecker(CheckerManager &Mgr) {
  Mgr.registerChecker<ChrootChecker>();
}

bool ento::shouldRegisterChrootChecker(const CheckerManager &) { return true; }
