diff --git a/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java b/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java index c17fcf72136e02fa8a44b1482e131b7494e54e5d..c60435331ec9becdd9848c2898697524663bb6dc 100644 --- a/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java +++ b/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java @@ -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 @@ class HttpsURLConnection extends HttpURLConnection throw new IllegalArgumentException( "no SSLSocketFactory specified"); } + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkSetFactory(); + } + sslSocketFactory = sf; } diff --git a/src/share/classes/java/awt/AWTKeyStroke.java b/src/share/classes/java/awt/AWTKeyStroke.java index fc311535d652926d06846a7dda5e3258ec4ac47f..13f6edd81f0a77a91fe68c5feef3b8540ef0a516 100644 --- a/src/share/classes/java/awt/AWTKeyStroke.java +++ b/src/share/classes/java/awt/AWTKeyStroke.java @@ -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 @@ import java.lang.reflect.Field; 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 @@ public class AWTKeyStroke implements Serializable { */ 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 @@ public class AWTKeyStroke implements Serializable { 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 @@ public class AWTKeyStroke implements Serializable { } 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 @@ public class AWTKeyStroke implements Serializable { 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 @@ public class AWTKeyStroke implements Serializable { if (stroke == null) { stroke = cacheKey; cache.put(stroke, stroke); - cacheKey = null; + AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY); } - return stroke; } diff --git a/src/share/classes/java/io/InputStream.java b/src/share/classes/java/io/InputStream.java index 23c166ed67399bed8f2201a63b070721a1d666b5..63d31d51f994bd5b4de5608317d4149d980c9f2d 100644 --- a/src/share/classes/java/io/InputStream.java +++ b/src/share/classes/java/io/InputStream.java @@ -44,10 +44,9 @@ package java.io; */ 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 @@ public abstract class InputStream implements Closeable { 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; } diff --git a/src/share/classes/javax/net/ssl/HttpsURLConnection.java b/src/share/classes/javax/net/ssl/HttpsURLConnection.java index fbd8fca13722ecf85a5e0a9446ed817eac4bdab6..5027b9a578824e351b894d79c86634f4bc34c229 100644 --- a/src/share/classes/javax/net/ssl/HttpsURLConnection.java +++ b/src/share/classes/javax/net/ssl/HttpsURLConnection.java @@ -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 @@ class HttpsURLConnection extends HttpURLConnection * @param sf the SSL socket factory * @throws IllegalArgumentException if the SSLSocketFactory * parameter is null. + * @throws SecurityException if a security manager exists and its + * checkSetFactory method does not allow + * a socket factory to be specified. * @see #getSSLSocketFactory() */ public void setSSLSocketFactory(SSLSocketFactory sf) { @@ -355,6 +358,10 @@ class HttpsURLConnection extends HttpURLConnection "no SSLSocketFactory specified"); } + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkSetFactory(); + } sslSocketFactory = sf; } diff --git a/src/share/classes/javax/net/ssl/SSLEngine.java b/src/share/classes/javax/net/ssl/SSLEngine.java index 2eea55121cb6ce401edaacb0fd79e6ab4d135627..411626cd7a13e8ff6abfd8fa1f9fd6407068fd8e 100644 --- a/src/share/classes/javax/net/ssl/SSLEngine.java +++ b/src/share/classes/javax/net/ssl/SSLEngine.java @@ -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 @@ public abstract class SSLEngine { * If this SSLEngine has not yet started its initial * handshake, this method will automatically start the handshake. *

- * 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 * ByteBuffer's position is updated to reflect the diff --git a/src/share/classes/sun/net/ResourceManager.java b/src/share/classes/sun/net/ResourceManager.java index 11bfc46481950da1521c239327084208e424a5aa..068b8484728adf9f94f030cdbee8f827c77254d8 100644 --- a/src/share/classes/sun/net/ResourceManager.java +++ b/src/share/classes/sun/net/ResourceManager.java @@ -41,13 +41,14 @@ public class ResourceManager { /* 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; diff --git a/src/share/classes/sun/rmi/registry/RegistryImpl.java b/src/share/classes/sun/rmi/registry/RegistryImpl.java index 4878609c088c14d552275a7e57bbced16936a687..db18eb3364dab05f1920d98268198500816ac5fb 100644 --- a/src/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/src/share/classes/sun/rmi/registry/RegistryImpl.java @@ -38,13 +38,23 @@ import java.rmi.server.ServerNotActiveException; 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 @@ public class RegistryImpl extends java.rmi.server.RemoteServer 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 @@ public class RegistryImpl extends java.rmi.server.RemoteServer 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() { + 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 @@ public class RegistryImpl extends java.rmi.server.RemoteServer } 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() { + 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 }); + } } diff --git a/src/share/classes/sun/rmi/server/LoaderHandler.java b/src/share/classes/sun/rmi/server/LoaderHandler.java index 541c7840e0802cd3395cc1e73c6da07f48a3e217..52d9ee55172e157c2a0aff87a4f2da0c1111e863 100644 --- a/src/share/classes/sun/rmi/server/LoaderHandler.java +++ b/src/share/classes/sun/rmi/server/LoaderHandler.java @@ -1031,9 +1031,9 @@ public final class LoaderHandler { * 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]; diff --git a/src/share/classes/sun/rmi/server/UnicastServerRef.java b/src/share/classes/sun/rmi/server/UnicastServerRef.java index 9a0c1afb5785c4768e6579a3c70e1b3fe94185c0..fe199a23137bd610a6205e25be97d5c2587e86ca 100644 --- a/src/share/classes/sun/rmi/server/UnicastServerRef.java +++ b/src/share/classes/sun/rmi/server/UnicastServerRef.java @@ -390,6 +390,12 @@ public class UnicastServerRef extends UnicastRef 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", diff --git a/src/share/classes/sun/security/ssl/AppOutputStream.java b/src/share/classes/sun/security/ssl/AppOutputStream.java index 34f3be6d6a5a2c5faba2a03e5067da7e01c58918..6be00b8e2d1db0c1b0ad3f4fa428d31196e041ef 100644 --- a/src/share/classes/sun/security/ssl/AppOutputStream.java +++ b/src/share/classes/sun/security/ssl/AppOutputStream.java @@ -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 @@ class AppOutputStream extends OutputStream { // 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) { diff --git a/src/share/classes/sun/security/ssl/CipherBox.java b/src/share/classes/sun/security/ssl/CipherBox.java index 16f0643a7c580366b73cd38e1fb72f931fb2a13c..4305b44635b1ebdc96d47b053a31dc39b78ea40d 100644 --- a/src/share/classes/sun/security/ssl/CipherBox.java +++ b/src/share/classes/sun/security/ssl/CipherBox.java @@ -112,6 +112,11 @@ final class CipherBox { */ 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 @@ final class CipherBox { private CipherBox() { this.protocolVersion = ProtocolVersion.DEFAULT; this.cipher = null; + this.isCBCMode = false; } /** @@ -148,6 +154,7 @@ final class CipherBox { random = JsseJce.getSecureRandom(); } this.random = random; + this.isCBCMode = bulkCipher.isCBCMode; /* * RFC 4346 recommends two algorithms used to generated the @@ -694,4 +701,12 @@ final class CipherBox { } } + /* + * Does the cipher use CBC mode? + * + * @return true if the cipher use CBC mode, false otherwise. + */ + boolean isCBCMode() { + return isCBCMode; + } } diff --git a/src/share/classes/sun/security/ssl/CipherSuite.java b/src/share/classes/sun/security/ssl/CipherSuite.java index 116afa43d7045ccd6df51df73bd963c06f4fb78a..bbf66ade7e1eeef3849c22ac0599f058c0dc20f9 100644 --- a/src/share/classes/sun/security/ssl/CipherSuite.java +++ b/src/share/classes/sun/security/ssl/CipherSuite.java @@ -420,10 +420,16 @@ final class CipherSuite implements Comparable { // 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 @@ final class CipherSuite implements Comparable { 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; diff --git a/src/share/classes/sun/security/ssl/EngineOutputRecord.java b/src/share/classes/sun/security/ssl/EngineOutputRecord.java index 60a428396e4cc11f60c363515f205c8a58b560ff..707fd04f8d367fe7d66dd0c0324e1bde08462941 100644 --- a/src/share/classes/sun/security/ssl/EngineOutputRecord.java +++ b/src/share/classes/sun/security/ssl/EngineOutputRecord.java @@ -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 @@ import sun.misc.HexDumpEncoder; */ final class EngineOutputRecord extends OutputRecord { + private SSLEngineImpl engine; private EngineWriter writer; private boolean finishedMsg = false; @@ -62,6 +63,7 @@ final class EngineOutputRecord extends OutputRecord { */ EngineOutputRecord(byte type, SSLEngineImpl engine) { super(type, recordSize(type)); + this.engine = engine; writer = engine.writer; } @@ -227,11 +229,50 @@ final class EngineOutputRecord extends OutputRecord { * 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. */ diff --git a/src/share/classes/sun/security/ssl/Record.java b/src/share/classes/sun/security/ssl/Record.java index 1378e107afc52fd007d7d9d59371c28879ca1287..92c8a3ebbe0e3f8c91780d529edd61bcb6650180 100644 --- a/src/share/classes/sun/security/ssl/Record.java +++ b/src/share/classes/sun/security/ssl/Record.java @@ -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 @@ interface Record { + 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. * diff --git a/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/src/share/classes/sun/security/ssl/SSLEngineImpl.java index 461cbaa20549bd0e12b146ada4313b1f3dc32004..8616a71ef13286d3cb2e84162c83b23eb255928e 100644 --- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java +++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java @@ -308,6 +308,11 @@ final public class SSLEngineImpl extends SSLEngine { private Object unwrapLock; Object writeLock; + /* + * Is it the first application record to write? + */ + private boolean isFirstAppOutputRecord = true; + /* * Class and subclass dynamic debugging support */ @@ -612,6 +617,9 @@ final public class SSLEngineImpl extends SSLEngine { // See comment above. oldCipher.dispose(); + + // reset the flag of the first application record + isFirstAppOutputRecord = true; } /* @@ -1286,9 +1294,35 @@ final public class SSLEngineImpl extends SSLEngine { } } + /* + * 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. */ diff --git a/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/share/classes/sun/security/ssl/SSLSocketImpl.java index 5bfdd46c07448ef45e0724b7cfb9d951ab0d2133..814f7d2933adbb0000e16aca5ae20573a76b8f6b 100644 --- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -369,6 +369,11 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { /* 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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { 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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { // See comment above. oldCipher.dispose(); + + // reset the flag of the first application record + isFirstAppOutputRecord = true; } /* diff --git a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp index 17c48a4ceac3c66a6314274080095167b46676b2..cee146d4db44e8e88893172882189c4481cf6e9d 100644 --- a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp +++ b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp @@ -1112,11 +1112,14 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) { 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 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) { 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 diff --git a/src/share/native/com/sun/java/util/jar/pack/utils.cpp b/src/share/native/com/sun/java/util/jar/pack/utils.cpp index 0f770d8064a2b236c5cfc75e361cd3bc6a95048c..e5197e1a3f121d62fcb7fd5bb0e49c7bd902c9e1 100644 --- a/src/share/native/com/sun/java/util/jar/pack/utils.cpp +++ b/src/share/native/com/sun/java/util/jar/pack/utils.cpp @@ -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 @@ void* must_malloc(size_t size) { 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 { diff --git a/src/share/native/com/sun/java/util/jar/pack/utils.h b/src/share/native/com/sun/java/util/jar/pack/utils.h index d24e5b50ea81dc29f76ee5ef3626c73ff2447e28..89619316a0eafc882365180f83c2f91aa640aa7d 100644 --- a/src/share/native/com/sun/java/util/jar/pack/utils.h +++ b/src/share/native/com/sun/java/util/jar/pack/utils.h @@ -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 @@ void mtrace(char c, void* ptr, size_t size); #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) { diff --git a/src/share/native/sun/java2d/loops/TransformHelper.c b/src/share/native/sun/java2d/loops/TransformHelper.c index a511774747630d953a34c4f5ca67811fe9dffab6..23bba354756c6404f9126494d1210b99cdb600bd 100644 --- a/src/share/native/sun/java2d/loops/TransformHelper.c +++ b/src/share/native/sun/java2d/loops/TransformHelper.c @@ -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 @@ Java_sun_java2d_loops_TransformHelper_Transform TransformHelperFunc *pHelperFunc; TransformInterpFunc *pInterpFunc; jdouble xorig, yorig; - jint numedges; + jlong numedges; jint *pEdges; jint edgebuf[2 + MAXEDGES * 2]; union { @@ -379,19 +379,44 @@ Java_sun_java2d_loops_TransformHelper_Transform } 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 @@ Java_sun_java2d_loops_TransformHelper_Transform } else { pEdges[0] = pEdges[1] = 0; } - 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) { + (*env)->ReleasePrimitiveArrayCritical(env, edgeArray, pEdges, 0); + } else if (pEdges != edgebuf) { free(pEdges); } + SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); + SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); } static void diff --git a/src/windows/classes/java/lang/ProcessImpl.java b/src/windows/classes/java/lang/ProcessImpl.java index 05891161a42ed2769afb4e7a94a9c54824cd654a..88486e5f4725616a7e8cdc7d07f109d86f00e12e 100644 --- a/src/windows/classes/java/lang/ProcessImpl.java +++ b/src/windows/classes/java/lang/ProcessImpl.java @@ -60,10 +60,11 @@ final class ProcessImpl extends Process { 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( diff --git a/src/windows/native/sun/windows/awt_Window.cpp b/src/windows/native/sun/windows/awt_Window.cpp index c742aca9000e00dca54446ec066a3aa4e28390c4..83f6f0b9b1cee5c3c171a3c1a9cae960fae58502 100644 --- a/src/windows/native/sun/windows/awt_Window.cpp +++ b/src/windows/native/sun/windows/awt_Window.cpp @@ -355,7 +355,7 @@ void AwtWindow::RepositionSecurityWarning(JNIEnv *env) 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 @@ void AwtWindow::StartSecurityAnimation(AnimationKind kind) 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); diff --git a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java index 9a18be3240fe82d34e7056ebc2097096c66031b5..432aed4ffe360cf11893f816f526fae850e42ea3 100644 --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java @@ -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 */ diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java index c29f55a04b9f80dd22097f5e8c4c9f7e38b757d2..dfdefa9f1f76307b741ad6b1296570596a200a96 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java @@ -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 */ diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java index 849e739c8236f026bd2910462238690cec3b6bba..5960ea639926fe8b8665792576940979c66ed668 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java @@ -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 */ diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java index 9740b67021e37765df28c94083ce1b2699f18cfb..498df71463aad1eca72f7b806f6725051c4981c7 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java @@ -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 */ diff --git a/test/sun/tools/jstatd/jstatdExternalRegistry.sh b/test/sun/tools/jstatd/jstatdExternalRegistry.sh index 8e7d220ef68c56bc9f5b9b5d784bd4fdb79ce45d..c4d09b58b983943ecf5bea05f7a3bf3351560b6b 100644 --- a/test/sun/tools/jstatd/jstatdExternalRegistry.sh +++ b/test/sun/tools/jstatd/jstatdExternalRegistry.sh @@ -22,7 +22,7 @@ # # @test -# @bug 4990825 +# @bug 4990825 7092186 # @run shell/timeout=90 jstatdExternalRegistry.sh # @summary Test functionality of 'jstatd -p&' with an external RMI registry