diff --git a/.hgtags b/.hgtags
index 11089cb41c2d38c2079fac2e11460816ce7b5a9d..8d7752645ce794eb7694f3fe51f14feca7b8f333 100644
--- a/.hgtags
+++ b/.hgtags
@@ -389,6 +389,7 @@ f0d5cb59b0e6a67fa102465458cc4725c6e59089 jdk8u40-b25
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 @@ d7cc3225f1050de03b236b92e12c547f21697013 jdk8u72-b11
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 @@ e6f4eb91a1fa895c2f4520e4cca0ae6f2ca14fbb jdk8u75-b09
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 @@ cbafa4c725f9d80fd369dd7979dd97682ae284e6 jdk8u76-b09
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
diff --git a/src/share/classes/com/sun/crypto/provider/AESCipher.java b/src/share/classes/com/sun/crypto/provider/AESCipher.java
index 32cb3e39d3dfecda66dd43b930d9afde52ef2865..9d11f0091df1ad01eeec4e6503b8677941c676dd 100644
--- a/src/share/classes/com/sun/crypto/provider/AESCipher.java
+++ b/src/share/classes/com/sun/crypto/provider/AESCipher.java
@@ -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 @@ abstract class AESCipher extends CipherSpi {
*/
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 @@ abstract class AESCipher extends CipherSpi {
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 @@ abstract class AESCipher extends CipherSpi {
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
checkKeySize(key, fixedKeySize);
+ updateCalled = false;
core.init(opmode, key, params, random);
}
@@ -344,6 +351,7 @@ abstract class AESCipher extends CipherSpi {
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
checkKeySize(key, fixedKeySize);
+ updateCalled = false;
core.init(opmode, key, params, random);
}
@@ -368,6 +376,7 @@ abstract class AESCipher extends CipherSpi {
*/
protected byte[] engineUpdate(byte[] input, int inputOffset,
int inputLen) {
+ updateCalled = true;
return core.update(input, inputOffset, inputLen);
}
@@ -397,6 +406,7 @@ abstract class AESCipher extends CipherSpi {
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 @@ abstract class AESCipher extends CipherSpi {
*/
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 @@ abstract class AESCipher extends CipherSpi {
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 @@ abstract class AESCipher extends CipherSpi {
*/
@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 @@ abstract class AESCipher extends CipherSpi {
*/
@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) {
diff --git a/src/share/classes/com/sun/crypto/provider/CipherCore.java b/src/share/classes/com/sun/crypto/provider/CipherCore.java
index 408da30579cb6985dbe689d872676fb06b680418..79f66cd094e3d6e172a4949c80bcbaa6ae24fc9e 100644
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java
+++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java
@@ -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 @@ final class CipherCore {
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 @@ final class CipherCore {
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 @@ final class CipherCore {
}
}
+ /**
+ * 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
diff --git a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
index df98d9318622ee21fc57cf2c0e6b5197721e0c82..e4edbf061f3edced8b1eb8a9a9a203eb9ba1aa10 100644
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
+++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
@@ -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 @@ final class GaloisCounterMode extends FeedbackCipher {
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 @@ final class GaloisCounterMode extends FeedbackCipher {
}
}
- // 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 @@ final class GaloisCounterMode extends FeedbackCipher {
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 @@ final class GaloisCounterMode extends FeedbackCipher {
} 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 @@ final class GaloisCounterMode extends FeedbackCipher {
// 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;
-
- 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);
+ 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);
+ }
}
+ aadBuffer = null;
}
}
@@ -386,6 +418,8 @@ final class GaloisCounterMode extends FeedbackCipher {
* @param outOfs the offset in out
*/
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 @@ final class GaloisCounterMode extends FeedbackCipher {
*/
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 @@ final class GaloisCounterMode extends FeedbackCipher {
* @param outOfs the offset in out
*/
int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
+ checkDataLength(ibuffer.size(), len);
+
processAAD();
if (len > 0) {
@@ -488,10 +530,21 @@ final class GaloisCounterMode extends FeedbackCipher {
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 @@ final class GaloisCounterMode extends FeedbackCipher {
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();
diff --git a/src/share/classes/com/sun/jmx/remote/security/JMXSubjectDomainCombiner.java b/src/share/classes/com/sun/jmx/remote/security/JMXSubjectDomainCombiner.java
index 4961ac6286a67530202452b6b57602be1ee4b8b5..141a332c61c678e8faa63228c36b6b2a7b79b668 100644
--- a/src/share/classes/com/sun/jmx/remote/security/JMXSubjectDomainCombiner.java
+++ b/src/share/classes/com/sun/jmx/remote/security/JMXSubjectDomainCombiner.java
@@ -81,7 +81,7 @@ public class JMXSubjectDomainCombiner extends SubjectDomainCombiner {
* 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.
diff --git a/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/src/share/classes/java/lang/invoke/DirectMethodHandle.java
index cabd0716341678ae1b0fbe9f8471669e2d09c8e9..df3c2be141952fc9fc76d9069884d444333a7344 100644
--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java
+++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java
@@ -158,7 +158,7 @@ class DirectMethodHandle extends MethodHandle {
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;
diff --git a/src/share/classes/java/lang/invoke/LambdaForm.java b/src/share/classes/java/lang/invoke/LambdaForm.java
index 09a742f55ec01069cbc5bac896c9aca36275c330..9420d3b042e847c7e238d141cdcc46d6daf4f8d2 100644
--- a/src/share/classes/java/lang/invoke/LambdaForm.java
+++ b/src/share/classes/java/lang/invoke/LambdaForm.java
@@ -1034,7 +1034,7 @@ class LambdaForm {
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 @@ class LambdaForm {
// 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 @@ class LambdaForm {
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];
diff --git a/src/share/classes/java/lang/invoke/MemberName.java b/src/share/classes/java/lang/invoke/MemberName.java
index bcc08e71d912373b3d0aecd408c86de8c7cc5040..b2fc757390e8df67231b8783d48de96911d57370 100644
--- a/src/share/classes/java/lang/invoke/MemberName.java
+++ b/src/share/classes/java/lang/invoke/MemberName.java
@@ -341,7 +341,6 @@ import java.util.Objects;
}
/** 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 @@ import java.util.Objects;
switch (name) {
case "invoke":
case "invokeExact":
- case "invokeBasic": // internal sig-poly method
return true;
default:
return false;
diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java
index 85118904818e28d50d6ed615b3ca4987697457a4..4e8494a19b03e117a52d0d82b81e2bd9352514dd 100644
--- a/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -864,8 +864,6 @@ assertEquals("", (String) MH_newString.invokeExact());
return invoker(type);
if ("invokeExact".equals(name))
return exactInvoker(type);
- if ("invokeBasic".equals(name))
- return basicInvoker(type);
assert(!MemberName.isMethodHandleInvokeName(name));
return null;
}
diff --git a/src/share/classes/java/security/ProtectionDomain.java b/src/share/classes/java/security/ProtectionDomain.java
index b1778490f5a6dacc18e2250ff5e9999472bf5f7c..ffd2def18d108dcbd33819f34ea5cf70d90e6ad4 100644
--- a/src/share/classes/java/security/ProtectionDomain.java
+++ b/src/share/classes/java/security/ProtectionDomain.java
@@ -475,6 +475,11 @@ public class ProtectionDomain {
}
};
}
+
+ @Override
+ public boolean getStaticPermissionsField(ProtectionDomain pd) {
+ return pd.staticPermissions;
+ }
});
}
}
diff --git a/src/share/classes/javax/security/auth/SubjectDomainCombiner.java b/src/share/classes/javax/security/auth/SubjectDomainCombiner.java
index da75d68342506ca3be7584b41d79a70c08b79199..89812d28476dfda6ca221a09c24db9f5c9df7388 100644
--- a/src/share/classes/javax/security/auth/SubjectDomainCombiner.java
+++ b/src/share/classes/javax/security/auth/SubjectDomainCombiner.java
@@ -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.security.Security;
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 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
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 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
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 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
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.
-
- // get the original perms
- Permissions perms = new Permissions();
- PermissionCollection coll = pd.getPermissions();
- java.util.Enumeration e;
- if (coll != null) {
- synchronized (coll) {
- e = coll.elements();
- while (e.hasMoreElements()) {
- Permission newPerm =
+ 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 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() {
- @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");
+ // get perms from the policy
+ final java.security.CodeSource finalCs = pd.getCodeSource();
+ final Subject finalS = subject;
+ PermissionCollection newPerms =
+ java.security.AccessController.doPrivileged
+ (new PrivilegedAction() {
+ @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");
+ }
}
}
+ subjectPd = new ProtectionDomain
+ (finalCs, perms, pd.getClassLoader(), principals);
}
- subjectPd = new ProtectionDomain
- (finalCs, perms, pd.getClassLoader(), principals);
-
if (allowCaching)
cachedPDs.putValue(pd, subjectPd);
}
diff --git a/src/share/classes/sun/misc/JavaSecurityProtectionDomainAccess.java b/src/share/classes/sun/misc/JavaSecurityProtectionDomainAccess.java
index 95560ffab68210ca69a5ddc299b80e2780dc0204..3567f350f23cbc47ddfd5335840d702828db78a8 100644
--- a/src/share/classes/sun/misc/JavaSecurityProtectionDomainAccess.java
+++ b/src/share/classes/sun/misc/JavaSecurityProtectionDomainAccess.java
@@ -36,4 +36,9 @@ public interface JavaSecurityProtectionDomainAccess {
* Returns the ProtectionDomainCache.
*/
ProtectionDomainCache getProtectionDomainCache();
+
+ /**
+ * Returns the staticPermissions field of the specified object
+ */
+ boolean getStaticPermissionsField(ProtectionDomain pd);
}
diff --git a/src/windows/classes/sun/nio/ch/PipeImpl.java b/src/windows/classes/sun/nio/ch/PipeImpl.java
index b86580dccadc7d2713ca56fc4392c9710b778c59..d1052cf6489707a4cd0d84ee4c2f6fb3212fc46c 100644
--- a/src/windows/classes/sun/nio/ch/PipeImpl.java
+++ b/src/windows/classes/sun/nio/ch/PipeImpl.java
@@ -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.nio.channels.spi.*;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
+import java.security.SecureRandom;
import java.util.Random;
@@ -47,24 +48,16 @@ import java.util.Random;
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
{
@@ -112,6 +105,10 @@ class PipeImpl
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 @@ class PipeImpl
// 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();
}
diff --git a/src/windows/native/sun/windows/awt_Font.cpp b/src/windows/native/sun/windows/awt_Font.cpp
index a3d59656297d920d18f3d2e5784ac4c3fb2de206..76bdd84ffdd08d03468d68591173456e6702bbf9 100644
--- a/src/windows/native/sun/windows/awt_Font.cpp
+++ b/src/windows/native/sun/windows/awt_Font.cpp
@@ -256,7 +256,7 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale)
AwtFont* awtFont = NULL;
jobjectArray compFont = NULL;
- int cfnum;
+ int cfnum = 0;
try {
if (env->EnsureLocalCapacity(3) < 0)
@@ -264,7 +264,9 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale)
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 @@ int AwtFont::getFontDescriptorNumber(JNIEnv *env, jobject font,
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 @@ SIZE AwtFont::DrawStringSize_sub(jstring str, HDC hDC,
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;
diff --git a/src/windows/native/sun/windows/awt_Font.h b/src/windows/native/sun/windows/awt_Font.h
index 83df5e7fba21c609f70a57043b1314dbb891c889..3f4d8e6a67db624c8a2a4b3aaf5c4d69a5fdf1c9 100644
--- a/src/windows/native/sun/windows/awt_Font.h
+++ b/src/windows/native/sun/windows/awt_Font.h
@@ -230,11 +230,14 @@ public:
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;
}
/*