//===- Chrootchecker.cpp -------- Basic security checks ----------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines chroot checker, which checks improper use of chroot.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.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/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/ADT/ImmutableMap.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::PreStmt<CallExpr> > {
  mutable IdentifierInfo *II_chroot, *II_chdir;
  // This bug refers to possibly break out of a chroot() jail.
  mutable std::unique_ptr<BuiltinBug> BT_BreakJail;

public:
  ChrootChecker() : II_chroot(nullptr), II_chdir(nullptr) {}

  static void *getTag() {
    static int x;
    return &x;
  }

  bool evalCall(const CallExpr *CE, CheckerContext &C) const;
  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;

private:
  void Chroot(CheckerContext &C, const CallExpr *CE) const;
  void Chdir(CheckerContext &C, const CallExpr *CE) const;
};

} // end anonymous namespace

bool ChrootChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
  const FunctionDecl *FD = C.getCalleeDecl(CE);
  if (!FD)
    return false;

  ASTContext &Ctx = C.getASTContext();
  if (!II_chroot)
    II_chroot = &Ctx.Idents.get("chroot");
  if (!II_chdir)
    II_chdir = &Ctx.Idents.get("chdir");

  if (FD->getIdentifier() == II_chroot) {
    Chroot(C, CE);
    return true;
  }
  if (FD->getIdentifier() == II_chdir) {
    Chdir(C, CE);
    return true;
  }

  return false;
}

void ChrootChecker::Chroot(CheckerContext &C, const CallExpr *CE) 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::Chdir(CheckerContext &C, const CallExpr *CE) 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 = CE->getArg(0);
  SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());

  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::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
  const FunctionDecl *FD = C.getCalleeDecl(CE);
  if (!FD)
    return;

  ASTContext &Ctx = C.getASTContext();
  if (!II_chroot)
    II_chroot = &Ctx.Idents.get("chroot");
  if (!II_chdir)
    II_chdir = &Ctx.Idents.get("chdir");

  // Ingnore chroot and chdir.
  if (FD->getIdentifier() == II_chroot || FD->getIdentifier() == II_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));
      }

  return;
}

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