From 1548d49d0566fb824af881b70e290f629765537b Mon Sep 17 00:00:00 2001 From: chaos-warzh Date: Mon, 27 May 2024 16:16:18 +0800 Subject: [PATCH] Demo 1.3, done! +several features --- .../taie/analysis/pta/PointerAnalysis.java | 5 +- .../pta/PointerAnalysisResultImpl.java | 9 +- .../pta/core/cs/element/AbstractPointer.java | 14 ++ .../analysis/pta/core/cs/element/Pointer.java | 4 + .../pta/core/solver/DefaultSolver.java | 2 +- .../analysis/pta/plugin/CompositePlugin.java | 10 ++ .../pta/plugin/taint/DCTaintAnalysis.java | 104 ------------ .../pta/plugin/taint/DynamicConfig.java | 123 -------------- .../pta/plugin/taint/SinkHandler.java | 65 +++++++- .../pta/plugin/taint/TaintAnalysis.java | 156 +++++++++++++++++- .../analysis/pta/pts/DelegatePointsToSet.java | 6 + .../taie/analysis/pta/pts/PointsToSet.java | 3 + 12 files changed, 252 insertions(+), 249 deletions(-) delete mode 100644 src/main/java/pascal/taie/analysis/pta/plugin/taint/DCTaintAnalysis.java delete mode 100644 src/main/java/pascal/taie/analysis/pta/plugin/taint/DynamicConfig.java diff --git a/src/main/java/pascal/taie/analysis/pta/PointerAnalysis.java b/src/main/java/pascal/taie/analysis/pta/PointerAnalysis.java index f60dec721..f9d99bf44 100644 --- a/src/main/java/pascal/taie/analysis/pta/PointerAnalysis.java +++ b/src/main/java/pascal/taie/analysis/pta/PointerAnalysis.java @@ -38,7 +38,6 @@ import pascal.taie.analysis.pta.plugin.EntryPointHandler; import pascal.taie.analysis.pta.plugin.Plugin; import pascal.taie.analysis.pta.plugin.ReferenceHandler; -import pascal.taie.analysis.pta.plugin.ResultProcessor; import pascal.taie.analysis.pta.plugin.ThreadHandler; import pascal.taie.analysis.pta.plugin.exception.ExceptionAnalysis; import pascal.taie.analysis.pta.plugin.invokedynamic.InvokeDynamicAnalysis; @@ -46,7 +45,6 @@ import pascal.taie.analysis.pta.plugin.invokedynamic.LambdaAnalysis; import pascal.taie.analysis.pta.plugin.natives.NativeModeller; import pascal.taie.analysis.pta.plugin.reflection.ReflectionAnalysis; -import pascal.taie.analysis.pta.plugin.taint.DCTaintAnalysis; import pascal.taie.analysis.pta.plugin.taint.TaintAnalysis; import pascal.taie.analysis.pta.toolkit.CollectionMethods; import pascal.taie.analysis.pta.toolkit.mahjong.Mahjong; @@ -153,8 +151,7 @@ private static void setPlugin(Solver solver, AnalysisOptions options) { plugin.addPlugin(new InvokeDynamicAnalysis()); } if (options.getString("taint-config") != null) { -// plugin.addPlugin(new TaintAnalysis()); - plugin.addPlugin(new DCTaintAnalysis()); + plugin.addPlugin(new TaintAnalysis()); } // plugin.addPlugin(new ResultProcessor()); // add plugins specified in options diff --git a/src/main/java/pascal/taie/analysis/pta/PointerAnalysisResultImpl.java b/src/main/java/pascal/taie/analysis/pta/PointerAnalysisResultImpl.java index 6c6399172..bde8fdb7d 100644 --- a/src/main/java/pascal/taie/analysis/pta/PointerAnalysisResultImpl.java +++ b/src/main/java/pascal/taie/analysis/pta/PointerAnalysisResultImpl.java @@ -180,8 +180,7 @@ public Set getPointsToSet(Var var) { if (!propTypes.isAllowed(var)) { return Set.of(); } -// return varPointsTo.computeIfAbsent(var, v -> - return varPointsTo.compute(var, (__, v) -> + return varPointsTo.computeIfAbsent(var, v -> removeContexts(csManager.getCSVarsOf(var) .stream() .flatMap(Pointer::objects))); @@ -207,8 +206,7 @@ public Set getPointsToSet(Var base, JField field) { return Set.of(); } // TODO - properly handle non-exist base.field -// return ifieldPointsTo.computeIfAbsent(new Pair<>(base, field), p -> - return ifieldPointsTo.compute(new Pair<>(base, field), (k, v) -> + return ifieldPointsTo.computeIfAbsent(new Pair<>(base, field), p -> removeContexts(csManager.getCSVarsOf(base) .stream() .flatMap(Pointer::objects) @@ -272,8 +270,7 @@ public Set getPointsToSet(Var base, Var index) { logger.warn("{} is not an array", base); return Set.of(); } -// return arrayPointsTo.computeIfAbsent(base, b -> - return arrayPointsTo.compute(base, (b, __) -> + return arrayPointsTo.computeIfAbsent(base, b -> removeContexts(csManager.getCSVarsOf(b) .stream() .flatMap(Pointer::objects) diff --git a/src/main/java/pascal/taie/analysis/pta/core/cs/element/AbstractPointer.java b/src/main/java/pascal/taie/analysis/pta/core/cs/element/AbstractPointer.java index edc4242f2..d72bc153c 100644 --- a/src/main/java/pascal/taie/analysis/pta/core/cs/element/AbstractPointer.java +++ b/src/main/java/pascal/taie/analysis/pta/core/cs/element/AbstractPointer.java @@ -66,6 +66,20 @@ public void setPointsToSet(PointsToSet pointsToSet) { this.pointsToSet = pointsToSet; } + @Override + public void rmFromPointsToIf(Predicate predicate) { + if (pointsToSet != null) { + pointsToSet.removeIf(predicate); + } + } + + @Override + public void rmFromOutEdgesIf(Predicate predicate) { + if (! outEdges.isEmpty()) { + outEdges.removeIf(predicate); + } + } + @Override public void addFilter(Predicate filter) { if (filters.isEmpty()) { diff --git a/src/main/java/pascal/taie/analysis/pta/core/cs/element/Pointer.java b/src/main/java/pascal/taie/analysis/pta/core/cs/element/Pointer.java index 113c1b983..a2f5abd78 100644 --- a/src/main/java/pascal/taie/analysis/pta/core/cs/element/Pointer.java +++ b/src/main/java/pascal/taie/analysis/pta/core/cs/element/Pointer.java @@ -52,6 +52,10 @@ public interface Pointer extends Indexable { @Nullable PointsToSet getPointsToSet(); + void rmFromPointsToIf(Predicate predicate); + + void rmFromOutEdgesIf(Predicate predicate); + /** * Sets the associated points-to set of this pointer. */ diff --git a/src/main/java/pascal/taie/analysis/pta/core/solver/DefaultSolver.java b/src/main/java/pascal/taie/analysis/pta/core/solver/DefaultSolver.java index c73d82eaa..f0313dce3 100644 --- a/src/main/java/pascal/taie/analysis/pta/core/solver/DefaultSolver.java +++ b/src/main/java/pascal/taie/analysis/pta/core/solver/DefaultSolver.java @@ -304,7 +304,7 @@ private void stop() { /** * Processes work list entries until the work list is empty. */ - public void analyze() { + private void analyze() { while (!workList.isEmpty() && !isTimeout) { // phase starts while (!workList.isEmpty() && !isTimeout) { diff --git a/src/main/java/pascal/taie/analysis/pta/plugin/CompositePlugin.java b/src/main/java/pascal/taie/analysis/pta/plugin/CompositePlugin.java index 6f967f7e0..00e51ad04 100644 --- a/src/main/java/pascal/taie/analysis/pta/plugin/CompositePlugin.java +++ b/src/main/java/pascal/taie/analysis/pta/plugin/CompositePlugin.java @@ -89,6 +89,16 @@ private void addPlugin(Plugin plugin, List plugins, } } + public void clearAllPlugins() { + allPlugins.clear(); + onNewPointsToSetPlugins.clear(); + onNewCallEdgePlugins.clear(); + onNewMethodPlugins.clear(); + onNewStmtPlugins.clear(); + onNewCSMethodPlugins.clear(); + onUnresolvedCallPlugins.clear(); + } + @Override public void setSolver(Solver solver) { allPlugins.forEach(p -> p.setSolver(solver)); diff --git a/src/main/java/pascal/taie/analysis/pta/plugin/taint/DCTaintAnalysis.java b/src/main/java/pascal/taie/analysis/pta/plugin/taint/DCTaintAnalysis.java deleted file mode 100644 index c6938653e..000000000 --- a/src/main/java/pascal/taie/analysis/pta/plugin/taint/DCTaintAnalysis.java +++ /dev/null @@ -1,104 +0,0 @@ -package pascal.taie.analysis.pta.plugin.taint; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import pascal.taie.analysis.graph.callgraph.Edge; -import pascal.taie.analysis.pta.core.cs.context.Context; -import pascal.taie.analysis.pta.core.cs.element.CSCallSite; -import pascal.taie.analysis.pta.core.cs.element.CSMethod; -import pascal.taie.analysis.pta.core.cs.element.CSObj; -import pascal.taie.analysis.pta.core.cs.element.CSVar; -import pascal.taie.analysis.pta.core.solver.Solver; -import pascal.taie.analysis.pta.plugin.CompositePlugin; -import pascal.taie.analysis.pta.plugin.Plugin; -import pascal.taie.analysis.pta.pts.PointsToSet; -import pascal.taie.ir.stmt.Invoke; -import pascal.taie.ir.stmt.Stmt; -import pascal.taie.language.classes.JMethod; - -public class DCTaintAnalysis extends CompositePlugin { - - private static final Logger logger = LogManager.getLogger(DCTaintAnalysis.class); - - private HandlerContext context; - - private boolean firstFinish = true; - - private TaintAnalysis taintAnalysis; - - @Override - public void setSolver(Solver solver) { - TaintManager manager = new TaintManager(solver.getHeapModel()); - TaintConfig config = TaintConfig.loadConfig( - solver.getOptions().getString("taint-config"), - solver.getHierarchy(), - solver.getTypeSystem()); - context = new HandlerContext(solver, manager, config); - - taintAnalysis = new TaintAnalysis(); - taintAnalysis.setSolver(solver); - } - - @Override - public void onFinish() { - taintAnalysis.onFinish(); - - boolean dynamicConfigured = true; -// dynamicConfigured = false; - if (dynamicConfigured && firstFinish) { - firstFinish = false; - logger.info("Dynamic configuration is enabled."); - try { - DynamicConfig dynamicConfig = new DynamicConfig(this, context.solver()); - dynamicConfig.start(); - } catch (Exception e) { - logger.error("Failed to configure dynamic analysis.", e); - } - } - } - - @Override - public void addPlugin(Plugin... plugins) { - taintAnalysis.addPlugin(plugins); - } - - @Override - public void onStart() { - taintAnalysis.onStart(); - } - - @Override - public void onPhaseFinish() { - taintAnalysis.onPhaseFinish(); - } - - @Override - public void onNewPointsToSet(CSVar csVar, PointsToSet pts) { - taintAnalysis.onNewPointsToSet(csVar, pts); - } - - @Override - public void onNewCallEdge(Edge edge) { - taintAnalysis.onNewCallEdge(edge); - } - - @Override - public void onNewMethod(JMethod method) { - taintAnalysis.onNewMethod(method); - } - - @Override - public void onNewStmt(Stmt stmt, JMethod container) { - taintAnalysis.onNewStmt(stmt, container); - } - - @Override - public void onNewCSMethod(CSMethod csMethod) { - taintAnalysis.onNewCSMethod(csMethod); - } - - @Override - public void onUnresolvedCall(CSObj recv, Context context, Invoke invoke) { - taintAnalysis.onUnresolvedCall(recv, context, invoke); - } -} diff --git a/src/main/java/pascal/taie/analysis/pta/plugin/taint/DynamicConfig.java b/src/main/java/pascal/taie/analysis/pta/plugin/taint/DynamicConfig.java deleted file mode 100644 index 6b7f4315f..000000000 --- a/src/main/java/pascal/taie/analysis/pta/plugin/taint/DynamicConfig.java +++ /dev/null @@ -1,123 +0,0 @@ -package pascal.taie.analysis.pta.plugin.taint; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import pascal.taie.analysis.graph.flowgraph.FlowKind; -import pascal.taie.analysis.pta.core.cs.element.*; -import pascal.taie.analysis.pta.core.heap.MockObj; -import pascal.taie.analysis.pta.core.solver.*; -import pascal.taie.analysis.pta.plugin.Plugin; -import pascal.taie.analysis.pta.pts.PointsToSet; -import pascal.taie.config.AnalysisOptions; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import java.util.stream.Collectors; - -class DynamicConfig { - private static final Logger logger = LogManager.getLogger(DynamicConfig.class); - - private final Plugin plugin; - - private final Solver solver; - - private final CSManager csManager; - - DynamicConfig(Plugin plugin, Solver solver) { - csManager = solver.getCSManager(); - this.plugin = plugin; - this.solver = solver; - } - - private void reset() { - csManager.pointers().forEach(p -> { - if (p.getPointsToSet() != null) { - PointsToSet pointsToSet = solver.makePointsToSet(); - for (var v : p.getPointsToSet()) { - if (!(v.getObject() instanceof MockObj mockObj && - mockObj.getDescriptor().string().equals("TaintObj"))) { - pointsToSet.addObject(v); - } - } - p.setPointsToSet(pointsToSet); - } - }); - - // feature: objManager was not reset - csManager.pointers().forEach(p -> { - ArrayList outEdges = p.getOutEdges().stream() - .filter(e -> !(e.kind() == FlowKind.OTHER && e.getInfo().equals("OTHER.TaintTransferEdge"))) - .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); - - try { - Field outEdgesF = p.getClass().getSuperclass().getDeclaredField("outEdges"); - outEdgesF.setAccessible(true); - outEdgesF.set(p, outEdges); - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - private void prepare(String config) { - try { - // update the taint config: - Method updateM = solver.getOptions().getClass().getDeclaredMethod("update", AnalysisOptions.class); - updateM.setAccessible(true); - updateM.invoke(solver.getOptions(), new AnalysisOptions(Map.of( "taint-config", config))); - } catch (Exception e) { - e.printStackTrace(); - } - - plugin.setSolver(solver); - solver.setPlugin(plugin); - - // add entries to WL (for taint analysis) - // SourceHandler/TransferHandler/... used - solver.getCallGraph().reachableMethods().forEach(m -> - m.getEdges().forEach(plugin::onNewCallEdge)); - solver.getCallGraph().reachableMethods().forEach(plugin::onNewCSMethod); - - for (var m: solver.getCallGraph().reachableMethods().toList()) { - m.getMethod().getIR().forEach(stmt -> plugin.onNewStmt(stmt, m.getMethod())); - // para taints handled here: - m.getMethod().getIR().getParams() - .forEach(para -> { - CSVar csPara = csManager.getCSVar(m.getContext(), para); - plugin.onNewPointsToSet(csPara, csPara.getPointsToSet()); - }); - } - } - - private void analyze() { - ((DefaultSolver)solver).analyze(); - } - - void start() { - - String config1 = "src/test/resources/pta/taint/taint-config-2.yml"; - String config2 = "src/test/resources/pta/taint/taint-config.yml"; - - reset(); - prepare(config1); - logger.info("Start analysis with config: {}", config1); - analyze(); - - - reset(); - prepare(config2); - logger.info("Start analysis with config: {}", config2); - analyze(); - -// reset(); -// prepare(config1); -// logger.info("Start analysis with config: {}", config1); -// analyze(); -// -// reset(); -// prepare(config2); -// logger.info("Start analysis with config: {}", config2); -// analyze(); - } -} diff --git a/src/main/java/pascal/taie/analysis/pta/plugin/taint/SinkHandler.java b/src/main/java/pascal/taie/analysis/pta/plugin/taint/SinkHandler.java index 5f5f4efe3..4a2a2d3e8 100644 --- a/src/main/java/pascal/taie/analysis/pta/plugin/taint/SinkHandler.java +++ b/src/main/java/pascal/taie/analysis/pta/plugin/taint/SinkHandler.java @@ -25,18 +25,22 @@ import pascal.taie.analysis.graph.callgraph.CallKind; import pascal.taie.analysis.graph.callgraph.Edge; import pascal.taie.analysis.pta.PointerAnalysisResult; +import pascal.taie.analysis.pta.core.cs.element.*; +import pascal.taie.analysis.pta.core.heap.HeapModel; import pascal.taie.analysis.pta.core.heap.Obj; import pascal.taie.analysis.pta.plugin.util.InvokeUtils; import pascal.taie.ir.exp.Var; import pascal.taie.ir.stmt.Invoke; +import pascal.taie.language.classes.JField; import pascal.taie.language.classes.JMethod; -import pascal.taie.util.collection.MultiMap; -import pascal.taie.util.collection.MultiMapCollector; -import pascal.taie.util.collection.Sets; +import pascal.taie.util.Canonicalizer; +import pascal.taie.util.collection.*; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Handles sinks in taint analysis. @@ -45,9 +49,17 @@ class SinkHandler extends Handler { private final List sinks; + private final CSManager csManager; + + private final HeapModel heapModel; + + private final PointerToSetManager ptsManager = new PointerToSetManager(); + SinkHandler(HandlerContext context) { super(context); sinks = context.config().sinks(); + csManager = context.solver().getCSManager(); + heapModel = context.solver().getHeapModel(); } Set collectTaintFlows() { @@ -59,7 +71,7 @@ Set collectTaintFlows() { // TODO: handle other call edges .filter(e -> e.getKind() != CallKind.OTHER) .map(Edge::getCallSite) - .map(sinkCall -> collectTaintFlows(result, sinkCall, sink)) + .map(sinkCall -> collectTaintFlows(sinkCall, sink)) .forEach(taintFlows::addAll); } if (callSiteMode) { @@ -73,7 +85,7 @@ Set collectTaintFlows() { JMethod callee = callSite.getMethodRef().resolveNullable(); if (callee != null) { for (Sink sink : sinkMap.get(callee)) { - taintFlows.addAll(collectTaintFlows(result, callSite, sink)); + taintFlows.addAll(collectTaintFlows(callSite, sink)); } } }); @@ -82,15 +94,15 @@ Set collectTaintFlows() { } private Set collectTaintFlows( - PointerAnalysisResult result, Invoke sinkCall, Sink sink) { + Invoke sinkCall, Sink sink) { IndexRef indexRef = sink.indexRef(); Var arg = InvokeUtils.getVar(sinkCall, indexRef.index()); SinkPoint sinkPoint = new SinkPoint(sinkCall, indexRef); // obtain objects to check for different IndexRef.Kind Set objs = switch (indexRef.kind()) { - case VAR -> result.getPointsToSet(arg); - case ARRAY -> result.getPointsToSet(arg, (Var) null); - case FIELD -> result.getPointsToSet(arg, indexRef.field()); + case VAR -> ptsManager.getPointsToSet(arg); + case ARRAY -> ptsManager.getPointsToSet(arg, (Var) null); + case FIELD -> ptsManager.getPointsToSet(arg, indexRef.field()); }; return objs.stream() .filter(manager::isTaint) @@ -98,4 +110,39 @@ private Set collectTaintFlows( .map(sourcePoint -> new TaintFlow(sourcePoint, sinkPoint)) .collect(Collectors.toSet()); } + + class PointerToSetManager { + // todo: don't repeat urself! + + private static final Canonicalizer> canonicalizer = new Canonicalizer<>(); + + private Set removeContexts(Stream objects) { + Set set = new HybridBitSet<>(heapModel, true); + objects.map(CSObj::getObject).forEach(set::add); + return canonicalizer.get(Collections.unmodifiableSet(set)); + } + + Set getPointsToSet(Var var) { + return removeContexts(csManager.getCSVarsOf(var) + .stream() + .flatMap(Pointer::objects)); + } + + Set getPointsToSet(Var base, JField field) { + return removeContexts(csManager.getCSVarsOf(base) + .stream() + .flatMap(Pointer::objects) + .map(o -> csManager.getInstanceField(o, field)) + .flatMap(InstanceField::objects)); + } + + Set getPointsToSet(Var base, Var index) { + return removeContexts(csManager.getCSVarsOf(base) + .stream() + .flatMap(Pointer::objects) + .map(csManager::getArrayIndex) + .flatMap(ArrayIndex::objects)); + } + + } } diff --git a/src/main/java/pascal/taie/analysis/pta/plugin/taint/TaintAnalysis.java b/src/main/java/pascal/taie/analysis/pta/plugin/taint/TaintAnalysis.java index 1ae00550a..a0b0e74bb 100644 --- a/src/main/java/pascal/taie/analysis/pta/plugin/taint/TaintAnalysis.java +++ b/src/main/java/pascal/taie/analysis/pta/plugin/taint/TaintAnalysis.java @@ -25,11 +25,16 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import pascal.taie.World; +import pascal.taie.analysis.pta.core.cs.element.CSManager; +import pascal.taie.analysis.pta.core.cs.element.CSVar; import pascal.taie.analysis.pta.core.solver.Solver; import pascal.taie.analysis.pta.plugin.CompositePlugin; import pascal.taie.util.Timer; import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.util.Scanner; import java.util.Set; public class TaintAnalysis extends CompositePlugin { @@ -40,6 +45,10 @@ public class TaintAnalysis extends CompositePlugin { private HandlerContext context; + private boolean callSiteMode; + + private TaintRestarter restarter; + @Override public void setSolver(Solver solver) { TaintManager manager = new TaintManager(solver.getHeapModel()); @@ -53,10 +62,11 @@ public void setSolver(Solver solver) { new TransferHandler(context), new SanitizerHandler(context)); + callSiteMode = config.callSiteMode(); + restarter = new TaintRestarter(this, context.solver()); } - @Override - public void onFinish() { + private void sinkAndReport() { Set taintFlows = new SinkHandler(context).collectTaintFlows(); logger.info("Detected {} taint flow(s):", taintFlows.size()); taintFlows.forEach(logger::info); @@ -68,4 +78,146 @@ public void onFinish() { new File(World.get().getOptions().getOutputDir(), TAINT_FLOW_GRAPH_FILE)), "TFGDumper"); } + + + public void startFileWatcher(Path filePath) throws IOException, InterruptedException { + WatchService watchService = FileSystems.getDefault().newWatchService(); + filePath.getParent().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); + + WatchKey key; + while (true) { + key = watchService.take(); // block until a file event occur + + for (WatchEvent event : key.pollEvents()) { + WatchEvent.Kind kind = event.kind(); + + if (kind == StandardWatchEventKinds.OVERFLOW) { + continue; + } else { + WatchEvent ev = (WatchEvent) event; + Path fileName = ev.context(); + + if (fileName.toFile().getName().equals(filePath.toFile().getName())) { + logger.info("File has been modified: " + filePath); + reloadConfigAndRestart(); + return; + } + } + } + + boolean valid = key.reset(); + if (!valid) { + break; + } + } + } + + private void reloadConfigAndRestart() { + logger.info("Reloading configuration and restarting..."); + // ... 读取配置文件 ... + restarter.start(); + } + + @Override + public void onPhaseFinish() { + boolean dynamicConfigured = true; + if (dynamicConfigured) { + // report taint flows: + sinkAndReport(); + + // wait for user's input, if `exit`, skip; if `continue`, then try file listen + System.out.println("Change your taint config and continue."); + String path = (String) context.solver().getOptions().get("taint-config"); + Path configPath = Paths.get(path); + try { + startFileWatcher(configPath); + } catch (Exception e) { + e.printStackTrace(); + } + +// Scanner scanner = new Scanner(System.in); +// while (true) { +// if (scanner.hasNextLine()) { +// String line = scanner.nextLine(); +// if (line.equals("exit") || line.equals("q")) { +// scanner.close(); +// return; +// } else if (line.equals("continue") || line.equals("c")) { +// scanner.close(); +// break; +// } else { +// System.out.println("Unknown command: " + line); +// } +// } +// } + + // gen taints + logger.info("Dynamic configuration is enabled."); + restarter.start(); + } + } + + @Override + public void onFinish() { + sinkAndReport(); + } + + class TaintRestarter { + private final TaintAnalysis taintAnalysis; + + private final Solver solver; + + private final CSManager csManager; + + TaintRestarter(TaintAnalysis taintAnalysis, Solver solver) { + csManager = solver.getCSManager(); + this.taintAnalysis = taintAnalysis; + this.solver = solver; + } + + private void reset() { + csManager.pointers().forEach(p -> { + p.rmFromPointsToIf(csObj -> context.manager().isTaint(csObj.getObject())); + p.rmFromOutEdgesIf(TaintTransferEdge.class::isInstance); + }); + } + + private void prepare() { + // clear its compositing plugins + taintAnalysis.clearAllPlugins(); + taintAnalysis.setSolver(solver); + + // add entries to WL (for taint analysis) + // SourceHandler/TransferHandler/... used + + // you have to call this earlier than onNewCSMethod, and it's designed for Call Site Mode + if (callSiteMode) { + // Must do it before anything!!! + solver.getCallGraph().reachableMethods().forEach( + m -> m.getMethod().getIR().forEach(stmt -> taintAnalysis.onNewStmt(stmt, m.getMethod())) + ); + } + + // perhaps use `edges()` ? + solver.getCallGraph().reachableMethods().forEach(m -> + m.getEdges().forEach(taintAnalysis::onNewCallEdge)); + + solver.getCallGraph().reachableMethods().forEach(m -> { + // field taint + taintAnalysis.onNewCSMethod(m); + // para taints handled here: + m.getMethod().getIR().getParams() + .forEach(para -> { + CSVar csPara = csManager.getCSVar(m.getContext(), para); + taintAnalysis.onNewPointsToSet(csPara, csPara.getPointsToSet()); + }); + }); + } + + void start() { + reset(); + prepare(); + logger.info("Start taint analysis!"); + } + } } diff --git a/src/main/java/pascal/taie/analysis/pta/pts/DelegatePointsToSet.java b/src/main/java/pascal/taie/analysis/pta/pts/DelegatePointsToSet.java index f44f5219e..2f0a642d0 100644 --- a/src/main/java/pascal/taie/analysis/pta/pts/DelegatePointsToSet.java +++ b/src/main/java/pascal/taie/analysis/pta/pts/DelegatePointsToSet.java @@ -27,6 +27,7 @@ import java.util.Collections; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Stream; /** @@ -58,6 +59,11 @@ public boolean addAll(PointsToSet pts) { } } + @Override + public void removeIf(Predicate predicate) { + set.removeIf(predicate); + } + @Override public boolean contains(CSObj obj) { return set.contains(obj); diff --git a/src/main/java/pascal/taie/analysis/pta/pts/PointsToSet.java b/src/main/java/pascal/taie/analysis/pta/pts/PointsToSet.java index 228522967..af191b568 100644 --- a/src/main/java/pascal/taie/analysis/pta/pts/PointsToSet.java +++ b/src/main/java/pascal/taie/analysis/pta/pts/PointsToSet.java @@ -27,6 +27,7 @@ import java.util.Iterator; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Stream; /** @@ -57,6 +58,8 @@ public interface PointsToSet extends Iterable, Copyable { */ PointsToSet addAllDiff(PointsToSet pts); + void removeIf(Predicate predicate); + /** * @return true if this set contains given object, otherwise false. */