--- a/jdk/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, 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
@@ -179,6 +179,12 @@
throw new IllegalArgumentException(
"no SSLSocketFactory specified");
}
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkSetFactory();
+ }
+
sslSocketFactory = sf;
}
--- a/jdk/src/share/classes/java/awt/AWTKeyStroke.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/java/awt/AWTKeyStroke.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, 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
@@ -25,6 +25,7 @@
package java.awt;
import java.awt.event.KeyEvent;
+import sun.awt.AppContext;
import java.awt.event.InputEvent;
import java.util.Collections;
import java.util.HashMap;
@@ -66,9 +67,6 @@
public class AWTKeyStroke implements Serializable {
static final long serialVersionUID = -6430539691155161871L;
- private static Map cache;
- private static AWTKeyStroke cacheKey;
- private static Constructor ctor = getCtor(AWTKeyStroke.class);
private static Map modifierKeywords;
/**
* Associates VK_XXX (as a String) with code (as Integer). This is
@@ -77,6 +75,25 @@
*/
private static VKCollection vks;
+ //A key for the collection of AWTKeyStrokes within AppContext.
+ private static Object APP_CONTEXT_CACHE_KEY = new Object();
+ //A key withing the cache
+ private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke();
+
+ /*
+ * Reads keystroke class from AppContext and if null, puts there the
+ * AWTKeyStroke class.
+ * Must be called under locked AWTKeyStro
+ */
+ private static Class getAWTKeyStrokeClass() {
+ Class clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
+ if (clazz == null) {
+ clazz = AWTKeyStroke.class;
+ AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class);
+ }
+ return clazz;
+ }
+
private char keyChar = KeyEvent.CHAR_UNDEFINED;
private int keyCode = KeyEvent.VK_UNDEFINED;
private int modifiers;
@@ -164,9 +181,12 @@
if (subclass == null) {
throw new IllegalArgumentException("subclass cannot be null");
}
- if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) {
- // Already registered
- return;
+ synchronized (AWTKeyStroke.class) {
+ Class keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
+ if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){
+ // Already registered
+ return;
+ }
}
if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
throw new ClassCastException("subclass is not derived from AWTKeyStroke");
@@ -197,9 +217,9 @@
}
synchronized (AWTKeyStroke.class) {
- AWTKeyStroke.ctor = ctor;
- cache = null;
- cacheKey = null;
+ AppContext.getAppContext().put(AWTKeyStroke.class, subclass);
+ AppContext.getAppContext().remove(APP_CONTEXT_CACHE_KEY);
+ AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
}
}
@@ -229,13 +249,19 @@
private static synchronized AWTKeyStroke getCachedStroke
(char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
{
+ Map cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY);
+ AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY);
+
if (cache == null) {
cache = new HashMap();
+ AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache);
}
if (cacheKey == null) {
try {
- cacheKey = (AWTKeyStroke)ctor.newInstance((Object[]) null);
+ Class clazz = getAWTKeyStrokeClass();
+ cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null);
+ AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey);
} catch (InstantiationException e) {
assert(false);
} catch (IllegalAccessException e) {
@@ -253,9 +279,8 @@
if (stroke == null) {
stroke = cacheKey;
cache.put(stroke, stroke);
- cacheKey = null;
+ AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
}
-
return stroke;
}
--- a/jdk/src/share/classes/java/io/InputStream.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/java/io/InputStream.java Mon Nov 14 18:18:22 2011 -0800
@@ -44,10 +44,9 @@
*/
public abstract class InputStream implements Closeable {
- // SKIP_BUFFER_SIZE is used to determine the size of skipBuffer
- private static final int SKIP_BUFFER_SIZE = 2048;
- // skipBuffer is initialized in skip(long), if needed.
- private static byte[] skipBuffer;
+ // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
+ // use when skipping.
+ private static final int MAX_SKIP_BUFFER_SIZE = 2048;
/**
* Reads the next byte of data from the input stream. The value byte is
@@ -212,18 +211,15 @@
long remaining = n;
int nr;
- if (skipBuffer == null)
- skipBuffer = new byte[SKIP_BUFFER_SIZE];
-
- byte[] localSkipBuffer = skipBuffer;
if (n <= 0) {
return 0;
}
+ int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
+ byte[] skipBuffer = new byte[size];
while (remaining > 0) {
- nr = read(localSkipBuffer, 0,
- (int) Math.min(SKIP_BUFFER_SIZE, remaining));
+ nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
if (nr < 0) {
break;
}
--- a/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -347,6 +347,9 @@
* @param sf the SSL socket factory
* @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
* parameter is null.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkSetFactory</code> method does not allow
+ * a socket factory to be specified.
* @see #getSSLSocketFactory()
*/
public void setSSLSocketFactory(SSLSocketFactory sf) {
@@ -355,6 +358,10 @@
"no SSLSocketFactory specified");
}
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkSetFactory();
+ }
sslSocketFactory = sf;
}
--- a/jdk/src/share/classes/javax/net/ssl/SSLEngine.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/SSLEngine.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -538,7 +538,7 @@
* If this <code>SSLEngine</code> has not yet started its initial
* handshake, this method will automatically start the handshake.
* <P>
- * This method will attempt to produce one SSL/TLS packet, and will
+ * This method will attempt to produce SSL/TLS records, and will
* consume as much source data as possible, but will never consume
* more than the sum of the bytes remaining in each buffer. Each
* <code>ByteBuffer</code>'s position is updated to reflect the
--- a/jdk/src/share/classes/sun/net/ResourceManager.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/net/ResourceManager.java Mon Nov 14 18:18:22 2011 -0800
@@ -41,13 +41,14 @@
/* default maximum number of udp sockets per VM
* when a security manager is enabled.
- * The default is 1024 which is high enough to be useful
+ * The default is 25 which is high enough to be useful
* but low enough to be well below the maximum number
- * of port numbers actually available on all OSes for
- * such sockets (5000 on some versions of windows)
+ * of port numbers actually available on all OSes
+ * when multiplied by the maximum feasible number of VM processes
+ * that could practically be spawned.
*/
- private static final int DEFAULT_MAX_SOCKETS = 1024;
+ private static final int DEFAULT_MAX_SOCKETS = 25;
private static final int maxSockets;
private static final AtomicInteger numSockets;
--- a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java Mon Nov 14 18:18:22 2011 -0800
@@ -38,13 +38,23 @@
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Policy;
import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
import java.text.MessageFormat;
+import sun.rmi.server.LoaderHandler;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.server.UnicastServerRef2;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.ObjectTable;
import sun.rmi.transport.Target;
+import sun.security.action.GetPropertyAction;
/**
* A "registry" exists on every node that allows RMI connections to
@@ -325,6 +335,19 @@
URL[] urls = sun.misc.URLClassPath.pathToURLs(envcp);
ClassLoader cl = new URLClassLoader(urls);
+ String codebaseProperty = null;
+ String prop = java.security.AccessController.doPrivileged(
+ new GetPropertyAction("java.rmi.server.codebase"));
+ if (prop != null && prop.trim().length() > 0) {
+ codebaseProperty = prop;
+ }
+ URL[] codebaseURLs = null;
+ if (codebaseProperty != null) {
+ codebaseURLs = sun.misc.URLClassPath.pathToURLs(codebaseProperty);
+ } else {
+ codebaseURLs = new URL[0];
+ }
+
/*
* Fix bugid 4242317: Classes defined by this class loader should
* be annotated with the value of the "java.rmi.server.codebase"
@@ -334,11 +357,19 @@
Thread.currentThread().setContextClassLoader(cl);
- int regPort = Registry.REGISTRY_PORT;
- if (args.length >= 1) {
- regPort = Integer.parseInt(args[0]);
+ final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])
+ : Registry.REGISTRY_PORT;
+ try {
+ registry = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<RegistryImpl>() {
+ public RegistryImpl run() throws RemoteException {
+ return new RegistryImpl(regPort);
+ }
+ }, getAccessControlContext(codebaseURLs));
+ } catch (PrivilegedActionException ex) {
+ throw (RemoteException) ex.getException();
}
- registry = new RegistryImpl(regPort);
+
// prevent registry from exiting
while (true) {
try {
@@ -358,4 +389,48 @@
}
System.exit(1);
}
+
+ /**
+ * Generates an AccessControlContext from several URLs.
+ * The approach used here is taken from the similar method
+ * getAccessControlContext() in the sun.applet.AppletPanel class.
+ */
+ private static AccessControlContext getAccessControlContext(URL[] urls) {
+ // begin with permissions granted to all code in current policy
+ PermissionCollection perms = AccessController.doPrivileged(
+ new java.security.PrivilegedAction<PermissionCollection>() {
+ public PermissionCollection run() {
+ CodeSource codesource = new CodeSource(null,
+ (java.security.cert.Certificate[]) null);
+ Policy p = java.security.Policy.getPolicy();
+ if (p != null) {
+ return p.getPermissions(codesource);
+ } else {
+ return new Permissions();
+ }
+ }
+ });
+
+ /*
+ * Anyone can connect to the registry and the registry can connect
+ * to and possibly download stubs from anywhere. Downloaded stubs and
+ * related classes themselves are more tightly limited by RMI.
+ */
+ perms.add(new SocketPermission("*", "connect,accept"));
+
+ perms.add(new RuntimePermission("accessClassInPackage.sun.*"));
+
+ // add permissions required to load from codebase URL path
+ LoaderHandler.addPermissionsForURLs(urls, perms, false);
+
+ /*
+ * Create an AccessControlContext that consists of a single
+ * protection domain with only the permissions calculated above.
+ */
+ ProtectionDomain pd = new ProtectionDomain(
+ new CodeSource((urls.length > 0 ? urls[0] : null),
+ (java.security.cert.Certificate[]) null),
+ perms);
+ return new AccessControlContext(new ProtectionDomain[] { pd });
+ }
}
--- a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java Mon Nov 14 18:18:22 2011 -0800
@@ -1031,9 +1031,9 @@
* loader. A given permission is only added to the collection if
* it is not already implied by the collection.
*/
- private static void addPermissionsForURLs(URL[] urls,
- PermissionCollection perms,
- boolean forLoader)
+ public static void addPermissionsForURLs(URL[] urls,
+ PermissionCollection perms,
+ boolean forLoader)
{
for (int i = 0; i < urls.length; i++) {
URL url = urls[i];
--- a/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java Mon Nov 14 18:18:22 2011 -0800
@@ -390,6 +390,12 @@
ObjectInput in;
try {
in = call.getInputStream();
+ try {
+ Class<?> clazz = Class.forName("sun.rmi.transport.DGCImpl_Skel");
+ if (clazz.isAssignableFrom(skel.getClass())) {
+ ((MarshalInputStream)in).useCodebaseOnly();
+ }
+ } catch (ClassNotFoundException ignore) { }
hash = in.readLong();
} catch (Exception readEx) {
throw new UnmarshalException("error unmarshalling call header",
--- a/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, 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
@@ -69,12 +69,38 @@
// check if the Socket is invalid (error or closed)
c.checkWrite();
+ /*
+ * By default, we counter chosen plaintext issues on CBC mode
+ * ciphersuites in SSLv3/TLS1.0 by sending one byte of application
+ * data in the first record of every payload, and the rest in
+ * subsequent record(s). Note that the issues have been solved in
+ * TLS 1.1 or later.
+ *
+ * It is not necessary to split the very first application record of
+ * a freshly negotiated TLS session, as there is no previous
+ * application data to guess. To improve compatibility, we will not
+ * split such records.
+ *
+ * This avoids issues in the outbound direction. For a full fix,
+ * the peer must have similar protections.
+ */
+ boolean isFirstRecordOfThePayload = true;
+
// Always flush at the end of each application level record.
// This lets application synchronize read and write streams
// however they like; if we buffered here, they couldn't.
try {
do {
- int howmuch = Math.min(len, r.availableDataBytes());
+ int howmuch;
+ if (isFirstRecordOfThePayload && c.needToSplitPayload()) {
+ howmuch = Math.min(0x01, r.availableDataBytes());
+ } else {
+ howmuch = Math.min(len, r.availableDataBytes());
+ }
+
+ if (isFirstRecordOfThePayload && howmuch != 0) {
+ isFirstRecordOfThePayload = false;
+ }
// NOTE: *must* call c.writeRecord() even for howmuch == 0
if (howmuch > 0) {
--- a/jdk/src/share/classes/sun/security/ssl/CipherBox.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/CipherBox.java Mon Nov 14 18:18:22 2011 -0800
@@ -113,6 +113,11 @@
private SecureRandom random;
/**
+ * Is the cipher of CBC mode?
+ */
+ private final boolean isCBCMode;
+
+ /**
* Fixed masks of various block size, as the initial decryption IVs
* for TLS 1.1 or later.
*
@@ -128,6 +133,7 @@
private CipherBox() {
this.protocolVersion = ProtocolVersion.DEFAULT;
this.cipher = null;
+ this.isCBCMode = false;
}
/**
@@ -148,6 +154,7 @@
random = JsseJce.getSecureRandom();
}
this.random = random;
+ this.isCBCMode = bulkCipher.isCBCMode;
/*
* RFC 4346 recommends two algorithms used to generated the
@@ -694,4 +701,12 @@
}
}
+ /*
+ * Does the cipher use CBC mode?
+ *
+ * @return true if the cipher use CBC mode, false otherwise.
+ */
+ boolean isCBCMode() {
+ return isCBCMode;
+ }
}
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Mon Nov 14 18:18:22 2011 -0800
@@ -420,10 +420,16 @@
// exportable under 512/40 bit rules
final boolean exportable;
+ // Is the cipher algorithm of Cipher Block Chaining (CBC) mode?
+ final boolean isCBCMode;
+
BulkCipher(String transformation, int keySize,
int expandedKeySize, int ivSize, boolean allowed) {
this.transformation = transformation;
- this.algorithm = transformation.split("/")[0];
+ String[] splits = transformation.split("/");
+ this.algorithm = splits[0];
+ this.isCBCMode =
+ splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
this.description = this.algorithm + "/" + (keySize << 3);
this.keySize = keySize;
this.ivSize = ivSize;
@@ -436,7 +442,10 @@
BulkCipher(String transformation, int keySize,
int ivSize, boolean allowed) {
this.transformation = transformation;
- this.algorithm = transformation.split("/")[0];
+ String[] splits = transformation.split("/");
+ this.algorithm = splits[0];
+ this.isCBCMode =
+ splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
this.description = this.algorithm + "/" + (keySize << 3);
this.keySize = keySize;
this.ivSize = ivSize;
--- a/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -46,6 +46,7 @@
*/
final class EngineOutputRecord extends OutputRecord {
+ private SSLEngineImpl engine;
private EngineWriter writer;
private boolean finishedMsg = false;
@@ -62,6 +63,7 @@
*/
EngineOutputRecord(byte type, SSLEngineImpl engine) {
super(type, recordSize(type));
+ this.engine = engine;
writer = engine.writer;
}
@@ -227,12 +229,51 @@
* implementations are fragile and don't like to see empty
* records, so this increases robustness.
*/
- int length = Math.min(ea.getAppRemaining(), maxDataSize);
- if (length == 0) {
+ if (ea.getAppRemaining() == 0) {
return;
}
/*
+ * By default, we counter chosen plaintext issues on CBC mode
+ * ciphersuites in SSLv3/TLS1.0 by sending one byte of application
+ * data in the first record of every payload, and the rest in
+ * subsequent record(s). Note that the issues have been solved in
+ * TLS 1.1 or later.
+ *
+ * It is not necessary to split the very first application record of
+ * a freshly negotiated TLS session, as there is no previous
+ * application data to guess. To improve compatibility, we will not
+ * split such records.
+ *
+ * Because of the compatibility, we'd better produce no more than
+ * SSLSession.getPacketBufferSize() net data for each wrap. As we
+ * need a one-byte record at first, the 2nd record size should be
+ * equal to or less than Record.maxDataSizeMinusOneByteRecord.
+ *
+ * This avoids issues in the outbound direction. For a full fix,
+ * the peer must have similar protections.
+ */
+ int length;
+ if (engine.needToSplitPayload(writeCipher, protocolVersion)) {
+ write(ea, writeMAC, writeCipher, 0x01);
+ ea.resetLim(); // reset application data buffer limit
+ length = Math.min(ea.getAppRemaining(),
+ maxDataSizeMinusOneByteRecord);
+ } else {
+ length = Math.min(ea.getAppRemaining(), maxDataSize);
+ }
+
+ // Don't bother to really write empty records.
+ if (length > 0) {
+ write(ea, writeMAC, writeCipher, length);
+ }
+
+ return;
+ }
+
+ void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher,
+ int length) throws IOException {
+ /*
* Copy out existing buffer values.
*/
ByteBuffer dstBB = ea.netData;
--- a/jdk/src/share/classes/sun/security/ssl/Record.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/Record.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, 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
@@ -67,6 +67,23 @@
+ maxPadding // padding
+ trailerSize; // MAC
+ static final boolean enableCBCProtection =
+ Debug.getBooleanProperty("jsse.enableCBCProtection", true);
+
+ /*
+ * For CBC protection in SSL3/TLS1, we break some plaintext into two
+ * packets. Max application data size for the second packet.
+ */
+ static final int maxDataSizeMinusOneByteRecord =
+ maxDataSize // max data size
+ - ( // max one byte record size
+ headerSize // header
+ + maxIVLength // iv
+ + 1 // one byte data
+ + maxPadding // padding
+ + trailerSize // MAC
+ );
+
/*
* The maximum large record size.
*
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Mon Nov 14 18:18:22 2011 -0800
@@ -309,6 +309,11 @@
Object writeLock;
/*
+ * Is it the first application record to write?
+ */
+ private boolean isFirstAppOutputRecord = true;
+
+ /*
* Class and subclass dynamic debugging support
*/
private static final Debug debug = Debug.getInstance("ssl");
@@ -612,6 +617,9 @@
// See comment above.
oldCipher.dispose();
+
+ // reset the flag of the first application record
+ isFirstAppOutputRecord = true;
}
/*
@@ -1286,10 +1294,36 @@
}
}
+ /*
+ * turn off the flag of the first application record if we really
+ * consumed at least byte.
+ */
+ if (isFirstAppOutputRecord && ea.deltaApp() > 0) {
+ isFirstAppOutputRecord = false;
+ }
+
return hsStatus;
}
/*
+ * Need to split the payload except the following cases:
+ *
+ * 1. protocol version is TLS 1.1 or later;
+ * 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
+ * 3. the payload is the first application record of a freshly
+ * negotiated TLS session.
+ * 4. the CBC protection is disabled;
+ *
+ * More details, please refer to
+ * EngineOutputRecord.write(EngineArgs, MAC, CipherBox).
+ */
+ boolean needToSplitPayload(CipherBox cipher, ProtocolVersion protocol) {
+ return (protocol.v <= ProtocolVersion.TLS10.v) &&
+ cipher.isCBCMode() && !isFirstAppOutputRecord &&
+ Record.enableCBCProtection;
+ }
+
+ /*
* Non-application OutputRecords go through here.
*/
void writeRecord(EngineOutputRecord eor) throws IOException {
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Mon Nov 14 18:18:22 2011 -0800
@@ -369,6 +369,11 @@
/* Class and subclass dynamic debugging support */
private static final Debug debug = Debug.getInstance("ssl");
+ /*
+ * Is it the first application record to write?
+ */
+ private boolean isFirstAppOutputRecord = true;
+
//
// CONSTRUCTORS AND INITIALIZATION CODE
//
@@ -802,8 +807,35 @@
if (connectionState < cs_ERROR) {
checkSequenceNumber(writeMAC, r.contentType());
}
+
+ // turn off the flag of the first application record
+ if (isFirstAppOutputRecord &&
+ r.contentType() == Record.ct_application_data) {
+ isFirstAppOutputRecord = false;
+ }
}
+ /*
+ * Need to split the payload except the following cases:
+ *
+ * 1. protocol version is TLS 1.1 or later;
+ * 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
+ * 3. the payload is the first application record of a freshly
+ * negotiated TLS session.
+ * 4. the CBC protection is disabled;
+ *
+ * More details, please refer to AppOutputStream.write(byte[], int, int).
+ */
+ boolean needToSplitPayload() {
+ writeLock.lock();
+ try {
+ return (protocolVersion.v <= ProtocolVersion.TLS10.v) &&
+ writeCipher.isCBCMode() && !isFirstAppOutputRecord &&
+ Record.enableCBCProtection;
+ } finally {
+ writeLock.unlock();
+ }
+ }
/*
* Read an application data record. Alerts and handshake
@@ -2030,6 +2062,9 @@
// See comment above.
oldCipher.dispose();
+
+ // reset the flag of the first application record
+ isFirstAppOutputRecord = true;
}
/*
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Mon Nov 14 18:18:22 2011 -0800
@@ -1112,11 +1112,14 @@
uint size3 = suffix * 3;
if (suffix == 0) continue; // done with empty string
chars.malloc(size3);
+ CHECK;
byte* chp = chars.ptr;
band saved_band = cp_Utf8_big_chars;
cp_Utf8_big_chars.readData(suffix);
+ CHECK;
for (int j = 0; j < suffix; j++) {
unsigned short ch = cp_Utf8_big_chars.getInt();
+ CHECK;
chp = store_Utf8_char(chp, ch);
}
chars.realloc(chp - chars.ptr);
@@ -1134,10 +1137,12 @@
CHECK;
int prevlen = 0; // previous string length (in chars)
tmallocs.add(bigbuf.ptr); // free after this block
+ CHECK;
cp_Utf8_prefix.rewind();
for (i = 0; i < len; i++) {
bytes& chars = allsuffixes[i];
int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
+ CHECK;
int suffix = (int)chars.len;
byte* fillp;
// by induction, the buffer is already filled with the prefix
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, 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
@@ -52,7 +52,7 @@
if (msize >= 0 && msize < sizeof(int))
msize = sizeof(int); // see 0xbaadf00d below
#endif
- void* ptr = (msize > PSIZE_MAX) ? null : malloc(msize);
+ void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : malloc(msize);
if (ptr != null) {
memset(ptr, 0, size);
} else {
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/utils.h Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/utils.h Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, 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
@@ -33,7 +33,7 @@
#endif
// overflow management
-#define OVERFLOW ((size_t)-1)
+#define OVERFLOW ((uint)-1)
#define PSIZE_MAX (OVERFLOW/2) /* normal size limit */
inline size_t scale_size(size_t size, size_t scale) {
--- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, 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
@@ -284,7 +284,7 @@
TransformHelperFunc *pHelperFunc;
TransformInterpFunc *pInterpFunc;
jdouble xorig, yorig;
- jint numedges;
+ jlong numedges;
jint *pEdges;
jint edgebuf[2 + MAXEDGES * 2];
union {
@@ -379,19 +379,44 @@
}
Region_IntersectBounds(&clipInfo, &dstInfo.bounds);
- numedges = (dstInfo.bounds.y2 - dstInfo.bounds.y1);
- if (numedges > MAXEDGES) {
- pEdges = malloc((2 + 2 * numedges) * sizeof (*pEdges));
- if (pEdges == NULL) {
- SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
- SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
- /* edgeArray should already contain zeros for min/maxy */
- return;
- }
+ numedges = (((jlong) dstInfo.bounds.y2) - ((jlong) dstInfo.bounds.y1));
+ if (numedges <= 0) {
+ pEdges = NULL;
+ } else if (!JNU_IsNull(env, edgeArray)) {
+ /*
+ * Ideally Java should allocate an array large enough, but if
+ * we ever have a miscommunication about the number of edge
+ * lines, or if the Java array calculation should overflow to
+ * a positive number and succeed in allocating an array that
+ * is too small, we need to verify that it can still hold the
+ * number of integers that we plan to store to be safe.
+ */
+ jsize edgesize = (*env)->GetArrayLength(env, edgeArray);
+ /* (edgesize/2 - 1) should avoid any overflow or underflow. */
+ pEdges = (((edgesize / 2) - 1) >= numedges)
+ ? (*env)->GetPrimitiveArrayCritical(env, edgeArray, NULL)
+ : NULL;
+ } else if (numedges > MAXEDGES) {
+ /* numedges variable (jlong) can be at most ((1<<32)-1) */
+ /* memsize can overflow a jint, but not a jlong */
+ jlong memsize = ((numedges * 2) + 2) * sizeof(*pEdges);
+ pEdges = (memsize == ((size_t) memsize))
+ ? malloc((size_t) memsize)
+ : NULL;
} else {
pEdges = edgebuf;
}
+ if (pEdges == NULL) {
+ if (numedges > 0) {
+ JNU_ThrowInternalError(env, "Unable to allocate edge list");
+ }
+ SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
+ SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
+ /* edgeArray should already contain zeros for min/maxy */
+ return;
+ }
+
Transform_GetInfo(env, itxform, &itxInfo);
if (!Region_IsEmpty(&clipInfo)) {
@@ -500,14 +525,14 @@
} else {
pEdges[0] = pEdges[1] = 0;
}
+
+ if (!JNU_IsNull(env, edgeArray)) {
+ (*env)->ReleasePrimitiveArrayCritical(env, edgeArray, pEdges, 0);
+ } else if (pEdges != edgebuf) {
+ free(pEdges);
+ }
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
- if (!JNU_IsNull(env, edgeArray)) {
- (*env)->SetIntArrayRegion(env, edgeArray, 0, 2+numedges*2, pEdges);
- }
- if (pEdges != edgebuf) {
- free(pEdges);
- }
}
static void
--- a/jdk/src/windows/classes/java/lang/ProcessImpl.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java Mon Nov 14 18:18:22 2011 -0800
@@ -60,10 +60,11 @@
throws IOException
{
if (append) {
+ String path = f.getPath();
SecurityManager sm = System.getSecurityManager();
if (sm != null)
- sm.checkWrite(f.getPath());
- long handle = openForAtomicAppend(f.getPath());
+ sm.checkWrite(path);
+ long handle = openForAtomicAppend(path);
final FileDescriptor fd = new FileDescriptor();
fdAccess.setHandle(fd, handle);
return AccessController.doPrivileged(
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Mon Nov 14 18:18:22 2011 -0800
@@ -355,7 +355,7 @@
RECT rect;
CalculateWarningWindowBounds(env, &rect);
- ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(),
+ ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE |
@@ -835,7 +835,7 @@
if (securityAnimationKind == akShow) {
::SetWindowPos(warningWindow,
- IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(),
+ IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,10 +1,7 @@
/*
* @test
* @build TestThread Traffic Handler ServerHandler ServerThread ClientThread
- * @run main/othervm/timeout=140 main
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
+ * @run main/othervm/timeout=140 -Djsse.enableCBCProtection=false main
* @summary Make sure that different configurations of SSL sockets work
*/
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -29,6 +29,8 @@
* This is a simple hack to test a bunch of conditions and check
* their return codes.
*
+ * @run main/othervm -Djsse.enableCBCProtection=false CheckStatus
+ *
* @author Brad Wetmore
*/
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, 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
@@ -30,6 +30,8 @@
* This is to test larger buffer arrays, and make sure the maximum
* is being passed.
*
+ * @run main/othervm -Djsse.enableCBCProtection=false LargeBufs
+ *
* @author Brad R. Wetmore
*/
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java Mon Nov 14 18:18:22 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2011, 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
@@ -27,10 +27,7 @@
* @bug 6388456
* @summary Need adjustable TLS max record size for interoperability
* with non-compliant
- * @run main/othervm LargePacket
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
+ * @run main/othervm -Djsse.enableCBCProtection=false LargePacket
*
* @author Xuelei Fan
*/
--- a/jdk/test/sun/tools/jstatd/jstatdExternalRegistry.sh Mon Nov 14 18:15:37 2011 -0800
+++ b/jdk/test/sun/tools/jstatd/jstatdExternalRegistry.sh Mon Nov 14 18:18:22 2011 -0800
@@ -22,7 +22,7 @@
#
# @test
-# @bug 4990825
+# @bug 4990825 7092186
# @run shell/timeout=90 jstatdExternalRegistry.sh
# @summary Test functionality of 'jstatd -p<port>&' with an external RMI registry