Example #1
0
// Helper to find the set of values described by a TSpecifier
std::set<const Value*>
getValues(const ImmutableCallSite cs, TSpecifier TS) {
  std::set<const Value*> Values;
  switch (TS) {
    case Ret:
      assert(!cs.getInstruction()->getType()->isVoidTy());
      Values.insert(cs.getInstruction());
      break;
    case Arg0:
      assert(0 < cs.arg_size());
      Values.insert(cs.getArgument(0));
      break;
    case Arg1:
      assert(1 < cs.arg_size());
      Values.insert(cs.getArgument(1));
      break;
    case Arg2:
      assert(2 < cs.arg_size());
      Values.insert(cs.getArgument(2));
      break;
    case Arg3:
      assert(3 < cs.arg_size());
      Values.insert(cs.getArgument(3));
      break;
    case Arg4:
      assert(4 < cs.arg_size());
      Values.insert(cs.getArgument(4));
      break;
    case AllArgs:
      assert(!cs.arg_empty());
      for (unsigned i = 0; i < cs.arg_size(); ++i)
        Values.insert(cs.getArgument(i));
      break;
    case VarArgs: {
      const Value *Callee = cs.getCalledValue()->stripPointerCasts();
      FunctionType *CalleeType =
        dyn_cast<FunctionType>(
          dyn_cast<PointerType>(Callee->getType())->getElementType()
          );
      for (unsigned i = CalleeType->getNumParams(); i < cs.arg_size(); ++i)
        Values.insert(cs.getArgument(i));
      break;
    }
  }
  return Values;
}
Example #2
0
std::vector<FlowRecord>
StdLib::process(const ContextID ctxt, const ImmutableCallSite cs) const {
  const CallSummary *S;
  bool found = findEntry(cs, S);
  assert(found);

  std::vector<FlowRecord> flows;

  // If there are no flows for this call, return empty vector
  // Similarly if the call has no arguments we already know
  // it has no sources so just return empty vector.
  if (S->Sources.empty() || cs.arg_empty()) {
    return flows;
  }

  // Otherwise, build up a flow record for this summary
  FlowRecord flow(ctxt, ctxt);

  // First, process all sources
  for (std::vector<TaintDecl>::const_iterator I = S->Sources.begin(),
       E = S->Sources.end(); I != E; ++I) {
    const TaintDecl & TD = *I;
    assert(TD.end == T_Source);

    std::set<const Value*> Values = getValues(cs, TD.which);
    switch (TD.what) {
      case V: // Value
        flow.addSourceValue(Values.begin(), Values.end());
        break;
      case D: // DirectPtr
        flow.addSourceDirectPtr(Values.begin(), Values.end());
        break;
      case R: // Reachable
        flow.addSourceReachablePtr(Values.begin(), Values.end());
        break;
    }
  }

  // Then add all sinks
  for (std::vector<TaintDecl>::const_iterator I = S->Sinks.begin(),
       E = S->Sinks.end(); I != E; ++I) {
    const TaintDecl & TD = *I;
    assert(TD.end == T_Sink);

    std::set<const Value*> Values = getValues(cs, TD.which);
    switch (TD.what) {
      case V: // Value
        flow.addSinkValue(Values.begin(), Values.end());
        break;
      case D: // DirectPtr
        flow.addSinkDirectPtr(Values.begin(), Values.end());
        break;
      case R: // Reachable
        flow.addSinkReachablePtr(Values.begin(), Values.end());
        break;
    }
  }

  // Finally, stash it in the vector and return
  flows.push_back(flow);
  return flows;
}