Ejemplo n.º 1
0
void ClassHierarchyUtils::cacheAllCalleesForVirtualCalls(Module& M) {
  if (!cachingDone) {
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
        if (CallInst* C = dyn_cast<CallInst>(&*I)) {
          GlobalVariable* definingTypeVTableVar = NULL;
          GlobalVariable* staticTypeVTableVar = NULL;
          bool hasMetadata = false;
          if (MDNode* N = I->getMetadata("soaap_defining_vtable_var")) {
            definingTypeVTableVar = cast<GlobalVariable>(N->getOperand(0));
            hasMetadata = true;
          }
          else if (MDNode* N = I->getMetadata("soaap_defining_vtable_name")) {
            ConstantDataArray* definingTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0));
            string definingTypeVTableConstantStr = definingTypeVTableConstant->getAsString().str();
            //dbgs() << "definingTypeVTableConstantStr: " << definingTypeVTableConstantStr << "\n";
            definingTypeVTableVar = M.getGlobalVariable(definingTypeVTableConstantStr, true);
            hasMetadata = true;
          }
          if (MDNode* N = I->getMetadata("soaap_static_vtable_var")) {
            staticTypeVTableVar = cast<GlobalVariable>(N->getOperand(0));
            hasMetadata = true;
          }
          else if (MDNode* N = I->getMetadata("soaap_static_vtable_name")) {
            ConstantDataArray* staticTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0));
            string staticTypeVTableConstantStr = staticTypeVTableConstant->getAsString().str();
            //dbgs() << "staticTypeVTableConstantStr: " << staticTypeVTableConstantStr << "\n";
            staticTypeVTableVar = M.getGlobalVariable(staticTypeVTableConstantStr, true);
            hasMetadata = true;
          }
          if (definingTypeVTableVar != NULL) {
            SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found definingVTableVar: " << *definingTypeVTableVar << "\n");
            if (staticTypeVTableVar == NULL) {
              dbgs() << "definingVTableVar is not null, but staticTypeVTableVar is NULL\n";
              // This could be the case if no instance of the static type is ever created
              staticTypeVTableVar = definingTypeVTableVar;
            }
            callToCalleesCache[C] = findAllCalleesForVirtualCall(C, definingTypeVTableVar, staticTypeVTableVar, M);
          }
          else if (hasMetadata) {
            dbgs() << "Defining VTable is NULL!\n";
            I->dump();
          }
        }
      }
    }
    cachingDone = true;
  }
}
Ejemplo n.º 2
0
void AssertionSiteInstrumenter::ParseAssertionLocation(
  Location *Loc, CallInst *Call) {

  assert(Call->getCalledFunction()->getName() == INLINE_ASSERTION);

  if (Call->getNumArgOperands() < 4)
    panic("TESLA assertion must have at least 4 arguments");

  // The filename (argument 1) should be a global variable.
  GlobalVariable *NameVar =
    dyn_cast<GlobalVariable>(Call->getOperand(1)->stripPointerCasts());

  ConstantDataArray *A;
  if (!NameVar ||
      !(A = dyn_cast_or_null<ConstantDataArray>(NameVar->getInitializer()))) {
    Call->dump();
    panic("unable to parse filename from TESLA assertion");
  }

  *Loc->mutable_filename() = A->getAsString();


  // The line and counter values should be constant integers.
  ConstantInt *Line = dyn_cast<ConstantInt>(Call->getOperand(2));
  if (!Line) {
    Call->getOperand(2)->dump();
    panic("assertion line must be a constant int");
  }

  Loc->set_line(Line->getLimitedValue(INT_MAX));

  ConstantInt *Count = dyn_cast<ConstantInt>(Call->getOperand(3));
  if (!Count) {
    Call->getOperand(3)->dump();
    panic("assertion count must be a constant int");
  }

  Loc->set_counter(Count->getLimitedValue(INT_MAX));
}
Ejemplo n.º 3
0
SandboxVector SandboxUtils::findSandboxes(Module& M) {
  FunctionIntMap funcToOverhead;
  FunctionIntMap funcToClearances;
  map<Function*,string> funcToSandboxName;
  map<string,FunctionSet> sandboxNameToEntryPoints;
  StringSet ephemeralSandboxes;

  SandboxVector sandboxes;

  // function-level annotations of sandboxed code
  Regex *sboxPerfRegex = new Regex("perf_overhead_\\(([0-9]{1,2})\\)", true);
  SmallVector<StringRef, 4> matches;
  if (GlobalVariable* lga = M.getNamedGlobal("llvm.global.annotations")) {
    ConstantArray* lgaArray = dyn_cast<ConstantArray>(lga->getInitializer()->stripPointerCasts());
    for (User::op_iterator i=lgaArray->op_begin(), e = lgaArray->op_end(); e!=i; i++) {
      ConstantStruct* lgaArrayElement = dyn_cast<ConstantStruct>(i->get());

      // get the annotation value first
      GlobalVariable* annotationStrVar = dyn_cast<GlobalVariable>(lgaArrayElement->getOperand(1)->stripPointerCasts());
      ConstantDataArray* annotationStrArray = dyn_cast<ConstantDataArray>(annotationStrVar->getInitializer());
      StringRef annotationStrArrayCString = annotationStrArray->getAsCString();
      GlobalValue* annotatedVal = dyn_cast<GlobalValue>(lgaArrayElement->getOperand(0)->stripPointerCasts());
      if (isa<Function>(annotatedVal)) {
        Function* annotatedFunc = dyn_cast<Function>(annotatedVal);
        StringRef sandboxName;
        if (annotationStrArrayCString.startswith(SANDBOX_PERSISTENT) || annotationStrArrayCString.startswith(SANDBOX_EPHEMERAL)) {
          sandboxEntryPoints.insert(annotatedFunc);
          outs() << INDENT_1 << "Found sandbox entrypoint " << annotatedFunc->getName() << "\n";
          outs() << INDENT_2 << "Annotation string: " << annotationStrArrayCString << "\n";
          if (annotationStrArrayCString.startswith(SANDBOX_PERSISTENT)) {
            sandboxName = annotationStrArrayCString.substr(strlen(SANDBOX_PERSISTENT)+1);
          }
          else if (annotationStrArrayCString.startswith(SANDBOX_EPHEMERAL)) {
            sandboxName = annotationStrArrayCString.substr(strlen(SANDBOX_EPHEMERAL)+1);
            ephemeralSandboxes.insert(sandboxName);
          }
          outs() << INDENT_2 << "Sandbox name: " << sandboxName << "\n";
          if (funcToSandboxName.find(annotatedFunc) != funcToSandboxName.end()) {
            outs() << INDENT_1 << "*** Error: Function " << annotatedFunc->getName() << " is already an entrypoint for another sandbox\n";
          }
          else {
            funcToSandboxName[annotatedFunc] = sandboxName;
            sandboxNameToEntryPoints[sandboxName].insert(annotatedFunc);
          }
        }
        else if (sboxPerfRegex->match(annotationStrArrayCString, &matches)) {
          int overhead;
          outs() << INDENT_2 << "Threshold set to " << matches[1].str() <<
                  "%\n";
          matches[1].getAsInteger(0, overhead);
          funcToOverhead[annotatedFunc] = overhead;
        }
        else if (annotationStrArrayCString.startswith(CLEARANCE)) {
          StringRef className = annotationStrArrayCString.substr(strlen(CLEARANCE)+1);
          outs() << INDENT_2 << "Sandbox has clearance for \"" << className << "\"\n";
          ClassifiedUtils::assignBitIdxToClassName(className);
          funcToClearances[annotatedFunc] |= (1 << ClassifiedUtils::getBitIdxFromClassName(className));
        }
      }
    }
  }

  // TODO: sanity check overhead and clearance annotations

  // Combine all annotation information for function-level sandboxes to create Sandbox instances
  for (pair<string,FunctionSet> p : sandboxNameToEntryPoints) {
    string sandboxName = p.first;
    FunctionSet entryPoints = p.second;
    int idx = assignBitIdxToSandboxName(sandboxName);
    int overhead = 0;
    int clearances = 0; 
    bool persistent = find(ephemeralSandboxes.begin(), ephemeralSandboxes.end(), sandboxName) == ephemeralSandboxes.end();

    // set overhead and clearances; any of the entry points could be annotated
    for (Function* entryPoint : entryPoints) {
      if (funcToOverhead.find(entryPoint) != funcToOverhead.end()) {
        overhead = funcToOverhead[entryPoint];
      }
      if (funcToClearances.find(entryPoint) != funcToClearances.end()) {
        clearances = funcToClearances[entryPoint];
      }
    }

		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Creating new Sandbox instance for " << sandboxName << "\n");
    sandboxes.push_back(new Sandbox(sandboxName, idx, entryPoints, persistent, M, overhead, clearances));
		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Created new Sandbox instance\n");
  }

  /*
  for (map<Function*,string>::iterator I=funcToSandboxName.begin(), E=funcToSandboxName.end(); I!=E; I++) {
    Function* entryPoint = I->first;
    string sandboxName = I->second;
    int idx = assignBitIdxToSandboxName(sandboxName);
    int overhead = funcToOverhead[entryPoint];
    int clearances = funcToClearances[entryPoint];
    bool persistent = find(ephemeralSandboxes.begin(), ephemeralSandboxes.end(), entryPoint) == ephemeralSandboxes.end();
		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Creating new Sandbox instance\n");
    sandboxes.push_back(new Sandbox(sandboxName, idx, entryPoint, persistent, M, overhead, clearances));
		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Created new Sandbox instance\n");
  }
  */

  // Handle sandboxed code regions, i.e. start_sandboxed_code(N) and end_sandboxed_code(N) blocks 
  if (Function* SboxStart = M.getFunction("llvm.annotation.i32")) {
    for (User* U : SboxStart->users()) {
      if (IntrinsicInst* annotCall = dyn_cast<IntrinsicInst>(U)) {
        GlobalVariable* annotationStrVar = dyn_cast<GlobalVariable>(annotCall->getOperand(1)->stripPointerCasts());
        ConstantDataArray* annotationStrValArray = dyn_cast<ConstantDataArray>(annotationStrVar->getInitializer());
        StringRef annotationStrValCString = annotationStrValArray->getAsCString();
        
        if (annotationStrValCString.startswith(SOAAP_SANDBOX_REGION_START)) {
          StringRef sandboxName = annotationStrValCString.substr(strlen(SOAAP_SANDBOX_REGION_START)+1); //+1 because of _
          SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_3 << "Found start of sandboxed code region: "; annotCall->dump(););
          InstVector sandboxedInsts;
          findAllSandboxedInstructions(annotCall, sandboxName, sandboxedInsts);
          int idx = assignBitIdxToSandboxName(sandboxName);
          sandboxes.push_back(new Sandbox(sandboxName, idx, sandboxedInsts, false, M)); //TODO: obtain persistent/ephemeral information in a better way (currently we obtain it from the creation point)
        }
      }
Ejemplo n.º 4
0
void PrivilegedCallAnalysis::doAnalysis(Module& M, SandboxVector& sandboxes) {
  // first find all methods annotated as being privileged and then check calls within sandboxes
  if (GlobalVariable* lga = M.getNamedGlobal("llvm.global.annotations")) {
    ConstantArray* lgaArray = dyn_cast<ConstantArray>(lga->getInitializer()->stripPointerCasts());
    for (User::op_iterator i=lgaArray->op_begin(), e = lgaArray->op_end(); e!=i; i++) {
      ConstantStruct* lgaArrayElement = dyn_cast<ConstantStruct>(i->get());

      // get the annotation value first
      GlobalVariable* annotationStrVar = dyn_cast<GlobalVariable>(lgaArrayElement->getOperand(1)->stripPointerCasts());
      ConstantDataArray* annotationStrArray = dyn_cast<ConstantDataArray>(annotationStrVar->getInitializer());
      StringRef annotationStrArrayCString = annotationStrArray->getAsCString();

      GlobalValue* annotatedVal = dyn_cast<GlobalValue>(lgaArrayElement->getOperand(0)->stripPointerCasts());
      if (isa<Function>(annotatedVal)) {
        Function* annotatedFunc = dyn_cast<Function>(annotatedVal);
        if (annotationStrArrayCString == SOAAP_PRIVILEGED) {
          outs() << "   Found function: " << annotatedFunc->getName() << "\n";
          privAnnotFuncs.push_back(annotatedFunc);
        }
      }
    }
  }          

  // now check calls within sandboxes
  for (Function* privilegedFunc : privAnnotFuncs) {
    for (User* U : privilegedFunc->users()) {
      if (CallInst* C = dyn_cast<CallInst>(U)) {
        Function* enclosingFunc = C->getParent()->getParent();
        for (Sandbox* S : sandboxes) {
          if (!S->hasCallgate(privilegedFunc) && S->containsFunction(enclosingFunc)) {
            outs() << " *** Sandbox \"" << S->getName() << "\" calls privileged function \"" << privilegedFunc->getName() << "\" that they are not allowed to. If intended, annotate this permission using the __soaap_callgates annotation.\n";
            if (MDNode *N = C->getMetadata("dbg")) {  // Here I is an LLVM instruction
              DILocation Loc(N);                      // DILocation is in DebugInfo.h
              unsigned Line = Loc.getLineNumber();
              StringRef File = Loc.getFilename();
              outs() << " +++ Line " << Line << " of file " << File << "\n";
            }
          }
        }
      }
    }
  }

  /*
  for (Sandbox* S : sandboxes) {
    FunctionVector callgates = S->getCallgates();
    for (Function* F : S->getFunctions()) {
      for (BasicBlock& BB : F->getBasicBlockList()) {
        for (Instruction& I : BB.getInstList()) {
          if (CallInst* C = dyn_cast<CallInst>(&I)) {
            if (Function* Target = C->getCalledFunction()) {
              if (find(privAnnotFuncs.begin(), privAnnotFuncs.end(), Target) != privAnnotFuncs.end()) {
                // check if this sandbox is allowed to call the privileged function
                DEBUG(dbgs() << "   Found privileged call: "); 
                DEBUG(C->dump());
                if (find(callgates.begin(), callgates.end(), Target) == callgates.end()) {
                  outs() << " *** Sandbox \"" << S->getName() << "\" calls privileged function \"" << Target->getName() << "\" that they are not allowed to. If intended, annotate this permission using the __soaap_callgates annotation.\n";
                  if (MDNode *N = C->getMetadata("dbg")) {  // Here I is an LLVM instruction
                    DILocation Loc(N);                      // DILocation is in DebugInfo.h
                    unsigned Line = Loc.getLineNumber();
                    StringRef File = Loc.getFilename();
                    outs() << " +++ Line " << Line << " of file " << File << "\n";
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  */
}