From efd20e61ae06fbbd15af58cac93bf6eeaeb6418e Mon Sep 17 00:00:00 2001 From: katherine-hough <32645020+katherine-hough@users.noreply.github.com> Date: Wed, 29 Nov 2023 12:05:08 -0500 Subject: [PATCH] * Refactored * Fixed missing mask from SunUnsafeMasker --- .../columbia/cs/psl/phosphor/Phosphor.java | 10 +- .../runtime/mask/JdkUnsafeAdapter.java | 5 + .../runtime/mask/SunUnsafeAdapter.java | 5 + .../runtime/mask/SunUnsafeMasker.java | 194 +++++---------- .../phosphor/runtime/mask/UnsafeAdapter.java | 2 + .../runtime/mask/UnsafeMaskerHelper.java | 232 ++++++++++-------- 6 files changed, 210 insertions(+), 238 deletions(-) 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 3debb85fe..8549b1ebb 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 @@ -42,13 +42,15 @@ public static InstrumentationAdaptor getInstrumentation() { } @InvokedViaInstrumentation(record = TaintMethodRecord.INSTRUMENT_CLASS_BYTES) - public static byte[] instrumentClassBytes(byte[] in) { - return new PCLoggingTransformer().transform(null, null, null, null, in, false); + public static byte[] instrumentClassBytes(byte[] classFileBuffer) { + byte[] result = new PCLoggingTransformer().transform(null, null, null, null, classFileBuffer, false); + return result == null ? classFileBuffer : result; } @InvokedViaInstrumentation(record = TaintMethodRecord.INSTRUMENT_CLASS_BYTES_ANONYMOUS) - public static byte[] instrumentClassBytesAnonymous(byte[] in) { - return new PCLoggingTransformer().transform(null, null, null, null, in, true); + public static byte[] instrumentClassBytesAnonymous(byte[] classFileBuffer) { + byte[] result = new PCLoggingTransformer().transform(null, null, null, null, classFileBuffer, true); + return result == null ? classFileBuffer : result; } private static String[] parseOptions(String agentArgs) { 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 index f3c6d80f2..b9b37db0e 100644 --- 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 @@ -18,6 +18,11 @@ public long getInvalidFieldOffset() { return Unsafe.INVALID_FIELD_OFFSET; } + @Override + public Class defineAnonymousClass(Class hostClass, byte[] data, Object[] cpPatches) { + return unsafe.defineAnonymousClass(hostClass, data, cpPatches); + } + @Override public Class defineClass( String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) { 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 index 39eab02cb..97b3f5437 100644 --- 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 @@ -25,6 +25,11 @@ private static Class defineClass( return null; } + @Override + public Class defineAnonymousClass(Class hostClass, byte[] data, Object[] cpPatches) { + return unsafe.defineAnonymousClass(hostClass, data, cpPatches); + } + @Override public Class defineClass( String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) { 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 f7fbbc9e9..932a1652f 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 @@ -15,7 +15,11 @@ @SuppressWarnings("unused") public final class SunUnsafeMasker { - private static final UnsafeAdapter ADAPTER = UnsafeMaskerHelper.ADAPTER; + @Mask(owner = Unsafe.class) + public static Class defineAnonymousClass(Object unsafe, Class hostClass, byte[] data, Object[] cpPatches) { + byte[] instrumented = Phosphor.instrumentClassBytesAnonymous(data); + return ADAPTER.defineAnonymousClass(hostClass, instrumented, cpPatches); + } @Mask(owner = Unsafe.class) public static Class defineClass( @@ -38,26 +42,34 @@ public static Class defineClass( @Mask(owner = Unsafe.class) public static Object getObject(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - return getObjectPolicy(o, offset, frame, SpecialAccessPolicy.NONE); + return getObjectAndTag(o, offset, frame, SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static Object getObjectVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - return getObjectPolicy(o, offset, frame, SpecialAccessPolicy.VOLATILE); + return getObjectAndTag(o, offset, frame, SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static boolean compareAndSwapInt( Object unsafe, Object o, long offset, int expected, int x, PhosphorStackFrame frame) { + boolean result = ADAPTER.compareAndSwapInt(unwrap(o), offset, expected, x); + if (result) { + putTag(o, offset, frame.getArgTaint(4), SpecialAccessPolicy.VOLATILE); + } frame.returnTaint = Taint.emptyTaint(); - return swapTag(o, offset, frame, ADAPTER.compareAndSwapInt(unwrap(o), offset, expected, x)); + return result; } @Mask(owner = Unsafe.class) public static boolean compareAndSwapLong( Object unsafe, Object o, long offset, long expected, long x, PhosphorStackFrame frame) { + boolean result = ADAPTER.compareAndSwapLong(unwrap(o), offset, expected, x); + if (result) { + putTag(o, offset, frame.getArgTaint(4), SpecialAccessPolicy.VOLATILE); + } frame.returnTaint = Taint.emptyTaint(); - return swapTag(o, offset, frame, ADAPTER.compareAndSwapLong(unwrap(o), offset, expected, x)); + return result; } @Mask(owner = Unsafe.class) @@ -71,7 +83,7 @@ public static boolean compareAndSwapObject( ret = ADAPTER.compareAndSwapObject(array.val, offset, expected, x); if (ret) { if (array.getVal() != null && array.getVal().getClass().isArray()) { - int index = getArrayIndex(ADAPTER, (TaggedArray) o, offset); + int index = getTaggedArrayIndex((TaggedArray) o, offset); array.setTaint(index, valueTaint); } } @@ -81,7 +93,7 @@ public static boolean compareAndSwapObject( if (x instanceof TaggedArray || expected instanceof TaggedArray) { // Need to be careful - maybe we are hitting a 1D primitive array field if (o != null) { - pair = getOffsetPair(ADAPTER, o, offset); + pair = getOffsetPair(o, offset); } if (pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { // We are doing a CAS on a 1d primitive array field @@ -95,7 +107,7 @@ public static boolean compareAndSwapObject( // without unwrapping ret = ADAPTER.compareAndSwapObject(o, offset, expected, x); if (pair == null && o != null) { - pair = getOffsetPair(ADAPTER, o, offset); + pair = getOffsetPair(o, offset); } } if (pair != null && ret) { @@ -112,97 +124,97 @@ public static boolean compareAndSwapObject( @Mask(owner = Unsafe.class) public static boolean getBoolean(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getBoolean(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static boolean getBooleanVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getBooleanVolatile(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static byte getByte(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getByte(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static byte getByteVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getByteVolatile(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static char getChar(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getChar(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static char getCharVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getCharVolatile(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static double getDouble(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getDouble(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static double getDoubleVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getDoubleVolatile(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static float getFloat(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getFloat(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static float getFloatVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getFloatVolatile(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static int getInt(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getInt(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static int getIntVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getIntVolatile(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static long getLong(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getLong(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static long getLongVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getLongVolatile(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static short getShort(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.NONE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.NONE); return ADAPTER.getShort(unwrap(o), offset); } @Mask(owner = Unsafe.class) public static short getShortVolatile(Object unsafe, Object o, long offset, PhosphorStackFrame frame) { - getTagPrimitive(o, offset, frame, SpecialAccessPolicy.VOLATILE); + frame.returnTaint = getTagPrimitive(o, offset, SpecialAccessPolicy.VOLATILE); return ADAPTER.getShortVolatile(unwrap(o), offset); } @@ -227,215 +239,123 @@ public static void copyMemory( @Mask(owner = Unsafe.class) public static void putBoolean(Object unsafe, Object o, long offset, boolean x, PhosphorStackFrame frame) { ADAPTER.putBoolean(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putBooleanVolatile(Object unsafe, Object o, long offset, boolean x, PhosphorStackFrame frame) { ADAPTER.putBooleanVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putByte(Object unsafe, Object o, long offset, byte x, PhosphorStackFrame frame) { ADAPTER.putByte(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putByteVolatile(Object unsafe, Object o, long offset, byte x, PhosphorStackFrame frame) { ADAPTER.putByteVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putChar(Object unsafe, Object o, long offset, char x, PhosphorStackFrame frame) { ADAPTER.putChar(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putCharVolatile(Object unsafe, Object o, long offset, char x, PhosphorStackFrame frame) { ADAPTER.putCharVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putDouble(Object unsafe, Object o, long offset, double x, PhosphorStackFrame frame) { ADAPTER.putDouble(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putDoubleVolatile(Object unsafe, Object o, long offset, double x, PhosphorStackFrame frame) { ADAPTER.putDoubleVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putFloat(Object unsafe, Object o, long offset, float x, PhosphorStackFrame frame) { ADAPTER.putFloat(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putFloatVolatile(Object unsafe, Object o, long offset, float x, PhosphorStackFrame frame) { ADAPTER.putFloatVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putInt(Object unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { ADAPTER.putInt(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putIntVolatile(Object unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { ADAPTER.putIntVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putLong(Object unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { ADAPTER.putLong(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putLongVolatile(Object unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { ADAPTER.putLongVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putObject(Object unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { - putObject(o, offset, x, frame, SpecialAccessPolicy.NONE); + putObjectAndTag(o, offset, x, frame, SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putObjectVolatile(Object unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { - putObject(o, offset, x, frame, SpecialAccessPolicy.VOLATILE); + putObjectAndTag(o, offset, x, frame, SpecialAccessPolicy.VOLATILE); } @Mask(owner = Unsafe.class) public static void putOrderedInt(Object unsafe, Object o, long offset, int x, PhosphorStackFrame frame) { ADAPTER.putOrderedInt(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.ORDERED); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.ORDERED); } @Mask(owner = Unsafe.class) public static void putOrderedLong(Object unsafe, Object o, long offset, long x, PhosphorStackFrame frame) { ADAPTER.putOrderedLong(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.ORDERED); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.ORDERED); } @Mask(owner = Unsafe.class) public static void putOrderedObject(Object unsafe, Object o, long offset, Object x, PhosphorStackFrame frame) { - putObject(o, offset, x, frame, SpecialAccessPolicy.ORDERED); + putObjectAndTag(o, offset, x, frame, SpecialAccessPolicy.ORDERED); } @Mask(owner = Unsafe.class) public static void putShort(Object unsafe, Object o, long offset, short x, PhosphorStackFrame frame) { ADAPTER.putShort(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.NONE); } @Mask(owner = Unsafe.class) public static void putShortVolatile(Object unsafe, Object o, long offset, short x, PhosphorStackFrame frame) { ADAPTER.putShortVolatile(unwrap(o), offset, x); - putTagPrimitive(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); - } - - 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 { - getTag(ADAPTER, o, offset, frame, policy); - } - } - - 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 { - putTag(ADAPTER, o, offset, valTaint, policy); - } - } - - 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 { - // 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); - return policy.getObject(ADAPTER, o, offset); - } - } - - 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 (o != null) { - pair = getOffsetPair(ADAPTER, o, offset); - } - if (pair != null) { - if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - Object x1 = frame.getArgTaint(3); - policy.putObject(ADAPTER, o, pair.tagFieldOffset, x1); - } - if (pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { - policy.putObject(ADAPTER, o, pair.wrappedFieldOffset, x); - Object x1 = MultiDArrayUtils.unbox1DOrNull(x); - policy.putObject(ADAPTER, o, offset, x1); - } else { - policy.putObject(ADAPTER, o, offset, x); - } - } else { - Object x1 = MultiDArrayUtils.unbox1DOrNull(x); - policy.putObject(ADAPTER, o, offset, x1); - } - } - } - - 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)); - } - } - } - } - return swap; - } - - private static Object unwrap(Object object) { - return object instanceof TaggedArray ? ((TaggedArray) object).getVal() : object; + UnsafeMaskerHelper.putTag(o, offset, frame.getArgTaint(3), SpecialAccessPolicy.VOLATILE); } } \ 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 d9275111e..963364aec 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 @@ -65,6 +65,8 @@ public interface UnsafeAdapter { int arrayIndexScale(Class arrayClass); + Class defineAnonymousClass(Class hostClass, byte[] data, Object[] cpPatches); + Class defineClass( String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain); 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 index 465fc4a82..0c94aae1d 100644 --- 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 @@ -2,19 +2,23 @@ import edu.columbia.cs.psl.phosphor.Configuration; 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.SinglyLinkedList; import edu.columbia.cs.psl.phosphor.struct.TaggedArray; +import edu.columbia.cs.psl.phosphor.struct.TaggedReferenceArray; 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. + * + * Utility method for ensuring that method calls from {@link jdk.internal.misc.Unsafe} and + * {@link sun.misc.Unsafe} that set or retrieve values from fields or array operate on both the + * original value and its associated taint tag. */ public class UnsafeMaskerHelper { private UnsafeMaskerHelper() { @@ -23,48 +27,22 @@ private UnsafeMaskerHelper() { public static final UnsafeAdapter ADAPTER = Configuration.IS_JAVA_8 ? new SunUnsafeAdapter() : new JdkUnsafeAdapter(); - /* 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(); + /** + * Used to disambiguate between a static field of a given type and an instance field of java.lang.Class + */ + private 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) { + private static SinglyLinkedList getOffsetPairs(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) { - // - } - } + long fieldOffset = (isStatic ? ADAPTER.staticFieldOffset(field) : ADAPTER.objectFieldOffset(field)); + long tagOffset = getTagOffset(clazz, field, isStatic); + long wrapperOffset = getWrapperOffset(clazz, field, isStatic); list.enqueue(new OffsetPair(isStatic, fieldOffset, wrapperOffset, tagOffset)); } catch (Exception e) { // @@ -74,19 +52,49 @@ private static SinglyLinkedList getOffsetPairs(UnsafeAdapter unsafe, 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) { + private static long getTagOffset(Class clazz, Field field, boolean isStatic) { + try { + if (!field.getName().equals("SPECIES_DATA")) { + Field taintField = clazz.getField(field.getName() + TaintUtils.TAINT_FIELD); + if (Configuration.TAINT_TAG_OBJ_CLASS.equals(taintField.getType())) { + return (isStatic ? ADAPTER.staticFieldOffset(taintField) : ADAPTER.objectFieldOffset(taintField)); + } + } + } catch (Exception e) { + // + } + return ADAPTER.getInvalidFieldOffset(); + } + + private static long getWrapperOffset(Class clazz, Field field, boolean isStatic) { + if (field.getType().isArray()) { + try { + Field wrapperField = clazz.getField(field.getName() + TaintUtils.TAINT_WRAPPER_FIELD); + if (TaggedArray.class.isAssignableFrom(wrapperField.getType())) { + return (isStatic + ? ADAPTER.staticFieldOffset(wrapperField) + : ADAPTER.objectFieldOffset(wrapperField)); + } + } catch (Exception e) { + // + } + } + return ADAPTER.getInvalidFieldOffset(); + } + + public static OffsetPair getOffsetPair(Object o, long offset) { try { Class cl = null; boolean isStatic = false; - if (o instanceof Class) { + if (o == null) { + return null; + } else 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. + // the class' class. if (LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS == ADAPTER.getInvalidFieldOffset()) { - findLastInstanceFieldOnJavaLangClass(unsafe); + findLastInstanceFieldOnJavaLangClass(); } if (offset > LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS) { /* We are not accessing an instance field of java.lang.Class, hence, we must be accessing @@ -96,17 +104,15 @@ public static OffsetPair getOffsetPair(UnsafeAdapter unsafe, Object o, long offs } /* Otherwise, we are accessing an instance field of java.lang.Class */ } - if (cl == null && o != null) { + if (cl == 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; - } + if (InstrumentedJREFieldHelper.get$$PHOSPHOR_OFFSET_CACHE(cl) == null) { + InstrumentedJREFieldHelper.set$$PHOSPHOR_OFFSET_CACHE(cl, getOffsetPairs(cl)); + } + for (OffsetPair pair : InstrumentedJREFieldHelper.get$$PHOSPHOR_OFFSET_CACHE(cl)) { + if (pair.origFieldOffset == offset && pair.isStatic == isStatic) { + return pair; } } return null; @@ -115,13 +121,13 @@ public static OffsetPair getOffsetPair(UnsafeAdapter unsafe, Object o, long offs } } - private static void findLastInstanceFieldOnJavaLangClass(UnsafeAdapter adapter) { + private static void findLastInstanceFieldOnJavaLangClass() { for (Field field : Class.class.getDeclaredFields()) { try { if (Modifier.isStatic(field.getModifiers())) { continue; } - long fieldOffset = adapter.objectFieldOffset(field); + long fieldOffset = ADAPTER.objectFieldOffset(field); if (fieldOffset > LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS) { LAST_INSTANCE_OFFSET_JAVA_LANG_CLASS = fieldOffset; } @@ -131,59 +137,91 @@ private static void findLastInstanceFieldOnJavaLangClass(UnsafeAdapter adapter) } } - /** - * 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; + public static int getTaggedArrayIndex(TaggedArray array, long offset) { + Class clazz = array.getVal().getClass(); + long baseOffset = ADAPTER.arrayBaseOffset(clazz); + long scale = ADAPTER.arrayIndexScale(clazz); + // Calculate the index based off the offset + return (int) ((offset - baseOffset) / scale); + } + + public static void putTag(Object o, long offset, Taint valTaint, SpecialAccessPolicy policy) { + if (o instanceof TaggedArray) { + TaggedArray array = (TaggedArray) o; + int index = getTaggedArrayIndex(array, offset); + array.setTaint(index, valTaint); + } else { + OffsetPair pair = getOffsetPair(o, offset); + if (pair != null && pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { + policy.putObject(ADAPTER, o, pair.tagFieldOffset, valTaint); } } } - /** - * 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); + public static Taint getTag(Object o, long offset, SpecialAccessPolicy policy) { + OffsetPair pair = getOffsetPair(o, offset); + if (pair != null && pair.tagFieldOffset != ADAPTER.getInvalidFieldOffset()) { + return (Taint) policy.getObject(ADAPTER, o, pair.tagFieldOffset); + } + return Taint.emptyTaint(); + } + + public static Taint getTagPrimitive(Object o, long offset, SpecialAccessPolicy policy) { + if (o instanceof TaggedArray) { + TaggedArray array = (TaggedArray) o; + int index = getTaggedArrayIndex(array, offset); + return array.getTaintOrEmpty(index); + } else { + return getTag(o, offset, policy); } - 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 Object getObjectAndTag(Object o, long offset, PhosphorStackFrame frame, SpecialAccessPolicy policy) { + if (o instanceof TaggedReferenceArray) { + TaggedReferenceArray array = (TaggedReferenceArray) o; + int index = getTaggedArrayIndex(array, offset); + // Propagate the offset taint tag to the index + return array.get(index, frame.getArgTaint(1), frame); + } else { + // Is this trying to return a field that is wrapped? + OffsetPair pair = getOffsetPair(o, offset); + // TODO check + if (pair != null && pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { + offset = pair.wrappedFieldOffset; } + frame.returnTaint = getTag(o, offset, policy); + return policy.getObject(ADAPTER, o, offset); } } - 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 static Object unwrap(Object object) { + return object instanceof TaggedArray ? ((TaggedArray) object).getVal() : object; } + public static void putObjectAndTag( + Object o, long offset, Object x, PhosphorStackFrame frame, SpecialAccessPolicy policy) { + if (o instanceof TaggedReferenceArray) { + TaggedReferenceArray array = (TaggedReferenceArray) o; + int index = getTaggedArrayIndex(array, offset); + array.set(index, x, frame.getArgTaint(3)); + } else { + OffsetPair pair = getOffsetPair(o, offset); + if (pair != null) { + if (pair.tagFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { + Object x1 = frame.getArgTaint(3); + policy.putObject(ADAPTER, o, pair.tagFieldOffset, x1); + } + if (pair.wrappedFieldOffset != UnsafeProxy.INVALID_FIELD_OFFSET) { + policy.putObject(ADAPTER, o, pair.wrappedFieldOffset, x); + Object x1 = MultiDArrayUtils.unbox1DOrNull(x); + policy.putObject(ADAPTER, o, offset, x1); + } else { + policy.putObject(ADAPTER, o, offset, x); + } + } else { + Object x1 = MultiDArrayUtils.unbox1DOrNull(x); + policy.putObject(ADAPTER, o, offset, x1); + } + } + } }