changeset 12134:cdfb600c2dce jdk8u102-b05

Merge
author asaha
date Mon, 23 May 2016 08:49:22 -0700
parents 47e20a90bdbb (current diff) 78376dde5cc3 (diff)
children ced91280e78a
files .hgtags
diffstat 15 files changed, 251 insertions(+), 126 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Apr 25 09:33:15 2016 -0700
+++ b/.hgtags	Mon May 23 08:49:22 2016 -0700
@@ -389,6 +389,7 @@
 d4453d784fb6c52e4ed998b167588551e2fd43c5 jdk8u40-b27
 5a45234e0fc14ff943e13dc1f8966818acaeb4de jdk8u40-b31
 d8ac13c5eafe422d3425dc1aebebfcdf8ca67e2d jdk8u40-b32
+c7fbbf6133c339fb56f03241de28666774023d5d jdk8u40-b33
 1ecc234bd38950a2bc047aa253a5e803f0836a4e jdk8u45-b00
 e0c7864bbca3f76cde680722f2ae58dff2bff61d jdk8u45-b01
 9505c0392cddbfb905401e9fccc23262edc3254f jdk8u45-b02
@@ -534,17 +535,26 @@
 d841d3fdae44f120883dab0a3a809a054cd0274b jdk8u72-b13
 f6d24d424cd2af4d2612f7737d3d9a25f58b882d jdk8u72-b14
 f3e86cc607260bae368b52d88d7bc8883ee767e3 jdk8u72-b15
+1d4b343084874b1afa1cdd504b9b1e50bab7f121 jdk8u72-b31
 892eb9ab179650b89b7bab6bc42f079391c98624 jdk8u73-b00
 9b77d3ca0d66a117c3cc0e0a74b8059545b22f0e jdk8u73-b01
 2ab13901d6f14bab0dcf4823d5e378a421fba7e2 jdk8u73-b02
 9a843dc6f959f62c61014a3a71ec9aa329f1daf1 jdk8u74-b00
 e829ab80dfd828803aa8837411900faeaa1254a5 jdk8u74-b01
 32c49f4a16599e376e4e46bb33c7bcc486e52ff3 jdk8u74-b02
+9c828e688240362b6f1b761b619cdaa070462c4e jdk8u74-b31
+6968ca30f8fdc9429fcd56187e16f46b215b474b jdk8u74-b32
+02e1209648050922a5a9f2789d9d359795f6f834 jdk8u77-b00
+f08584a0fde9344b0aa4766984266ca68b9a5018 jdk8u77-b01
+1a3e81c05703bb36def80a57681e1692c866f621 jdk8u77-b02
+c44179bce874a97e93ffd7b76a226af417e017a4 jdk8u77-b03
+8c3f4e540348daed7263bae092b0e5f212478b00 jdk8u77-b31
 1d4b343084874b1afa1cdd504b9b1e50bab7f121 jdk8u72-b31
 7cfd2c51c501df909833aa0fb6e40c50c61621ed jdk8u75-b00
 9e00a43602f87930c2318b2567002871ad9c59dd jdk8u75-b01
 9de301db625bb1b462aad3ebd8347118b94bb728 jdk8u75-b02
 dcacefa73649a2d821267b6bff1d70aa10a06801 jdk8u75-b03
+f6cc9dbb5db5883385c91bb71ca02081220aaf3d jdk8u101-b00
 de91f05824c5398cb2d2f666ff404aaa165498de jdk8u75-b04
 4138b3f27ffea524185a604c3f4f149c7e5ba780 jdk8u75-b05
 32f64c19b5fba8beeae5236ca6e480bd8e99698a jdk8u75-b06
@@ -557,6 +567,7 @@
 f08584a0fde9344b0aa4766984266ca68b9a5018 jdk8u77-b01
 1a3e81c05703bb36def80a57681e1692c866f621 jdk8u77-b02
 c44179bce874a97e93ffd7b76a226af417e017a4 jdk8u77-b03
+8c3f4e540348daed7263bae092b0e5f212478b00 jdk8u77-b31
 71f59a00df6c8f3bd5c6d6631a4988a431adab56 jdk8u91-b00
 7ade7a1ab10ff893f62cce9440b4a839aa19c250 jdk8u91-b13
 f8725698a870b6be82fad578e78a55910b259975 jdk8u91-b14
