Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangt2333 committed May 29, 2024
1 parent c2295b7 commit 003b3d1
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ public void setPointsToSet(PointsToSet pointsToSet) {
this.pointsToSet = pointsToSet;
}

@Override
public void removeObjsIf(Predicate<CSObj> filter) {
if (pointsToSet != null) {
pointsToSet.removeIf(filter);
}
}

@Override
public void addFilter(Predicate<CSObj> filter) {
if (filters.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ public interface Pointer extends Indexable {
*/
void setPointsToSet(PointsToSet pointsToSet);

/**
* Removes objects pointed to by this pointer if they satisfy the filter.
*/
void removeObjsIf(Predicate<CSObj> filter);

/**
* Adds filter to filter out objects pointed to by this pointer.
*/
Expand Down Expand Up @@ -104,6 +99,10 @@ public interface Pointer extends Indexable {

/**
* Removes out edges of this pointer if they satisfy the filter.
* <p>
* <strong>Note:</strong> This method should not be used during pointer analysis iterations,
* as it can break the monotonicity of the analysis.
* </p>
*/
void removeEdgesIf(Predicate<PointerFlowEdge> filter);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ private void addPlugin(Plugin plugin, List<Plugin> plugins,
}

public void clearPlugins() {
Stream.of(allPlugins, onNewPointsToSetPlugins, onNewCallEdgePlugins,
onNewMethodPlugins, onNewStmtPlugins, onNewCSMethodPlugins,
onUnresolvedCallPlugins).forEach(List::clear);
Stream.of(allPlugins,
onNewPointsToSetPlugins, onNewCallEdgePlugins, onNewMethodPlugins,
onNewStmtPlugins, onNewCSMethodPlugins, onUnresolvedCallPlugins
).forEach(List::clear);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,4 @@ private Set<TaintFlow> collectTaintFlows(
.map(sourcePoint -> new TaintFlow(sourcePoint, sinkPoint))
.collect(Collectors.toSet());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,22 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pascal.taie.World;
import pascal.taie.analysis.graph.callgraph.CallGraph;
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.CSManager;
import pascal.taie.analysis.pta.core.cs.element.CSMethod;
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.pts.PointsToSet;
import pascal.taie.config.AnalysisOptions;
import pascal.taie.ir.IR;
import pascal.taie.language.classes.JMethod;
import pascal.taie.util.Timer;

import javax.annotation.Nullable;
import java.io.File;
import java.util.Scanner;
import java.util.Set;

public class TaintAnalysis extends CompositePlugin {
Expand All @@ -55,11 +59,13 @@ public class TaintAnalysis extends CompositePlugin {
public void setSolver(Solver solver) {
this.solver = solver;
AnalysisOptions options = solver.getOptions();
isInteractive = options.getBoolean("taint-interactive");
isInteractive = options.getBoolean("taint-interactive-mode");
initialize();
}

private void initialize() {
// reset sub-plugins
clearPlugins();
TaintManager manager = new TaintManager(solver.getHeapModel());
TaintConfig config = TaintConfig.loadConfig(
solver.getOptions().getString("taint-config"),
Expand All @@ -70,62 +76,87 @@ private void initialize() {
addPlugin(new SourceHandler(context),
new TransferHandler(context),
new SanitizerHandler(context));
}

/**
* Add comment
*/
private boolean reInitialize() {
clearPlugins();
initialize();
// clear all taint objects and taint edges
CSManager csManager = solver.getCSManager();
TaintManager taintManager = context.manager();
csManager.pointers().forEach(p -> {
p.removeObjsIf(csObj -> taintManager.isTaint(csObj.getObject()));
PointsToSet pts = p.getPointsToSet();
if (pts != null) {
pts.removeIf(csObj -> manager.isTaint(csObj.getObject()));
}
p.removeEdgesIf(TaintTransferEdge.class::isInstance);
});
solver.getCallGraph().reachableMethods().forEach(csMethod -> {
JMethod method = csMethod.getMethod();
Context ctxt = csMethod.getContext();
IR ir = csMethod.getMethod().getIR();
if (context.config().callSiteMode()) {
ir.forEach(stmt -> onNewStmt(stmt, method));
}
csMethod.getEdges().forEach(this::onNewCallEdge);
this.onNewCSMethod(csMethod);
ir.getParams().forEach(param -> {
CSVar csParam = csManager.getCSVar(ctxt, param);
onNewPointsToSet(csParam, csParam.getPointsToSet());
// trigger the creation of taint objects
CallGraph<CSCallSite, CSMethod> cg = solver.getCallGraph();
if (cg != null) {
cg.reachableMethods().forEach(csMethod -> {
JMethod method = csMethod.getMethod();
Context ctxt = csMethod.getContext();
IR ir = csMethod.getMethod().getIR();
if (context.config().callSiteMode()) {
ir.forEach(stmt -> onNewStmt(stmt, method));
}
csMethod.getEdges().forEach(this::onNewCallEdge);
this.onNewCSMethod(csMethod);
ir.getParams().forEach(param -> {
CSVar csParam = csManager.getCSVar(ctxt, param);
onNewPointsToSet(csParam, csParam.getPointsToSet());
});
});
});
return !taintManager.getTaintObjs().isEmpty();
}
}

@Override
public void onPhaseFinish() {
reportTaintFlows();
if (isInteractive) {
Scanner scan = new Scanner(System.in);
while (true) {
logger.info("Change your taint config, and input 'r' to continue, 'e' to exit:");
if (!scan.hasNextLine()) {
System.out.println("Taint Analysis is in interactive mode,"
+ " you can change your taint config and run the analysis again.\n"
+ "Enter 'r' to run, 'e' to exit: ");
String input = nextLineFromConsole();
if (input == null) {
break;
}
String input = scan.nextLine().strip();
input = input.strip();
System.out.println("You have entered: '" + input + "'");
if ("r".equals(input)) {
if (reInitialize()) {
initialize();
if (!context.manager().getTaintObjs().isEmpty()) {
break;
}
} else if ("e".equals(input)) {
isInteractive = false;
break;
} else {
logger.error("Invalid input");
}
}
}
}

/**
* A utility method for reading one line from the console using {@code System.in}.
* This method does not use buffering to ensure it does not read more than necessary.
* <br>
*
* @return one line line read from the console,
* or {@code null} if no line is available
*/
@Nullable
private static String nextLineFromConsole() {
StringBuilder sb = new StringBuilder();
try {
int c;
while ((c = System.in.read()) != -1) {
if (c == '\r' || c == '\n') {
break;
}
sb.append((char) c);
}
} catch (Exception e) {
logger.error("Error reading from console", e);
}
return sb.toString();
}

private void reportTaintFlows() {
Set<TaintFlow> taintFlows = new SinkHandler(context).collectTaintFlows();
logger.info("Detected {} taint flow(s):", taintFlows.size());
Expand All @@ -137,5 +168,4 @@ private void reportTaintFlows() {
new File(World.get().getOptions().getOutputDir(), TAINT_FLOW_GRAPH_FILE)),
"TFGDumper");
}

}
4 changes: 4 additions & 0 deletions src/main/java/pascal/taie/analysis/pta/pts/PointsToSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public interface PointsToSet extends Iterable<CSObj>, Copyable<PointsToSet> {

/**
* Removes objects from this set if they satisfy the filter.
* <p>
* <strong>Note:</strong> This method should be used with caution during pointer analysis iterations,
* as it can break the monotonicity of the analysis.
* </p>
*/
void removeIf(Predicate<CSObj> filter);

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/tai-e-analyses.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
reflection-log: null # path to reflection log, required when reflection option is log
taint-config: null # path to config file of taint analysis,
# when this file is given, taint analysis will be enabled
taint-interactive: false # whether enable interactive taint analysis
taint-interactive-mode: false # whether enable interactive taint analysis
plugins: [ ] # | [ pluginClass, ... ]
time-limit: -1 # set time limit (in seconds) for pointer analysis,
# -1 means no time limit
Expand Down
6 changes: 3 additions & 3 deletions src/test/java/pascal/taie/analysis/pta/TaintTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ void test(String mainClass, String... opts) {
void testInteractiveTaintAnalysis() {
InputStream originalSystemIn = System.in;
try {
InputStream testIn = new ByteArrayInputStream("r\ne\n".getBytes());
System.setIn(testIn);
String simulatedInput = "r\nr\ne";
System.setIn(new ByteArrayInputStream(simulatedInput.getBytes()));
Main.main(
"-pp",
"-cp", "src/test/resources/pta/taint",
Expand All @@ -89,7 +89,7 @@ void testInteractiveTaintAnalysis() {
+ "implicit-entries:false;"
+ "only-app:true;"
+ "distinguish-string-constants:all;"
+ "interactive-taint-analysis:true;"
+ "taint-interactive-mode:true;"
+ TAINT_CONFIG
);
} finally {
Expand Down

0 comments on commit 003b3d1

Please sign in to comment.