Skip to content

Commit

Permalink
* Fixed issue with failure in AnnotationInstCase not being reported f…
Browse files Browse the repository at this point in the history
…or Java 8

* Fixed failure in AnnotationInstCase for Java 8 by patching ASM for Java 8
* Fixed JavaDoc warnings
* Refactored ConfigurationEmbeddingMV
* Moved classes not used to by the agent at runtime to the package edu.columbia.cs.psl.phosphor.agent
  • Loading branch information
katherine-hough committed Nov 27, 2023
1 parent 805c4d6 commit 0772550
Show file tree
Hide file tree
Showing 27 changed files with 400 additions and 417 deletions.
54 changes: 34 additions & 20 deletions Phosphor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,26 +59,6 @@
<forceCreation>true</forceCreation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-stubs</id>
<goals>
<goal>java</goal>
</goals>
<phase>process-classes</phase>
<configuration>
<mainClass>edu.columbia.cs.psl.phosphor.instrumenter.InstrumentedJREProxyGenerator
</mainClass>
<arguments>
<argument>${project.build.outputDirectory}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand Down Expand Up @@ -131,6 +111,40 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-stubs</id>
<goals>
<goal>java</goal>
</goals>
<phase>process-classes</phase>
<configuration>
<mainClass>edu.columbia.cs.psl.phosphor.agent.InstrumentedJREProxyGenerator
</mainClass>
<arguments>
<argument>${project.build.outputDirectory}</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>patch</id>
<goals>
<goal>java</goal>
</goals>
<phase>package</phase>
<configuration>
<mainClass>edu.columbia.cs.psl.phosphor.agent.PhosphorPatcher
</mainClass>
<arguments>
<argument>${project.build.directory}/${project.build.finalName}.jar</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import edu.columbia.cs.psl.phosphor.control.ControlFlowManager;
import edu.columbia.cs.psl.phosphor.control.standard.StandardControlFlowManager;
import edu.columbia.cs.psl.phosphor.instrumenter.DataAndControlFlowTagFactory;
import edu.columbia.cs.psl.phosphor.instrumenter.TaintAdapter;
import edu.columbia.cs.psl.phosphor.instrumenter.TaintTagFactory;
import edu.columbia.cs.psl.phosphor.instrumenter.TaintTrackingClassVisitor;
import edu.columbia.cs.psl.phosphor.runtime.DerivedTaintListener;
import edu.columbia.cs.psl.phosphor.runtime.Taint;
import edu.columbia.cs.psl.phosphor.runtime.TaintSourceWrapper;
Expand All @@ -14,36 +12,30 @@
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;

import java.io.IOException;
import java.net.URL;
import java.util.Properties;