@@ -576,6 +587,13 @@
 ea965fea71f612d65013192aa637d88e05915b10 jdk8u92-b00
 cc8d0d6c6f9543120836e70e0aa3fa9c9b6fe0f3 jdk8u92-b13
 4f06a20cdc59ce9742e6538ff4b9040baba0778a jdk8u92-b14
+5875e297cfcf18304b4b062dc44fa9be312ad6e8 jdk8u92-b31
+f6cc9dbb5db5883385c91bb71ca02081220aaf3d jdk8u81-b00
+00f8f39308687cde45f23282871c46cc6c2f10b3 jdk8u101-b01
+6042757c329b1b96fa6bc931e09306794f5c50c0 jdk8u101-b02
+25934d0d38fe10383ff22eb3f39bf5e8b9e73ac9 jdk8u101-b03
+ebc56c2e803597ef409a5296addc986b390d934d jdk8u101-b04
+c387bd2fb7db40467bd9aa803c8510a04ca32bae jdk8u101-b05
 39baa472e20c13c0eb1243eb5dce589e82f78143 jdk8u76-b00
 6ea3aea950d19d803475b3f4d704a2942e71b302 jdk8u76-b01
 4de4cffb5988cd68959ce4bbd14c6d4547078c91 jdk8u76-b02
--- a/src/share/classes/com/sun/crypto/provider/AESCipher.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/com/sun/crypto/provider/AESCipher.java	Mon May 23 08:49:22 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -172,6 +172,11 @@
      */
     private final int fixedKeySize; // in bytes, -1 if no restriction
 
+    /*
+     * needed to enforce ISE thrown when updateAAD is called after update for GCM mode.
+     */
+    private boolean updateCalled;
+
     /**
      * Creates an instance of AES cipher with default ECB mode and
      * PKCS5Padding.
@@ -304,6 +309,7 @@
     protected void engineInit(int opmode, Key key, SecureRandom random)
         throws InvalidKeyException {
         checkKeySize(key, fixedKeySize);
+        updateCalled = false;
         core.init(opmode, key, random);
     }
 
@@ -336,6 +342,7 @@
                               SecureRandom random)
         throws InvalidKeyException, InvalidAlgorithmParameterException {
         checkKeySize(key, fixedKeySize);
+        updateCalled = false;
         core.init(opmode, key, params, random);
     }
 
@@ -344,6 +351,7 @@
                               SecureRandom random)
         throws InvalidKeyException, InvalidAlgorithmParameterException {
         checkKeySize(key, fixedKeySize);
+        updateCalled = false;
         core.init(opmode, key, params, random);
     }
 
@@ -368,6 +376,7 @@
      */
     protected byte[] engineUpdate(byte[] input, int inputOffset,
                                   int inputLen) {
+        updateCalled = true;
         return core.update(input, inputOffset, inputLen);
     }
 
@@ -397,6 +406,7 @@
     protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
                                byte[] output, int outputOffset)
         throws ShortBufferException {
+        updateCalled = true;
         return core.update(input, inputOffset, inputLen, output,
                            outputOffset);
     }
@@ -433,7 +443,9 @@
      */
     protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
         throws IllegalBlockSizeException, BadPaddingException {
-        return core.doFinal(input, inputOffset, inputLen);
+        byte[] out = core.doFinal(input, inputOffset, inputLen);
+        updateCalled = false;
+        return out;
     }
 
     /**
@@ -476,8 +488,10 @@
                                 byte[] output, int outputOffset)
         throws IllegalBlockSizeException, ShortBufferException,
                BadPaddingException {
-        return core.doFinal(input, inputOffset, inputLen, output,
-                            outputOffset);
+        int outLen = core.doFinal(input, inputOffset, inputLen, output,
+                                  outputOffset);
+        updateCalled = false;
+        return outLen;
     }
 
     /**
@@ -574,6 +588,9 @@
      */
     @Override
     protected void engineUpdateAAD(byte[] src, int offset, int len) {
+        if (core.getMode() == CipherCore.GCM_MODE && updateCalled) {
+            throw new IllegalStateException("AAD must be supplied before encryption/decryption starts");
+        }
         core.updateAAD(src, offset, len);
     }
 
