Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsafe Masking Changes #210

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class Configuration {
public static ControlFlowManager controlFlowManager = new StandardControlFlowManager();
public static String controlFlowManagerPackage = null;
public static boolean QUIET_MODE = false;
// Option is set for Java 9+ JVM by the embedded configuration
public static boolean IS_JAVA_8 = true;
public static Set<String> ignoredMethods = new HashSet<>();
public static TaintTagFactory taintTagFactory = new DataAndControlFlowTagFactory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import edu.columbia.cs.psl.phosphor.instrumenter.*;
import edu.columbia.cs.psl.phosphor.instrumenter.asm.OffsetPreservingClassReader;
import edu.columbia.cs.psl.phosphor.mask.SerializationFixingCV;
import edu.columbia.cs.psl.phosphor.org.objectweb.asm.commons.OurSerialVersionUIDAdder;
import edu.columbia.cs.psl.phosphor.runtime.StringUtils;
import edu.columbia.cs.psl.phosphor.runtime.TaintInstrumented;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ public static InstrumentationAdaptor getInstrumentation() {
}

@InvokedViaInstrumentation(record = TaintMethodRecord.INSTRUMENT_CLASS_BYTES)
public static byte[] instrumentClassBytes(byte[] in) {
return new PCLoggingTransformer().transform(null, null, null, null, in, false);
public static byte[] instrumentClassBytes(byte[] classFileBuffer) {
byte[] result = new PCLoggingTransformer().transform(null, null, null, null, classFileBuffer, false);
return result == null ? classFileBuffer : result;
}

@InvokedViaInstrumentation(record = TaintMethodRecord.INSTRUMENT_CLASS_BYTES_ANONYMOUS)
public static byte[] instrumentClassBytesAnonymous(byte[] in) {
return new PCLoggingTransformer().transform(null, null, null, null, in, true);
public static byte[] instrumentClassBytesAnonymous(byte[] classFileBuffer) {
byte[] result = new PCLoggingTransformer().transform(null, null, null, null, classFileBuffer, true);
return result == null ? classFileBuffer : result;
}

private static String[] parseOptions(String agentArgs) {
Expand All @@ -64,9 +66,6 @@ private static String[] parseOptions(String agentArgs) {
}
}
}
if (Configuration.IS_JAVA_8) {
options.addLast("-java8");
}
return options.toArray(new String[0]);
}

Expand Down Expand Up @@ -172,7 +171,6 @@ public static boolean isUninstrumentedField(String owner, String name) {
}

public static boolean isUnsafeClass(String className) {
return (Configuration.IS_JAVA_8 && "sun/misc/Unsafe".equals(className))
|| (!Configuration.IS_JAVA_8 && "jdk/internal/misc/Unsafe".equals(className));
return "sun/misc/Unsafe".equals(className) || "jdk/internal/misc/Unsafe".equals(className);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,6 @@ public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine com
}
}
},
JAVA_8(new PhosphorOptionBuilder(null, true, true).alternativeName("java8")) {
@Override
public void configure(boolean forRuntimeInst, boolean isPresent, CommandLine commandLine) {
Configuration.IS_JAVA_8 = isPresent;
}
},
JVM_MODULES(new PhosphorOptionBuilder("For Java 9+ JVM generation: list of Java modules to include in instrumented JVM",
true, false).argType(String.class).alternativeName("jvmModules")) {
@Override
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;

public final class AsmPatchingCV 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 AsmPatchingCV(ClassVisitor classVisitor) {
super(Configuration.ASM_VERSION, classVisitor);
}

@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 AsmPatchingMV(mv);
}

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

private static class AsmPatchingMV extends MethodVisitor {
public AsmPatchingMV(MethodVisitor mv) {
super(Configuration.ASM_VERSION, 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);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package edu.columbia.cs.psl.phosphor.agent;

import edu.columbia.cs.psl.phosphor.Configuration;
import edu.columbia.cs.psl.phosphor.instrumenter.TaintMethodRecord;
import edu.columbia.cs.psl.phosphor.struct.harmony.util.Set;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import static org.objectweb.asm.Opcodes.*;

/**
* Embeds the current values for the field of {@link Configuration} into the class file for {@link Configuration}.
*/
public class ConfigurationEmbeddingCV extends ClassVisitor {
private static final String TARGET_METHOD_NAME = "<clinit>";

protected ConfigurationEmbeddingCV(ClassVisitor classVisitor) {
super(Configuration.ASM_VERSION, classVisitor);
}

@Override
public MethodVisitor visitMethod(
int access, String name, String descriptor, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
return !name.equals(TARGET_METHOD_NAME) ? mv : new ConfigurationEmbeddingMV(mv);
}

public static boolean isApplicable(String className) {
return Type.getInternalName(Configuration.class).equals(className);
}

private static class ConfigurationEmbeddingMV extends MethodVisitor {
protected ConfigurationEmbeddingMV(MethodVisitor methodVisitor) {
super(Configuration.ASM_VERSION, methodVisitor);
}

@Override
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
if (opcode == Opcodes.PUTSTATIC) {
try {
Field f = Configuration.class.getField(name);
f.setAccessible(true);
if (Modifier.isPublic(f.getModifiers()) || !Modifier.isFinal(f.getModifiers())) {
replaceValue(Type.getType(descriptor), f.get(null));
}
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to access field owned by " + Configuration.class, e);
}
}
super.visitFieldInsn(opcode, owner, name, descriptor);
}

private void replaceValue(Type type, Object newValue) {
switch (type.getSort()) {
case Type.VOID:
case Type.ARRAY:
case Type.METHOD:
return;
}
// Pop the original value
super.visitInsn(type.getSize() == 1 ? POP : POP2);
// Push the new value
if (type.getSort() != Type.OBJECT || newValue instanceof String) {
super.visitLdcInsn(newValue);
} else if (newValue == null) {
super.visitInsn(ACONST_NULL);
} else if (newValue instanceof Class) {
mv.visitLdcInsn(Type.getType((Class<?>) newValue));
} else if (newValue instanceof Set) {
Set<?> set = (Set<?>) newValue;
newInstance(newValue.getClass());
for (Object element : set) {
super.visitInsn(DUP);
super.visitLdcInsn(element);
TaintMethodRecord.SET_ADD.delegateVisit(mv);
super.visitInsn(POP);
}
} else {
newInstance(newValue.getClass());
}
}

private void newInstance(Class<?> clazz) {
try {
clazz.getConstructor();
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Public, zero-argument constructor not found for: " + clazz);
}
String className = Type.getInternalName(clazz);
super.visitTypeInsn(Opcodes.NEW, className);
super.visitInsn(DUP);
super.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V", false);
}
}
}

This file was deleted.

Loading