@Override public boolean mayAlias(AccessPath ap1, AccessPath ap2) { return ap1.equals(ap2); }
public Abstraction deriveNewAbstraction(AccessPath p, Stmt currentStmt, boolean isImplicit) { // If the new abstraction looks exactly like the current one, there is // no need to create a new object if (this.accessPath.equals(p) && this.currentStmt == currentStmt && this.isImplicit == isImplicit) return this; Abstraction abs = deriveNewAbstractionMutable(p, currentStmt); if (abs == null) return null; abs.isImplicit = isImplicit; return abs; }
@Override public AccessPath clone() { // The empty access path is a singleton if (this == emptyAccessPath) return this; AccessPath a = new AccessPath(value, fields, baseType, fieldTypes, taintSubFields, cutOffApproximation, arrayTaintType, canHaveImmutableAliases); assert a.equals(this); return a; }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Abstraction other = (Abstraction) obj; // If we have already computed hash codes, we can use them for // comparison if (this.hashCode != 0 && other.hashCode != 0 && this.hashCode != other.hashCode) return false; if (accessPath == null) { if (other.accessPath != null) return false; } else if (!accessPath.equals(other.accessPath)) return false; return localEquals(other); }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; SummarySourceInfo other = (SummarySourceInfo) obj; if (isAlias != other.isAlias) return false; if (sourceAP == null) { if (other.sourceAP != null) return false; } else if (!sourceAP.equals(other.sourceAP)) return false; if (isInCallee != other.isInCallee) return false; return true; }
@Override public boolean equals(Abstraction abs1, Abstraction abs2) { if (abs1 == abs2) return true; if (abs1 == null || abs2 == null || abs1.getClass() != abs2.getClass()) return false; // If we have already computed hash codes, we can use them for // comparison int hashCode1 = abs1.neighborHashCode; int hashCode2 = abs2.neighborHashCode; if (hashCode1 != 0 && hashCode2 != 0 && hashCode1 != hashCode2) return false; if (abs1.accessPath == null) { if (abs2.accessPath != null) return false; } else if (!abs1.accessPath.equals(abs2.accessPath)) return false; if (abs1.predecessor == null) { if (abs2.predecessor != null) return false; } else if (!abs1.predecessor.equals(abs2.predecessor)) return false; if (abs1.currentStmt == null) { if (abs2.currentStmt != null) return false; } else if (!abs1.currentStmt.equals(abs2.currentStmt)) return false; return abs1.localEquals(abs2); }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; SummarySourceContextAndPath other = (SummarySourceContextAndPath) obj; if (callees == null) { if (other.callees != null) return false; } else if (!callees.equals(other.callees)) return false; if (manager == null) { if (other.manager != null) return false; } else if (!manager.equals(other.manager)) return false; if (curAP == null) { if (other.curAP != null) return false; } else if (!curAP.equals(other.curAP)) return false; if (isAlias != other.isAlias) return false; // We deliberately ignore the depth to avoid infinite progression into // recursive method calls return true; }
if (other.accessPath != null) return false; } else if (!accessPath.equals(other.accessPath)) return false; if (userData == null) {
@Override public boolean equals(Object o) { if (super.equals(o)) return true; if (o == null || getClass() != o.getClass()) return false; AbstractResultSourceSinkInfo si = (AbstractResultSourceSinkInfo) o; if (InfoflowConfiguration.getOneResultPerAccessPath() && !this.accessPath.equals(si.accessPath)) return false; if (definition == null) { if (si.definition != null) return false; } else if (!definition.equals(si.definition)) return false; if (stmt == null) { if (si.stmt != null) return false; } else if (!stmt.equals(si.stmt)) return false; if (userData == null) { if (si.userData != null) return false; } else if (!userData.equals(si.userData)) return false; return true; }
@Override public boolean mayAlias(AccessPath ap1, AccessPath ap2) { // If it's the same access path, the two alias trivially if (ap1 == ap2 || ap1.equals(ap2)) return true; // Check the full access path for aliasing PointsToSet ptaAP1 = getPointsToSet(ap1); PointsToSet ptaAP2 = getPointsToSet(ap2); if (ptaAP1.hasNonEmptyIntersection(ptaAP2)) return true; // No aliasing found return false; }
@Override public Collection<Abstraction> propagateCallToReturnFlow(Abstraction d1, Abstraction source, Stmt stmt, ByReferenceBoolean killSource, ByReferenceBoolean killAll) { // Compute the taint wrapper taints Collection<Abstraction> wrapperTaints = computeWrapperTaints(d1, stmt, source); if (wrapperTaints != null) { // If the taint wrapper generated an abstraction for // the incoming access path, we assume it to be handled // and do not pass on the incoming abstraction on our own for (Abstraction wrapperAbs : wrapperTaints) if (wrapperAbs.getAccessPath().equals(source.getAccessPath())) { if (wrapperAbs != source) killSource.value = true; break; } } return wrapperTaints; }
/** * Checks whether there is a path between the given source and sink. * * @param sink The sink to which there may be a path * @param source The source from which there may be a path * @return True if there is a path between the given source and sink, false * otherwise */ public boolean isPathBetween(Stmt sink, Stmt source) { if (this.results == null) return false; Set<ResultSourceInfo> sources = null; for (ResultSinkInfo sI : this.results.keySet()) { if (sI.getStmt().equals(sink)) { sources = this.results.get(sI); break; } } if (sources == null) return false; for (ResultSourceInfo src : sources) if (src.getAccessPath().equals(source)) return true; return false; }
/** * 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; }
protected Abstraction deriveNewAbstractionMutable(AccessPath p, Stmt currentStmt) { // An abstraction needs an access path if (p == null) return null; if (this.accessPath.equals(p) && this.currentStmt == currentStmt) { Abstraction abs = clone(); abs.currentStmt = currentStmt; return abs; } Abstraction abs = new Abstraction(p, this); abs.predecessor = this; abs.currentStmt = currentStmt; abs.propagationPathLength = propagationPathLength + 1; if (!abs.getAccessPath().isEmpty()) abs.postdominators = null; if (!abs.isAbstractionActive()) abs.dependsOnCutAP = abs.dependsOnCutAP || p.isCutOffApproximation(); abs.sourceContext = null; return abs; }
if (!sinkAP.equals(sourceAP) || isAliasedField) {
Abstraction targetAB = mappedAP.equals(newSource.getAccessPath()) ? newSource : newSource.deriveNewAbstraction(mappedAP, null); addTaintViaStmt(d1, assignStmt, targetAB, res, cutFirstField,
&& source.getAccessPath().equals(source.getPredecessor().getAccessPath())) return null;