public AccessPath createAccessPath(Value val, SootField[] appendingFields, Type valType, Type[] appendingFieldTypes, boolean taintSubFields, boolean cutFirstField, boolean reduceBases, ArrayTaintType arrayTaintType) { return createAccessPath(val, appendingFields, valType, appendingFieldTypes, taintSubFields, cutFirstField, reduceBases, arrayTaintType, false); }
public AccessPath createAccessPath(Value val, SootField[] appendingFields, boolean taintSubFields) { return createAccessPath(val, appendingFields, null, null, taintSubFields, false, true, ArrayTaintType.ContentsAndLength); }
public AccessPath createAccessPath(Value val, boolean taintSubFields) { return createAccessPath(val, (SootField[]) null, null, (Type[]) null, taintSubFields, false, true, ArrayTaintType.ContentsAndLength); }
public AccessPath createAccessPath(Value val, Type valType, boolean taintSubFields, ArrayTaintType arrayTaintType) { return createAccessPath(val, null, valType, null, taintSubFields, false, true, arrayTaintType); }
/** * Gets whether two values may potentially point to the same runtime object * * @param val1 The first value * @param val2 The second value * @return True if the two values may potentially point to the same runtime * object, otherwise false */ public boolean mayAlias(Value val1, Value val2) { // What cannot be represented in an access path cannot alias if (!AccessPath.canContainValue(val1) || !AccessPath.canContainValue(val2)) return false; // Constants can never alias if (val1 instanceof Constant || val2 instanceof Constant) return false; // If the two values are equal, they alias by definition if (val1 == val2) return true; // If we have an interactive aliasing algorithm, we check that as well if (aliasingStrategy.isInteractive()) return aliasingStrategy.mayAlias(manager.getAccessPathFactory().createAccessPath(val1, false), manager.getAccessPathFactory().createAccessPath(val2, false)); return false; }
/** * Explicitly handles String.getChars() which does not really fit our * declarative model * * @param invokeExpr * The invocation of String.getChars() * @param taintedPath * The tainted access path * @return The set of new taints to pass on in the taint propagation */ private Set<AccessPath> handleStringGetChars(InvokeExpr invokeExpr, AccessPath taintedPath) { // If the base object is tainted, the third argument gets tainted as // well if (((InstanceInvokeExpr) invokeExpr).getBase() == taintedPath.getPlainValue()) return new TwoElementSet<AccessPath>(taintedPath, manager.getAccessPathFactory().createAccessPath(invokeExpr.getArg(2), true)); return Collections.singleton(taintedPath); }
@Override public Set<Abstraction> getTaintedValues(Stmt call, Abstraction source, Value[] params) { // Check the fallback handler first, before doing an over-approximation if (fallbackHandler.supportsCall(call)) return fallbackHandler.getTaintedValues(call, source, params); // Check whether we have an incoming access path boolean found = false; for (Value val : call.getInvokeExpr().getArgs()) if (val == source.getAccessPath().getPlainValue()) { found = true; break; } if (!found) return Collections.emptySet(); // We over-approximate native method calls if (call instanceof DefinitionStmt) { DefinitionStmt defStmt = (DefinitionStmt) call; return Collections.singleton(source.deriveNewAbstraction( manager.getAccessPathFactory().createAccessPath(defStmt.getLeftOp(), true), call)); } return Collections.emptySet(); }
/** * Appends additional fields to the given access path * * @param original The original access path to which to append the fields * @param apFields The fields to append * @param apFieldTypes The types of the fields to append * @param taintSubFields True if the new access path shall taint all objects * reachable through it, false if it shall only point to * precisely one object * @return The new access path */ public AccessPath appendFields(AccessPath original, SootField[] apFields, Type[] apFieldTypes, boolean taintSubFields) { int offset = original.getFields() == null ? 0 : original.getFields().length; SootField[] fields = new SootField[offset + (apFields == null ? 0 : apFields.length)]; Type[] fieldTypes = new Type[offset + (apFields == null ? 0 : apFields.length)]; if (original.getFields() != null) { System.arraycopy(original.getFields(), 0, fields, 0, original.getFields().length); System.arraycopy(original.getFieldTypes(), 0, fieldTypes, 0, original.getFieldTypes().length); } if (apFields != null && apFields.length > 0) { System.arraycopy(apFields, 0, fields, offset, apFields.length); System.arraycopy(apFieldTypes, 0, fieldTypes, offset, apFieldTypes.length); } return createAccessPath(original.getPlainValue(), fields, original.getBaseType(), fieldTypes, taintSubFields, false, true, original.getArrayTaintType()); }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { if (sCallSite instanceof AssignStmt) { AssignStmt assignStmt = (AssignStmt) sCallSite; if (assignStmt.getRightOp().toString().contains("taintedBySourceSinkManager")) return new SourceInfo(null, manager.getAccessPathFactory().createAccessPath(assignStmt.getLeftOp(), true)); else return null; } return null; }
@Override public Set<AccessPath> getTaintsForMethodInternal(Stmt stmt, AccessPath taintedPath) { assert stmt.containsInvokeExpr(); // Do not provide models for application classes if (!stmt.getInvokeExpr().getMethod().getDeclaringClass().isLibraryClass()) return null; // For the moment, we don't implement static taints on wrappers. Pass it on // not to break anything if (taintedPath.isStaticFieldRef()) return Collections.singleton(taintedPath); if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); // If the base object is tainted, the return value is always tainted if (taintedPath.getPlainValue().equals(iiExpr.getBase())) if (stmt instanceof AssignStmt) return Collections.singleton(manager.getAccessPathFactory() .createAccessPath(((AssignStmt) stmt).getLeftOp(), taintedPath.getTaintSubFields())); } // If one of the parameters is tainted, the return value is tainted, too for (Value param : stmt.getInvokeExpr().getArgs()) if (taintedPath.getPlainValue().equals(param)) if (stmt instanceof AssignStmt) return Collections.singleton(manager.getAccessPathFactory() .createAccessPath(((AssignStmt) stmt).getLeftOp(), taintedPath.getTaintSubFields())); return Collections.emptySet(); }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { // If this is not the method we are looking for, we skip it SootMethod currentMethod = manager.getICFG().getMethodOf(sCallSite); if (!isMethodToSummarize(currentMethod)) return null; if (sCallSite instanceof DefinitionStmt) { DefinitionStmt jstmt = (DefinitionStmt) sCallSite; Value leftOp = jstmt.getLeftOp(); Value rightOp = jstmt.getRightOp(); // check if we have a source with apl = 0 (this or parameter source) if (rightOp instanceof ParameterRef) { ParameterRef pref = (ParameterRef) rightOp; logger.debug("source: " + sCallSite + " " + currentMethod.getSignature()); if (debug) System.out.println("source: " + sCallSite + " " + currentMethod.getSignature()); return new SourceInfo(null, manager.getAccessPathFactory().createAccessPath(leftOp, true), Collections.singletonList( sourceSinkFactory.createParameterSource(pref.getIndex(), pref.getType().toString()))); } else if (rightOp instanceof ThisRef) { ThisRef tref = (ThisRef) rightOp; if (debug) System.out.println("source: (this)" + sCallSite + " " + currentMethod.getSignature()); return new SourceInfo(null, manager.getAccessPathFactory().createAccessPath(leftOp, true), Collections.singletonList(sourceSinkFactory.createThisSource(tref.getType().toString()))); } } return null; }
/** * value val gets new base, fields are preserved. * * @param original The original access path * @param val The new base value * @param reduceBases True if circular types shall be reduced to bases * @param arrayTaintType The way a tainted array shall be handled * @return This access path with the base replaced by the value given in the val * parameter */ public AccessPath copyWithNewValue(AccessPath original, Value val, Type newType, boolean cutFirstField, boolean reduceBases, ArrayTaintType arrayTaintType) { // If this copy would not add any new information, we can safely use the // old // object if (original.getPlainValue() != null && original.getPlainValue().equals(val) && original.getBaseType().equals(newType) && original.getArrayTaintType() == arrayTaintType) return original; // Create the new access path AccessPath newAP = createAccessPath(val, original.getFields(), newType, original.getFieldTypes(), original.getTaintSubFields(), cutFirstField, reduceBases, arrayTaintType, original.getCanHaveImmutableAliases()); // Again, check whether we can do without the new object if (newAP != null && newAP.equals(original)) return original; else return newAP; }
@Override public void computeAliasTaints(Abstraction d1, Stmt src, Value targetValue, Set<Abstraction> taintSet, SootMethod method, Abstraction newAbs) { // Use global aliasing Value baseValue = ((InstanceFieldRef) targetValue).getBase(); Set<AccessPath> aliases = methodToAliases.getUnchecked(method).get (manager.getAccessPathFactory().createAccessPath(baseValue, true)); if (aliases != null) for (AccessPath ap : aliases) { AccessPath newAP = manager.getAccessPathFactory().merge(ap, newAbs.getAccessPath()); Abstraction aliasAbs = newAbs.deriveNewAbstraction(newAP, null); if (taintSet.add(aliasAbs)) // We have found a new alias. This new base object may however yet // again alias with something, so we need to check again if (ap.isInstanceFieldRef()) { InstanceFieldRef aliasBaseVal = Jimple.v().newInstanceFieldRef (ap.getPlainValue(), ap.getFirstField().makeRef()); computeAliasTaints(d1, src, aliasBaseVal, taintSet, method, aliasAbs); } } }
/** * Converts a taint into an access path that is valid inside a given method. * This models that a taint is propagated into the method and from there on in * normal IFDS. * * @param t The taint to convert * @param sm The method in which the access path shall be created * @return The access path derived from the given taint and method */ private AccessPath createAccessPathInMethod(Taint t, SootMethod sm) { // Convert the taints to Soot objects SootField[] fields = safeGetFields(t.getAccessPath()); Type[] types = safeGetTypes(t.getAccessPathTypes(), fields); Type baseType = TypeUtils.getTypeFromString(t.getBaseType()); // A return value cannot be propagated into a method if (t.isReturn()) throw new RuntimeException("Unsupported taint type"); if (t.isParameter()) { Local l = sm.getActiveBody().getParameterLocal(t.getParameterIndex()); return manager.getAccessPathFactory().createAccessPath(l, fields, baseType, types, true, false, true, ArrayTaintType.ContentsAndLength); } if (t.isField() || t.isGapBaseObject()) { Local l = sm.getActiveBody().getThisLocal(); return manager.getAccessPathFactory().createAccessPath(l, fields, baseType, types, true, false, true, ArrayTaintType.ContentsAndLength); } throw new RuntimeException("Failed to convert taint " + t); }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { if (sCallSite.containsInvokeExpr()) { InvokeExpr iexpr = sCallSite.getInvokeExpr(); String name = iexpr.getMethod().getName(); boolean includeExistingImmutableAliases = name.equals("annotatedSource"); if ((name.equals("source") || includeExistingImmutableAliases) && iexpr.getArgCount() > 0) { AccessPath ap = manager.getAccessPathFactory().createAccessPath(iexpr.getArg(0), null, null, null, true, false, true, AccessPath.ArrayTaintType.ContentsAndLength, true); return new SourceInfo(null, ap); } } return null; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { if (sCallSite.containsInvokeExpr() && sCallSite instanceof DefinitionStmt && sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret")) { AccessPath ap = manager.getAccessPathFactory() .createAccessPath(((DefinitionStmt) sCallSite).getLeftOp(), true); return new SourceInfo(null, ap); } return null; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { if (sCallSite.containsInvokeExpr() && sCallSite instanceof DefinitionStmt && sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret")) { AccessPath ap = manager.getAccessPathFactory() .createAccessPath(((DefinitionStmt) sCallSite).getLeftOp(), false); return new SourceInfo(null, ap); } return null; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { if (sCallSite instanceof DefinitionStmt && sCallSite.containsInvokeExpr() && sCallSite.getInvokeExpr().getMethod().getName().equals("currentTimeMillis")) { Value val = ((DefinitionStmt) sCallSite).getLeftOp(); return new SourceInfo(null, manager.getAccessPathFactory().createAccessPath(val, true)); } return null; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { if (sCallSite instanceof DefinitionStmt && sCallSite.containsInvokeExpr() && sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret")) { Value val = ((DefinitionStmt) sCallSite).getLeftOp(); return new SourceInfo(null, manager.getAccessPathFactory().createAccessPath(val, true)); } return null; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) { if (sCallSite.containsInvokeExpr() && sCallSite instanceof DefinitionStmt && (sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret") || (sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret2")))) { AccessPath ap = manager.getAccessPathFactory() .createAccessPath(((DefinitionStmt) sCallSite).getLeftOp(), true); return new SourceInfo(null, ap); } return null; }