diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Configuration.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Configuration.java index d19cbb78d..31bd7acd4 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Configuration.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Configuration.java @@ -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 ignoredMethods = new HashSet<>(); public static TaintTagFactory taintTagFactory = new DataAndControlFlowTagFactory(); diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Phosphor.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Phosphor.java index 335a5988f..3debb85fe 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Phosphor.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/Phosphor.java @@ -64,9 +64,6 @@ private static String[] parseOptions(String agentArgs) { } } } - if (Configuration.IS_JAVA_8) { - options.addLast("-java8"); - } return options.toArray(new String[0]); } @@ -172,7 +169,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); } } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/PhosphorOption.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/PhosphorOption.java index 26a5609d0..3551655dc 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/PhosphorOption.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/PhosphorOption.java @@ -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 diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/InstrumentedJREProxyGenerator.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/InstrumentedJREProxyGenerator.java index 5ce61e8fa..8f07bdeaa 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/InstrumentedJREProxyGenerator.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/InstrumentedJREProxyGenerator.java @@ -18,12 +18,6 @@ public class InstrumentedJREProxyGenerator { public static void main(String[] args) throws IOException { String outputDir = args[0]; - String pathToUnsafePropagator = outputDir - + "/edu/columbia/cs/psl/phosphor/runtime/jdk/unsupported/RuntimeSunMiscUnsafePropagator.class"; - byte[] buffer = InstrumentUtil.readAllBytes(new File(pathToUnsafePropagator)); - byte[] instrumentedUnsafe = - PhosphorPatcher.apply(buffer, cv -> new UnsafePatchingCV(cv, "sun/misc/Unsafe", false)); - Files.write(Paths.get(pathToUnsafePropagator), instrumentedUnsafe); for (String clazz : CLASSES) { String classLocation = outputDir + '/' + clazz.replace('.', '/') + ".class"; ClassReader cr = new ClassReader(InstrumentUtil.readAllBytes(new File(classLocation))); @@ -75,26 +69,14 @@ public static void generateFieldHelper(GeneratorAdapter ga, String name, String name = name.substring(6); } String fieldName = name.substring(3); - Type actualFieldType = null; if (name.startsWith("get")) { ga.visitVarInsn(Opcodes.ALOAD, 0); - ga.visitFieldInsn( - Opcodes.GETFIELD, - fieldOwner, - fieldName, - (actualFieldType != null ? actualFieldType.getDescriptor() : returnType.getDescriptor())); + ga.visitFieldInsn(Opcodes.GETFIELD, fieldOwner, fieldName, returnType.getDescriptor()); } else { Type argType = Type.getArgumentTypes(descriptor)[1]; ga.visitVarInsn(Opcodes.ALOAD, 0); ga.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), 1); - if (actualFieldType != null) { - ga.visitTypeInsn(Opcodes.CHECKCAST, actualFieldType.getInternalName()); - } - ga.visitFieldInsn( - Opcodes.PUTFIELD, - fieldOwner, - fieldName, - (actualFieldType != null ? actualFieldType.getDescriptor() : argType.getDescriptor())); + ga.visitFieldInsn(Opcodes.PUTFIELD, fieldOwner, fieldName, argType.getDescriptor()); } } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/PhosphorPatcher.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/PhosphorPatcher.java index e7c956f3e..49c728e38 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/PhosphorPatcher.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/PhosphorPatcher.java @@ -55,6 +55,8 @@ private static byte[] patch(String name, byte[] classFileBuffer) { return apply(classFileBuffer, AsmPatchingCV::new); } else if (MaskRegistryPatchingCV.isApplicable(name)) { return apply(classFileBuffer, MaskRegistryPatchingCV::new); + } else if (UnsafeAdapterPatchingCV.isApplicable(name)) { + return apply(classFileBuffer, UnsafeAdapterPatchingCV::new); } return classFileBuffer; } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/UnsafeAdapterPatchingCV.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/UnsafeAdapterPatchingCV.java new file mode 100644 index 000000000..764b9a359 --- /dev/null +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/UnsafeAdapterPatchingCV.java @@ -0,0 +1,49 @@ +package edu.columbia.cs.psl.phosphor.agent; + +import edu.columbia.cs.psl.phosphor.Configuration; +import edu.columbia.cs.psl.phosphor.runtime.mask.JdkUnsafeAdapter; +import edu.columbia.cs.psl.phosphor.runtime.mask.SunUnsafeAdapter; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; + +import java.util.regex.Pattern; + +public class UnsafeAdapterPatchingCV extends ClassVisitor { + private String className; + + public UnsafeAdapterPatchingCV(ClassVisitor cv) { + super(Configuration.ASM_VERSION, cv); + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + super.visit(version, access, name, signature, superName, interfaces); + className = name; + } + + @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) { + if (owner.equals(className) && opcode == Opcodes.INVOKESTATIC) { + Type[] args = Type.getArgumentTypes(descriptor); + owner = args[0].getInternalName(); + descriptor = descriptor.replaceFirst(Pattern.quote(args[0].getDescriptor()), ""); + super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, descriptor, false); + } else { + super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); + } + } + }; + } + + public static boolean isApplicable(String className) { + return Type.getInternalName(SunUnsafeAdapter.class).equals(className) + || Type.getInternalName(JdkUnsafeAdapter.class).equals(className); + } +} diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/UnsafePatchingCV.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/UnsafePatchingCV.java index 1be139f38..b9b5f4b11 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/UnsafePatchingCV.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/agent/UnsafePatchingCV.java @@ -1,7 +1,7 @@ package edu.columbia.cs.psl.phosphor.agent; import edu.columbia.cs.psl.phosphor.Configuration; -import edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported.UnsafeProxy; +import edu.columbia.cs.psl.phosphor.runtime.mask.UnsafeProxy; import org.objectweb.asm.*; class UnsafePatchingCV extends ClassVisitor { diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/MaskRegistry.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/MaskRegistry.java index c6fb6e63e..41bbef3af 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/MaskRegistry.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/MaskRegistry.java @@ -7,6 +7,7 @@ import edu.columbia.cs.psl.phosphor.instrumenter.TaintMethodRecord; import edu.columbia.cs.psl.phosphor.struct.harmony.util.HashMap; import edu.columbia.cs.psl.phosphor.struct.harmony.util.Map; +import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; public final class MaskRegistry { @@ -58,5 +59,9 @@ public MaskInfo(MethodRecordImpl record) { public MethodRecordImpl getRecord() { return record; } + + public void accept(MethodVisitor mv) { + record.delegateVisit(mv); + } } } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ObjectStreamReflectionMV.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ObjectStreamReflectionMV.java index c394cde2e..7079202d6 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ObjectStreamReflectionMV.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ObjectStreamReflectionMV.java @@ -2,7 +2,6 @@ import edu.columbia.cs.psl.phosphor.Configuration; import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; import static edu.columbia.cs.psl.phosphor.instrumenter.TaintMethodRecord.IS_INSTANCE; @@ -23,9 +22,7 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc, // Even if we are not masking other methods, this must be masked IS_INSTANCE.delegateVisit(mv); } else if (owner.equals("sun/misc/Unsafe") && shouldMask(name)) { - owner = ReflectionMVFactory.getRuntimeUnsafePropagatorClassName(); - super.visitMethodInsn( - Opcodes.INVOKESTATIC, owner, name, "(Lsun/misc/Unsafe;" + desc.substring(1), isInterface); + MaskRegistry.getMask(owner, name, desc).accept(mv); } else { super.visitMethodInsn(opcode, owner, name, desc, isInterface); } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionHidingMV.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionHidingMV.java index e5df94add..4c8e038b1 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionHidingMV.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionHidingMV.java @@ -1,12 +1,9 @@ package edu.columbia.cs.psl.phosphor.mask; import edu.columbia.cs.psl.phosphor.Configuration; -import edu.columbia.cs.psl.phosphor.Phosphor; import edu.columbia.cs.psl.phosphor.instrumenter.LocalVariableManager; -import edu.columbia.cs.psl.phosphor.runtime.ArrayReflectionMasker; -import edu.columbia.cs.psl.phosphor.runtime.CharacterUtils; -import edu.columbia.cs.psl.phosphor.runtime.PhosphorStackFrame; -import edu.columbia.cs.psl.phosphor.runtime.ReflectionMasker; +import edu.columbia.cs.psl.phosphor.mask.MaskRegistry.MaskInfo; +import edu.columbia.cs.psl.phosphor.runtime.*; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -15,7 +12,6 @@ import java.lang.reflect.Method; import static edu.columbia.cs.psl.phosphor.instrumenter.TaintMethodRecord.*; -import static edu.columbia.cs.psl.phosphor.instrumenter.TaintTrackingClassVisitor.CONTROL_STACK_DESC; class ReflectionHidingMV extends ReflectionMV implements Opcodes { private final String className; @@ -36,108 +32,96 @@ public void setLvs(LocalVariableManager lvs) { this.lvs = lvs; } - /* Returns whether a method instruction with the specified information is for a method added to Unsafe by Phosphor - * that retrieves the value of a field of a Java heap object. */ - private boolean isUnsafeFieldGetter(int opcode, String owner, String name, Type[] args, String nameWithoutSuffix) { - if (opcode != INVOKEVIRTUAL || !Phosphor.isUnsafeClass(owner)) { - return false; - } else { - if (args.length < 1 || !args[0].equals(Type.getType(Object.class))) { - return false; - } - if (Configuration.IS_JAVA_8) { - switch (nameWithoutSuffix) { - case "getBoolean": - case "getByte": - case "getChar": - case "getDouble": - case "getFloat": - case "getInt": - case "getLong": - case "getObject": - case "getShort": - case "getBooleanVolatile": - case "getByteVolatile": - case "getCharVolatile": - case "getDoubleVolatile": - case "getFloatVolatile": - case "getLongVolatile": - case "getIntVolatile": - case "getObjectVolatile": - case "getShortVolatile": - return true; - default: - return false; - } - } - return false; + @Override + public void visitCode() { + super.visitCode(); + if (this.className.equals("java/lang/invoke/MethodHandles$Lookup") + && this.methodName.startsWith("defineHiddenClass")) { + super.visitVarInsn(ALOAD, 1); + INSTRUMENT_CLASS_BYTES.delegateVisit(mv); + super.visitVarInsn(ASTORE, 1); } } - /* Returns whether a method instruction with the specified information is for a method added to Unsafe by Phosphor - * that sets the value of a field of a Java heap object. */ - private boolean isUnsafeFieldSetter(int opcode, String owner, String name, Type[] args, String nameWithoutSuffix) { - if (opcode != INVOKEVIRTUAL || !Phosphor.isUnsafeClass(owner)) { - return false; - } else { - if (args.length < 1 || !args[0].equals(Type.getType(Object.class))) { - return false; - } - if (Configuration.IS_JAVA_8) { - switch (nameWithoutSuffix) { - case "putBoolean": - case "putByte": - case "putChar": - case "putDouble": - case "putFloat": - case "putInt": - case "putLong": - case "putObject": - case "putShort": - case "putBooleanVolatile": - case "putByteVolatile": - case "putCharVolatile": - case "putDoubleVolatile": - case "putFloatVolatile": - case "putIntVolatile": - case "putLongVolatile": - case "putObjectVolatile": - case "putShortVolatile": - case "putOrderedInt": - case "putOrderedLong": - case "putOrderedObject": - return true; - default: - return false; - } - } - return false; + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) { + String descWithoutStackFrame = desc.replace(PhosphorStackFrame.DESCRIPTOR, ""); + if ((className.equals("java/io/ObjectOutputStream") || className.equals("java/io/ObjectInputStream")) + && owner.equals("java/lang/Class") + && name.startsWith("isInstance")) { + IS_INSTANCE.delegateVisit(mv); + return; + } + switch (owner) { + case "jdk/internal/reflect/Reflection": + maskReflection(opcode, owner, name, desc, isInterface); + return; + case "java/lang/reflect/Array": + maskArray(opcode, owner, name, desc, isInterface); + return; + case "java/lang/Character": + maskCharacter(opcode, owner, name, desc, isInterface); + return; + case "sun/reflect/NativeMethodAccessorImpl": + case "jdk/internal/reflect/NativeMethodAccessorImpl": + maskMethodAccessor(opcode, owner, name, desc, isInterface); + return; + case "sun/reflect/NativeConstructorAccessorImpl": + case "jdk/internal/reflect/NativeConstructorAccessorImpl": + maskConstructorAccessor(opcode, owner, name, desc, isInterface); + return; + case "jdk/internal/misc/Unsafe": + maskUnsafe(opcode, owner, name, desc, isInterface, descWithoutStackFrame); + return; + default: + super.visitMethodInsn(opcode, owner, name, desc, isInterface); + fixReturn(owner, name, name, descWithoutStackFrame); } } - /* Returns whether a method instruction with the specified information is for a method added to Unsafe by Phosphor - * for a compareAndSwap method. */ - private boolean isUnsafeCAS(String owner, String nameWithoutSuffix) { - if (Phosphor.isUnsafeClass(owner)) { - if (Configuration.IS_JAVA_8) { - return "compareAndSwapInt".equals(nameWithoutSuffix) - || "compareAndSwapLong".equals(nameWithoutSuffix) - || "compareAndSwapObject".equals(nameWithoutSuffix); + private void maskUnsafe( + int opcode, String owner, String name, String desc, boolean isInterface, String descWithoutStackFrame) { + MaskInfo mask = MaskRegistry.getMask(owner, name, desc); + if (mask != null) { + if (!name.equals("defineClass") || patchAnonymousClasses) { + mask.accept(mv); + return; } } - return false; + if (patchAnonymousClasses + && name.equals("defineAnonymousClass") + && descWithoutStackFrame.equals("(Ljava/lang/Class;[B[Ljava/lang/Object;)Ljava/lang/Class;")) { + super.visitInsn(POP); + super.visitInsn(SWAP); + INSTRUMENT_CLASS_BYTES_ANONYMOUS.delegateVisit(mv); + super.visitInsn(SWAP); + desc = descWithoutStackFrame; // Go directly to the native call + super.visitMethodInsn(opcode, owner, name, desc, isInterface); + } else if (shouldPatchUnsafe(name, descWithoutStackFrame)) { + name = name.replace("Object", "Reference"); + desc = "(L" + owner + ";" + desc.substring(1); + owner = Type.getInternalName(RuntimeJDKInternalUnsafePropagator.class); + super.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc, false); + } else { + super.visitMethodInsn(opcode, owner, name, desc, isInterface); + } } - private boolean isUnsafeIntrinsic(String owner, String name, String desc) { - if (Configuration.IS_JAVA_8) { - return false; // These intrinsics are only for 9+ - } - if (!Phosphor.isUnsafeClass(owner)) { - return false; - } + private boolean shouldPatchUnsafe(String name, String originalDesc) { // Java 11 uses get/putObject instead of Reference name = name.replace("Object", "Reference"); - switch (desc) { + switch (name) { + case "allocateUninitializedArray": + case "copyMemory": + case "copySwapMemory": + return true; + default: + return isUnsafeIntrinsic(name, originalDesc); + } + } + + private boolean isUnsafeIntrinsic(String name, String originalDesc) { + switch (originalDesc) { case "(Ljava/lang/Object;JLjava/lang/Object;)V": switch (name) { case "putReference": @@ -254,9 +238,8 @@ private boolean isUnsafeIntrinsic(String owner, String name, String desc) { return true; } case "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;": - switch (name) { - case "getAndSetReference": - return true; + if (name.equals("getAndSetReference")) { + return true; } case "(Ljava/lang/Object;JC)V": switch (name) { @@ -403,140 +386,6 @@ private boolean isUnsafeIntrinsic(String owner, String name, String desc) { return false; } - private boolean isUnsafeCopyMemory(String owner, String name, String nameWithoutSuffix) { - if (Phosphor.isUnsafeClass(owner)) { - switch (nameWithoutSuffix) { - case "copyMemory": - case "copySwapMemory": - return true; - } - } - return false; - } - - @Override - public void visitCode() { - super.visitCode(); - if (this.className.equals("java/lang/invoke/MethodHandles$Lookup") - && this.methodName.startsWith("defineHiddenClass")) { - super.visitVarInsn(ALOAD, 1); - INSTRUMENT_CLASS_BYTES.delegateVisit(mv); - super.visitVarInsn(ASTORE, 1); - } - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) { - Type[] args = Type.getArgumentTypes(desc); - String descWithoutStackFrame = desc.replace(PhosphorStackFrame.DESCRIPTOR, ""); - if ((className.equals("java/io/ObjectOutputStream") || className.equals("java/io/ObjectInputStream")) - && owner.equals("java/lang/Class") - && name.startsWith("isInstance")) { - IS_INSTANCE.delegateVisit(mv); - return; - } - switch (owner) { - case "jdk/internal/reflect/Reflection": - maskReflection(opcode, owner, name, desc, isInterface); - return; - case "java/lang/reflect/Array": - maskArray(opcode, owner, name, desc, isInterface); - return; - case "java/lang/Character": - maskCharacter(opcode, owner, name, desc, isInterface); - return; - case "sun/reflect/NativeMethodAccessorImpl": - case "jdk/internal/reflect/NativeMethodAccessorImpl": - maskMethodAccessor(opcode, owner, name, desc, isInterface); - return; - case "sun/reflect/NativeConstructorAccessorImpl": - case "jdk/internal/reflect/NativeConstructorAccessorImpl": - maskConstructorAccessor(opcode, owner, name, desc, isInterface); - return; - default: - if (Phosphor.isUnsafeClass(owner)) { - patchUnsafe(opcode, owner, name, desc, isInterface, descWithoutStackFrame, args, name); - } else { - super.visitMethodInsn(opcode, owner, name, desc, isInterface); - fixReturn(owner, name, name, descWithoutStackFrame); - } - } - } - - private void patchUnsafe( - int opcode, - String owner, - String name, - String desc, - boolean isInterface, - String descWithoutStackFrame, - Type[] args, - String nameWithoutSuffix) { - if (patchAnonymousClasses - && name.equals("defineAnonymousClass") - && descWithoutStackFrame.equals("(Ljava/lang/Class;[B[Ljava/lang/Object;)Ljava/lang/Class;")) { - super.visitInsn(POP); - super.visitInsn(SWAP); - INSTRUMENT_CLASS_BYTES_ANONYMOUS.delegateVisit(mv); - super.visitInsn(SWAP); - desc = descWithoutStackFrame; // Go directly to the native call - super.visitMethodInsn(opcode, owner, name, desc, isInterface); - } else if (patchAnonymousClasses - && name.equals("defineClass") - && Configuration.IS_JAVA_8 - && descWithoutStackFrame.equals( - "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;")) { - desc = "(Lsun/misc/Unsafe;" + desc.substring(1); - super.visitMethodInsn( - Opcodes.INVOKESTATIC, ReflectionMVFactory.getRuntimeUnsafePropagatorClassName(), name, desc, false); - } else if (name.equals("allocateUninitializedArray")) { - desc = "(L" + owner + ";" + desc.substring(1); - super.visitMethodInsn( - Opcodes.INVOKESTATIC, ReflectionMVFactory.getRuntimeUnsafePropagatorClassName(), name, desc, false); - } else if (isUnsafeIntrinsic(owner, name, descWithoutStackFrame) - || isUnsafeFieldGetter(opcode, owner, name, args, nameWithoutSuffix)) { - if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_HEADERS_NO_TRACKING) { - desc = desc.replace(CONTROL_STACK_DESC, ""); - // in control tracking mode, pop the control stack off of the stack to reuse the existing method - // but first, pop the null that's there for the erased return type. - if (isUnsafeReferenceFieldGetter(nameWithoutSuffix)) { - super.visitInsn(POP); - } - super.visitInsn(SWAP); - super.visitInsn(POP); - if (isUnsafeReferenceFieldGetter(nameWithoutSuffix)) { - super.visitInsn(ACONST_NULL); - } - } - desc = "(L" + owner + ";" + desc.substring(1); - if (isUnsafeIntrinsic(owner, name, descWithoutStackFrame)) { - // Java 11 uses get/putObject instead of Reference - name = name.replace("Object", "Reference"); - } - super.visitMethodInsn( - Opcodes.INVOKESTATIC, ReflectionMVFactory.getRuntimeUnsafePropagatorClassName(), name, desc, false); - } else if (isUnsafeFieldSetter(opcode, owner, name, args, nameWithoutSuffix)) { - if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_HEADERS_NO_TRACKING) { - desc = desc.replace(CONTROL_STACK_DESC, ""); - super.visitInsn(POP); - } - desc = "(L" + owner + ";" + desc.substring(1); - super.visitMethodInsn( - Opcodes.INVOKESTATIC, ReflectionMVFactory.getRuntimeUnsafePropagatorClassName(), name, desc, false); - } else if (isUnsafeCAS(owner, nameWithoutSuffix) || isUnsafeCopyMemory(owner, name, nameWithoutSuffix)) { - if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_HEADERS_NO_TRACKING) { - desc = desc.replace(CONTROL_STACK_DESC, ""); - super.visitInsn(SWAP); - super.visitInsn(POP); - } - desc = "(L" + owner + ";" + desc.substring(1); - super.visitMethodInsn( - INVOKESTATIC, ReflectionMVFactory.getRuntimeUnsafePropagatorClassName(), name, desc, isInterface); - } else { - super.visitMethodInsn(opcode, owner, name, desc, isInterface); - } - } - private void maskReflection(int opcode, String owner, String name, String desc, boolean isInterface) { // If we in a wrapped method and called by the wrapper // get the caller class of the wrapper not this stack frame @@ -640,12 +489,4 @@ private void fixReturn(String owner, String name, String nameWithoutSuffix, Stri } } } - - private static boolean isUnsafeReferenceFieldGetter(String methodName) { - if (Configuration.IS_JAVA_8) { - return "getObject".equals(methodName) || "getObjectVolatile".equals(methodName); - } - // TODO Java 11? - return "getReference".equals(methodName) || "getReferenceVolatile".equals(methodName); - } } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionMVFactory.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionMVFactory.java index e7e65792d..62e448506 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionMVFactory.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/mask/ReflectionMVFactory.java @@ -1,15 +1,9 @@ package edu.columbia.cs.psl.phosphor.mask; -import edu.columbia.cs.psl.phosphor.Configuration; -import edu.columbia.cs.psl.phosphor.runtime.RuntimeJDKInternalUnsafePropagator; -import edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported.RuntimeSunMiscUnsafePropagator; import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; public final class ReflectionMVFactory { public static ReflectionMV create(MethodVisitor mv, String className, String methodName) { - // TODO - MaskRegistry.MaskInfo mask = MaskRegistry.getMask(className, methodName, "()V"); if (ObjectStreamReflectionMV.isApplicable(className, methodName)) { return new ObjectStreamReflectionMV(mv, className, methodName); } else if (DisabledReflectionMV.isApplicable(className, methodName)) { @@ -18,11 +12,4 @@ public static ReflectionMV create(MethodVisitor mv, String className, String met return new ReflectionHidingMV(mv, className, methodName); } } - - public static String getRuntimeUnsafePropagatorClassName() { - return Type.getInternalName( - Configuration.IS_JAVA_8 - ? RuntimeSunMiscUnsafePropagator.class - : RuntimeJDKInternalUnsafePropagator.class); - } } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/RuntimeJDKInternalUnsafePropagator.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/RuntimeJDKInternalUnsafePropagator.java index 75fe45a0e..06092c842 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/RuntimeJDKInternalUnsafePropagator.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/RuntimeJDKInternalUnsafePropagator.java @@ -2,7 +2,7 @@ import edu.columbia.cs.psl.phosphor.Configuration; import edu.columbia.cs.psl.phosphor.TaintUtils; -import edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported.UnsafeProxy; +import edu.columbia.cs.psl.phosphor.runtime.mask.UnsafeProxy; import edu.columbia.cs.psl.phosphor.runtime.proxied.InstrumentedJREFieldHelper; import edu.columbia.cs.psl.phosphor.struct.*; import edu.columbia.cs.psl.phosphor.struct.harmony.util.StringBuilder; diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/jdk/unsupported/RuntimeSunMiscUnsafePropagator.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/jdk/unsupported/RuntimeSunMiscUnsafePropagator.java deleted file mode 100644 index b22915a40..000000000 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/jdk/unsupported/RuntimeSunMiscUnsafePropagator.java +++ /dev/null @@ -1,806 +0,0 @@ -package edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported; - -import edu.columbia.cs.psl.phosphor.Configuration; -import edu.columbia.cs.psl.phosphor.Phosphor; -import edu.columbia.cs.psl.phosphor.TaintUtils; -import edu.columbia.cs.psl.phosphor.runtime.MultiDArrayUtils; -import edu.columbia.cs.psl.phosphor.runtime.PhosphorStackFrame; -import edu.columbia.cs.psl.phosphor.runtime.RuntimeJDKInternalUnsafePropagator.OffsetPair; -import edu.columbia.cs.psl.phosphor.runtime.Taint; -import edu.columbia.cs.psl.phosphor.runtime.proxied.InstrumentedJREFieldHelper; -import edu.columbia.cs.psl.phosphor.struct.*; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.security.ProtectionDomain; - -/* Ensures that calls methods in Unsafe that set or retrieve the value of a field of a Java heap object set and - * retrieve both the original field and its associated taint field if it has one. */ -public class RuntimeSunMiscUnsafePropagator { - - private RuntimeSunMiscUnsafePropagator() { - // Prevents this class from being instantiated - } - - /* Used to disambiguate between a static field of a given type and an instance field of java.lang.Class */ - static long LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS = UnsafeProxy.INVALID_FIELD_OFFSET; - - /* Stores pairs containing the offset of an original, non-static primitive or primitive array field for the specified - * class and the offset of the tag field associated with that original field. */ - private static SinglyLinkedList getOffsetPairs(UnsafeProxy unsafe, Class targetClazz) { - SinglyLinkedList list = new SinglyLinkedList<>(); - for(Class clazz = targetClazz; clazz != null && !Object.class.equals(clazz); clazz = clazz.getSuperclass()) { - for(Field field : clazz.getDeclaredFields()) { - try { - Class fieldClazz = field.getType(); - boolean isStatic = Modifier.isStatic(field.getModifiers()); - long fieldOffset = (isStatic ? unsafe.staticFieldOffset(field) : unsafe.objectFieldOffset(field)); - long tagOffset = UnsafeProxy.INVALID_FIELD_OFFSET; - long wrapperOffset = UnsafeProxy.INVALID_FIELD_OFFSET; - try { - if(!field.getName().equals("SPECIES_DATA")) { - Field taintField = clazz.getField(field.getName() + TaintUtils.TAINT_FIELD); - if (taintField.getType().equals(Configuration.TAINT_TAG_OBJ_CLASS)) { - tagOffset = (isStatic ? unsafe.staticFieldOffset(taintField) : unsafe.objectFieldOffset(taintField)); - } - } - } catch(Exception e) { - // - } - if(fieldClazz.isArray()) { - try { - Field taintField = clazz.getField(field.getName() + TaintUtils.TAINT_WRAPPER_FIELD); - Class taintClazz = taintField.getType(); - if(taintClazz != null && TaggedArray.class.isAssignableFrom(taintClazz)) { - wrapperOffset = (isStatic ? unsafe.staticFieldOffset(taintField) : unsafe.objectFieldOffset(taintField)); - } - } catch(Exception e) { - // - } - } - list.enqueue(new OffsetPair(isStatic, fieldOffset, wrapperOffset, tagOffset)); - } catch(Exception e) { - // - } - } - } - return list; - } - - /* returns an offset pair for the specified object's class where either the original field offset or the tag field - * offset matches the specified offset or null if such an offset pair could not be found. */ - public static OffsetPair getOffsetPair(UnsafeProxy unsafe, Object o, long offset) { - try { - Class cl = null; - boolean isStatic = false; - if(o instanceof Class) { - /* We MIGHT be accessing a static field of this class, in which case we should take - the offset from *this* class instance (o). But, we might also be accessing an instance - field of the type Class, in which case we want to use the classes's class. - */ - if(LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS == UnsafeProxy.INVALID_FIELD_OFFSET) { - findLastInstanceFieldOnJavaLangClass(unsafe); - } - if(offset > LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS) { - /* We are not accessing an instance field of java.lang.Class, hence, we must be accessing - * a static field of type (Class) o */ - cl = (Class) o; - isStatic = true; - } - /* Otherwise, we are accessing an instance field of java.lang.Class */ - } - if(cl == null && o != null && o.getClass() != null) { - cl = o.getClass(); - } - if(cl != null) { - if(InstrumentedJREFieldHelper.get$$PHOSPHOR_OFFSET_CACHE(cl) == null) { - InstrumentedJREFieldHelper.set$$PHOSPHOR_OFFSET_CACHE(cl, getOffsetPairs(unsafe, cl)); - } - for(OffsetPair pair : InstrumentedJREFieldHelper.get$$PHOSPHOR_OFFSET_CACHE(cl)) { - if(pair.origFieldOffset == offset && pair.isStatic == isStatic) { - return pair; - } - } - } - return null; - } catch(Exception e) { - return null; - } - } - - private static void findLastInstanceFieldOnJavaLangClass(UnsafeProxy unsafe) { - for(Field field : Class.class.getDeclaredFields()) { - try { - Class fieldClazz = field.getType(); - boolean isStatic = Modifier.isStatic(field.getModifiers()); - if(isStatic) { - continue; - } - long fieldOffset = unsafe.objectFieldOffset(field); - if(fieldOffset > LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS) { - LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS = fieldOffset; - } - } catch(Exception e) { - // - } - } - } - - /* If prealloc is a wrapped primitive type, set it's taint to be the value of the field at the specified offset in the - * other specified object. Otherwise returns the value of the field at the specified offset in the specified object. */ - public static void getTag(UnsafeProxy unsafe, Object obj, long originalOffset, PhosphorStackFrame stackFrame, SpecialAccessPolicy policy) { - stackFrame.returnTaint = Taint.emptyTaint(); - OffsetPair pair = getOffsetPair(unsafe, obj, originalOffset); - if(pair != null && pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - Object result = (policy == SpecialAccessPolicy.VOLATILE) ? unsafe.getObjectVolatile(obj, pair.tagFieldOffset) : unsafe.getObject(obj, pair.tagFieldOffset); - if(result instanceof Taint) { - stackFrame.returnTaint = (Taint) result; - } - } - } - - /* If the specified Object value is a wrapped primitive type, puts it's taint into the field at the specified offset in the - * other specified object. Otherwise if the specified Object value is null or a lazy array wrapper put the specified Object - * value into the field at the specified offset in the other specified object. */ - public static void putTag(UnsafeProxy unsafe, Object obj, long offset, Taint tag, SpecialAccessPolicy policy) { - OffsetPair pair = null; - if(obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if(pair != null) { - switch(policy) { - case ORDERED: - unsafe.putOrderedObject(obj, pair.tagFieldOffset, tag); - break; - case VOLATILE: - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, tag); - break; - default: - unsafe.putObject(obj, pair.tagFieldOffset, tag); - } - } - } - - /* If the specified TaintedPrimitiveWithObjTag and TaggedArray's component types match sets a tag - * in the specified TaggedArray at a calculated index. - * type's match. */ - public static void swapArrayElementTag(UnsafeProxy unsafe, TaggedArray tags, long offset, Taint valueTaint) { - if(tags.getVal() != null && tags.getVal().getClass().isArray()) { - Class clazz = tags.getVal().getClass(); - long baseOffset = unsafe.arrayBaseOffset(clazz); - long scale = unsafe.arrayIndexScale(clazz); - // Calculate the index based off the offset - int index = (int) ((offset - baseOffset) / scale); - if(tags.taints == null && valueTaint != null && !valueTaint.isEmpty()) { - tags.taints = new Taint[tags.getLength()]; - } - if(tags.taints != null) { - tags.taints[index] = valueTaint; - } - } - } - - public static void copyMemory(UnsafeProxy unsafe, Object src, long srcAddress, Object dest, long destAddress, long length, PhosphorStackFrame stackFrame) { - if(src instanceof TaggedArray) { - src = ((TaggedArray) src).getVal(); - } - if(dest instanceof TaggedArray) { - dest = ((TaggedArray) dest).getVal(); - } - unsafe.copyMemory(src, srcAddress, dest, destAddress, length); - } - - public static void copyMemory(UnsafeProxy unsafe, long srcAddress, long destAddress, long length, PhosphorStackFrame stackFrame) { - unsafe.copyMemory(srcAddress, destAddress, length); - } - - public static boolean compareAndSwapObject(UnsafeProxy unsafe, Object obj, long offset, Object expected, Object value, PhosphorStackFrame stackFrame) { - stackFrame.returnTaint = Taint.emptyTaint(); - boolean ret = false; - if(obj instanceof TaggedReferenceArray) { - Taint valueTaint = stackFrame.getArgTaint(4); - ret = unsafe.compareAndSwapObject(((TaggedReferenceArray) obj).val, offset, expected, value); - if(ret) { - swapArrayElementTag(unsafe, (TaggedArray) obj, offset, valueTaint); - } - } else { - OffsetPair pair = null; - boolean didCAS = false; - if(value instanceof TaggedArray || expected instanceof TaggedArray) { - //Need to be careful - maybe we are hitting a 1D primitive array field - if(obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if(pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - //We are doing a CAS on a 1d primitive array field - ret = unsafe.compareAndSwapObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(expected), MultiDArrayUtils.unbox1DOrNull(value)); - didCAS = true; - } - } - if(!didCAS) { - //Either this is not a wrapped array, or we are storing it to the place where it should be stored without unwrapping - ret = unsafe.compareAndSwapObject(obj, offset, expected, value); - if(pair == null && obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - } - - if(pair != null && ret) { - if(pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, stackFrame.getArgTaint(4)); - } - if(pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.wrappedFieldOffset, value); - } - } - } - return ret; - } - - public static boolean compareAndSwapInt(UnsafeProxy unsafe, Object obj, long offset, int expected, int value, PhosphorStackFrame phosphorStackFrame) { - phosphorStackFrame.returnTaint = Taint.emptyTaint(); - boolean ret = false; - if(obj instanceof TaggedIntArray) { - ret = unsafe.compareAndSwapInt(((TaggedIntArray) obj).val, offset, expected, value); - if(ret) { - swapArrayElementTag(unsafe, (TaggedArray) obj, offset, phosphorStackFrame.getArgTaint(4)); - } - } else { - ret = unsafe.compareAndSwapInt(obj, offset, expected, value); - OffsetPair pair = null; - if(obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if(pair != null && ret) { - if(pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(4)); - } - } - } - return ret; - } - - public static boolean compareAndSwapLong(UnsafeProxy unsafe, Object obj, long offset, long expected, long value, PhosphorStackFrame phosphorStackFrame) { - phosphorStackFrame.returnTaint = Taint.emptyTaint(); - boolean ret = false; - if(obj instanceof TaggedLongArray) { - ret = unsafe.compareAndSwapLong(((TaggedLongArray) obj).val, offset, expected, value); - if(ret) { - swapArrayElementTag(unsafe, (TaggedArray) obj, offset, phosphorStackFrame.getArgTaint(4)); - } - } else { - ret = unsafe.compareAndSwapLong(obj, offset, expected, value); - OffsetPair pair = null; - if(obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if(pair != null && ret) { - if(pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(4)); - } - } - } - return ret; - } - - public static int unsafeIndexFor(UnsafeProxy unsafe, TaggedArray array, long offset) { - Class clazz = array.getVal().getClass(); - long baseOffset = unsafe.arrayBaseOffset(clazz); - long scale = unsafe.arrayIndexScale(clazz); - // Calculate the index based off the offset - int index = (int) ((offset - baseOffset) / scale); - return index; - } - - public static void putObject(UnsafeProxy unsafe, Object obj, long offset, Object val, PhosphorStackFrame phosphorStackFrame) { - if(obj instanceof TaggedReferenceArray) { - ((TaggedReferenceArray) obj).set(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), val, phosphorStackFrame.getArgTaint(3)); - } else { - OffsetPair pair = null; - if(obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if(pair != null) { - if(pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObject(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(3)); - } - if(pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObject(obj, pair.wrappedFieldOffset, val); - unsafe.putObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } else { - unsafe.putObject(obj, offset, val); - } - } else { - unsafe.putObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } - } - } - - public static void putOrderedObject(UnsafeProxy unsafe, Object obj, long offset, Object val, PhosphorStackFrame phosphorStackFrame) { - if(obj instanceof TaggedReferenceArray) { - ((TaggedReferenceArray) obj).set(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), val, phosphorStackFrame.getArgTaint(3)); - } else { - OffsetPair pair = null; - if(obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if(pair != null) { - if(pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putOrderedObject(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(3)); - } - if(pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putOrderedObject(obj, pair.wrappedFieldOffset, val); - unsafe.putOrderedObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } else { - unsafe.putOrderedObject(obj, offset, val); - } - } else { - unsafe.putOrderedObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } - } - } - - public static void putObjectVolatile(UnsafeProxy unsafe, Object obj, long offset, Object val, PhosphorStackFrame phosphorStackFrame) { - if(obj instanceof TaggedReferenceArray) { - ((TaggedReferenceArray) obj).set(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), val, phosphorStackFrame.getArgTaint(3)); - } else { - unsafe.putObjectVolatile(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - OffsetPair pair = null; - if(obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if(pair != null) { - if(pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(3)); - } - if(pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.wrappedFieldOffset, val); - unsafe.putObjectVolatile(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } else { - unsafe.putObjectVolatile(obj, offset, val); - } - } else { - unsafe.putObjectVolatile(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } - } - } - - public static Object getObject(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedReferenceArray) { - //Push the taint from the `offset` argument to the `idx` argument for get - return ((TaggedReferenceArray) obj).get(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), stackFrame.getArgTaint(1), stackFrame); - } else { - //Is this trying to return a field that is wrapped? - OffsetPair pair = getOffsetPair(unsafe, obj, offset); - if(pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - offset = pair.wrappedFieldOffset; - } - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getObject(obj, offset); - } - } - - public static Object getObjectVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedReferenceArray) { - //Push the taint from the `offset` argument to the `idx` argument for get - return ((TaggedReferenceArray) obj).get(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), stackFrame.getArgTaint(1), stackFrame); - } else { - //Is this trying to return a field that is wrapped? - OffsetPair pair = getOffsetPair(unsafe, obj, offset); - if(pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - offset = pair.wrappedFieldOffset; - } - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getObjectVolatile(obj, offset); - } - } - - public static void putByte(UnsafeProxy unsafe, Object obj, long offset, byte val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putByte(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putByte(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putByteVolatile(UnsafeProxy unsafe, Object obj, long offset, byte val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putByteVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putByte(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static byte getByte(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getByte(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getByte(obj, offset); - } - } - - public static byte getByteVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getByteVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getByteVolatile(obj, offset); - } - } - - public static void putBoolean(UnsafeProxy unsafe, Object obj, long offset, boolean val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putBoolean(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putBoolean(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putBooleanVolatile(UnsafeProxy unsafe, Object obj, long offset, boolean val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putBooleanVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putBoolean(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static boolean getBoolean(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getBoolean(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getBoolean(obj, offset); - } - } - - public static boolean getBooleanVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getBooleanVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getBooleanVolatile(obj, offset); - } - } - - public static void putChar(UnsafeProxy unsafe, Object obj, long offset, char val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putChar(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putChar(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putCharVolatile(UnsafeProxy unsafe, Object obj, long offset, char val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putCharVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putChar(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static char getChar(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getChar(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getChar(obj, offset); - } - } - - public static char getCharVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getCharVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getCharVolatile(obj, offset); - } - } - - public static void putFloat(UnsafeProxy unsafe, Object obj, long offset, float val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putFloat(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putFloat(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putFloatVolatile(UnsafeProxy unsafe, Object obj, long offset, float val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - - if(obj instanceof TaggedArray) { - unsafe.putFloatVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putFloat(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static float getFloat(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getFloat(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getFloat(obj, offset); - } - } - - public static float getFloatVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getFloatVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getFloatVolatile(obj, offset); - } - } - - public static void putOrderedInt(UnsafeProxy unsafe, Object obj, long offset, int val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putOrderedInt(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putOrderedInt(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.ORDERED); - } - } - - public static void putInt(UnsafeProxy unsafe, Object obj, long offset, int val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putInt(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putInt(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putIntVolatile(UnsafeProxy unsafe, Object obj, long offset, int val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putIntVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putInt(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static int getInt(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getInt(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getInt(obj, offset); - } - } - - public static int getIntVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getIntVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getIntVolatile(obj, offset); - } - } - - public static void putDouble(UnsafeProxy unsafe, Object obj, long offset, double val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putDouble(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putDouble(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putDoubleVolatile(UnsafeProxy unsafe, Object obj, long offset, double val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putDoubleVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putDouble(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static double getDouble(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getDouble(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getDouble(obj, offset); - } - } - - public static double getDoubleVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getDoubleVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getDoubleVolatile(obj, offset); - } - } - - public static void putShort(UnsafeProxy unsafe, Object obj, long offset, short val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putShort(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putShort(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putShortVolatile(UnsafeProxy unsafe, Object obj, long offset, short val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putShortVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putShort(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static short getShort(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getShort(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getShort(obj, offset); - } - } - - public static short getShortVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getShortVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getShortVolatile(obj, offset); - } - } - - public static void putLong(UnsafeProxy unsafe, Object obj, long offset, long val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putLong(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putLong(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static void putOrderedLong(UnsafeProxy unsafe, Object obj, long offset, long val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putOrderedLong(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putOrderedLong(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.ORDERED); - } - } - - public static void putLongVolatile(UnsafeProxy unsafe, Object obj, long offset, long val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if(obj instanceof TaggedArray) { - unsafe.putLongVolatile(((TaggedArray) obj).getVal(), offset, val); - if((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putLong(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, SpecialAccessPolicy.NONE); - } - } - - public static long getLong(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getLong(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.NONE); - return unsafe.getLong(obj, offset); - } - } - - /* for static fields, obj is a class. for instance fields of a class object, obj is also a class. if we want static fields, we need - * offsets from *this* class's declared fields. for instance fields, we */ - public static long getLongVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if(obj instanceof TaggedArray) { - stackFrame.returnTaint = ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getLongVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, SpecialAccessPolicy.VOLATILE); - return unsafe.getLongVolatile(obj, offset); - } - } - - public static Class defineClass(UnsafeProxy unsafe, String var1, byte[] var2, int var3, int var4, ClassLoader var5, ProtectionDomain var6, PhosphorStackFrame phosphorStackFrame) { - byte[] instrumented = Phosphor.instrumentClassBytes(var2); - return unsafe.defineClass(var1, instrumented, 0, instrumented.length, var5, var6); - } - - public enum SpecialAccessPolicy { - VOLATILE, - ORDERED, - NONE - } - -} diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/JdkUnsafeAdapter.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/JdkUnsafeAdapter.java new file mode 100644 index 000000000..f3c6d80f2 --- /dev/null +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/JdkUnsafeAdapter.java @@ -0,0 +1,301 @@ +package edu.columbia.cs.psl.phosphor.runtime.mask; + +import jdk.internal.misc.Unsafe; + +import java.lang.reflect.Field; +import java.security.ProtectionDomain; + +/** + * Note that the various get/put Object methods are deprecated but present in Java 21. + * If they are removed in future Java versions, we will need to patch these when packing the specific Java installation. + */ +@SuppressWarnings("unused") +public class JdkUnsafeAdapter implements UnsafeAdapter { + private final Unsafe unsafe = Unsafe.getUnsafe(); + + @Override + public long getInvalidFieldOffset() { + return Unsafe.INVALID_FIELD_OFFSET; + } + + @Override + public Class defineClass( + String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) { + return unsafe.defineClass0(name, b, off, len, loader, protectionDomain); + } + + @Override + public int getInt(Object o, long offset) { + return unsafe.getInt(o, offset); + } + + @Override + public void putInt(Object o, long offset, int x) { + unsafe.putInt(o, offset, x); + } + + @Override + public Object getObject(Object o, long offset) { + return unsafe.getObject(o, offset); + } + + @Override + public void putObject(Object o, long offset, Object x) { + unsafe.putObject(o, offset, x); + } + + @Override + public boolean getBoolean(Object o, long offset) { + return unsafe.getBoolean(o, offset); + } + + @Override + public void putBoolean(Object o, long offset, boolean x) { + unsafe.putBoolean(o, offset, x); + } + + @Override + public byte getByte(Object o, long offset) { + return unsafe.getByte(o, offset); + } + + @Override + public void putByte(Object o, long offset, byte x) { + unsafe.putByte(o, offset, x); + } + + @Override + public short getShort(Object o, long offset) { + return unsafe.getShort(o, offset); + } + + @Override + public void putShort(Object o, long offset, short x) { + unsafe.putShort(o, offset, x); + } + + @Override + public char getChar(Object o, long offset) { + return unsafe.getChar(o, offset); + } + + @Override + public void putChar(Object o, long offset, char x) { + unsafe.putChar(o, offset, x); + } + + @Override + public long getLong(Object o, long offset) { + return unsafe.getLong(o, offset); + } + + @Override + public void putLong(Object o, long offset, long x) { + unsafe.putLong(o, offset, x); + } + + @Override + public float getFloat(Object o, long offset) { + return unsafe.getFloat(o, offset); + } + + @Override + public void putFloat(Object o, long offset, float x) { + unsafe.putFloat(o, offset, x); + } + + @Override + public double getDouble(Object o, long offset) { + return unsafe.getDouble(o, offset); + } + + @Override + public void putDouble(Object o, long offset, double x) { + unsafe.putDouble(o, offset, x); + } + + @Override + public byte getByte(long address) { + return unsafe.getByte(address); + } + + @Override + public short getShort(long address) { + return unsafe.getShort(address); + } + + @Override + public char getChar(long address) { + return unsafe.getChar(address); + } + + @Override + public int getInt(long address) { + return unsafe.getInt(address); + } + + @Override + public long getLong(long address) { + return unsafe.getLong(address); + } + + @Override + public float getFloat(long address) { + return unsafe.getFloat(address); + } + + @Override + public double getDouble(long address) { + return unsafe.getDouble(address); + } + + @Override + public void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) { + unsafe.copyMemory(srcBase, srcOffset, destBase, destOffset, bytes); + } + + @Override + public void copyMemory(long srcAddress, long destAddress, long bytes) { + unsafe.copyMemory(srcAddress, destAddress, bytes); + } + + @Override + public long objectFieldOffset(Field f) { + return unsafe.objectFieldOffset(f); + } + + @Override + public long staticFieldOffset(Field f) { + return unsafe.staticFieldOffset(f); + } + + @Override + public int arrayBaseOffset(Class arrayClass) { + return unsafe.arrayBaseOffset(arrayClass); + } + + @Override + public int arrayIndexScale(Class arrayClass) { + return unsafe.arrayIndexScale(arrayClass); + } + + @Override + public Object getObjectVolatile(Object o, long offset) { + return unsafe.getObjectVolatile(o, offset); + } + + @Override + public void putObjectVolatile(Object o, long offset, Object x) { + unsafe.putObjectVolatile(o, offset, x); + } + + @Override + public boolean compareAndSwapObject(Object o, long offset, Object expected, Object x) { + return unsafe.compareAndSetObject(o, offset, expected, x); + } + + @Override + public int getIntVolatile(Object o, long offset) { + return unsafe.getIntVolatile(o, offset); + } + + @Override + public void putIntVolatile(Object o, long offset, int x) { + unsafe.putIntVolatile(o, offset, x); + } + + @Override + public boolean getBooleanVolatile(Object o, long offset) { + return unsafe.getBooleanVolatile(o, offset); + } + + @Override + public void putBooleanVolatile(Object o, long offset, boolean x) { + unsafe.putBooleanVolatile(o, offset, x); + } + + @Override + public byte getByteVolatile(Object o, long offset) { + return unsafe.getByteVolatile(o, offset); + } + + @Override + public void putByteVolatile(Object o, long offset, byte x) { + unsafe.putByteVolatile(o, offset, x); + } + + @Override + public short getShortVolatile(Object o, long offset) { + return unsafe.getShortVolatile(o, offset); + } + + @Override + public void putShortVolatile(Object o, long offset, short x) { + unsafe.putShortVolatile(o, offset, x); + } + + @Override + public char getCharVolatile(Object o, long offset) { + return unsafe.getCharVolatile(o, offset); + } + + @Override + public void putCharVolatile(Object o, long offset, char x) { + unsafe.putCharVolatile(o, offset, x); + } + + @Override + public long getLongVolatile(Object o, long offset) { + return unsafe.getLongVolatile(o, offset); + } + + @Override + public void putLongVolatile(Object o, long offset, long x) { + unsafe.putLongVolatile(o, offset, x); + } + + @Override + public float getFloatVolatile(Object o, long offset) { + return unsafe.getFloatVolatile(o, offset); + } + + @Override + public void putFloatVolatile(Object o, long offset, float x) { + unsafe.putFloatVolatile(o, offset, x); + } + + @Override + public double getDoubleVolatile(Object o, long offset) { + return unsafe.getDoubleVolatile(o, offset); + } + + @Override + public void putDoubleVolatile(Object o, long offset, double x) { + unsafe.putDoubleVolatile(o, offset, x); + } + + @Override + public void putOrderedObject(Object o, long offset, Object x) { + unsafe.putObjectRelease(o, offset, x); + } + + @Override + public boolean compareAndSwapInt(Object o, long offset, int expected, int x) { + return unsafe.compareAndSetInt(o, offset, expected, x); + } + + @Override + public boolean compareAndSwapLong(Object o, long offset, long expected, long x) { + return unsafe.compareAndSetLong(o, offset, expected, x); + } + + @Override + public void putOrderedInt(Object o, long offset, int x) { + unsafe.putIntRelease(o, offset, x); + } + + @Override + public void putOrderedLong(Object o, long offset, long x) { + unsafe.putLongRelease(o, offset, x); + } +} \ No newline at end of file diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/SunUnsafeAdapter.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/SunUnsafeAdapter.java new file mode 100644 index 000000000..39eab02cb --- /dev/null +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/SunUnsafeAdapter.java @@ -0,0 +1,309 @@ +package edu.columbia.cs.psl.phosphor.runtime.mask; + +import sun.misc.Unsafe; + +import java.lang.reflect.Field; +import java.security.ProtectionDomain; + +public class SunUnsafeAdapter implements UnsafeAdapter { + private final Unsafe unsafe = Unsafe.getUnsafe(); + + @Override + public long getInvalidFieldOffset() { + return Unsafe.INVALID_FIELD_OFFSET; + } + + @SuppressWarnings("unused") + private static Class defineClass( + Unsafe unsafe, + String name, + byte[] b, + int off, + int len, + ClassLoader loader, + ProtectionDomain protectionDomain) { + return null; + } + + @Override + public Class defineClass( + String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) { + // This will be fixed by the patcher + return defineClass(unsafe, name, b, off, len, loader, protectionDomain); + } + + @Override + public int getInt(Object o, long offset) { + return unsafe.getInt(o, offset); + } + + @Override + public void putInt(Object o, long offset, int x) { + unsafe.putInt(o, offset, x); + } + + @Override + public Object getObject(Object o, long offset) { + return unsafe.getObject(o, offset); + } + + @Override + public void putObject(Object o, long offset, Object x) { + unsafe.putObject(o, offset, x); + } + + @Override + public boolean getBoolean(Object o, long offset) { + return unsafe.getBoolean(o, offset); + } + + @Override + public void putBoolean(Object o, long offset, boolean x) { + unsafe.putBoolean(o, offset, x); + } + + @Override + public byte getByte(Object o, long offset) { + return unsafe.getByte(o, offset); + } + + @Override + public void putByte(Object o, long offset, byte x) { + unsafe.putByte(o, offset, x); + } + + @Override + public short getShort(Object o, long offset) { + return unsafe.getShort(o, offset); + } + + @Override + public void putShort(Object o, long offset, short x) { + unsafe.putShort(o, offset, x); + } + + @Override + public char getChar(Object o, long offset) { + return unsafe.getChar(o, offset); + } + + @Override + public void putChar(Object o, long offset, char x) { + unsafe.putChar(o, offset, x); + } + + @Override + public long getLong(Object o, long offset) { + return unsafe.getLong(o, offset); + } + + @Override + public void putLong(Object o, long offset, long x) { + unsafe.putLong(o, offset, x); + } + + @Override + public float getFloat(Object o, long offset) { + return unsafe.getFloat(o, offset); + } + + @Override + public void putFloat(Object o, long offset, float x) { + unsafe.putFloat(o, offset, x); + } + + @Override + public double getDouble(Object o, long offset) { + return unsafe.getDouble(o, offset); + } + + @Override + public void putDouble(Object o, long offset, double x) { + unsafe.putDouble(o, offset, x); + } + + @Override + public byte getByte(long address) { + return unsafe.getByte(address); + } + + @Override + public short getShort(long address) { + return unsafe.getShort(address); + } + + @Override + public char getChar(long address) { + return unsafe.getChar(address); + } + + @Override + public int getInt(long address) { + return unsafe.getInt(address); + } + + @Override + public long getLong(long address) { + return unsafe.getLong(address); + } + + @Override + public float getFloat(long address) { + return unsafe.getFloat(address); + } + + @Override + public double getDouble(long address) { + return unsafe.getDouble(address); + } + + @Override + public void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) { + unsafe.copyMemory(srcBase, srcOffset, destBase, destOffset, bytes); + } + + @Override + public void copyMemory(long srcAddress, long destAddress, long bytes) { + unsafe.copyMemory(srcAddress, destAddress, bytes); + } + + @Override + public long objectFieldOffset(Field f) { + return unsafe.objectFieldOffset(f); + } + + @Override + public long staticFieldOffset(Field f) { + return unsafe.staticFieldOffset(f); + } + + @Override + public int arrayBaseOffset(Class arrayClass) { + return unsafe.arrayBaseOffset(arrayClass); + } + + @Override + public int arrayIndexScale(Class arrayClass) { + return unsafe.arrayIndexScale(arrayClass); + } + + @Override + public Object getObjectVolatile(Object o, long offset) { + return unsafe.getObjectVolatile(o, offset); + } + + @Override + public void putObjectVolatile(Object o, long offset, Object x) { + unsafe.putObjectVolatile(o, offset, x); + } + + @Override + public boolean compareAndSwapObject(Object obj, long offset, Object expected, Object value) { + return unsafe.compareAndSwapObject(obj, offset, expected, value); + } + + @Override + public int getIntVolatile(Object o, long offset) { + return unsafe.getIntVolatile(o, offset); + } + + @Override + public void putIntVolatile(Object o, long offset, int x) { + unsafe.putIntVolatile(o, offset, x); + } + + @Override + public boolean getBooleanVolatile(Object o, long offset) { + return unsafe.getBooleanVolatile(o, offset); + } + + @Override + public void putBooleanVolatile(Object o, long offset, boolean x) { + unsafe.putBooleanVolatile(o, offset, x); + } + + @Override + public byte getByteVolatile(Object o, long offset) { + return unsafe.getByteVolatile(o, offset); + } + + @Override + public void putByteVolatile(Object o, long offset, byte x) { + unsafe.putByteVolatile(o, offset, x); + } + + @Override + public short getShortVolatile(Object o, long offset) { + return unsafe.getShortVolatile(o, offset); + } + + @Override + public void putShortVolatile(Object o, long offset, short x) { + unsafe.putShortVolatile(o, offset, x); + } + + @Override + public char getCharVolatile(Object o, long offset) { + return unsafe.getCharVolatile(o, offset); + } + + @Override + public void putCharVolatile(Object o, long offset, char x) { + unsafe.putCharVolatile(o, offset, x); + } + + @Override + public long getLongVolatile(Object o, long offset) { + return unsafe.getLongVolatile(o, offset); + } + + @Override + public void putLongVolatile(Object o, long offset, long x) { + unsafe.putLongVolatile(o, offset, x); + } + + @Override + public float getFloatVolatile(Object o, long offset) { + return unsafe.getFloatVolatile(o, offset); + } + + @Override + public void putFloatVolatile(Object o, long offset, float x) { + unsafe.putFloatVolatile(o, offset, x); + } + + @Override + public double getDoubleVolatile(Object o, long offset) { + return unsafe.getDoubleVolatile(o, offset); + } + + @Override + public void putDoubleVolatile(Object o, long offset, double x) { + unsafe.putDoubleVolatile(o, offset, x); + } + + @Override + public void putOrderedObject(Object o, long offset, Object x) { + unsafe.putOrderedObject(o, offset, x); + } + + @Override + public boolean compareAndSwapInt(Object val, long offset, int expected, int value) { + return unsafe.compareAndSwapInt(val, offset, expected, value); + } + + @Override + public boolean compareAndSwapLong(Object val, long offset, long expected, long value) { + return unsafe.compareAndSwapLong(val, offset, expected, value); + } + + @Override + public void putOrderedInt(Object o, long offset, int x) { + unsafe.putOrderedInt(o, offset, x); + } + + @Override + public void putOrderedLong(Object o, long offset, long x) { + unsafe.putOrderedLong(o, offset, x); + } +} diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/SunUnsafeMasker.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/SunUnsafeMasker.java index 28e62ada7..ad8702347 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/SunUnsafeMasker.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/SunUnsafeMasker.java @@ -5,17 +5,13 @@ import edu.columbia.cs.psl.phosphor.runtime.PhosphorStackFrame; import edu.columbia.cs.psl.phosphor.runtime.RuntimeJDKInternalUnsafePropagator; import edu.columbia.cs.psl.phosphor.runtime.Taint; -import edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported.RuntimeSunMiscUnsafePropagator; -import edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported.UnsafeProxy; import edu.columbia.cs.psl.phosphor.struct.TaggedArray; -import edu.columbia.cs.psl.phosphor.struct.TaggedIntArray; -import edu.columbia.cs.psl.phosphor.struct.TaggedLongArray; import edu.columbia.cs.psl.phosphor.struct.TaggedReferenceArray; import sun.misc.Unsafe; import java.security.ProtectionDomain; -import static edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported.RuntimeSunMiscUnsafePropagator.*; +import static edu.columbia.cs.psl.phosphor.runtime.mask.UnsafeMaskerHelper.*; @SuppressWarnings("unused") public final class SunUnsafeMasker { @@ -42,487 +38,172 @@ public static Class defineClass( @Mask(owner = Unsafe.class) public static Object getObject(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return null; - } - - public static Object getObject(UnsafeProxy unsafe, Object o, long offset, PhosphorStackFrame frame) { - if (o instanceof TaggedReferenceArray) { - // Push the taint from the `offset` argument to the `idx` argument for get - return ((TaggedReferenceArray) o) - .get(unsafeIndexFor(unsafe, (TaggedArray) o, offset), frame.getArgTaint(1), frame); - } else { - // Is this trying to return a field that is wrapped? - RuntimeJDKInternalUnsafePropagator.OffsetPair pair = getOffsetPair(unsafe, o, offset); - if (pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - offset = pair.wrappedFieldOffset; - } - getTag(unsafe, o, offset, frame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getObject(o, offset); - } + return getObjectPolicy(o, offset, frame, SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static Object getObjectVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return null; - } - - public static Object getObjectVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedReferenceArray) { - // Push the taint from the `offset` argument to the `idx` argument for get - return ((TaggedReferenceArray) obj) - .get(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), stackFrame.getArgTaint(1), stackFrame); - } else { - // Is this trying to return a field that is wrapped? - RuntimeJDKInternalUnsafePropagator.OffsetPair pair = getOffsetPair(unsafe, obj, offset); - if (pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - offset = pair.wrappedFieldOffset; - } - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getObjectVolatile(obj, offset); - } - } - - public static boolean compareAndSwapInt( - UnsafeProxy unsafe, - Object obj, - long offset, - int expected, - int value, - PhosphorStackFrame phosphorStackFrame) { - phosphorStackFrame.returnTaint = Taint.emptyTaint(); - boolean ret = false; - if (obj instanceof TaggedIntArray) { - ret = unsafe.compareAndSwapInt(((TaggedIntArray) obj).val, offset, expected, value); - if (ret) { - swapArrayElementTag(unsafe, (TaggedArray) obj, offset, phosphorStackFrame.getArgTaint(4)); - } - } else { - ret = unsafe.compareAndSwapInt(obj, offset, expected, value); - RuntimeJDKInternalUnsafePropagator.OffsetPair pair = null; - if (obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if (pair != null && ret) { - if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(4)); - } - } - } - return ret; + return getObjectPolicy(o, offset, frame, SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static boolean compareAndSwapInt( Unsafe unsafe, Object o, long offset, int expected, int x, PhosphorStackFrame frame) { - return false; - } - - public static boolean compareAndSwapLong( - UnsafeProxy unsafe, - Object obj, - long offset, - long expected, - long value, - PhosphorStackFrame phosphorStackFrame) { - phosphorStackFrame.returnTaint = Taint.emptyTaint(); - boolean ret; - if (obj instanceof TaggedLongArray) { - ret = unsafe.compareAndSwapLong(((TaggedLongArray) obj).val, offset, expected, value); - if (ret) { - swapArrayElementTag(unsafe, (TaggedArray) obj, offset, phosphorStackFrame.getArgTaint(4)); - } - } else { - ret = unsafe.compareAndSwapLong(obj, offset, expected, value); - RuntimeJDKInternalUnsafePropagator.OffsetPair pair = null; - if (obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if (pair != null && ret) { - if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(4)); - } - } - } - return ret; + frame.returnTaint = Taint.emptyTaint(); + return swapTag(o, offset, frame, adapter.compareAndSwapInt(unwrap(o), offset, expected, x)); } @Mask(owner = Unsafe.class) public static boolean compareAndSwapLong( Unsafe unsafe, Object o, long offset, long expected, long x, PhosphorStackFrame frame) { - return false; + frame.returnTaint = Taint.emptyTaint(); + return swapTag(o, offset, frame, adapter.compareAndSwapLong(unwrap(o), offset, expected, x)); } + @Mask(owner = Unsafe.class) public static boolean compareAndSwapObject( - UnsafeProxy unsafe, Object obj, long offset, Object expected, Object value, PhosphorStackFrame stackFrame) { - stackFrame.returnTaint = Taint.emptyTaint(); + Unsafe unsafe, Object o, long offset, Object expected, Object x, PhosphorStackFrame frame) { + frame.returnTaint = Taint.emptyTaint(); boolean ret = false; - if (obj instanceof TaggedReferenceArray) { - Taint valueTaint = stackFrame.getArgTaint(4); - ret = unsafe.compareAndSwapObject(((TaggedReferenceArray) obj).val, offset, expected, value); + if (o instanceof TaggedReferenceArray) { + Taint valueTaint = frame.getArgTaint(4); + TaggedReferenceArray array = (TaggedReferenceArray) o; + ret = adapter.compareAndSwapObject(array.val, offset, expected, x); if (ret) { - swapArrayElementTag(unsafe, (TaggedArray) obj, offset, valueTaint); + if (array.getVal() != null && array.getVal().getClass().isArray()) { + int index = getArrayIndex(adapter, (TaggedArray) o, offset); + array.setTaint(index, valueTaint); + } } } else { RuntimeJDKInternalUnsafePropagator.OffsetPair pair = null; boolean didCAS = false; - if (value instanceof TaggedArray || expected instanceof TaggedArray) { + if (x instanceof TaggedArray || expected instanceof TaggedArray) { // Need to be careful - maybe we are hitting a 1D primitive array field - if (obj != null) { - pair = getOffsetPair(unsafe, obj, offset); + if (o != null) { + pair = getOffsetPair(adapter, o, offset); } if (pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { // We are doing a CAS on a 1d primitive array field - ret = unsafe.compareAndSwapObject( - obj, - offset, - MultiDArrayUtils.unbox1DOrNull(expected), - MultiDArrayUtils.unbox1DOrNull(value)); + ret = adapter.compareAndSwapObject( + o, offset, MultiDArrayUtils.unbox1DOrNull(expected), MultiDArrayUtils.unbox1DOrNull(x)); didCAS = true; } } if (!didCAS) { // Either this is not a wrapped array, or we are storing it to the place where it should be stored // without unwrapping - ret = unsafe.compareAndSwapObject(obj, offset, expected, value); - if (pair == null && obj != null) { - pair = getOffsetPair(unsafe, obj, offset); + ret = adapter.compareAndSwapObject(o, offset, expected, x); + if (pair == null && o != null) { + pair = getOffsetPair(adapter, o, offset); } } if (pair != null && ret) { if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, stackFrame.getArgTaint(4)); + adapter.putObjectVolatile(o, pair.tagFieldOffset, frame.getArgTaint(4)); } if (pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.wrappedFieldOffset, value); + adapter.putObjectVolatile(o, pair.wrappedFieldOffset, x); } } } return ret; } - @Mask(owner = Unsafe.class) - public static boolean compareAndSwapObject( - Unsafe unsafe, Object o, long offset, Object expected, Object x, PhosphorStackFrame frame) { - return false; - } - @Mask(owner = Unsafe.class) public static boolean getBoolean(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return false; - } - - public static boolean getBoolean(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getBoolean(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getBoolean(obj, offset); - } - } - - public static boolean getBooleanVolatile( - UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getBooleanVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getBooleanVolatile(obj, offset); - } + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getBoolean(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static boolean getBooleanVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return false; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getBooleanVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static byte getByte(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static byte getByte(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getByte(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getByte(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static byte getByte(Unsafe unsafe, long address, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getByte(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static byte getByteVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static byte getByteVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getByteVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getByteVolatile(obj, offset); - } + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getByteVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static char getChar(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static char getChar(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getChar(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getChar(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static char getChar(Unsafe unsafe, long address, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getChar(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static char getCharVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static char getCharVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getCharVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getCharVolatile(obj, offset); - } + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getCharVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static double getDouble(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static double getDouble(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getDouble(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getDouble(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static double getDouble(Unsafe unsafe, long address, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getDouble(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static double getDoubleVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static double getDoubleVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getDoubleVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getDoubleVolatile(obj, offset); - } + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getDoubleVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static float getFloat(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static float getFloat(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getFloat(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getFloat(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static float getFloat(Unsafe unsafe, long address, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getFloat(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static float getFloatVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static float getFloatVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getFloatVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getFloatVolatile(obj, offset); - } + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getFloatVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static int getInt(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static int getInt(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getInt(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getInt(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static int getInt(Unsafe unsafe, long address, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getInt(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static int getIntVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static int getIntVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getIntVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getIntVolatile(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static int getLoadAverage(Unsafe unsafe, double[] loadavg, int nelems, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getIntVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static long getLong(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static long getLong(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getLong(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getLong(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static long getLong(Unsafe unsafe, long address, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getLong(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static long getLongVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static long getLongVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getLongVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getLongVolatile(obj, offset); - } + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getLongVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static short getShort(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static short getShort(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getShort(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - return unsafe.getShort(obj, offset); - } - } - - @Mask(owner = Unsafe.class) - public static short getShort(Unsafe unsafe, long address, PhosphorStackFrame frame) { - return 0; + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + return adapter.getShort(unwrap(0), offset); } @Mask(owner = Unsafe.class) public static short getShortVolatile(Unsafe unsafe, Object o, long offset, PhosphorStackFrame frame) { - return 0; - } - - public static short getShortVolatile(UnsafeProxy unsafe, Object obj, long offset, PhosphorStackFrame stackFrame) { - if (obj instanceof TaggedArray) { - stackFrame.returnTaint = - ((TaggedArray) obj).getTaintOrEmpty(unsafeIndexFor(unsafe, (TaggedArray) obj, offset)); - return unsafe.getShortVolatile(((TaggedArray) obj).getVal(), offset); - } else { - getTag(unsafe, obj, offset, stackFrame, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.VOLATILE); - return unsafe.getShortVolatile(obj, offset); - } - } - - public static void copyMemory( - UnsafeProxy unsafe, - Object src, - long srcAddress, - Object dest, - long destAddress, - long length, - PhosphorStackFrame stackFrame) { - if (src instanceof TaggedArray) { - src = ((TaggedArray) src).getVal(); - } - if (dest instanceof TaggedArray) { - dest = ((TaggedArray) dest).getVal(); - } - unsafe.copyMemory(src, srcAddress, dest, destAddress, length); - } - - public static void copyMemory( - UnsafeProxy unsafe, long srcAddress, long destAddress, long length, PhosphorStackFrame stackFrame) { - unsafe.copyMemory(srcAddress, destAddress, length); + getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return adapter.getShortVolatile(unwrap(0), offset); } @Mask(owner = Unsafe.class) @@ -534,475 +215,244 @@ public static void copyMemory( long destOffset, long bytes, PhosphorStackFrame frame) { - // + adapter.copyMemory(unwrap(srcBase), srcOffset, unwrap(destBase), destOffset, bytes); } - public void copyMemory(Unsafe unsafe, long var1, long var3, long var5, PhosphorStackFrame frame) { - copyMemory(unsafe, null, var1, null, var3, var5, frame); - } - - public static void putBoolean( - UnsafeProxy unsafe, Object obj, long offset, boolean val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putBoolean(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putBoolean(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + @Mask(owner = Unsafe.class) + public static void copyMemory( + Unsafe unsafe, long srcAddress, long destAddress, long length, PhosphorStackFrame frame) { + adapter.copyMemory(srcAddress, destAddress, length); } @Mask(owner = Unsafe.class) public static void putBoolean(Unsafe unsafe, Object o, long offset, boolean x, PhosphorStackFrame frame) { - // - } - - public static void putBooleanVolatile( - UnsafeProxy unsafe, Object obj, long offset, boolean val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putBooleanVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putBoolean(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + adapter.putBoolean(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putBooleanVolatile(Unsafe unsafe, Object o, long offset, boolean x, PhosphorStackFrame frame) { - // + adapter.putBooleanVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putByte(Unsafe unsafe, Object o, long offset, byte x, PhosphorStackFrame frame) { - // - } - - public static void putByte(UnsafeProxy unsafe, Object obj, long offset, byte val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putByte(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putByte(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } - } - - @Mask(owner = Unsafe.class) - public static void putByte(Unsafe unsafe, long address, byte x, PhosphorStackFrame frame) { - // - } - - public static void putByteVolatile( - UnsafeProxy unsafe, Object obj, long offset, byte val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putByteVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putByte(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + adapter.putByte(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putByteVolatile(Unsafe unsafe, Object o, long offset, byte x, PhosphorStackFrame frame) { - // + adapter.putByteVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putChar(Unsafe unsafe, Object o, long offset, char x, PhosphorStackFrame frame) { - // - } - - public static void putChar(UnsafeProxy unsafe, Object obj, long offset, char val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putChar(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putChar(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } - } - - @Mask(owner = Unsafe.class) - public static void putChar(Unsafe unsafe, long address, char x, PhosphorStackFrame frame) { - // - } - - public static void putCharVolatile( - UnsafeProxy unsafe, Object obj, long offset, char val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putCharVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putChar(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + adapter.putChar(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putCharVolatile(Unsafe unsafe, Object o, long offset, char x, PhosphorStackFrame frame) { - // - } - - public static void putDouble( - UnsafeProxy unsafe, Object obj, long offset, double val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putDouble(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putDouble(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + adapter.putCharVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putDouble(Unsafe unsafe, Object o, long offset, double x, PhosphorStackFrame frame) { - // - } - - @Mask(owner = Unsafe.class) - public static void putDouble(Unsafe unsafe, long address, double x, PhosphorStackFrame frame) { - // - } - - public static void putDoubleVolatile( - UnsafeProxy unsafe, Object obj, long offset, double val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putDoubleVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putDouble(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + adapter.putDouble(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putDoubleVolatile(Unsafe unsafe, Object o, long offset, double x, PhosphorStackFrame frame) { - // + adapter.putDoubleVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putFloat(Unsafe unsafe, Object o, long offset, float x, PhosphorStackFrame frame) { - // - } - - public static void putFloat(UnsafeProxy unsafe, Object obj, long offset, float val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putFloat(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putFloat(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } - } - - @Mask(owner = Unsafe.class) - public static void putFloat(Unsafe unsafe, long address, float x, PhosphorStackFrame frame) { - // - } - - public static void putFloatVolatile( - UnsafeProxy unsafe, Object obj, long offset, float val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putFloatVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putFloat(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + adapter.putFloat(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putFloatVolatile(Unsafe unsafe, Object o, long offset, float x, PhosphorStackFrame frame) { - // + adapter.putFloatVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putInt(Unsafe unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { - // - } - - public static void putInt(UnsafeProxy unsafe, Object obj, long offset, int val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putInt(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putInt(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + adapter.putInt(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) - public static void putInt(Unsafe unsafe, long address, int x, PhosphorStackFrame frame) { - // + public static void putIntVolatile(Unsafe unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { + adapter.putIntVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } - public static void putIntVolatile( - UnsafeProxy unsafe, Object obj, long offset, int val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putIntVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putInt(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + @Mask(owner = Unsafe.class) + public static void putLong(Unsafe unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { + adapter.putLong(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) - public static void putIntVolatile(Unsafe unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { - // + public static void putLongVolatile(Unsafe unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { + adapter.putLongVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) - public static void putLong(Unsafe unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { - // + public static void putObject(Unsafe unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { + putObject(o, offset, x, frame, SpecialAccessPolicy.NONE); } - public static void putLong(UnsafeProxy unsafe, Object obj, long offset, long val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putLong(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putLong(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + @Mask(owner = Unsafe.class) + public static void putObjectVolatile(Unsafe unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { + putObject(o, offset, x, frame, SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) - public static void putLong(Unsafe unsafe, long address, long x, PhosphorStackFrame frame) { - // + public static void putOrderedInt(Unsafe unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { + adapter.putOrderedInt(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.ORDERED); } - public static void putLongVolatile( - UnsafeProxy unsafe, Object obj, long offset, long val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putLongVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putLong(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } + @Mask(owner = Unsafe.class) + public static void putOrderedLong(Unsafe unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { + adapter.putOrderedLong(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.ORDERED); } @Mask(owner = Unsafe.class) - public static void putLongVolatile(Unsafe unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { - // + public static void putOrderedObject(Unsafe unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { + putObject(o, offset, x, frame, SpecialAccessPolicy.ORDERED); } - public static void putObject( - UnsafeProxy unsafe, Object obj, long offset, Object val, PhosphorStackFrame phosphorStackFrame) { - if (obj instanceof TaggedReferenceArray) { - ((TaggedReferenceArray) obj) - .set(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), val, phosphorStackFrame.getArgTaint(3)); - } else { - RuntimeJDKInternalUnsafePropagator.OffsetPair pair = null; - if (obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if (pair != null) { - if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObject(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(3)); - } - if (pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObject(obj, pair.wrappedFieldOffset, val); - unsafe.putObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } else { - unsafe.putObject(obj, offset, val); - } - } else { - unsafe.putObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } - } + @Mask(owner = Unsafe.class) + public static void putShort(Unsafe unsafe, Object o, long offset, short x, PhosphorStackFrame frame) { + adapter.putShort(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) - public static void putObject(Unsafe unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { - // + public static void putShortVolatile(Unsafe unsafe, Object o, long offset, short x, PhosphorStackFrame frame) { + adapter.putShortVolatile(unwrap(o), offset, x); + putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } - public static void putObjectVolatile( - UnsafeProxy unsafe, Object obj, long offset, Object val, PhosphorStackFrame phosphorStackFrame) { - if (obj instanceof TaggedReferenceArray) { - ((TaggedReferenceArray) obj) - .set(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), val, phosphorStackFrame.getArgTaint(3)); + private static void getTagPrimitive(Object o, long offset, PhosphorStackFrame frame, SpecialAccessPolicy policy) { + if (o instanceof TaggedArray) { + TaggedArray array = (TaggedArray) o; + int index = getArrayIndex(adapter, array, offset); + frame.returnTaint = array.getTaintOrEmpty(index); } else { - unsafe.putObjectVolatile(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - RuntimeJDKInternalUnsafePropagator.OffsetPair pair = null; - if (obj != null) { - pair = getOffsetPair(unsafe, obj, offset); - } - if (pair != null) { - if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(3)); - } - if (pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putObjectVolatile(obj, pair.wrappedFieldOffset, val); - unsafe.putObjectVolatile(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } else { - unsafe.putObjectVolatile(obj, offset, val); - } - } else { - unsafe.putObjectVolatile(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); - } + getTag(adapter, o, offset, frame, policy); } } - @Mask(owner = Unsafe.class) - public static void putObjectVolatile(Unsafe unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { - // - } - - public static void putOrderedInt( - UnsafeProxy unsafe, Object obj, long offset, int val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putOrderedInt(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } + private static void putTagPrimitive(Object o, long offset, Taint valTaint, SpecialAccessPolicy policy) { + if (o instanceof TaggedArray) { + TaggedArray array = (TaggedArray) o; + int index = getArrayIndex(adapter, array, offset); + array.setTaint(index, valTaint); } else { - unsafe.putOrderedInt(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.ORDERED); + putTag(adapter, o, offset, valTaint, policy); } } - @Mask(owner = Unsafe.class) - public static void putOrderedInt(Unsafe unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { - // + private static void putObject(Object o, long offset, Object x, SpecialAccessPolicy policy) { + switch (policy) { + case NONE: + adapter.putObject(o, offset, x); + return; + case VOLATILE: + adapter.putObjectVolatile(o, offset, x); + return; + default: + throw new IllegalArgumentException(); + } } - public static void putOrderedLong( - UnsafeProxy unsafe, Object obj, long offset, long val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putOrderedLong(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } + private static Object getObjectPolicy(Object o, long offset, PhosphorStackFrame frame, SpecialAccessPolicy policy) { + if (o instanceof TaggedReferenceArray) { + // Push the taint from the `offset` argument to the `idx` argument for get + TaggedReferenceArray array = (TaggedReferenceArray) o; + int index = getArrayIndex(adapter, array, offset); + return array.get(index, frame.getArgTaint(1), frame); } else { - unsafe.putOrderedLong(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.ORDERED); + // Is this trying to return a field that is wrapped? + RuntimeJDKInternalUnsafePropagator.OffsetPair pair = getOffsetPair(adapter, o, offset); + if (pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { + offset = pair.wrappedFieldOffset; + } + getTag(adapter, o, offset, frame, policy); + switch (policy) { + case NONE: + return adapter.getObject(o, offset); + case VOLATILE: + return adapter.getObjectVolatile(o, offset); + default: + throw new IllegalArgumentException(); + } } } - @Mask(owner = Unsafe.class) - public static void putOrderedLong(Unsafe unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { - // - } - - public static void putOrderedObject( - UnsafeProxy unsafe, Object obj, long offset, Object val, PhosphorStackFrame phosphorStackFrame) { - if (obj instanceof TaggedReferenceArray) { - ((TaggedReferenceArray) obj) - .set(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), val, phosphorStackFrame.getArgTaint(3)); + private static void putObject( + Object o, long offset, Object x, PhosphorStackFrame frame, SpecialAccessPolicy policy) { + if (o instanceof TaggedReferenceArray) { + TaggedReferenceArray array = (TaggedReferenceArray) o; + int index = getArrayIndex(adapter, array, offset); + array.set(index, x, frame.getArgTaint(3)); } else { RuntimeJDKInternalUnsafePropagator.OffsetPair pair = null; - if (obj != null) { - pair = getOffsetPair(unsafe, obj, offset); + if (o != null) { + pair = getOffsetPair(adapter, o, offset); } if (pair != null) { if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putOrderedObject(obj, pair.tagFieldOffset, phosphorStackFrame.getArgTaint(3)); + putObject(o, pair.tagFieldOffset, frame.getArgTaint(3), policy); } if (pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - unsafe.putOrderedObject(obj, pair.wrappedFieldOffset, val); - unsafe.putOrderedObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); + putObject(o, pair.wrappedFieldOffset, x, policy); + putObject(o, offset, MultiDArrayUtils.unbox1DOrNull(x), policy); } else { - unsafe.putOrderedObject(obj, offset, val); + putObject(o, offset, x, policy); } } else { - unsafe.putOrderedObject(obj, offset, MultiDArrayUtils.unbox1DOrNull(val)); + putObject(o, offset, MultiDArrayUtils.unbox1DOrNull(x), policy); } } } - @Mask(owner = Unsafe.class) - public static void putOrderedObject(Unsafe unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { - // - } - - @Mask(owner = Unsafe.class) - public static void putShort(Unsafe unsafe, Object o, long offset, short x, PhosphorStackFrame frame) { - // - } - - public static void putShort(UnsafeProxy unsafe, Object obj, long offset, short val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putShort(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); - } - } else { - unsafe.putShort(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); - } - } - - @Mask(owner = Unsafe.class) - public static void putShort(Unsafe unsafe, long address, short x, PhosphorStackFrame frame) { - // - } - - public static void putShortVolatile( - UnsafeProxy unsafe, Object obj, long offset, short val, PhosphorStackFrame stackFrame) { - Taint valTaint = stackFrame.getArgTaint(3); - if (obj instanceof TaggedArray) { - unsafe.putShortVolatile(((TaggedArray) obj).getVal(), offset, val); - if ((valTaint != null && !valTaint.isEmpty()) || ((TaggedArray) obj).taints != null) { - ((TaggedArray) obj).setTaint(unsafeIndexFor(unsafe, (TaggedArray) obj, offset), valTaint); + private static boolean swapTag(Object o, long offset, PhosphorStackFrame frame, boolean swap) { + if (swap) { + if (o instanceof TaggedArray) { + Taint valueTaint = frame.getArgTaint(4); + TaggedArray array = (TaggedArray) o; + if (array.getVal() != null && array.getVal().getClass().isArray()) { + int index = getArrayIndex(adapter, array, offset); + array.setTaint(index, valueTaint); + } + } else if (o != null) { + RuntimeJDKInternalUnsafePropagator.OffsetPair pair = getOffsetPair(adapter, o, offset); + if (pair != null) { + if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { + adapter.putObjectVolatile(o, pair.tagFieldOffset, frame.getArgTaint(4)); + } + } } - } else { - unsafe.putShort(obj, offset, val); - putTag(unsafe, obj, offset, valTaint, RuntimeSunMiscUnsafePropagator.SpecialAccessPolicy.NONE); } + return swap; } - @Mask(owner = Unsafe.class) - public static void putShortVolatile(Unsafe unsafe, Object o, long offset, short x, PhosphorStackFrame frame) { - // + private static Object unwrap(Object object) { + return object instanceof TaggedArray ? ((TaggedArray) object).getVal() : object; } } \ No newline at end of file diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeAdapter.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeAdapter.java index fa53df1de..d9275111e 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeAdapter.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeAdapter.java @@ -1,10 +1,122 @@ package edu.columbia.cs.psl.phosphor.runtime.mask; +import java.lang.reflect.Field; import java.security.ProtectionDomain; -public class UnsafeAdapter { - public Class defineClass(String name, byte[] b, int off, int len, ClassLoader loader, - ProtectionDomain protectionDomain) { - return null; - } +@SuppressWarnings("unused") +public interface UnsafeAdapter { + long getInvalidFieldOffset(); + + int getInt(Object o, long offset); + + void putInt(Object o, long offset, int x); + + boolean getBoolean(Object o, long offset); + + void putBoolean(Object o, long offset, boolean x); + + byte getByte(Object o, long offset); + + void putByte(Object o, long offset, byte x); + + short getShort(Object o, long offset); + + void putShort(Object o, long offset, short x); + + char getChar(Object o, long offset); + + void putChar(Object o, long offset, char x); + + long getLong(Object o, long offset); + + void putLong(Object o, long offset, long x); + + float getFloat(Object o, long offset); + + void putFloat(Object o, long offset, float x); + + double getDouble(Object o, long offset); + + void putDouble(Object o, long offset, double x); + + byte getByte(long address); + + short getShort(long address); + + char getChar(long address); + + int getInt(long address); + + long getLong(long address); + + float getFloat(long address); + + double getDouble(long address); + + void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes); + + void copyMemory(long srcAddress, long destAddress, long bytes); + + long objectFieldOffset(Field f); + + long staticFieldOffset(Field f); + + int arrayBaseOffset(Class arrayClass); + + int arrayIndexScale(Class arrayClass); + + Class defineClass( + String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain); + + int getIntVolatile(Object o, long offset); + + void putIntVolatile(Object o, long offset, int x); + + boolean getBooleanVolatile(Object o, long offset); + + void putBooleanVolatile(Object o, long offset, boolean x); + + byte getByteVolatile(Object o, long offset); + + void putByteVolatile(Object o, long offset, byte x); + + short getShortVolatile(Object o, long offset); + + void putShortVolatile(Object o, long offset, short x); + + char getCharVolatile(Object o, long offset); + + void putCharVolatile(Object o, long offset, char x); + + long getLongVolatile(Object o, long offset); + + void putLongVolatile(Object o, long offset, long x); + + float getFloatVolatile(Object o, long offset); + + void putFloatVolatile(Object o, long offset, float x); + + double getDoubleVolatile(Object o, long offset); + + void putDoubleVolatile(Object o, long offset, double x); + + Object getObject(Object o, long offset); + + Object getObjectVolatile(Object o, long offset); + + void putObject(Object o, long offset, Object x); + + void putObjectVolatile(Object o, long offset, Object x); + + boolean compareAndSwapObject(Object obj, long offset, Object expected, Object value); + + void putOrderedObject(Object obj, long offset, Object val); + + boolean compareAndSwapInt(Object val, long offset, int expected, int value); + + boolean compareAndSwapLong(Object val, long offset, long expected, long value); + + void putOrderedInt(Object obj, long offset, int val); + + void putOrderedLong(Object obj, long offset, long val); } diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeMaskerHelper.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeMaskerHelper.java new file mode 100644 index 000000000..930805bdf --- /dev/null +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeMaskerHelper.java @@ -0,0 +1,193 @@ +package edu.columbia.cs.psl.phosphor.runtime.mask; + +import edu.columbia.cs.psl.phosphor.Configuration; +import edu.columbia.cs.psl.phosphor.TaintUtils; +import edu.columbia.cs.psl.phosphor.runtime.PhosphorStackFrame; +import edu.columbia.cs.psl.phosphor.runtime.RuntimeJDKInternalUnsafePropagator.OffsetPair; +import edu.columbia.cs.psl.phosphor.runtime.Taint; +import edu.columbia.cs.psl.phosphor.runtime.proxied.InstrumentedJREFieldHelper; +import edu.columbia.cs.psl.phosphor.struct.SinglyLinkedList; +import edu.columbia.cs.psl.phosphor.struct.TaggedArray; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +/** + * Ensures that calls methods in Unsafe that set or retrieve the value of a field of a Java heap object set and + * retrieve both the original field and its associated taint field if it has one. + */ +public class UnsafeMaskerHelper { + private UnsafeMaskerHelper() { + // Prevents this class from being instantiated + } + + public static final UnsafeAdapter ADAPTER = new SunUnsafeAdapter(); + /* Used to disambiguate between a static field of a given type and an instance field of java.lang.Class */ + static long LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS = ADAPTER.getInvalidFieldOffset(); + + /* Stores pairs containing the offset of an original, non-static primitive or primitive array field for the specified + * class and the offset of the tag field associated with that original field. */ + private static SinglyLinkedList getOffsetPairs(UnsafeAdapter unsafe, Class targetClazz) { + SinglyLinkedList list = new SinglyLinkedList<>(); + for (Class clazz = targetClazz; + clazz != null && !Object.class.equals(clazz); + clazz = clazz.getSuperclass()) { + for (Field field : clazz.getDeclaredFields()) { + try { + Class fieldClazz = field.getType(); + boolean isStatic = Modifier.isStatic(field.getModifiers()); + long fieldOffset = (isStatic ? unsafe.staticFieldOffset(field) : unsafe.objectFieldOffset(field)); + long tagOffset = ADAPTER.getInvalidFieldOffset(); + long wrapperOffset = ADAPTER.getInvalidFieldOffset(); + try { + if (!field.getName().equals("SPECIES_DATA")) { + Field taintField = clazz.getField(field.getName() + TaintUtils.TAINT_FIELD); + if (taintField.getType().equals(Configuration.TAINT_TAG_OBJ_CLASS)) { + tagOffset = (isStatic + ? unsafe.staticFieldOffset(taintField) + : unsafe.objectFieldOffset(taintField)); + } + } + } catch (Exception e) { + // + } + if (fieldClazz.isArray()) { + try { + Field taintField = clazz.getField(field.getName() + TaintUtils.TAINT_WRAPPER_FIELD); + Class taintClazz = taintField.getType(); + if (TaggedArray.class.isAssignableFrom(taintClazz)) { + wrapperOffset = (isStatic + ? unsafe.staticFieldOffset(taintField) + : unsafe.objectFieldOffset(taintField)); + } + } catch (Exception e) { + // + } + } + list.enqueue(new OffsetPair(isStatic, fieldOffset, wrapperOffset, tagOffset)); + } catch (Exception e) { + // + } + } + } + return list; + } + + /* returns an offset pair for the specified object's class where either the original field offset or the tag field + * offset matches the specified offset or null if such an offset pair could not be found. */ + public static OffsetPair getOffsetPair(UnsafeAdapter unsafe, Object o, long offset) { + try { + Class cl = null; + boolean isStatic = false; + if (o instanceof Class) { + // We MIGHT be accessing a static field of this class, in which case we should take + // the offset from *this* class instance (o). + // But we might also be accessing an instance field of the type Class, in which case we want to use + // the classes's class. + if (LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS == ADAPTER.getInvalidFieldOffset()) { + findLastInstanceFieldOnJavaLangClass(unsafe); + } + if (offset > LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS) { + /* We are not accessing an instance field of java.lang.Class, hence, we must be accessing + * a static field of type (Class) o */ + cl = (Class) o; + isStatic = true; + } + /* Otherwise, we are accessing an instance field of java.lang.Class */ + } + if (cl == null && o != null) { + cl = o.getClass(); + } + if (cl != null) { + if (InstrumentedJREFieldHelper.get$$PHOSPHOR_OFFSET_CACHE(cl) == null) { + InstrumentedJREFieldHelper.set$$PHOSPHOR_OFFSET_CACHE(cl, getOffsetPairs(unsafe, cl)); + } + for (OffsetPair pair : InstrumentedJREFieldHelper.get$$PHOSPHOR_OFFSET_CACHE(cl)) { + if (pair.origFieldOffset == offset && pair.isStatic == isStatic) { + return pair; + } + } + } + return null; + } catch (Exception e) { + return null; + } + } + + private static void findLastInstanceFieldOnJavaLangClass(UnsafeAdapter adapter) { + for (Field field : Class.class.getDeclaredFields()) { + try { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + long fieldOffset = adapter.objectFieldOffset(field); + if (fieldOffset > LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS) { + LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS = fieldOffset; + } + } catch (Exception e) { + // + } + } + } + + /** + * If prealloc is a wrapped primitive type, set it's taint to be the value of the field at the specified offset + * in the other specified object. + * Otherwise returns the value of the field at the specified offset in the specified object. + */ + public static void getTag( + UnsafeAdapter unsafe, + Object obj, + long originalOffset, + PhosphorStackFrame stackFrame, + SpecialAccessPolicy policy) { + stackFrame.returnTaint = Taint.emptyTaint(); + OffsetPair pair = getOffsetPair(unsafe, obj, originalOffset); + if (pair != null && pair.tagFieldOffset != ADAPTER.getInvalidFieldOffset()) { + Object result = (policy == SpecialAccessPolicy.VOLATILE) + ? unsafe.getObjectVolatile(obj, pair.tagFieldOffset) + : unsafe.getObject(obj, pair.tagFieldOffset); + if (result instanceof Taint) { + stackFrame.returnTaint = (Taint) result; + } + } + } + + /** + * If the specified Object value is a wrapped primitive type, puts it's taint into the field at the specified offset in the + * other specified object. Otherwise if the specified Object value is null or a lazy array wrapper put the specified Object + * value into the field at the specified offset in the other specified object. + */ + public static void putTag(UnsafeAdapter unsafe, Object obj, long offset, Taint tag, SpecialAccessPolicy policy) { + OffsetPair pair = null; + if (obj != null) { + pair = getOffsetPair(unsafe, obj, offset); + } + if (pair != null) { + switch (policy) { + case ORDERED: + unsafe.putOrderedObject(obj, pair.tagFieldOffset, tag); + break; + case VOLATILE: + unsafe.putObjectVolatile(obj, pair.tagFieldOffset, tag); + break; + default: + unsafe.putObject(obj, pair.tagFieldOffset, tag); + } + } + } + + public static int getArrayIndex(UnsafeAdapter unsafe, TaggedArray array, long offset) { + Class clazz = array.getVal().getClass(); + long baseOffset = unsafe.arrayBaseOffset(clazz); + long scale = unsafe.arrayIndexScale(clazz); + // Calculate the index based off the offset + return (int) ((offset - baseOffset) / scale); + } + + public enum SpecialAccessPolicy { + VOLATILE, + ORDERED, + NONE + } +} diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/jdk/unsupported/UnsafeProxy.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeProxy.java similarity index 99% rename from Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/jdk/unsupported/UnsafeProxy.java rename to Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeProxy.java index a2f98c7a0..d741a3452 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/jdk/unsupported/UnsafeProxy.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/runtime/mask/UnsafeProxy.java @@ -1,4 +1,4 @@ -package edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported; +package edu.columbia.cs.psl.phosphor.runtime.mask; import java.lang.reflect.Field; import java.security.ProtectionDomain; diff --git a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/struct/TaggedArray.java b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/struct/TaggedArray.java index bd2191890..aa4f8a2a1 100644 --- a/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/struct/TaggedArray.java +++ b/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/struct/TaggedArray.java @@ -85,7 +85,10 @@ public Taint getTaintOrEmpty(int idx) { } public void setTaint(int idx, Taint valTaint) { - if(taints == null) { + if (Taint.isEmpty(valTaint) && taints == null) { + return; + } + if (taints == null) { taints = new Taint[getLength()]; } taints[idx] = valTaint; diff --git a/README.md b/README.md index 1aefaf035..e8c2081ab 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,6 @@ If you choose, you can also use the Phosphor driver to instrument you applicatio application. This step is optional; Phosphor will dynamically instrument any classes not already instrumented at runtime as they are loaded by the JVM. -If you plan to run these classes in a Java 8 JVM, you **must** add `-java8` to the list of options passed to the driver. If you want to Phosphor to cache classes that are dynamically instrumented, then you can add the Java option `-DphosphorCacheDirectory=` when running your application, where <CACHE-DIRECTORY> is the file path to the directory where Phosphor should store the cached instrumented class files. diff --git a/phosphor-driver/src/main/java/edu/columbia/cs/psl/phosphor/driver/PhosphorInstrumentation.java b/phosphor-driver/src/main/java/edu/columbia/cs/psl/phosphor/driver/PhosphorInstrumentation.java index 809485056..6ff8082fb 100644 --- a/phosphor-driver/src/main/java/edu/columbia/cs/psl/phosphor/driver/PhosphorInstrumentation.java +++ b/phosphor-driver/src/main/java/edu/columbia/cs/psl/phosphor/driver/PhosphorInstrumentation.java @@ -1,8 +1,11 @@ package edu.columbia.cs.psl.phosphor.driver; -import edu.columbia.cs.psl.phosphor.*; -import edu.columbia.cs.psl.phosphor.agent.InstrumentUtil; +import edu.columbia.cs.psl.phosphor.Configuration; +import edu.columbia.cs.psl.phosphor.PCLoggingTransformer; +import edu.columbia.cs.psl.phosphor.Phosphor; +import edu.columbia.cs.psl.phosphor.PhosphorOption; import edu.columbia.cs.psl.phosphor.agent.EmbeddedPhosphorPatcher; +import edu.columbia.cs.psl.phosphor.agent.InstrumentUtil; import edu.columbia.cs.psl.phosphor.instrumenter.TaintTrackingClassVisitor; import edu.columbia.cs.psl.phosphor.org.apache.commons.cli.CommandLine; @@ -46,9 +49,7 @@ public void initialize(CommandLine line) throws IOException { transformer = new PCLoggingTransformer(); classPathElements = new HashSet<>(); classPathElements.add(InstrumentUtil.getClassPathElement(Phosphor.class)); - configurationClasses.stream() - .map(InstrumentUtil::getClassPathElement) - .forEach(classPathElements::add); + configurationClasses.stream().map(InstrumentUtil::getClassPathElement).forEach(classPathElements::add); } @Override @@ -63,7 +64,7 @@ public byte[] apply(byte[] classFileBuffer) { @Override public Patcher createPatcher(Function entryLocator) { - String path = "/java.base/jdk/internal/misc/Unsafe.class"; + String path = "/java.base/jdk/internal/misc/Unsafe.class"; EmbeddedPhosphorPatcher patcher = new EmbeddedPhosphorPatcher(entryLocator.apply(path)); return patcher::patch; }