@@ -606,6 +623,9 @@
      */
     @Override
     protected void engineUpdateAAD(ByteBuffer src) {
+        if (core.getMode() == CipherCore.GCM_MODE && updateCalled) {
+            throw new IllegalStateException("AAD must be supplied before encryption/decryption starts");
+        }
         if (src != null) {
             int aadLen = src.limit() - src.position();
             if (aadLen != 0) {
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java	Mon May 23 08:49:22 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -124,7 +124,7 @@
     private static final int PCBC_MODE = 4;
     private static final int CTR_MODE = 5;
     private static final int CTS_MODE = 6;
-    private static final int GCM_MODE = 7;
+    static final int GCM_MODE = 7;
 
     /*
      * variables used for performing the GCM (key+iv) uniqueness check.
@@ -196,7 +196,7 @@
             cipher = new CounterMode(rawImpl);
             unitBytes = 1;
             padding = null;
-        }  else if (modeUpperCase.startsWith("GCM")) {
+        }  else if (modeUpperCase.equals("GCM")) {
             // can only be used for block ciphers w/ 128-bit block size
             if (blockSize != 16) {
                 throw new NoSuchAlgorithmException
@@ -223,6 +223,15 @@
         }
     }
 
+    /**
+     * Returns the mode of this cipher.
+     *
+     * @return the parsed cipher mode
+     */
+    int getMode() {
+        return cipherMode;
+    }
+
     private static int getNumOfUnit(String mode, int offset, int blockSize)
         throws NoSuchAlgorithmException {
         int result = blockSize; // use blockSize as default value
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Mon May 23 08:49:22 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,16 @@
     static int DEFAULT_TAG_LEN = AES_BLOCK_SIZE;
     static int DEFAULT_IV_LEN = 12; // in bytes
 
+    // In NIST SP 800-38D, GCM input size is limited to be no longer
+    // than (2^36 - 32) bytes. Otherwise, the counter will wrap
+    // around and lead to a leak of plaintext.
+    // However, given the current GCM spec requirement that recovered
+    // text can only be returned after successful tag verification,
+    // we are bound by limiting the data size to the size limit of
+    // java byte array, e.g. Integer.MAX_VALUE, since all data
+    // can only be returned by the doFinal(...) call.
+    private static final int MAX_BUF_SIZE = Integer.MAX_VALUE;
+
     // buffer for AAD data; if null, meaning update has been called
     private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
     private int sizeOfAAD = 0;
@@ -89,9 +99,13 @@
         }
     }
 
-    // ivLen in bits
-    private static byte[] getLengthBlock(int ivLen) {
+    private static byte[] getLengthBlock(int ivLenInBytes) {
+        long ivLen = ((long)ivLenInBytes) << 3;
         byte[] out = new byte[AES_BLOCK_SIZE];
+        out[8] = (byte)(ivLen >>> 56);
+        out[9] = (byte)(ivLen >>> 48);
+        out[10] = (byte)(ivLen >>> 40);
+        out[11] = (byte)(ivLen >>> 32);
         out[12] = (byte)(ivLen >>> 24);
         out[13] = (byte)(ivLen >>> 16);
         out[14] = (byte)(ivLen >>> 8);
@@ -99,13 +113,22 @@
         return out;
     }
 
-    // aLen and cLen both in bits
-    private static byte[] getLengthBlock(int aLen, int cLen) {
+    private static byte[] getLengthBlock(int aLenInBytes, int cLenInBytes) {
+        long aLen = ((long)aLenInBytes) << 3;
+        long cLen = ((long)cLenInBytes) << 3;
         byte[] out = new byte[AES_BLOCK_SIZE];
+        out[0] = (byte)(aLen >>> 56);
+        out[1] = (byte)(aLen >>> 48);
+        out[2] = (byte)(aLen >>> 40);
+        out[3] = (byte)(aLen >>> 32);
         out[4] = (byte)(aLen >>> 24);
         out[5] = (byte)(aLen >>> 16);
         out[6] = (byte)(aLen >>> 8);
         out[7] = (byte)aLen;
+        out[8] = (byte)(cLen >>> 56);
+        out[9] = (byte)(cLen >>> 48);
+        out[10] = (byte)(cLen >>> 40);
+        out[11] = (byte)(cLen >>> 32);
         out[12] = (byte)(cLen >>> 24);
         out[13] = (byte)(cLen >>> 16);
         out[14] = (byte)(cLen >>> 8);
@@ -142,13 +165,20 @@
             } else {
                 g.update(iv);
             }
-            byte[] lengthBlock = getLengthBlock(iv.length*8);
+            byte[] lengthBlock = getLengthBlock(iv.length);
             g.update(lengthBlock);
             j0 = g.digest();
         }
         return j0;
     }
 
+    private static void checkDataLength(int processed, int len) {
+        if (processed > MAX_BUF_SIZE - len) {
+            throw new ProviderException("SunJCE provider only supports " +
+                "input size up to " + MAX_BUF_SIZE + " bytes");
+        }
+    }
+
     GaloisCounterMode(SymmetricCipher embeddedCipher) {
         super(embeddedCipher);
         aadBuffer = new ByteArrayOutputStream();
@@ -319,20 +349,22 @@
 
     // Feed the AAD data to GHASH, pad if necessary
     void processAAD() {
-        if (aadBuffer != null && aadBuffer.size() > 0) {
-            byte[] aad = aadBuffer.toByteArray();
-            sizeOfAAD = aad.length;
-            aadBuffer = null;
+        if (aadBuffer != null) {
+            if (aadBuffer.size() > 0) {
+                byte[] aad = aadBuffer.toByteArray();
+                sizeOfAAD = aad.length;
 
-            int lastLen = aad.length % AES_BLOCK_SIZE;
-            if (lastLen != 0) {
-                ghashAllToS.update(aad, 0, aad.length - lastLen);
-                byte[] padded = expandToOneBlock(aad, aad.length - lastLen,
-                                                 lastLen);
-                ghashAllToS.update(padded);
-            } else {
-                ghashAllToS.update(aad);
+                int lastLen = aad.length % AES_BLOCK_SIZE;
+                if (lastLen != 0) {
+                    ghashAllToS.update(aad, 0, aad.length - lastLen);
+                    byte[] padded = expandToOneBlock(aad, aad.length - lastLen,
+                                                     lastLen);
+                    ghashAllToS.update(padded);
+                } else {
+                    ghashAllToS.update(aad);
+                }
             }
+            aadBuffer = null;
         }
     }
 
@@ -386,6 +418,8 @@
      * @param outOfs the offset in <code>out</code>
      */
     int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
+        checkDataLength(processed, len);
+
         processAAD();
         if (len > 0) {
             gctrPAndC.update(in, inOfs, len, out, outOfs);
@@ -410,17 +444,23 @@
      */
     int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
         throws IllegalBlockSizeException, ShortBufferException {
+        if (len > MAX_BUF_SIZE - tagLenBytes) {
+            throw new ShortBufferException
+                ("Can't fit both data and tag into one buffer");
+        }
         if (out.length - outOfs < (len + tagLenBytes)) {
             throw new ShortBufferException("Output buffer too small");
         }
 
+        checkDataLength(processed, len);
+
         processAAD();
         if (len > 0) {
             doLastBlock(in, inOfs, len, out, outOfs, true);
         }
 
         byte[] lengthBlock =
-            getLengthBlock(sizeOfAAD*8, processed*8);
+            getLengthBlock(sizeOfAAD, processed);
         ghashAllToS.update(lengthBlock);
         byte[] s = ghashAllToS.digest();
         byte[] sOut = new byte[s.length];
@@ -454,6 +494,8 @@
      * @param outOfs the offset in <code>out</code>
      */
     int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
+        checkDataLength(ibuffer.size(), len);
+
         processAAD();
 
         if (len > 0) {
@@ -488,10 +530,21 @@
         if (len < tagLenBytes) {
             throw new AEADBadTagException("Input too short - need tag");
         }
+        // do this check here can also catch the potential integer overflow
+        // scenario for the subsequent output buffer capacity check.
+        checkDataLength(ibuffer.size(), (len - tagLenBytes));
+
         if (out.length - outOfs < ((ibuffer.size() + len) - tagLenBytes)) {
             throw new ShortBufferException("Output buffer too small");
         }
+
         processAAD();
+
+        // get the trailing tag bytes from 'in'
+        byte[] tag = new byte[tagLenBytes];
+        System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
+        len -= tagLenBytes;
+
         if (len != 0) {
             ibuffer.write(in, inOfs, len);
         }
@@ -502,17 +555,12 @@
         len = in.length;
         ibuffer.reset();
 
-        byte[] tag = new byte[tagLenBytes];
-        // get the trailing tag bytes from 'in'
-        System.arraycopy(in, len - tagLenBytes, tag, 0, tagLenBytes);
-        len -= tagLenBytes;
-
         if (len > 0) {
             doLastBlock(in, inOfs, len, out, outOfs, false);
         }
 
         byte[] lengthBlock =
-            getLengthBlock(sizeOfAAD*8, processed*8);
+            getLengthBlock(sizeOfAAD, processed);
         ghashAllToS.update(lengthBlock);
 
         byte[] s = ghashAllToS.digest();
--- a/src/share/classes/com/sun/jmx/remote/security/JMXSubjectDomainCombiner.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/com/sun/jmx/remote/security/JMXSubjectDomainCombiner.java	Mon May 23 08:49:22 2016 -0700
@@ -81,7 +81,7 @@
      * A ProtectionDomain with a null CodeSource and an empty permission set.
      */
     private static final ProtectionDomain pdNoPerms =
-        new ProtectionDomain(nullCodeSource, new Permissions());
+        new ProtectionDomain(nullCodeSource, new Permissions(), null, null);
 
     /**
      * Get the current AccessControlContext combined with the supplied subject.
--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java	Mon May 23 08:49:22 2016 -0700
@@ -158,7 +158,7 @@
     private static LambdaForm preparedLambdaForm(MemberName m) {
         assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
         MethodType mtype = m.getInvocationType().basicType();
-        assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m;
+        assert(!m.isMethodHandleInvoke()) : m;
         int which;
         switch (m.getReferenceKind()) {
         case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
--- a/src/share/classes/java/lang/invoke/LambdaForm.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/java/lang/invoke/LambdaForm.java	Mon May 23 08:49:22 2016 -0700
@@ -1034,7 +1034,7 @@
             this.member = member;
             this.resolvedHandle = resolvedHandle;
              // The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest.
-             //assert(!isInvokeBasic());
+             //assert(!isInvokeBasic(member));
         }
         NamedFunction(MethodType basicInvokerType) {
             assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType;
@@ -1045,13 +1045,13 @@
                 // necessary to pass BigArityTest
                 this.member = Invokers.invokeBasicMethod(basicInvokerType);
             }
-            assert(isInvokeBasic());
+            assert(isInvokeBasic(member));
         }
 
-        private boolean isInvokeBasic() {
+        private static boolean isInvokeBasic(MemberName member) {
             return member != null &&
-                   member.isMethodHandleInvoke() &&
-                   "invokeBasic".equals(member.getName());
+                   member.getDeclaringClass() == MethodHandle.class &&
+                  "invokeBasic".equals(member.getName());
         }
 
         // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
@@ -1191,7 +1191,7 @@
             assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
                     : Arrays.asList(mh, rtype, arity);
             MemberName member = mh.internalMemberName();
-            if (member != null && member.getName().equals("invokeBasic") && member.isMethodHandleInvoke()) {
+            if (isInvokeBasic(member)) {
                 assert(arity > 0);
                 assert(a[0] instanceof MethodHandle);
                 MethodHandle mh2 = (MethodHandle) a[0];
--- a/src/share/classes/java/lang/invoke/MemberName.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/java/lang/invoke/MemberName.java	Mon May 23 08:49:22 2016 -0700
@@ -341,7 +341,6 @@
     }
 
     /** Utility method to query if this member is a method handle invocation (invoke or invokeExact).
-     *  Also returns true for the non-public MH.invokeBasic.
      */
     public boolean isMethodHandleInvoke() {
         final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC;
@@ -356,7 +355,6 @@
         switch (name) {
         case "invoke":
         case "invokeExact":
-        case "invokeBasic":  // internal sig-poly method
             return true;
         default:
             return false;
--- a/src/share/classes/java/lang/invoke/MethodHandles.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java	Mon May 23 08:49:22 2016 -0700
@@ -864,8 +864,6 @@
                 return invoker(type);
             if ("invokeExact".equals(name))
                 return exactInvoker(type);
-            if ("invokeBasic".equals(name))
-                return basicInvoker(type);
             assert(!MemberName.isMethodHandleInvokeName(name));
             return null;
         }
--- a/src/share/classes/java/security/ProtectionDomain.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/java/security/ProtectionDomain.java	Mon May 23 08:49:22 2016 -0700
@@ -475,6 +475,11 @@
                         }
                     };
                 }
+
+                @Override
+                public boolean getStaticPermissionsField(ProtectionDomain pd) {
+                    return pd.staticPermissions;
+                }
             });
     }
 }
--- a/src/share/classes/javax/security/auth/SubjectDomainCombiner.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/javax/security/auth/SubjectDomainCombiner.java	Mon May 23 08:49:22 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,8 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 import java.lang.ref.WeakReference;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaSecurityProtectionDomainAccess;
 
 /**
  * A {@code SubjectDomainCombiner} updates ProtectionDomains
@@ -65,6 +67,9 @@
     private static final boolean allowCaching =
                                         (useJavaxPolicy && cachePolicy());
 
+    private static final JavaSecurityProtectionDomainAccess pdAccess =
+        SharedSecrets.getJavaSecurityProtectionDomainAccess();
+
     /**
      * Associate the provided {@code Subject} with this
      * {@code SubjectDomainCombiner}.
@@ -239,10 +244,16 @@
                 subjectPd = cachedPDs.getValue(pd);
 
                 if (subjectPd == null) {
-                    subjectPd = new ProtectionDomain(pd.getCodeSource(),
+                    if (pdAccess.getStaticPermissionsField(pd)) {
+                        // Need to keep static ProtectionDomain objects static
+                        subjectPd = new ProtectionDomain(pd.getCodeSource(),
+                                                pd.getPermissions());
+                    } else {
+                        subjectPd = new ProtectionDomain(pd.getCodeSource(),
                                                 pd.getPermissions(),
                                                 pd.getClassLoader(),
                                                 principals);
+                    }
                     cachedPDs.putValue(pd, subjectPd);
                 } else {
                     allNew = false;
@@ -341,60 +352,63 @@
                 ProtectionDomain subjectPd = cachedPDs.getValue(pd);
 
                 if (subjectPd == null) {
-
-                    // XXX
-                    // we must first add the original permissions.
-                    // that way when we later add the new JAAS permissions,
-                    // any unresolved JAAS-related permissions will
-                    // automatically get resolved.
+                    if (pdAccess.getStaticPermissionsField(pd)) {
+                        // keep static ProtectionDomain objects static
+                        subjectPd = new ProtectionDomain(pd.getCodeSource(),
+                                                pd.getPermissions());
+                    } else {
+                        // XXX
+                        // we must first add the original permissions.
+                        // that way when we later add the new JAAS permissions,
+                        // any unresolved JAAS-related permissions will
+                        // automatically get resolved.
 
-                    // get the original perms
-                    Permissions perms = new Permissions();
-                    PermissionCollection coll = pd.getPermissions();
-                    java.util.Enumeration<Permission> e;
-                    if (coll != null) {
-                        synchronized (coll) {
-                            e = coll.elements();
-                            while (e.hasMoreElements()) {
-                                Permission newPerm =
+                        // get the original perms
+                        Permissions perms = new Permissions();
+                        PermissionCollection coll = pd.getPermissions();
+                        java.util.Enumeration<Permission> e;
+                        if (coll != null) {
+                            synchronized (coll) {
+                                e = coll.elements();
+                                while (e.hasMoreElements()) {
+                                    Permission newPerm =
                                         e.nextElement();
-                                 perms.add(newPerm);
+                                    perms.add(newPerm);
+                                }
                             }
                         }
-                    }
-
-                    // get perms from the policy
 
-                    final java.security.CodeSource finalCs = pd.getCodeSource();
-                    final Subject finalS = subject;
-                    PermissionCollection newPerms =
-                        java.security.AccessController.doPrivileged
-                        (new PrivilegedAction<PermissionCollection>() {
-                        @SuppressWarnings("deprecation")
-                        public PermissionCollection run() {
-                          return
-                          javax.security.auth.Policy.getPolicy().getPermissions
-                                (finalS, finalCs);
-                        }
-                    });
+                        // get perms from the policy
+                        final java.security.CodeSource finalCs = pd.getCodeSource();
+                        final Subject finalS = subject;
+                        PermissionCollection newPerms =
+                            java.security.AccessController.doPrivileged
+                            (new PrivilegedAction<PermissionCollection>() {
+                            @SuppressWarnings("deprecation")
+                            public PermissionCollection run() {
+                                return
+                                    javax.security.auth.Policy.getPolicy().getPermissions
+                                    (finalS, finalCs);
+                            }
+                        });
 
-                    // add the newly granted perms,
-                    // avoiding duplicates
-                    synchronized (newPerms) {
-                        e = newPerms.elements();
-                        while (e.hasMoreElements()) {
-                            Permission newPerm = e.nextElement();
-                            if (!perms.implies(newPerm)) {
-                                perms.add(newPerm);
-                                if (debug != null)
-                                    debug.println (
-                                        "Adding perm " + newPerm + "\n");
+                        // add the newly granted perms,
+                        // avoiding duplicates
+                        synchronized (newPerms) {
+                            e = newPerms.elements();
+                            while (e.hasMoreElements()) {
+                                Permission newPerm = e.nextElement();
+                                if (!perms.implies(newPerm)) {
+                                    perms.add(newPerm);
+                                    if (debug != null)
+                                        debug.println (
+                                            "Adding perm " + newPerm + "\n");
+                                }
                             }
                         }
+                        subjectPd = new ProtectionDomain
+                            (finalCs, perms, pd.getClassLoader(), principals);
                     }
-                    subjectPd = new ProtectionDomain
-                        (finalCs, perms, pd.getClassLoader(), principals);
-
                     if (allowCaching)
                         cachedPDs.putValue(pd, subjectPd);
                 }
--- a/src/share/classes/sun/misc/JavaSecurityProtectionDomainAccess.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/share/classes/sun/misc/JavaSecurityProtectionDomainAccess.java	Mon May 23 08:49:22 2016 -0700
@@ -36,4 +36,9 @@
      * Returns the ProtectionDomainCache.
      */
     ProtectionDomainCache getProtectionDomainCache();
+
+    /**
+     * Returns the staticPermissions field of the specified object
+     */
+    boolean getStaticPermissionsField(ProtectionDomain pd);
 }
--- a/src/windows/classes/sun/nio/ch/PipeImpl.java	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/windows/classes/sun/nio/ch/PipeImpl.java	Mon May 23 08:49:22 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
+import java.security.SecureRandom;
 import java.util.Random;
 
 
@@ -47,24 +48,16 @@
 class PipeImpl
     extends Pipe
 {
+    // Number of bytes in the secret handshake.
+    private static final int NUM_SECRET_BYTES = 16;
+
+    // Random object for handshake values
+    private static final Random RANDOM_NUMBER_GENERATOR = new SecureRandom();
 
     // Source and sink channels
     private SourceChannel source;
     private SinkChannel sink;
 
-    // Random object for handshake values
-    private static final Random rnd;
-
-    static {
-        byte[] someBytes = new byte[8];
-        boolean resultOK = IOUtil.randomBytes(someBytes);
-        if (resultOK) {
-            rnd = new Random(ByteBuffer.wrap(someBytes).getLong());
-        } else {
-            rnd = new Random();
-        }
-    }
-
     private class Initializer
         implements PrivilegedExceptionAction<Void>
     {
@@ -112,6 +105,10 @@
                 SocketChannel sc2 = null;
 
                 try {
+                    // Create secret with a backing array.
+                    ByteBuffer secret = ByteBuffer.allocate(NUM_SECRET_BYTES);
+                    ByteBuffer bb = ByteBuffer.allocate(NUM_SECRET_BYTES);
+
                     // Loopback address
                     InetAddress lb = InetAddress.getByName("127.0.0.1");
                     assert(lb.isLoopbackAddress());
@@ -128,18 +125,22 @@
                         // Establish connection (assume connections are eagerly
                         // accepted)
                         sc1 = SocketChannel.open(sa);
-                        ByteBuffer bb = ByteBuffer.allocate(8);
-                        long secret = rnd.nextLong();
-                        bb.putLong(secret).flip();
-                        sc1.write(bb);
+                        RANDOM_NUMBER_GENERATOR.nextBytes(secret.array());
+                        do {
+                            sc1.write(secret);
+                        } while (secret.hasRemaining());
+                        secret.rewind();
 
                         // Get a connection and verify it is legitimate
                         sc2 = ssc.accept();
-                        bb.clear();
-                        sc2.read(bb);
+                        do {
+                            sc2.read(bb);
+                        } while (bb.hasRemaining());
                         bb.rewind();
-                        if (bb.getLong() == secret)
+
+                        if (bb.equals(secret))
                             break;
+
                         sc2.close();
                         sc1.close();
                     }
--- a/src/windows/native/sun/windows/awt_Font.cpp	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/windows/native/sun/windows/awt_Font.cpp	Mon May 23 08:49:22 2016 -0700
@@ -256,7 +256,7 @@
 
     AwtFont* awtFont = NULL;
     jobjectArray compFont = NULL;
-    int cfnum;
+    int cfnum = 0;
 
     try {
         if (env->EnsureLocalCapacity(3) < 0)
@@ -264,7 +264,9 @@
 
         if (IsMultiFont(env, font)) {
             compFont = GetComponentFonts(env, font);
-            cfnum = env->GetArrayLength(compFont);
+            if (compFont != NULL) {
+                cfnum = env->GetArrayLength(compFont);
+            }
         } else {
             compFont = NULL;
             cfnum = 0;
@@ -614,7 +616,9 @@
 
     if (IsMultiFont(env, font)) {
         array = GetComponentFonts(env, font);
-        num = env->GetArrayLength(array);
+        if (array != NULL) {
+            num = env->GetArrayLength(array);
+        }
     } else {
         array = NULL;
         num = 0;
@@ -672,14 +676,16 @@
 
     if (IsMultiFont(env, font)) {
         jobject peer = env->CallObjectMethod(font, AwtFont::peerMID);
-        array =  (jobjectArray)(env->CallObjectMethod(
-        peer, AwtFont::makeConvertedMultiFontStringMID, str));
-        DASSERT(!safe_ExceptionOccurred(env));
+        if (peer != NULL) {
+            array = (jobjectArray)(env->CallObjectMethod(
+            peer, AwtFont::makeConvertedMultiFontStringMID, str));
+            DASSERT(!safe_ExceptionOccurred(env));
 
-        if (array != NULL) {
-            arrayLength = env->GetArrayLength(array);
+            if (array != NULL) {
+                arrayLength = env->GetArrayLength(array);
+            }
+            env->DeleteLocalRef(peer);
         }
-        env->DeleteLocalRef(peer);
     } else {
         array = NULL;
         arrayLength = 0;
--- a/src/windows/native/sun/windows/awt_Font.h	Mon Apr 25 09:33:15 2016 -0700
+++ b/src/windows/native/sun/windows/awt_Font.h	Mon May 23 08:49:22 2016 -0700
@@ -230,11 +230,14 @@
     INLINE static jobjectArray GetComponentFonts(JNIEnv *env,
                                                      jobject font) {
       jobject platformFont = env->CallObjectMethod(font, AwtFont::peerMID);
-      jobjectArray result =
-          (jobjectArray)(env->GetObjectField(platformFont,
-                                             AwtFont::componentFontsID));
-      env->DeleteLocalRef(platformFont);
-      return result;
+      if (platformFont != NULL) {
+          jobjectArray result =
+              (jobjectArray)(env->GetObjectField(platformFont,
+                                                 AwtFont::componentFontsID));
+          env->DeleteLocalRef(platformFont);
+          return result;
+      }
+      return NULL;
     }
 
    /*