changeset 22115:919ea5f6486a

perform null and bounds checks for crypto intrinsics
author Doug Simon <doug.simon@oracle.com>
date Mon, 29 Jun 2015 14:22:03 +0200
parents d9f3acb4a9a1
children 1ca46ed9e31a
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java
diffstat 2 files changed, 30 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Sat Jun 27 18:02:44 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Mon Jun 29 14:22:03 2015 +0200
@@ -22,11 +22,15 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.word.Word.*;
+
+import java.lang.reflect.*;
+
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.common.*;
+import jdk.internal.jvmci.meta.*;
 import sun.misc.*;
 
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
@@ -45,6 +49,7 @@
 
     static final long kOffset;
     static final Class<?> AESCryptClass;
+    static final int AES_BLOCK_SIZE;
 
     static {
         try {
@@ -53,6 +58,9 @@
             ClassLoader cl = Launcher.getLauncher().getClassLoader();
             AESCryptClass = Class.forName("com.sun.crypto.provider.AESCrypt", true, cl);
             kOffset = UnsafeAccess.unsafe.objectFieldOffset(AESCryptClass.getDeclaredField("K"));
+            Field aesBlockSizeField = Class.forName("com.sun.crypto.provider.AESConstants", true, cl).getDeclaredField("AES_BLOCK_SIZE");
+            aesBlockSizeField.setAccessible(true);
+            AES_BLOCK_SIZE = aesBlockSizeField.getInt(null);
         } catch (Exception ex) {
             throw new JVMCIError(ex);
         }
@@ -67,6 +75,7 @@
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
+        checkArgs(in, inOffset, out, outOffset);
         Object realReceiver = PiNode.piCastNonNull(rcvr, AESCryptClass);
         Object kObject = UnsafeLoadNode.load(realReceiver, kOffset, Kind.Object, LocationIdentity.any());
         Word kAddr = fromWordBase(Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte)));
@@ -79,6 +88,15 @@
         }
     }
 
+    /**
+     * Perform null and array bounds checks for arguments to a cipher operation.
+     */
+    static void checkArgs(byte[] in, int inOffset, byte[] out, int outOffset) {
+        if (UnsignedMath.aboveThan(inOffset + AES_BLOCK_SIZE, in.length) || UnsignedMath.aboveThan(outOffset + AES_BLOCK_SIZE, out.length)) {
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+    }
+
     @NodeIntrinsic(ForeignCallNode.class)
     public static native void encryptBlockStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Word key);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Sat Jun 27 18:02:44 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Mon Jun 29 14:22:03 2015 +0200
@@ -22,10 +22,11 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.meta.*;
-import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import sun.misc.*;
 
 import com.oracle.graal.api.replacements.*;
@@ -93,6 +94,7 @@
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) {
+        AESCryptSubstitutions.checkArgs(in, inOffset, out, outOffset);
         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
         Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object, LocationIdentity.any());
         Object rObject = UnsafeLoadNode.load(realReceiver, rOffset, Kind.Object, LocationIdentity.any());
@@ -107,6 +109,12 @@
         }
     }
 
+    protected static void xxx(byte[] in, int inOffset, byte[] out, int outOffset) {
+        if (UnsignedMath.aboveThan(inOffset + AESCryptSubstitutions.AES_BLOCK_SIZE, in.length) || UnsignedMath.aboveThan(outOffset + AESCryptSubstitutions.AES_BLOCK_SIZE, out.length)) {
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+    }
+
     @NodeIntrinsic(ForeignCallNode.class)
     public static native void encryptAESCryptStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Word key, Word r, int inLength);