bool TaintAnalysis::transfer(const Function& func, const DataflowNode& node_, NodeState& state, const std::vector<Lattice*>& dfInfo) { static size_t ncalls = 0; if (debug) { *debug <<"TaintAnalysis::transfer-" <<++ncalls <<"(func=" <<func.get_name() <<",\n" <<" node={" <<StringUtility::makeOneLine(node_.toString()) <<"},\n" <<" state={" <<state.str(this, " ") <<",\n" <<" dfInfo[" <<dfInfo.size() <<"]={...})\n"; } SgNode *node = node_.getNode(); assert(!dfInfo.empty()); FiniteVarsExprsProductLattice *prodLat = dynamic_cast<FiniteVarsExprsProductLattice*>(dfInfo.front()); bool modified = magic_tainted(node, prodLat); // some values are automatically tainted based on their name // Process AST nodes that transfer taintedness. Most of these operations have one or more inputs from which a result // is always calculated the same way. So we just gather up the inputs and do the calculation at the very end of this // function. The other operations are handled individually within their "if" bodies. TaintLattice *result = NULL; // result pointer into the taint lattice std::vector<TaintLattice*> inputs; // input pointers into the taint lattice if (isSgAssignInitializer(node)) { // as in "int a = b" SgAssignInitializer *xop = isSgAssignInitializer(node); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop->get_operand()))); inputs.push_back(in1); } else if (isSgAggregateInitializer(node)) { // as in "int a[1] = {b}" SgAggregateInitializer *xop = isSgAggregateInitializer(node); const SgExpressionPtrList &exprs = xop->get_initializers()->get_expressions(); for (size_t i=0; i<exprs.size(); ++i) { varID in_id = SgExpr2Var(exprs[i]); TaintLattice *in = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in_id)); inputs.push_back(in); } } else if (isSgInitializedName(node)) { SgInitializedName *xop = isSgInitializedName(node); if (xop->get_initializer()) { varID in1_id = SgExpr2Var(xop->get_initializer()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } } else if (isSgValueExp(node)) { // numeric and character constants SgValueExp *xop = isSgValueExp(node); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop))); if (result) modified = result->set_vertex(TaintLattice::VERTEX_UNTAINTED); } else if (isSgAddressOfOp(node)) { // as in "&x". The result taintedness has nothing to do with the value in x. /*void*/ } else if (isSgBinaryOp(node)) { // as in "a + b" SgBinaryOp *xop = isSgBinaryOp(node); varID in1_id = SgExpr2Var(isSgExpression(xop->get_lhs_operand())); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); varID in2_id = SgExpr2Var(isSgExpression(xop->get_rhs_operand())); TaintLattice *in2 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in2_id)); inputs.push_back(in2); if (isSgAssignOp(node)) { // copy the rhs lattice to the lhs lattice (as well as the entire '=' expression result) assert(in1 && in2); modified = in1->meetUpdate(in2); } } else if (isSgUnaryOp(node)) { // as in "-a" SgUnaryOp *xop = isSgUnaryOp(node); varID in1_id = SgExpr2Var(xop->get_operand()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } else if (isSgReturnStmt(node)) { // as in "return a". The result will always be dead, so we're just doing this to get some debugging output. Most // of our test inputs are functions, and the test examines the function's returned taintedness. SgReturnStmt *xop = isSgReturnStmt(node); varID in1_id = SgExpr2Var(xop->get_expression()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } // Update the result lattice (unless dead) with the inputs (unless dead) by using the meedUpdate() method. All this // means is that the new result will be the maximum of the old result and all inputs, where "maximum" is defined such // that "tainted" is greater than "untainted" (and both of them are greater than bottom/unknown). for (size_t i=0; i<inputs.size(); ++i) if (debug) *debug <<"TaintAnalysis::transfer: input " <<(i+1) <<" is " <<lattice_info(inputs[i]) <<"\n"; if (!result && varID::isValidVarExp(node)) { varID result_id(node); // NOTE: constructor doesn't handle all SgExpression nodes, thus the next "if" result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (!result && isSgExpression(node)) { varID result_id = SgExpr2Var(isSgExpression(node)); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (result) { for (size_t i=0; i<inputs.size(); ++i) { if (inputs[i]) modified = result->meetUpdate(inputs[i]) || modified; } } if (debug) *debug <<"TaintAnalysis::transfer: result is " <<lattice_info(result) <<(modified?" (modified)":" (not modified)") <<"\n"; return modified; }
std::string getSgInitializedName(SgInitializedName* initName) { std::string exprStr; SgSymbol* initNameSym = initName->search_for_symbol_from_symbol_table(); std::string varInit = initializeVariable(initName); std::string retString; if (initName->get_initptr() != NULL) { SgInitializer* nameInitializer = initName->get_initializer(); VariantT var = nameInitializer->variantT(); switch (var) { case V_SgAggregateInitializer: { SgAggregateInitializer* aggInit = isSgAggregateInitializer(nameInitializer); if (!isSgArrayType(aggInit->get_type())) { std::cout << "currently only arrays use aggregate initializers, you are using " << aggInit->class_name() << std::endl; ROSE_ASSERT(false); } SgExprListExp* members = aggInit->get_initializers(); SgExpressionPtrList member_expressions = members->get_expressions(); std::string symName = SymbolToZ3[initNameSym]; ROSE_ASSERT(SymbolToInstances[initNameSym] == 0); int arrmem = 0; std::stringstream exprStream; for (SgExpressionPtrList::iterator i = member_expressions.begin(); i != member_expressions.end(); i++) { exprStream << "\n(assert (= (select " << symName << "_0 " << arrmem << ") " << getSgExpressionString((isSgAssignInitializer((*i))->get_operand())) << ")"; arrmem = arrmem+1; } retString = varInit + "\n" + exprStream.str(); #ifdef ARRAY_TEST std::cout << "retString: " << retString << std::endl; #endif break; } case V_SgCompoundInitializer: { std::cout << "SgCompoundInitializer not yet supported" << std::endl; ROSE_ASSERT(false); break; } case V_SgConstructorInitializer: { std::cout << "SgConstructorInitializer is not yet supported" << std::endl; ROSE_ASSERT(false); break; } case V_SgDesignatedInitializer: { std::cout << "SgDesignatedInitializer is not yet supported" << std::endl; ROSE_ASSERT(false); break; } case V_SgAssignInitializer: { SgAssignInitializer* assignInit = isSgAssignInitializer(nameInitializer); std::string symName = SymbolToZ3[initNameSym]; ROSE_ASSERT(SymbolToInstances[initNameSym] == 0); exprStr = "(assert (= " + symName + "_0 " + getSgExpressionString(assignInit->get_operand()) + "))"; retString = varInit + "\n" + exprStr; break; } default: { std::cout << "unknown initializer of type: " << nameInitializer->class_name() << std::endl; ROSE_ASSERT(false); break; } } } else { retString = varInit; } return retString; }