Exemple #1
0
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;
}
Exemple #2
0
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;
}