bool GenericTaintChecker::propagateFromPre(const CallExpr *CE, CheckerContext &C) const { ProgramStateRef State = C.getState(); // Depending on what was tainted at pre-visit, we determined a set of // arguments which should be tainted after the function returns. These are // stored in the state as TaintArgsOnPostVisit set. TaintArgsOnPostVisitTy TaintArgs = State->get<TaintArgsOnPostVisit>(); if (TaintArgs.isEmpty()) return false; for (llvm::ImmutableSet<unsigned>::iterator I = TaintArgs.begin(), E = TaintArgs.end(); I != E; ++I) { unsigned ArgNum = *I; // Special handling for the tainted return value. if (ArgNum == ReturnValueIndex) { State = State->addTaint(CE, C.getLocationContext()); continue; } // The arguments are pointer arguments. The data they are pointing at is // tainted after the call. if (CE->getNumArgs() < (ArgNum + 1)) return false; const Expr* Arg = CE->getArg(ArgNum); Optional<SVal> V = getPointedToSVal(C, Arg); if (V) State = State->addTaint(*V); } // Clear up the taint info from the state. State = State->remove<TaintArgsOnPostVisit>(); if (State != C.getState()) { C.addTransition(State); return true; } return false; }
// If argument 0(protocol domain) is network, the return value should get taint. ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE, CheckerContext &C) const { ProgramStateRef State = C.getState(); if (CE->getNumArgs() < 3) return State; SourceLocation DomLoc = CE->getArg(0)->getExprLoc(); StringRef DomName = C.getMacroNameOrSpelling(DomLoc); // White list the internal communication protocols. if (DomName.equals("AF_SYSTEM") || DomName.equals("AF_LOCAL") || DomName.equals("AF_UNIX") || DomName.equals("AF_RESERVED_36")) return State; State = State->addTaint(CE, C.getLocationContext()); return State; }
ProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE, CheckerContext &C) const { ProgramStateRef State = C.getState(); if (CE->getNumArgs() < 2) return State; // All arguments except for the very first one should get taint. for (unsigned int i = 1; i < CE->getNumArgs(); ++i) { // The arguments are pointer arguments. The data they are pointing at is // tainted after the call. const Expr* Arg = CE->getArg(i); Optional<SVal> V = getPointedToSVal(C, Arg); if (V) State = State->addTaint(*V); } return State; }