private void visitInvoke(InvokeInstruction obj) { TaintMethodSummary methodSummary = getMethodSummary(obj); Taint taint = getMethodTaint(methodSummary); if (taint.getState() == Taint.State.UNKNOWN) { taint.addTaintLocation(getLocation(), false); } transferTaintToMutables(methodSummary, taint); modelInstruction(obj, getNumWordsConsumed(obj), getNumWordsProduced(obj), taint); }
private int getPriority(Taint taint) { if (taint.isTainted()) { return Priorities.HIGH_PRIORITY; } else if (!taint.isSafe()) { return Priorities.NORMAL_PRIORITY; } else { return Priorities.IGNORE_PRIORITY; } }
@Override public void visitAALOAD(AALOAD obj) { try { Taint arrayTaint = getFrame().getStackValue(1); Taint pushTaint = new Taint(arrayTaint.getState()); modelInstruction(obj, getNumWordsConsumed(obj), getNumWordsProduced(obj), pushTaint); } catch (DataflowAnalysisException ex) { throw new InvalidBytecodeException("Not enough values on the stack", ex); } }
private void transferTaintToMutables(TaintMethodSummary methodSummary, Taint taint) throws RuntimeException { if (methodSummary == null || !methodSummary.hasMutableStackIndex()) { return; } int mutableStackIndex = methodSummary.getMutableStackIndex(); try { Taint stackValue = getFrame().getStackValue(mutableStackIndex); // needed especially for constructors stackValue.setState(taint.getState()); for (Location location : taint.getTaintedLocations()) { stackValue.addTaintLocation(location, true); } for (Location location : taint.getPossibleTaintedLocations()) { stackValue.addTaintLocation(location, false); } if (stackValue.hasValidLocalVariableIndex()) { int index = stackValue.getLocalVariableIndex(); getFrame().setValue(index, taint); } // else we are not able to transfer taint to a local variable } catch (DataflowAnalysisException ex) { throw new RuntimeException("Bad mutable stack index specification", ex); } }
private void reportBug(BugInstance bugInstance, Taint taint, String currentMethod) { if (taint.hasTaintedLocations()) { addSourceLines(taint.getTaintedLocations(), bugInstance); } else { addSourceLines(taint.getPossibleTaintedLocations(), bugInstance); } if (bugInstance.getPriority() == Priorities.NORMAL_PRIORITY && taint.hasTaintParameters()) { delayBugToReport(currentMethod, taint, bugInstance); } else { bugReporter.reportBug(bugInstance); } }
private void checkTaintSink( String calledMethod, TaintFrame fact, SourceLineAnnotation sourceLine, String currentMethod) throws DataflowAnalysisException { if (methodsWithSinks.containsKey(calledMethod)) { Set<TaintSink> sinks = methodsWithSinks.get(calledMethod); for (TaintSink sink : sinks) { Taint sinkTaint = sink.getTaint(); Set<Integer> taintParameters = sinkTaint.getTaintParameters(); Taint finalTaint = sinkTaint.getNonParametricTaint(); for (Integer offset : taintParameters) { Taint parameterTaint = fact.getStackValue(offset); finalTaint = Taint.merge(finalTaint, parameterTaint); } if (finalTaint == null) { continue; } if (finalTaint.isTainted()) { BugInstance bugInstance = sink.getBugInstance(); bugInstance.setPriority(Priorities.HIGH_PRIORITY); bugInstance.addSourceLine(sourceLine); } else if (finalTaint.hasTaintParameters()) { assert finalTaint.isUnknown(); BugInstance bugInstance = sink.getBugInstance(); bugInstance.addSourceLine(sourceLine); delayBugToReport(currentMethod, finalTaint, bugInstance); } } } }
@Override public void handleLoadInstruction(LoadInstruction obj) { int numProduced = obj.produceStack(cpg); if (numProduced == Constants.UNPREDICTABLE) { throw new InvalidBytecodeException("Unpredictable stack production"); } int index = obj.getIndex() + numProduced; while (numProduced-- > 0) { Taint value = getFrame().getValue(--index); // set local variable origin of a stack value value.setLocalVariableIndex(index); getFrame().pushValue(value); } }
private Taint getMethodTaint(TaintMethodSummary methodSummary) { if (methodSummary == null) { return getDefaultValue(); } if (methodSummary.hasConstantOutputTaint()) { Taint taint = new Taint(methodSummary.getOutputTaint()); if (taint.getState() == Taint.State.TAINTED) { taint.addTaintLocation(getLocation(), true); } return taint; } if (methodSummary.hasTransferParameters()) { return mergeTransferParameters(methodSummary.getTransferParameters()); } throw new IllegalStateException("invalid method summary"); }
private Taint mergeTransferParameters(Collection<Integer> transferParameters) { Taint taint = null; assert !transferParameters.isEmpty(); for (Integer transferParameter : transferParameters) { try { Taint value = getFrame().getStackValue(transferParameter); taint = (taint == null) ? value : Taint.merge(taint, value); } catch (DataflowAnalysisException ex) { throw new RuntimeException("Bad transfer parameter specification", ex); } } assert taint != null; return taint; }