public class Configuration {

public static final int ASM_VERSION = Opcodes.ASM9;
public static final String TAINT_TAG_DESC = "Ledu/columbia/cs/psl/phosphor/runtime/Taint;";
public static final String TAINT_TAG_INTERNAL_NAME = "edu/columbia/cs/psl/phosphor/runtime/Taint";
public static final String TAINT_TAG_ARRAY_INTERNAL_NAME = "edu/columbia/cs/psl/phosphor/struct/TaggedArray";
public static final Object TAINT_TAG_STACK_TYPE = "edu/columbia/cs/psl/phosphor/runtime/Taint";
public static final int TAINT_LOAD_OPCODE = Opcodes.ALOAD;
public static final int TAINT_STORE_OPCODE = Opcodes.ASTORE;
public static final Class<?> TAINT_TAG_OBJ_CLASS = (Taint.class);
public static final boolean DEBUG_STACK_FRAME_WRAPPERS = false;
public static boolean SKIP_LOCAL_VARIABLE_TABLE = false;
public static String ADDL_IGNORE = null;
public static String IGNORE = null;
public static boolean REFERENCE_TAINTING = true;
public static boolean DATAFLOW_TRACKING = true; //default
// default
public static boolean DATAFLOW_TRACKING = true;
public static boolean ARRAY_INDEX_TRACKING = false;
public static boolean IMPLICIT_TRACKING = false; //TODO need to set this at runtime somewhere
// TODO need to set this at runtime somewhere
public static boolean IMPLICIT_TRACKING = false;
public static boolean IMPLICIT_LIGHT_TRACKING;
public static boolean IMPLICIT_HEADERS_NO_TRACKING = false;
public static boolean IMPLICIT_EXCEPTION_FLOW = false;
public static boolean WITHOUT_BRANCH_NOT_TAKEN = false;
public static boolean SINGLE_TAINT_LABEL = false;
public static boolean ANNOTATE_LOOPS = false;
public static boolean WITH_ENUM_BY_VAL = false;
public static boolean WITH_UNBOX_ACMPEQ = false;
public static boolean PREALLOC_STACK_OPS = false;
public static boolean WITHOUT_PROPAGATION = false;
public static boolean WITHOUT_FIELD_HIDING = false;
public static boolean READ_AND_SAVE_BCI = false;
Expand All @@ -55,17 +47,11 @@ public class Configuration {
public static String controlFlowManagerPackage = null;
public static boolean QUIET_MODE = false;
public static boolean IS_JAVA_8 = true;

public static Set<String> ignoredMethods = new HashSet<>();

public static Class<? extends TaintAdapter> extensionMethodVisitor;
public static Class<? extends ClassVisitor> extensionClassVisitor;
public static TaintTagFactory taintTagFactory = new DataAndControlFlowTagFactory();
public static String taintTagFactoryPackage = null;
public static TaintSourceWrapper<?> autoTainter = new TaintSourceWrapper<>();
public static DerivedTaintListener derivedTaintListener = new DerivedTaintListener();
public static boolean WITH_HEAVY_OBJ_EQUALS_HASHCODE = false;
public static TransformationCache CACHE = null;
public static boolean TAINT_THROUGH_SERIALIZATION = true;

private Configuration() {
Expand All @@ -76,75 +62,5 @@ public static void init() {
if (IMPLICIT_TRACKING) {
ARRAY_INDEX_TRACKING = true;
}
if (TaintTrackingClassVisitor.class.getClassLoader() != null) {
URL r = TaintTrackingClassVisitor.class.getClassLoader().getResource("phosphor-mv");
if (r != null) {
try {
Properties props = new Properties();
props.load(r.openStream());
if (props.containsKey("extraMV")) {
extensionMethodVisitor = (Class<? extends TaintAdapter>) Class.forName(props.getProperty("extraMV"));
}
if (props.containsKey("extraCV")) {
extensionClassVisitor = (Class<? extends ClassVisitor>) Class.forName(props.getProperty("extraCV"));
}
if(props.containsKey("taintTagFactory")) {
taintTagFactory = (TaintTagFactory) Class.forName(props.getProperty("taintTagFactory")).newInstance();
}
if(props.containsKey("derivedTaintListener")) {
derivedTaintListener = (DerivedTaintListener) Class.forName(props.getProperty("derivedTaintListener")).newInstance();
}
} catch(IOException ex) {
//fail silently
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}

public static class Method {
final String name;
final String owner;

public Method(String name, String owner) {
this.name = name;
this.owner = owner;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(getClass() != obj.getClass()) {
return false;
}
Method other = (Method) obj;
if(name == null) {
if(other.name != null) {
return false;
}
} else if(!name.equals(other.name)) {
return false;
}
if(owner == null) {
return other.owner == null;
} else {
return owner.equals(other.owner);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ public byte[] transform(ClassLoader loader, final String className2, Class<?> cl
return classfileBuffer;
}
}
if (Configuration.CACHE != null) {
byte[] cachedClass = Configuration.CACHE.load(className, classfileBuffer);
if (Phosphor.CACHE != null) {
byte[] cachedClass = Phosphor.CACHE.load(className, classfileBuffer);
if (cachedClass != null) {
return cachedClass;
}
Expand Down Expand Up @@ -114,8 +114,8 @@ public byte[] transform(ClassLoader loader, final String className2, Class<?> cl
fos.write(instrumentedBytes);
fos.close();
}
if (Configuration.CACHE != null) {
Configuration.CACHE.store(className, classfileBuffer, instrumentedBytes);
if (Phosphor.CACHE != null) {
Phosphor.CACHE.store(className, classfileBuffer, instrumentedBytes);
}
return instrumentedBytes;
} catch (Throwable ex) {
Expand Down Expand Up @@ -162,10 +162,6 @@ static byte[] instrumentWithRetry(ClassReader cr, byte[] classFileBuffer, boolea
//
}
}
if (Configuration.extensionClassVisitor != null) {
Constructor<? extends ClassVisitor> extra = Configuration.extensionClassVisitor.getConstructor(ClassVisitor.class, Boolean.TYPE);
_cv = extra.newInstance(_cv, skipFrames);
}
if (Phosphor.DEBUG || TaintUtils.VERIFY_CLASS_GENERATION) {
_cv = new CheckClassAdapter(_cv, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public final class Phosphor {
public static boolean INSTRUMENTATION_EXCEPTION_OCCURRED = false;
public static ClassLoader bigLoader = Phosphor.class.getClassLoader();
public static InstrumentationAdaptor instrumentation;
public static TransformationCache CACHE = null;

private Phosphor() {
throw new AssertionError("Tried to instantiate static agent class: " + getClass());
Expand All @@ -27,7 +28,7 @@ public static void initialize(String agentArgs, InstrumentationAdaptor instrumen
PhosphorOption.configure(true, parseOptions(agentArgs));
}
if (System.getProperty("phosphorCacheDirectory") != null) {
Configuration.CACHE = TransformationCache.getInstance(System.getProperty("phosphorCacheDirectory"));
CACHE = TransformationCache.getInstance(System.getProperty("phosphorCacheDirectory"));
}
// Ensure that BasicSourceSinkManager and anything needed to call isSourceOrSinkOrTaintThrough gets initialized
BasicSourceSinkManager.loadTaintMethods();
Expand Down Expand Up @@ -74,7 +75,7 @@ public static boolean isIgnoredClass(String owner) {
|| taintTagFactoryPackage != null && StringUtils.startsWith(owner, taintTagFactoryPackage)
|| controlFlowManagerPackage != null && StringUtils.startsWith(owner, controlFlowManagerPackage)
|| (Configuration.controlFlowManager != null && Configuration.controlFlowManager.isIgnoredClass(owner))
|| (Configuration.ADDL_IGNORE != null && StringUtils.startsWith(owner, Configuration.ADDL_IGNORE))
|| (Configuration.IGNORE != null && StringUtils.startsWith(owner, Configuration.IGNORE))
// || !owner.startsWith("edu/columbia/cs/psl")
// For these classes: HotSpot expects fields to be at hardcoded offsets of these classes.
// If we instrument them, it will break those assumptions and segfault.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine com
.argType(String.class)) {
@Override
public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine commandLine) {
Configuration.CACHE = isPresent ? TransformationCache.getInstance(commandLine.getOptionValue(optionName)) :
Phosphor.CACHE = isPresent ? TransformationCache.getInstance(commandLine.getOptionValue(optionName)) :
null;
}
},
Expand Down Expand Up @@ -273,7 +273,7 @@ public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine com
@Override
public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine commandLine) {
if(isPresent) {
Configuration.ADDL_IGNORE = commandLine.getOptionValue(optionName);
Configuration.IGNORE = commandLine.getOptionValue(optionName);
}
}
},
Expand All @@ -295,9 +295,7 @@ public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine com
true, false).argType(String.class).alternativeName("jvmModules")) {
@Override
public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine commandLine) {
/*
Only used by instrumenter, which reads properties map
*/
// Only used by instrumenter, which reads properties map
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package edu.columbia.cs.psl.phosphor.agent;

import edu.columbia.cs.psl.phosphor.Configuration;
import edu.columbia.cs.psl.phosphor.instrumenter.TaintMethodRecord;
import org.objectweb.asm.*;

public class AsmPatcher extends ClassVisitor {
private static final String ASM_PREFIX = "edu/columbia/cs/psl/phosphor/org/objectweb/asm/";
private static final Type OBJECT_TYPE = Type.getType(Object.class);

public AsmPatcher(ClassWriter cw) {
super(Configuration.ASM_VERSION, cw);
}

@Override
public MethodVisitor visitMethod(
int access, String name, String descriptor, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
return new MethodVisitor(api, mv) {

@Override
public void visitMethodInsn(
int opcode, String owner, String name, String descriptor, boolean isInterface) {
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
// Ensure that the return value is unwrapped if necessary
if (owner.startsWith("java/") && OBJECT_TYPE.equals(Type.getReturnType(descriptor))) {
TaintMethodRecord.TAINTED_REFERENCE_ARRAY_UNWRAP.delegateVisit(mv);
}
}
};
}

public static byte[] patch(byte[] classFileBuffer) {
ClassReader cr = new ClassReader(classFileBuffer);
ClassWriter cw = new ClassWriter(cr, 0);
ClassVisitor cv = new AsmPatcher(cw);
cr.accept(cv, 0);
return cw.toByteArray();
}

public static boolean isApplicable(String className) {
return className.startsWith(ASM_PREFIX);
}
}
Loading

0 comments on commit 0772550

Please sign in to comment.