Mercurial > hg > release > icedtea6-1.11
changeset 2844:d9564350faa6
Add 2012/10/16 security patches.
2012-10-11 Andrew John Hughes <gnu.andrew@redhat.com>
* Makefile.am:
(SECURITY_PATCHES): Add new patches.
* patches/ecj/override.patch:
Add new cases in P11Key and RMIConnectionImpl
introduced by security patches.
* patches/security/20121016/6631398.patch,
* patches/security/20121016/7093490.patch,
* patches/security/20121016/7143535.patch,
* patches/security/20121016/7158800.patch,
* patches/security/20121016/7158801.patch,
* patches/security/20121016/7158804.patch,
* patches/security/20121016/7167656.patch,
* patches/security/20121016/7169884.patch,
* patches/security/20121016/7169888.patch,
* patches/security/20121016/7172522.patch,
* patches/security/20121016/7176337.patch,
* patches/security/20121016/7186286.patch,
* patches/security/20121016/7189103.patch,
* patches/security/20121016/7189490.patch,
* patches/security/20121016/7189567.patch,
* patches/security/20121016/7192975.patch,
* patches/security/20121016/7195194.patch,
* patches/security/20121016/7195917.patch,
* patches/security/20121016/7195919.patch,
* patches/security/20121016/7198296.patch,
* patches/security/20121016/7198606.patch:
New patches.
line wrap: on
line diff
--- a/ChangeLog Wed Sep 05 11:43:29 2012 +0200 +++ b/ChangeLog Thu Oct 11 21:32:13 2012 +0100 @@ -1,3 +1,33 @@ +2012-10-11 Andrew John Hughes <gnu.andrew@redhat.com> + + * Makefile.am: + (SECURITY_PATCHES): Add new patches. + * patches/ecj/override.patch: + Add new cases in P11Key and RMIConnectionImpl + introduced by security patches. + * patches/security/20121016/6631398.patch, + * patches/security/20121016/7093490.patch, + * patches/security/20121016/7143535.patch, + * patches/security/20121016/7158800.patch, + * patches/security/20121016/7158801.patch, + * patches/security/20121016/7158804.patch, + * patches/security/20121016/7167656.patch, + * patches/security/20121016/7169884.patch, + * patches/security/20121016/7169888.patch, + * patches/security/20121016/7172522.patch, + * patches/security/20121016/7176337.patch, + * patches/security/20121016/7186286.patch, + * patches/security/20121016/7189103.patch, + * patches/security/20121016/7189490.patch, + * patches/security/20121016/7189567.patch, + * patches/security/20121016/7192975.patch, + * patches/security/20121016/7195194.patch, + * patches/security/20121016/7195917.patch, + * patches/security/20121016/7195919.patch, + * patches/security/20121016/7198296.patch, + * patches/security/20121016/7198606.patch: + New patches. + 2012-09-05 Matthias Klose <doko@ubuntu.com> * configure.ac: Remove the Xp header and library checks.
--- a/Makefile.am Wed Sep 05 11:43:29 2012 +0200 +++ b/Makefile.am Thu Oct 11 21:32:13 2012 +0100 @@ -224,7 +224,28 @@ patches/security/20120612/7160757.patch \ patches/security/20120830/7162476-xmldecoder_via_classfinder.patch \ patches/security/20120830/7163201-simplify_toolkit_internal_references.patch \ - patches/security/20120830/7182135-impossible_to_use_some_editors_directly.patch + patches/security/20120830/7182135-impossible_to_use_some_editors_directly.patch \ + patches/security/20121016/6631398.patch \ + patches/security/20121016/7093490.patch \ + patches/security/20121016/7143535.patch \ + patches/security/20121016/7158800.patch \ + patches/security/20121016/7158801.patch \ + patches/security/20121016/7158804.patch \ + patches/security/20121016/7167656.patch \ + patches/security/20121016/7169884.patch \ + patches/security/20121016/7169888.patch \ + patches/security/20121016/7172522.patch \ + patches/security/20121016/7176337.patch \ + patches/security/20121016/7186286.patch \ + patches/security/20121016/7189103.patch \ + patches/security/20121016/7189490.patch \ + patches/security/20121016/7189567.patch \ + patches/security/20121016/7192975.patch \ + patches/security/20121016/7195194.patch \ + patches/security/20121016/7195917.patch \ + patches/security/20121016/7195919.patch \ + patches/security/20121016/7198296.patch \ + patches/security/20121016/7198606.patch SPECIAL_SECURITY_PATCH = patches/security/20120214/7112642.patch
--- a/patches/ecj/override.patch Wed Sep 05 11:43:29 2012 +0200 +++ b/patches/ecj/override.patch Thu Oct 11 21:32:13 2012 +0100 @@ -229,3 +229,25 @@ public int compareTo(X509IssuerSerial another) { int cissuer = issuer.toString() .compareTo(another.issuer.toString()); +diff -Nru openjdk-ecj.orig/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java openjdk-ecj/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +--- openjdk-ecj.orig/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java 2012-10-11 19:58:37.130814619 +0100 ++++ openjdk-ecj/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java 2012-10-11 19:59:39.699829277 +0100 +@@ -168,7 +168,6 @@ + this.defaultContextClassLoader = + AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { +- @Override + public ClassLoader run() { + return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), + dcl); +diff -Nru openjdk-ecj.orig/jdk/src/share/classes/sun/security/pkcs11/P11Key.java openjdk-ecj/jdk/src/share/classes/sun/security/pkcs11/P11Key.java +--- openjdk-ecj.orig/jdk/src/share/classes/sun/security/pkcs11/P11Key.java 2012-10-11 20:18:07.340676704 +0100 ++++ openjdk-ecj/jdk/src/share/classes/sun/security/pkcs11/P11Key.java 2012-10-11 20:17:40.092039288 +0100 +@@ -216,7 +216,6 @@ + /** + * Return bit length of the key. + */ +- @Override + public int length() { + return keyLength; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/6631398.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,20 @@ +# HG changeset patch +# User weijun +# Date 1339724916 -28800 +# Node ID 0fdc422fba9b63be684f1229af75f0c1f3ceec87 +# Parent f09937f0b2e32aa60a2cdd23f03a7e2d45091b60 +6631398: FilePermission improved path checking +Reviewed-by: mullan, skoivu, jdn + +diff --git a/src/share/classes/java/io/FilePermission.java b/src/share/classes/java/io/FilePermission.java +--- openjdk/jdk/src/share/classes/java/io/FilePermission.java ++++ openjdk/jdk/src/share/classes/java/io/FilePermission.java +@@ -399,7 +399,7 @@ + */ + + public int hashCode() { +- return this.cpath.hashCode(); ++ return 0; + } + + /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7093490.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,28 @@ +# HG changeset patch +# User coffeys +# Date 1340913225 -3600 +# Node ID e7334bb16ad694bed492da52e5713c8391e79ce8 +# Parent 0fdc422fba9b63be684f1229af75f0c1f3ceec87 +7093490: adjust package access in rmiregistry +Reviewed-by: smarks + +diff --git a/src/share/classes/sun/rmi/registry/RegistryImpl.java b/src/share/classes/sun/rmi/registry/RegistryImpl.java +--- openjdk/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java ++++ openjdk/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -405,7 +405,8 @@ + */ + perms.add(new SocketPermission("*", "connect,accept")); + +- perms.add(new RuntimePermission("accessClassInPackage.sun.*")); ++ perms.add(new RuntimePermission("accessClassInPackage.sun.jvmstat.*")); ++ perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*")); + + perms.add(new FilePermission("<<ALL FILES>>", "read")); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7143535.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,31 @@ +# HG changeset patch +# User sundar +# Date 1345469787 -14400 +# Node ID 1e170e3c1b682d0f98a61a47e5049535c5bd4999 +# Parent e7334bb16ad694bed492da52e5713c8391e79ce8 +7143535: ScriptEngine corrected permissions +Reviewed-by: mschoene + +diff --git a/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java b/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java +--- openjdk/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java ++++ openjdk/jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2005, 2012, 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 +@@ -130,7 +130,11 @@ + public RhinoScriptEngine() { + + if (System.getSecurityManager() != null) { +- accCtxt = AccessController.getContext(); ++ try { ++ AccessController.checkPermission(new AllPermission()); ++ } catch (AccessControlException ace) { ++ accCtxt = AccessController.getContext(); ++ } + } + + Context cx = enterContext();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7158800.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,1413 @@ +# HG changeset patch +# User kevinw +# Date 1345802362 -3600 +# Node ID 2faa3f7bad65189e69ab2f9a491743786bb8f07f +# Parent a080633e3a056dae9e94077c9ac4cf966137ade9 +7158800: Improve storage of symbol tables +7178670: runtime/7158800/BadUtf8.java fails in SymbolTable::rehash_table +7181200: JVM new hashing code breaks SA in product mode +7190262: Debug builds fail to verify String table with +UseCompressedStrings after 7158800 +Reviewed-by: coleenp + +diff --git a/src/share/vm/classfile/altHashing.cpp b/src/share/vm/classfile/altHashing.cpp +new file mode 100644 +--- /dev/null ++++ openjdk/hotspot/src/share/vm/classfile/altHashing.cpp +@@ -0,0 +1,304 @@ ++/* ++ * Copyright (c) 2012, 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 ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "classfile/altHashing.hpp" ++#include "classfile/symbolTable.hpp" ++#include "classfile/systemDictionary.hpp" ++#include "oops/markOop.hpp" ++#include "runtime/thread.hpp" ++ ++// Get the hash code of the classes mirror if it exists, otherwise just ++// return a random number, which is one of the possible hash code used for ++// objects. We don't want to call the synchronizer hash code to install ++// this value because it may safepoint. ++intptr_t object_hash(klassOop k) { ++ intptr_t hc = Klass::cast(k)->java_mirror()->mark()->hash(); ++ return hc != markOopDesc::no_hash ? hc : os::random(); ++} ++ ++// Seed value used for each alternative hash calculated. ++jint AltHashing::compute_seed() { ++ jlong nanos = os::javaTimeNanos(); ++ jlong now = os::javaTimeMillis(); ++ jint SEED_MATERIAL[8] = { ++ (jint) object_hash(SystemDictionary::String_klass()), ++ (jint) object_hash(SystemDictionary::System_klass()), ++ (jint) os::random(), // current thread isn't a java thread ++ (jint) (((julong)nanos) >> 32), ++ (jint) nanos, ++ (jint) (((julong)now) >> 32), ++ (jint) now, ++ (jint) (os::javaTimeNanos() >> 2) ++ }; ++ ++ return murmur3_32(SEED_MATERIAL, 8); ++} ++ ++ ++// Murmur3 hashing for Symbol ++jint AltHashing::murmur3_32(jint seed, const jbyte* data, int len) { ++ jint h1 = seed; ++ int count = len; ++ int offset = 0; ++ ++ // body ++ while (count >= 4) { ++ jint k1 = (data[offset] & 0x0FF) ++ | (data[offset + 1] & 0x0FF) << 8 ++ | (data[offset + 2] & 0x0FF) << 16 ++ | data[offset + 3] << 24; ++ ++ count -= 4; ++ offset += 4; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ ++ h1 ^= k1; ++ h1 = Integer_rotateLeft(h1, 13); ++ h1 = h1 * 5 + 0xe6546b64; ++ } ++ ++ // tail ++ ++ if (count > 0) { ++ jint k1 = 0; ++ ++ switch (count) { ++ case 3: ++ k1 ^= (data[offset + 2] & 0xff) << 16; ++ // fall through ++ case 2: ++ k1 ^= (data[offset + 1] & 0xff) << 8; ++ // fall through ++ case 1: ++ k1 ^= (data[offset] & 0xff); ++ // fall through ++ default: ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ h1 ^= k1; ++ } ++ } ++ ++ // finalization ++ h1 ^= len; ++ ++ // finalization mix force all bits of a hash block to avalanche ++ h1 ^= ((unsigned int)h1) >> 16; ++ h1 *= 0x85ebca6b; ++ h1 ^= ((unsigned int)h1) >> 13; ++ h1 *= 0xc2b2ae35; ++ h1 ^= ((unsigned int)h1) >> 16; ++ ++ return h1; ++} ++ ++// Murmur3 hashing for Strings ++jint AltHashing::murmur3_32(jint seed, const jchar* data, int len) { ++ jint h1 = seed; ++ ++ int off = 0; ++ int count = len; ++ ++ // body ++ while (count >= 2) { ++ jchar d1 = data[off++] & 0xFFFF; ++ jchar d2 = data[off++]; ++ jint k1 = (d1 | d2 << 16); ++ ++ count -= 2; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ ++ h1 ^= k1; ++ h1 = Integer_rotateLeft(h1, 13); ++ h1 = h1 * 5 + 0xe6546b64; ++ } ++ ++ // tail ++ ++ if (count > 0) { ++ int k1 = data[off]; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ h1 ^= k1; ++ } ++ ++ // finalization ++ h1 ^= len * 2; // (Character.SIZE / Byte.SIZE); ++ ++ // finalization mix force all bits of a hash block to avalanche ++ h1 ^= ((unsigned int)h1) >> 16; ++ h1 *= 0x85ebca6b; ++ h1 ^= ((unsigned int)h1) >> 13; ++ h1 *= 0xc2b2ae35; ++ h1 ^= ((unsigned int)h1) >> 16; ++ ++ return h1; ++} ++ ++// Hash used for the seed. ++jint AltHashing::murmur3_32(jint seed, const int* data, int len) { ++ jint h1 = seed; ++ ++ int off = 0; ++ int end = len; ++ ++ // body ++ while (off < end) { ++ jint k1 = data[off++]; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ ++ h1 ^= k1; ++ h1 = Integer_rotateLeft(h1, 13); ++ h1 = h1 * 5 + 0xe6546b64; ++ } ++ ++ // tail (always empty, as body is always 32-bit chunks) ++ ++ // finalization ++ ++ h1 ^= len * 4; // (Integer.SIZE / Byte.SIZE); ++ ++ // finalization mix force all bits of a hash block to avalanche ++ h1 ^= ((juint)h1) >> 16; ++ h1 *= 0x85ebca6b; ++ h1 ^= ((juint)h1) >> 13; ++ h1 *= 0xc2b2ae35; ++ h1 ^= ((juint)h1) >> 16; ++ ++ return h1; ++} ++ ++jint AltHashing::murmur3_32(const int* data, int len) { ++ return murmur3_32(0, data, len); ++} ++ ++#ifndef PRODUCT ++// Overloaded versions for internal test. ++jint AltHashing::murmur3_32(const jbyte* data, int len) { ++ return murmur3_32(0, data, len); ++} ++ ++jint AltHashing::murmur3_32(const jchar* data, int len) { ++ return murmur3_32(0, data, len); ++} ++ ++// Internal test for alternate hashing. Translated from JDK version ++// test/sun/misc/Hashing.java ++static const jbyte ONE_BYTE[] = { (jbyte) 0x80}; ++static const jbyte TWO_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81}; ++static const jchar ONE_CHAR[] = { (jchar) 0x8180}; ++static const jbyte THREE_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82}; ++static const jbyte FOUR_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83}; ++static const jchar TWO_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382}; ++static const jint ONE_INT[] = { 0x83828180}; ++static const jbyte SIX_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85}; ++static const jchar THREE_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584}; ++static const jbyte EIGHT_BYTE[] = { ++ (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, ++ (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85, ++ (jbyte) 0x86, (jbyte) 0x87}; ++static const jchar FOUR_CHAR[] = { ++ (jchar) 0x8180, (jchar) 0x8382, ++ (jchar) 0x8584, (jchar) 0x8786}; ++ ++static const jint TWO_INT[] = { 0x83828180, 0x87868584}; ++ ++static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3; ++ ++void AltHashing::testMurmur3_32_ByteArray() { ++ // printf("testMurmur3_32_ByteArray\n"); ++ ++ jbyte* vector = new jbyte[256]; ++ jbyte* hashes = new jbyte[4 * 256]; ++ ++ for (int i = 0; i < 256; i++) { ++ vector[i] = (jbyte) i; ++ } ++ ++ // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255} ++ for (int i = 0; i < 256; i++) { ++ jint hash = murmur3_32(256 - i, vector, i); ++ hashes[i * 4] = (jbyte) hash; ++ hashes[i * 4 + 1] = (jbyte) (((juint)hash) >> 8); ++ hashes[i * 4 + 2] = (jbyte) (((juint)hash) >> 16); ++ hashes[i * 4 + 3] = (jbyte) (((juint)hash) >> 24); ++ } ++ ++ // hash to get const result. ++ juint final_hash = murmur3_32(hashes, 4*256); ++ ++ assert (MURMUR3_32_X86_CHECK_VALUE == final_hash, ++ err_msg( ++ "Calculated hash result not as expected. Expected %08X got %08X\n", ++ MURMUR3_32_X86_CHECK_VALUE, ++ final_hash)); ++} ++ ++void AltHashing::testEquivalentHashes() { ++ jint jbytes, jchars, ints; ++ ++ // printf("testEquivalentHashes\n"); ++ ++ jbytes = murmur3_32(TWO_BYTE, 2); ++ jchars = murmur3_32(ONE_CHAR, 1); ++ assert (jbytes == jchars, ++ err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars)); ++ ++ jbytes = murmur3_32(FOUR_BYTE, 4); ++ jchars = murmur3_32(TWO_CHAR, 2); ++ ints = murmur3_32(ONE_INT, 1); ++ assert ((jbytes == jchars) && (jbytes == ints), ++ err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints)); ++ ++ jbytes = murmur3_32(SIX_BYTE, 6); ++ jchars = murmur3_32(THREE_CHAR, 3); ++ assert (jbytes == jchars, ++ err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars)); ++ ++ jbytes = murmur3_32(EIGHT_BYTE, 8); ++ jchars = murmur3_32(FOUR_CHAR, 4); ++ ints = murmur3_32(TWO_INT, 2); ++ assert ((jbytes == jchars) && (jbytes == ints), ++ err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints)); ++} ++ ++// Returns true if the alternate hashcode is correct ++void AltHashing::test_alt_hash() { ++ testMurmur3_32_ByteArray(); ++ testEquivalentHashes(); ++} ++#endif // PRODUCT +diff --git a/src/share/vm/classfile/altHashing.hpp b/src/share/vm/classfile/altHashing.hpp +new file mode 100644 +--- /dev/null ++++ openjdk/hotspot/src/share/vm/classfile/altHashing.hpp +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (c) 2012, 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 ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef SHARE_VM_CLASSFILE_ALTHASHING_HPP ++#define SHARE_VM_CLASSFILE_ALTHASHING_HPP ++ ++#include "prims/jni.h" ++#include "classfile/symbolTable.hpp" ++ ++/** ++ * Hashing utilities. ++ * ++ * Implementation of Murmur3 hashing. ++ * This code was translated from src/share/classes/sun/misc/Hashing.java ++ * code in the JDK. ++ */ ++ ++class AltHashing : AllStatic { ++ ++ // utility function copied from java/lang/Integer ++ static jint Integer_rotateLeft(jint i, int distance) { ++ return (i << distance) | (((juint)i) >> (32-distance)); ++ } ++ static jint murmur3_32(const int* data, int len); ++ static jint murmur3_32(jint seed, const int* data, int len); ++ ++#ifndef PRODUCT ++ // Hashing functions used for internal testing ++ static jint murmur3_32(const jbyte* data, int len); ++ static jint murmur3_32(const jchar* data, int len); ++ static void testMurmur3_32_ByteArray(); ++ static void testEquivalentHashes(); ++#endif // PRODUCT ++ ++ public: ++ static jint compute_seed(); ++ static jint murmur3_32(jint seed, const jbyte* data, int len); ++ static jint murmur3_32(jint seed, const jchar* data, int len); ++ NOT_PRODUCT(static void test_alt_hash();) ++}; ++#endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP +diff --git a/src/share/vm/classfile/javaClasses.cpp b/src/share/vm/classfile/javaClasses.cpp +--- openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp ++++ openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp +@@ -278,6 +278,28 @@ + return result; + } + ++unsigned int java_lang_String::to_hash(oop java_string) { ++ int length = java_lang_String::length(java_string); ++ // Zero length string will hash to zero with String.toHash() function. ++ if (length == 0) return 0; ++ ++ typeArrayOop value = java_lang_String::value(java_string); ++ int offset = java_lang_String::offset(java_string); ++ return java_lang_String::to_hash(value->char_at_addr(offset), length); ++} ++ ++unsigned int java_lang_String::hash_string(oop java_string) { ++ int length = java_lang_String::length(java_string); ++ // Zero length string doesn't hash necessarily hash to zero. ++ if (length == 0) { ++ return StringTable::hash_string(NULL, 0); ++ } ++ ++ typeArrayOop value = java_lang_String::value(java_string); ++ int offset = java_lang_String::offset(java_string); ++ return StringTable::hash_string(value->char_at_addr(offset), length); ++} ++ + symbolHandle java_lang_String::as_symbol(Handle java_string, TRAPS) { + oop obj = java_string(); + typeArrayOop value = java_lang_String::value(obj); +diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp +--- openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp ++++ openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp +@@ -109,6 +109,30 @@ + static char* as_platform_dependent_str(Handle java_string, TRAPS); + static jchar* as_unicode_string(oop java_string, int& length); + ++ // Compute the hash value for a java.lang.String object which would ++ // contain the characters passed in. ++ // ++ // As the hash value used by the String object itself, in ++ // String.hashCode(). This value is normally calculated in Java code ++ // in the String.hashCode method(), but is precomputed for String ++ // objects in the shared archive file. ++ // hash P(31) from Kernighan & Ritchie ++ // ++ // For this reason, THIS ALGORITHM MUST MATCH String.toHash(). ++ template <typename T> static unsigned int to_hash(T* s, int len) { ++ unsigned int h = 0; ++ while (len-- > 0) { ++ h = 31*h + (unsigned int) *s; ++ s++; ++ } ++ return h; ++ } ++ static unsigned int to_hash(oop java_string); ++ ++ // This is the string hash code used by the StringTable, which may be ++ // the same as String.toHash or an alternate hash code. ++ static unsigned int hash_string(oop java_string); ++ + static bool equals(oop java_string, jchar* chars, int len); + + // Conversion between '.' and '/' formats +diff --git a/src/share/vm/classfile/symbolTable.cpp b/src/share/vm/classfile/symbolTable.cpp +--- openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp ++++ openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp +@@ -23,6 +23,7 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/altHashing.hpp" + #include "classfile/javaClasses.hpp" + #include "classfile/symbolTable.hpp" + #include "classfile/systemDictionary.hpp" +@@ -34,16 +35,40 @@ + #include "oops/symbolKlass.hpp" + #include "runtime/mutexLocker.hpp" + #include "utilities/hashtable.inline.hpp" ++#include "utilities/numberSeq.hpp" + + // -------------------------------------------------------------------------- + + SymbolTable* SymbolTable::_the_table = NULL; ++bool SymbolTable::_needs_rehashing = false; ++ ++// Create a new table and using alternate hash code, populate the new table ++// with the existing strings. Set flag to use the alternate hash code afterwards. ++void SymbolTable::rehash_table() { ++ ++ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ++ // This should never happen with -Xshare:dump but it might in testing mode. ++ if (DumpSharedSpaces) return; ++ // Create a new symbol table ++ SymbolTable* new_table = new SymbolTable(); ++ ++ the_table()->move_to(new_table); ++ ++ // Delete the table and buckets (entries are reused in new table). ++ delete _the_table; ++ // Don't check if we need rehashing until the table gets unbalanced again. ++ // Then rehash with a new global seed. ++ _needs_rehashing = false; ++ _the_table = new_table; ++} + + // Lookup a symbol in a bucket. + + symbolOop SymbolTable::lookup(int index, const char* name, + int len, unsigned int hash) { ++ int count = 0; + for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { ++ count++; + if (e->hash() == hash) { + symbolOop sym = symbolOop(e->literal()); + if (sym->equals(name, len)) { +@@ -51,9 +76,20 @@ + } + } + } ++ // If the bucket size is too deep check if this hash code is insufficient. ++ if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { ++ _needs_rehashing = check_rehash_table(count); ++ } + return NULL; + } + ++// Pick hashing algorithm. ++unsigned int SymbolTable::hash_symbol(const char* s, int len) { ++ return the_table()->use_alternate_hashcode() ? ++ AltHashing::murmur3_32(the_table()->seed(), (const jbyte*)s, len) : ++ java_lang_String::to_hash(s, len); ++} ++ + + // We take care not to be blocking while holding the + // SymbolTable_lock. Otherwise, the system might deadlock, since the +@@ -71,8 +107,17 @@ + // Found + if (s != NULL) return s; + ++ // We assume that lookup() has been called already, that it failed, ++ // and symbol was not found. We create the symbol here. ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop s_oop = sk->allocate_symbol((u1*)name, len, CHECK_NULL); ++ symbolHandle sym (THREAD, s_oop); ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ + // Otherwise, add to symbol to table +- return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL); ++ return the_table()->basic_add(sym, index, (u1*)name, len, hashValue, CHECK_NULL); + } + + symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) { +@@ -108,7 +153,16 @@ + // We can't include the code in No_Safepoint_Verifier because of the + // ResourceMark. + +- return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL); ++ // We assume that lookup() has been called already, that it failed, ++ // and symbol was not found. We create the symbol here. ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop s_oop = sk->allocate_symbol((u1*)buffer, len, CHECK_NULL); ++ symbolHandle newsym (THREAD, s_oop); ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ ++ return the_table()->basic_add(newsym, index, (u1*)buffer, len, hashValue, CHECK_NULL); + } + + symbolOop SymbolTable::lookup_only(const char* name, int len, +@@ -156,36 +210,68 @@ + void SymbolTable::add(constantPoolHandle cp, int names_count, + const char** names, int* lengths, int* cp_indices, + unsigned int* hashValues, TRAPS) { +- SymbolTable* table = the_table(); +- bool added = table->basic_add(cp, names_count, names, lengths, +- cp_indices, hashValues, CHECK); +- if (!added) { ++ ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop sym_oops[symbol_alloc_batch_size]; ++ bool allocated = sk->allocate_symbols(names_count, names, lengths, ++ sym_oops, CHECK); ++ if (!allocated) { + // do it the hard way + for (int i=0; i<names_count; i++) { ++ assert(!Universe::heap()->is_in_reserved(names[i]) || GC_locker::is_active(), ++ "proposed name of symbol must be stable"); ++ ++ // We assume that lookup() has been called already, that it failed, ++ // and symbol was not found. We create the symbol here. ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop s_oop = sk->allocate_symbol((u1*)names[i], lengths[i], CHECK); ++ symbolHandle sym (THREAD, s_oop); ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ ++ SymbolTable* table = the_table(); + int index = table->hash_to_index(hashValues[i]); +- symbolOop sym = table->basic_add(index, (u1*)names[i], lengths[i], ++ symbolOop s = table->basic_add(sym, index, (u1*)names[i], lengths[i], + hashValues[i], CHECK); +- cp->symbol_at_put(cp_indices[i], sym); ++ cp->symbol_at_put(cp_indices[i], s); + } ++ return; + } ++ ++ symbolHandle syms[symbol_alloc_batch_size]; ++ for (int i=0; i<names_count; i++) { ++ syms[i] = symbolHandle(THREAD, sym_oops[i]); ++ } ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ ++ SymbolTable* table = the_table(); ++ bool added = table->basic_add(syms, cp, names_count, names, lengths, ++ cp_indices, hashValues, CHECK); ++ assert(added, "should always return true"); + } + +-symbolOop SymbolTable::basic_add(int index, u1 *name, int len, +- unsigned int hashValue, TRAPS) { +- assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), +- "proposed name of symbol must be stable"); +- +- // We assume that lookup() has been called already, that it failed, +- // and symbol was not found. We create the symbol here. +- symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); +- symbolOop s_oop = sk->allocate_symbol(name, len, CHECK_NULL); +- symbolHandle sym (THREAD, s_oop); +- +- // Allocation must be done before grapping the SymbolTable_lock lock +- MutexLocker ml(SymbolTable_lock, THREAD); ++symbolOop SymbolTable::basic_add(symbolHandle sym, int index_arg, u1 *name, int len, ++ unsigned int hashValue_arg, TRAPS) { ++ // Cannot hit a safepoint in this function because the "this" pointer can move. ++ No_Safepoint_Verifier nsv; + + assert(sym->equals((char*)name, len), "symbol must be properly initialized"); + ++ // Check if the symbol table has been rehashed, if so, need to recalculate ++ // the hash value and index. ++ unsigned int hashValue; ++ int index; ++ if (use_alternate_hashcode()) { ++ hashValue = hash_symbol((const char*)name, len); ++ index = hash_to_index(hashValue); ++ } else { ++ hashValue = hashValue_arg; ++ index = index_arg; ++ } ++ + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. + +@@ -201,48 +287,42 @@ + return sym(); + } + +-bool SymbolTable::basic_add(constantPoolHandle cp, int names_count, ++bool SymbolTable::basic_add(symbolHandle* syms, ++ constantPoolHandle cp, int names_count, + const char** names, int* lengths, + int* cp_indices, unsigned int* hashValues, + TRAPS) { +- symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); +- symbolOop sym_oops[symbol_alloc_batch_size]; +- bool allocated = sk->allocate_symbols(names_count, names, lengths, +- sym_oops, CHECK_false); +- if (!allocated) { +- return false; +- } +- symbolHandle syms[symbol_alloc_batch_size]; +- int i; +- for (i=0; i<names_count; i++) { +- syms[i] = symbolHandle(THREAD, sym_oops[i]); +- } ++ // Cannot hit a safepoint in this function because the "this" pointer can move. ++ No_Safepoint_Verifier nsv; + +- // Allocation must be done before grabbing the SymbolTable_lock lock +- MutexLocker ml(SymbolTable_lock, THREAD); +- +- for (i=0; i<names_count; i++) { ++ for (int i=0; i<names_count; i++) { + assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized"); ++ // Check if the symbol table has been rehashed, if so, need to recalculate ++ // the hash value. ++ unsigned int hashValue; ++ if (use_alternate_hashcode()) { ++ hashValue = hash_symbol(names[i], lengths[i]); ++ } else { ++ hashValue = hashValues[i]; ++ } + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. +- int index = hash_to_index(hashValues[i]); +- symbolOop test = lookup(index, names[i], lengths[i], hashValues[i]); ++ int index = hash_to_index(hashValue); ++ symbolOop test = lookup(index, names[i], lengths[i], hashValue); + if (test != NULL) { + // A race occurred and another thread introduced the symbol, this one + // will be dropped and collected. Use test instead. + cp->symbol_at_put(cp_indices[i], test); + } else { + symbolOop sym = syms[i](); +- HashtableEntry* entry = new_entry(hashValues[i], sym); ++ HashtableEntry* entry = new_entry(hashValue, sym); + add_entry(index, entry); + cp->symbol_at_put(cp_indices[i], sym); + } + } +- +- return true; ++ return true; // always returns true + } + +- + void SymbolTable::verify() { + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); +@@ -251,7 +331,7 @@ + guarantee(s != NULL, "symbol is NULL"); + s->verify(); + guarantee(s->is_perm(), "symbol not in permspace"); +- unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length()); ++ unsigned int h = hash_symbol((const char*)s->bytes(), s->utf8_length()); + guarantee(p->hash() == h, "broken hash in symbol table entry"); + guarantee(the_table()->hash_to_index(h) == i, + "wrong index in symbol table"); +@@ -259,6 +339,23 @@ + } + } + ++void SymbolTable::dump(outputStream* st) { ++ NumberSeq summary; ++ for (int i = 0; i < the_table()->table_size(); ++i) { ++ int count = 0; ++ for (HashtableEntry* e = the_table()->bucket(i); ++ e != NULL; e = e->next()) { ++ count++; ++ } ++ summary.add((double)count); ++ } ++ st->print_cr("SymbolTable statistics:"); ++ st->print_cr("Number of buckets : %7d", summary.num()); ++ st->print_cr("Average bucket size : %7.0f", summary.avg()); ++ st->print_cr("Variance of bucket size : %7.0f", summary.variance()); ++ st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd()); ++ st->print_cr("Maximum bucket size : %7.0f", summary.maximum()); ++} + + //--------------------------------------------------------------------------- + // Non-product code +@@ -321,7 +418,6 @@ + tty->print_cr(" %s %d: %d\n", "Number chains longer than", + results_length, out_of_range); + } +- + #endif // PRODUCT + + // -------------------------------------------------------------------------- +@@ -367,66 +463,56 @@ + // -------------------------------------------------------------------------- + + +-// Compute the hash value for a java.lang.String object which would +-// contain the characters passed in. This hash value is used for at +-// least two purposes. +-// +-// (a) As the hash value used by the StringTable for bucket selection +-// and comparison (stored in the HashtableEntry structures). This +-// is used in the String.intern() method. +-// +-// (b) As the hash value used by the String object itself, in +-// String.hashCode(). This value is normally calculate in Java code +-// in the String.hashCode method(), but is precomputed for String +-// objects in the shared archive file. +-// +-// For this reason, THIS ALGORITHM MUST MATCH String.hashCode(). ++StringTable* StringTable::_the_table = NULL; + +-int StringTable::hash_string(jchar* s, int len) { +- unsigned h = 0; +- while (len-- > 0) { +- h = 31*h + (unsigned) *s; +- s++; +- } +- return h; ++bool StringTable::_needs_rehashing = false; ++ ++// Pick hashing algorithm ++unsigned int StringTable::hash_string(const jchar* s, int len) { ++ return the_table()->use_alternate_hashcode() ? AltHashing::murmur3_32(the_table()->seed(), s, len) : ++ java_lang_String::to_hash(s, len); + } + +- +-StringTable* StringTable::_the_table = NULL; +- + oop StringTable::lookup(int index, jchar* name, + int len, unsigned int hash) { ++ int count = 0; + for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { ++ count++; + if (l->hash() == hash) { + if (java_lang_String::equals(l->literal(), name, len)) { + return l->literal(); + } + } + } ++ // If the bucket size is too deep check if this hash code is insufficient. ++ if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { ++ _needs_rehashing = check_rehash_table(count); ++ } + return NULL; + } + + +-oop StringTable::basic_add(int index, Handle string_or_null, jchar* name, +- int len, unsigned int hashValue, TRAPS) { +- debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); +- assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), +- "proposed name of symbol must be stable"); ++oop StringTable::basic_add(int index_arg, Handle string, jchar* name, ++ int len, unsigned int hashValue_arg, TRAPS) { + +- Handle string; +- // try to reuse the string if possible +- if (!string_or_null.is_null() && string_or_null()->is_perm()) { +- string = string_or_null; +- } else { +- string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); +- } +- +- // Allocation must be done before grapping the SymbolTable_lock lock +- MutexLocker ml(StringTable_lock, THREAD); ++ // Cannot hit a safepoint in this function because the "this" pointer can move. ++ No_Safepoint_Verifier nsv; + + assert(java_lang_String::equals(string(), name, len), + "string must be properly initialized"); + ++ // Check if the symbol table has been rehashed, if so, need to recalculate ++ // the hash value and index before second lookup. ++ unsigned int hashValue; ++ int index; ++ if (use_alternate_hashcode()) { ++ hashValue = hash_string(name, len); ++ index = hash_to_index(hashValue); ++ } else { ++ hashValue = hashValue_arg; ++ index = index_arg; ++ } ++ + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. + +@@ -456,13 +542,28 @@ + int len, TRAPS) { + unsigned int hashValue = hash_string(name, len); + int index = the_table()->hash_to_index(hashValue); +- oop string = the_table()->lookup(index, name, len, hashValue); ++ oop found_string = the_table()->lookup(index, name, len, hashValue); + + // Found +- if (string != NULL) return string; ++ if (found_string != NULL) return found_string; ++ ++ debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); ++ assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), ++ "proposed name of symbol must be stable"); ++ ++ Handle string; ++ // try to reuse the string if possible ++ if (!string_or_null.is_null() && string_or_null()->is_perm()) { ++ string = string_or_null; ++ } else { ++ string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); ++ } ++ ++ // Allocation must be done before grabbing the StringTable_lock lock ++ MutexLocker ml(StringTable_lock, THREAD); + + // Otherwise, add to symbol to table +- return the_table()->basic_add(index, string_or_null, name, len, ++ return the_table()->basic_add(index, string, name, len, + hashValue, CHECK_NULL); + } + +@@ -517,3 +618,41 @@ + } + } + } ++ ++void StringTable::dump(outputStream* st) { ++ NumberSeq summary; ++ for (int i = 0; i < the_table()->table_size(); ++i) { ++ HashtableEntry* p = the_table()->bucket(i); ++ int count = 0; ++ for ( ; p != NULL; p = p->next()) { ++ count++; ++ } ++ summary.add((double)count); ++ } ++ st->print_cr("StringTable statistics:"); ++ st->print_cr("Number of buckets : %7d", summary.num()); ++ st->print_cr("Average bucket size : %7.0f", summary.avg()); ++ st->print_cr("Variance of bucket size : %7.0f", summary.variance()); ++ st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd()); ++ st->print_cr("Maximum bucket size : %7.0f", summary.maximum()); ++} ++ ++ ++// Create a new table and using alternate hash code, populate the new table ++// with the existing strings. Set flag to use the alternate hash code afterwards. ++void StringTable::rehash_table() { ++ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ++ // This should never happen with -Xshare:dump but it might in testing mode. ++ if (DumpSharedSpaces) return; ++ StringTable* new_table = new StringTable(); ++ ++ // Rehash the table ++ the_table()->move_to(new_table); ++ ++ // Delete the table and buckets (entries are reused in new table). ++ delete _the_table; ++ // Don't check if we need rehashing until the table gets unbalanced again. ++ // Then rehash with a new global seed. ++ _needs_rehashing = false; ++ _the_table = new_table; ++} +diff --git a/src/share/vm/classfile/symbolTable.hpp b/src/share/vm/classfile/symbolTable.hpp +--- openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp ++++ openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp +@@ -40,6 +40,7 @@ + // - symbolTableEntrys are allocated in blocks to reduce the space overhead. + + class BoolObjectClosure; ++class outputStream; + + + class SymbolTable : public Hashtable { +@@ -49,10 +50,13 @@ + // The symbol table + static SymbolTable* _the_table; + ++ // Set if one bucket is out of balance due to hash algorithm deficiency ++ static bool _needs_rehashing; ++ + // Adding elements +- symbolOop basic_add(int index, u1* name, int len, ++ symbolOop basic_add(symbolHandle sym, int index, u1* name, int len, + unsigned int hashValue, TRAPS); +- bool basic_add(constantPoolHandle cp, int names_count, ++ bool basic_add(symbolHandle* syms, constantPoolHandle cp, int names_count, + const char** names, int* lengths, int* cp_indices, + unsigned int* hashValues, TRAPS); + +@@ -61,6 +65,8 @@ + symbol_table_size = 20011 + }; + ++ static unsigned int hash_symbol(const char* s, int len); ++ + symbolOop lookup(int index, const char* name, int len, unsigned int hash); + + SymbolTable() +@@ -70,7 +76,6 @@ + : Hashtable(symbol_table_size, sizeof (HashtableEntry), t, + number_of_entries) {} + +- + public: + enum { + symbol_alloc_batch_size = 8 +@@ -137,6 +142,7 @@ + + // Debugging + static void verify(); ++ static void dump(outputStream* st); + + // Sharing + static void copy_buckets(char** top, char*end) { +@@ -148,6 +154,10 @@ + static void reverse(void* boundary = NULL) { + ((Hashtable*)the_table())->reverse(boundary); + } ++ ++ // Rehash the symbol table if it gets out of balance ++ static void rehash_table(); ++ static bool needs_rehashing() { return _needs_rehashing; } + }; + + +@@ -158,8 +168,11 @@ + // The string table + static StringTable* _the_table; + ++ // Set if one bucket is out of balance due to hash algorithm deficiency ++ static bool _needs_rehashing; ++ + static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); +- oop basic_add(int index, Handle string_or_null, jchar* name, int len, ++ oop basic_add(int index, Handle string, jchar* name, int len, + unsigned int hashValue, TRAPS); + + // Table size +@@ -192,10 +205,6 @@ + _the_table = new StringTable(t, number_of_entries); + } + +- +- static int hash_string(jchar* s, int len); +- +- + // GC support + // Delete pointers to otherwise-unreachable objects. + static void unlink(BoolObjectClosure* cl) { +@@ -207,6 +216,14 @@ + the_table()->Hashtable::oops_do(f); + } + ++ // Hashing algorithm, used as the hash value used by the ++ // StringTable for bucket selection and comparison (stored in the ++ // HashtableEntry structures). This is used in the String.intern() method. ++ static unsigned int hash_string(const jchar* s, int len); ++ ++ // Internal test. ++ static void test_alt_hash() PRODUCT_RETURN; ++ + // Probing + static oop lookup(symbolOop symbol); + +@@ -217,6 +234,7 @@ + + // Debugging + static void verify(); ++ static void dump(outputStream* st); + + // Sharing + static void copy_buckets(char** top, char*end) { +@@ -228,6 +246,9 @@ + static void reverse() { + ((BasicHashtable*)the_table())->reverse(); + } ++ ++ // Rehash the symbol table if it gets out of balance ++ static void rehash_table(); ++ static bool needs_rehashing() { return _needs_rehashing; } + }; +- + #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP +diff --git a/src/share/vm/memory/dump.cpp b/src/share/vm/memory/dump.cpp +--- openjdk/hotspot/src/share/vm/memory/dump.cpp ++++ openjdk/hotspot/src/share/vm/memory/dump.cpp +@@ -62,8 +62,8 @@ + // written later, increasing the likelihood that the shared page contain + // the hash can be shared. + // +-// NOTE THAT the algorithm in StringTable::hash_string() MUST MATCH the +-// algorithm in java.lang.String.hashCode(). ++// NOTE THAT we have to call java_lang_String::to_hash() to match the ++// algorithm in java.lang.String.toHash(). + + class StringHashCodeClosure: public OopClosure { + private: +@@ -88,7 +88,7 @@ + } else { + int offset = java_lang_String::offset(obj); + jchar* s = value->char_at_addr(offset); +- hash = StringTable::hash_string(s, length); ++ hash = java_lang_String::to_hash(s, length); + } + obj->int_field_put(hash_offset, hash); + } +diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp +--- openjdk/hotspot/src/share/vm/runtime/globals.hpp ++++ openjdk/hotspot/src/share/vm/runtime/globals.hpp +@@ -2511,6 +2511,9 @@ + product(bool, UseHeavyMonitors, false, \ + "use heavyweight instead of lightweight Java monitors") \ + \ ++ product(bool, PrintStringTableStatistics, false, \ ++ "print statistics about the StringTable and SymbolTable") \ ++ \ + notproduct(bool, PrintSymbolTableSizeHistogram, false, \ + "print histogram of the symbol table") \ + \ +diff --git a/src/share/vm/runtime/init.cpp b/src/share/vm/runtime/init.cpp +--- openjdk/hotspot/src/share/vm/runtime/init.cpp ++++ openjdk/hotspot/src/share/vm/runtime/init.cpp +@@ -23,6 +23,7 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/symbolTable.hpp" + #include "code/icBuffer.hpp" + #include "gc_interface/collectedHeap.hpp" + #include "interpreter/bytecodes.hpp" +@@ -153,6 +154,10 @@ + // Print the collected safepoint statistics. + SafepointSynchronize::print_stat_on_exit(); + } ++ if (PrintStringTableStatistics) { ++ SymbolTable::dump(tty); ++ StringTable::dump(tty); ++ } + ostream_exit(); + } + } +diff --git a/src/share/vm/runtime/safepoint.cpp b/src/share/vm/runtime/safepoint.cpp +--- openjdk/hotspot/src/share/vm/runtime/safepoint.cpp ++++ openjdk/hotspot/src/share/vm/runtime/safepoint.cpp +@@ -23,6 +23,7 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/symbolTable.hpp" + #include "classfile/systemDictionary.hpp" + #include "code/codeCache.hpp" + #include "code/icBuffer.hpp" +@@ -501,8 +502,20 @@ + CompilationPolicy::policy()->do_safepoint_work(); + } + +- TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime); +- NMethodSweeper::scan_stacks(); ++ { ++ TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime); ++ NMethodSweeper::scan_stacks(); ++ } ++ ++ if (SymbolTable::needs_rehashing()) { ++ TraceTime t5("rehashing symbol table", TraceSafepointCleanupTime); ++ SymbolTable::rehash_table(); ++ } ++ ++ if (StringTable::needs_rehashing()) { ++ TraceTime t6("rehashing string table", TraceSafepointCleanupTime); ++ StringTable::rehash_table(); ++ } + } + + +diff --git a/src/share/vm/utilities/hashtable.cpp b/src/share/vm/utilities/hashtable.cpp +--- openjdk/hotspot/src/share/vm/utilities/hashtable.cpp ++++ openjdk/hotspot/src/share/vm/utilities/hashtable.cpp +@@ -1,5 +1,4 @@ +-/* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++/* * Copyright (c) 2003, 2012, 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 +@@ -23,7 +22,10 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/altHashing.hpp" ++#include "classfile/javaClasses.hpp" + #include "memory/allocation.inline.hpp" ++#include "memory/filemap.hpp" + #include "memory/resourceArea.hpp" + #include "oops/oop.inline.hpp" + #include "runtime/safepoint.hpp" +@@ -69,7 +71,6 @@ + + HashtableEntry* Hashtable::new_entry(unsigned int hashValue, oop obj) { + HashtableEntry* entry; +- + entry = (HashtableEntry*)BasicHashtable::new_entry(hashValue); + entry->set_literal(obj); // clears literal string field + HS_DTRACE_PROBE4(hs_private, hashtable__new_entry, +@@ -85,18 +86,24 @@ + // entries at a safepoint. + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + for (int i = 0; i < table_size(); ++i) { +- for (HashtableEntry** p = bucket_addr(i); *p != NULL; ) { +- HashtableEntry* entry = *p; +- if (entry->is_shared()) { ++ HashtableEntry** p = bucket_addr(i); ++ HashtableEntry* entry = bucket(i); ++ while (entry != NULL) { ++ // Shared entries are normally at the end of the bucket and if we run into ++ // a shared entry, then there is nothing more to remove. However, if we ++ // have rehashed the table, then the shared entries are no longer at the ++ // end of the bucket. ++ if (entry->is_shared() && !use_alternate_hashcode()) { + break; + } + assert(entry->literal() != NULL, "just checking"); +- if (is_alive->do_object_b(entry->literal())) { ++ if (entry->is_shared() || is_alive->do_object_b(entry->literal())) { + p = entry->next_addr(); + } else { + *p = entry->next(); + free_entry(entry); + } ++ entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); + } + } + } +@@ -123,6 +130,96 @@ + } + + ++// Check to see if the hashtable is unbalanced. The caller set a flag to ++// rehash at the next safepoint. If this bucket is 60 times greater than the ++// expected average bucket length, it's an unbalanced hashtable. ++// This is somewhat an arbitrary heuristic but if one bucket gets to ++// rehash_count which is currently 100, there's probably something wrong. ++ ++bool BasicHashtable::check_rehash_table(int count) { ++ assert(table_size() != 0, "underflow"); ++ if (count > (((double)number_of_entries()/(double)table_size())*rehash_multiple)) { ++ // Set a flag for the next safepoint, which should be at some guaranteed ++ // safepoint interval. ++ return true; ++ } ++ return false; ++} ++ ++unsigned int Hashtable::new_hash(oop string) { ++ ResourceMark rm; ++ int length; ++ if (java_lang_String::is_instance(string)) { ++ jchar* chars = java_lang_String::as_unicode_string(string, length); ++ // Use alternate hashing algorithm on the string ++ return AltHashing::murmur3_32(seed(), chars, length); ++ } else { ++ // Use alternate hashing algorithm on this symbol. ++ symbolOop symOop = (symbolOop) string; ++ return AltHashing::murmur3_32(seed(), (const jbyte*)symOop->bytes(), symOop->utf8_length()); ++ } ++} ++ ++// Create a new table and using alternate hash code, populate the new table ++// with the existing elements. This can be used to change the hash code ++// and could in the future change the size of the table. ++ ++void Hashtable::move_to(Hashtable* new_table) { ++ // Initialize the global seed for hashing. ++ assert(new_table->seed() == 0, "should be zero"); ++ _seed = AltHashing::compute_seed(); ++ assert(seed() != 0, "shouldn't be zero"); ++ new_table->set_seed(_seed); ++ ++ int saved_entry_count = this->number_of_entries(); ++ ++ // Iterate through the table and create a new entry for the new table ++ for (int i = 0; i < new_table->table_size(); ++i) { ++ for (HashtableEntry* p = bucket(i); p != NULL; ) { ++ HashtableEntry* next = p->next(); ++ oop string = p->literal(); ++ // Use alternate hashing algorithm on the symbol in the first table ++ unsigned int hashValue = new_hash(string); ++ // Get a new index relative to the new table (can also change size) ++ int index = new_table->hash_to_index(hashValue); ++ p->set_hash(hashValue); ++ // Keep the shared bit in the Hashtable entry to indicate that this entry ++ // can't be deleted. The shared bit is the LSB in the _next field so ++ // walking the hashtable past these entries requires ++ // BasicHashtableEntry::make_ptr() call. ++ bool keep_shared = p->is_shared(); ++ unlink_entry(p); ++ new_table->add_entry(index, p); ++ if (keep_shared) { ++ p->set_shared(); ++ } ++ p = next; ++ } ++ } ++ // give the new table the free list as well ++ new_table->copy_freelist(this); ++ assert(new_table->number_of_entries() == saved_entry_count, "lost entry on dictionary copy?"); ++ ++ // Destroy memory used by the buckets in the hashtable. The memory ++ // for the elements has been used in a new table and is not ++ // destroyed. The memory reuse will benefit resizing the SystemDictionary ++ // to avoid a memory allocation spike at safepoint. ++ free_buckets(); ++} ++ ++void BasicHashtable::free_buckets() { ++ if (NULL != _buckets) { ++ // Don't delete the buckets in the shared space. They aren't ++ // allocated by os::malloc ++ if (!UseSharedSpaces || ++ !FileMapInfo::current_info()->is_in_shared_space(_buckets)) { ++ FREE_C_HEAP_ARRAY(HashtableBucket, _buckets); ++ } ++ _buckets = NULL; ++ } ++} ++ ++ + // Reverse the order of elements in the hash buckets. + + void BasicHashtable::reverse() { +diff --git a/src/share/vm/utilities/hashtable.hpp b/src/share/vm/utilities/hashtable.hpp +--- openjdk/hotspot/src/share/vm/utilities/hashtable.hpp ++++ openjdk/hotspot/src/share/vm/utilities/hashtable.hpp +@@ -177,6 +177,11 @@ + void verify_lookup_length(double load); + #endif + ++ enum { ++ rehash_count = 100, ++ rehash_multiple = 60 ++ }; ++ + void initialize(int table_size, int entry_size, int number_of_entries); + + // Accessor +@@ -192,6 +197,29 @@ + // Table entry management + BasicHashtableEntry* new_entry(unsigned int hashValue); + ++ // Check that the table is unbalanced ++ bool check_rehash_table(int count); ++ ++ // Used when moving the entry to another table ++ // Clean up links, but do not add to free_list ++ void unlink_entry(BasicHashtableEntry* entry) { ++ entry->set_next(NULL); ++ --_number_of_entries; ++ } ++ ++ // Move over freelist and free block for allocation ++ void copy_freelist(BasicHashtable* src) { ++ _free_list = src->_free_list; ++ src->_free_list = NULL; ++ _first_free_entry = src->_first_free_entry; ++ src->_first_free_entry = NULL; ++ _end_block = src->_end_block; ++ src->_end_block = NULL; ++ } ++ ++ // Free the buckets in this hashtable ++ void free_buckets(); ++ + public: + void set_entry(int index, BasicHashtableEntry* entry); + +@@ -210,11 +238,11 @@ + + public: + Hashtable(int table_size, int entry_size) +- : BasicHashtable(table_size, entry_size) { } ++ : BasicHashtable(table_size, entry_size), _seed(0) { } + + Hashtable(int table_size, int entry_size, + HashtableBucket* buckets, int number_of_entries) +- : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { } ++ : BasicHashtable(table_size, entry_size, buckets, number_of_entries), _seed(0) { } + + // Invoke "f->do_oop" on the locations of all oops in the table. + void oops_do(OopClosure* f); +@@ -234,8 +262,6 @@ + + protected: + +- static unsigned int hash_symbol(const char* s, int len); +- + unsigned int compute_hash(symbolHandle name) { + return (unsigned int) name->identity_hash(); + } +@@ -256,6 +282,17 @@ + HashtableEntry** bucket_addr(int i) { + return (HashtableEntry**)BasicHashtable::bucket_addr(i); + } ++ ++ // Function to move these elements into the new table. ++ void move_to(Hashtable* new_table); ++ bool use_alternate_hashcode() { return _seed != 0; } ++ jint seed() { return _seed; } ++ void set_seed(jint seed) { _seed = seed; } ++ ++ private: ++ jint _seed; ++ ++ unsigned int new_hash(oop string); + }; + + +diff --git a/src/share/vm/utilities/hashtable.inline.hpp b/src/share/vm/utilities/hashtable.inline.hpp +--- openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp ++++ openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp +@@ -30,27 +30,6 @@ + + // Inline function definitions for hashtable.hpp. + +- +-// -------------------------------------------------------------------------- +-// Hash function +- +-// We originally used hashpjw, but hash P(31) gives just as good results +-// and is slighly faster. We would like a hash function that looks at every +-// character, since package names have large common prefixes, and also because +-// hash_or_fail does error checking while iterating. +- +-// hash P(31) from Kernighan & Ritchie +- +-inline unsigned int Hashtable::hash_symbol(const char* s, int len) { +- unsigned int h = 0; +- while (len-- > 0) { +- h = 31*h + (unsigned) *s; +- s++; +- } +- return h; +-} +- +- + // -------------------------------------------------------------------------- + + // Initialize a table.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7158801.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,30 @@ +# HG changeset patch +# User kvn +# Date 1337800285 25200 +# Node ID f7493d50b47d3946902e18153bcd912e37589d00 +# Parent 2faa3f7bad65189e69ab2f9a491743786bb8f07f +7158801: Improve VM CompileOnly option +Summary: Fixed buffer overflow during parsing flags -XX:CompileCommand=, -XX:CompileOnly= and command lines in .hotspot_compiler file. +Reviewed-by: never + +diff --git a/src/share/vm/compiler/compilerOracle.cpp b/src/share/vm/compiler/compilerOracle.cpp +--- openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp ++++ openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp +@@ -573,7 +573,7 @@ + char token[1024]; + int pos = 0; + int c = getc(stream); +- while(c != EOF) { ++ while(c != EOF && pos < (sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_from_line(token); +@@ -594,7 +594,7 @@ + int pos = 0; + const char* sp = str; + int c = *sp++; +- while (c != '\0') { ++ while (c != '\0' && pos < (sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_line(token);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7158804.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,28 @@ +# HG changeset patch +# User dbuck +# Date 1342799006 25200 +# Node ID fde4cc8479824449b03abedd5357500aec92e990 +# Parent f7493d50b47d3946902e18153bcd912e37589d00 +7158804: Improve config file parsing +Summary: see bugdb 13784108 for details +Reviewed-by: vikram, kamg + +diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp +--- openjdk/hotspot/src/share/vm/runtime/arguments.cpp ++++ openjdk/hotspot/src/share/vm/runtime/arguments.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1997, 2012, 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 +@@ -842,7 +842,7 @@ + bool result = true; + + int c = getc(stream); +- while(c != EOF) { ++ while(c != EOF && pos < (int)(sizeof(token)-1)) { + if (in_white_space) { + if (in_comment) { + if (c == '\n') in_comment = false;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7167656.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,75 @@ +# HG changeset patch +# User coffeys +# Date 1340139680 -3600 +# Node ID d04575148db287475168da344159e583f7bff02c +# Parent 1e170e3c1b682d0f98a61a47e5049535c5bd4999 +7167656: Multiple Seeders are being created +Reviewed-by: wetmore + +diff --git a/src/share/classes/sun/security/provider/SecureRandom.java b/src/share/classes/sun/security/provider/SecureRandom.java +--- openjdk/jdk/src/share/classes/sun/security/provider/SecureRandom.java ++++ openjdk/jdk/src/share/classes/sun/security/provider/SecureRandom.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1998, 2012, 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 +@@ -56,12 +56,6 @@ + + private static final long serialVersionUID = 3581829991155417889L; + +- /** +- * This static object will be seeded by SeedGenerator, and used +- * to seed future instances of SecureRandom +- */ +- private static SecureRandom seeder; +- + private static final int DIGEST_SIZE = 20; + private transient MessageDigest digest; + private byte[] state; +@@ -173,6 +167,28 @@ + } + + /** ++ * This static object will be seeded by SeedGenerator, and used ++ * to seed future instances of SHA1PRNG SecureRandoms. ++ * ++ * Bloch, Effective Java Second Edition: Item 71 ++ */ ++ private static class SeederHolder { ++ ++ private static final SecureRandom seeder; ++ ++ static { ++ /* ++ * Call to SeedGenerator.generateSeed() to add additional ++ * seed material (likely from the Native implementation). ++ */ ++ seeder = new SecureRandom(SeedGenerator.getSystemEntropy()); ++ byte [] b = new byte[DIGEST_SIZE]; ++ SeedGenerator.generateSeed(b); ++ seeder.engineSetSeed(b); ++ } ++ } ++ ++ /** + * Generates a user-specified number of random bytes. + * + * @param bytes the array to be filled in with random bytes. +@@ -183,13 +199,8 @@ + byte[] output = remainder; + + if (state == null) { +- if (seeder == null) { +- seeder = new SecureRandom(SeedGenerator.getSystemEntropy()); +- seeder.engineSetSeed(engineGenerateSeed(DIGEST_SIZE)); +- } +- + byte[] seed = new byte[DIGEST_SIZE]; +- seeder.engineNextBytes(seed); ++ SeederHolder.seeder.engineNextBytes(seed); + state = digest.digest(seed); + } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7169884.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,349 @@ +# HG changeset patch +# User robm +# Date 1347903606 -3600 +# Node ID 47e7c8e33cd82dade3e84af94bff125cdbdae062 +# Parent d04575148db287475168da344159e583f7bff02c +7169884: LogManager checks do not work correctly for sub-types +Reviewed-by: alanb + +diff --git a/src/share/classes/java/util/logging/FileHandler.java b/src/share/classes/java/util/logging/FileHandler.java +--- openjdk/jdk/src/share/classes/java/util/logging/FileHandler.java ++++ openjdk/jdk/src/share/classes/java/util/logging/FileHandler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -220,7 +220,7 @@ + * @exception NullPointerException if pattern property is an empty String. + */ + public FileHandler() throws IOException, SecurityException { +- checkAccess(); ++ checkPermission(); + configure(); + openFiles(); + } +@@ -246,7 +246,7 @@ + if (pattern.length() < 1 ) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = 0; +@@ -278,7 +278,7 @@ + if (pattern.length() < 1 ) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = 0; +@@ -315,7 +315,7 @@ + if (limit < 0 || count < 1 || pattern.length() < 1) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = limit; +@@ -354,7 +354,7 @@ + if (limit < 0 || count < 1 || pattern.length() < 1) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = limit; +@@ -367,7 +367,7 @@ + // configured instance variables. + private void openFiles() throws IOException { + LogManager manager = LogManager.getLogManager(); +- manager.checkAccess(); ++ manager.checkPermission(); + if (count < 1) { + throw new IllegalArgumentException("file count = " + count); + } +diff --git a/src/share/classes/java/util/logging/Handler.java b/src/share/classes/java/util/logging/Handler.java +--- openjdk/jdk/src/share/classes/java/util/logging/Handler.java ++++ openjdk/jdk/src/share/classes/java/util/logging/Handler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -111,7 +111,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public void setFormatter(Formatter newFormatter) throws SecurityException { +- checkAccess(); ++ checkPermission(); + // Check for a null pointer: + newFormatter.getClass(); + formatter = newFormatter; +@@ -140,7 +140,7 @@ + */ + public void setEncoding(String encoding) + throws SecurityException, java.io.UnsupportedEncodingException { +- checkAccess(); ++ checkPermission(); + if (encoding != null) { + try { + if(!java.nio.charset.Charset.isSupported(encoding)) { +@@ -175,7 +175,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public void setFilter(Filter newFilter) throws SecurityException { +- checkAccess(); ++ checkPermission(); + filter = newFilter; + } + +@@ -199,7 +199,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public void setErrorManager(ErrorManager em) { +- checkAccess(); ++ checkPermission(); + if (em == null) { + throw new NullPointerException(); + } +@@ -213,7 +213,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public ErrorManager getErrorManager() { +- checkAccess(); ++ checkPermission(); + return errorManager; + } + +@@ -253,7 +253,7 @@ + if (newLevel == null) { + throw new NullPointerException(); + } +- checkAccess(); ++ checkPermission(); + logLevel = newLevel; + } + +@@ -296,9 +296,9 @@ + // If "sealed" is true, we check that the caller has + // appropriate security privileges to update Handler + // state and if not throw a SecurityException. +- void checkAccess() throws SecurityException { ++ void checkPermission() throws SecurityException { + if (sealed) { +- manager.checkAccess(); ++ manager.checkPermission(); + } + } + } +diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java +--- openjdk/jdk/src/share/classes/java/util/logging/LogManager.java ++++ openjdk/jdk/src/share/classes/java/util/logging/LogManager.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -303,7 +303,7 @@ + if (l == null) { + throw new NullPointerException(); + } +- checkAccess(); ++ checkPermission(); + changes.addPropertyChangeListener(l); + } + +@@ -322,7 +322,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException { +- checkAccess(); ++ checkPermission(); + changes.removePropertyChangeListener(l); + } + +@@ -740,7 +740,7 @@ + * @exception IOException if there are IO problems reading the configuration. + */ + public void readConfiguration() throws IOException, SecurityException { +- checkAccess(); ++ checkPermission(); + + // if a configuration class is specified, load it and use it. + String cname = System.getProperty("java.util.logging.config.class"); +@@ -798,7 +798,7 @@ + */ + + public void reset() throws SecurityException { +- checkAccess(); ++ checkPermission(); + synchronized (this) { + props = new Properties(); + // Since we are doing a reset we no longer want to initialize +@@ -883,7 +883,7 @@ + * @exception IOException if there are problems reading from the stream. + */ + public void readConfiguration(InputStream ins) throws IOException, SecurityException { +- checkAccess(); ++ checkPermission(); + reset(); + + // Load the properties +@@ -1045,7 +1045,13 @@ + } + + +- private Permission ourPermission = new LoggingPermission("control", null); ++ private final Permission controlPermission = new LoggingPermission("control", null); ++ ++ void checkPermission() { ++ SecurityManager sm = System.getSecurityManager(); ++ if (sm != null) ++ sm.checkPermission(controlPermission); ++ } + + /** + * Check that the current context is trusted to modify the logging +@@ -1058,11 +1064,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public void checkAccess() throws SecurityException { +- SecurityManager sm = System.getSecurityManager(); +- if (sm == null) { +- return; +- } +- sm.checkPermission(ourPermission); ++ checkPermission(); + } + + // Nested class to represent a node in our tree of named loggers. +diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java +--- openjdk/jdk/src/share/classes/java/util/logging/Logger.java ++++ openjdk/jdk/src/share/classes/java/util/logging/Logger.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -266,13 +266,13 @@ + this.manager = manager; + } + +- private void checkAccess() throws SecurityException { ++ private void checkPermission() throws SecurityException { + if (!anonymous) { + if (manager == null) { + // Complete initialization of the global Logger. + manager = LogManager.getLogManager(); + } +- manager.checkAccess(); ++ manager.checkPermission(); + } + } + +@@ -454,7 +454,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public synchronized void setFilter(Filter newFilter) throws SecurityException { +- checkAccess(); ++ checkPermission(); + filter = newFilter; + } + +@@ -1145,7 +1145,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public void setLevel(Level newLevel) throws SecurityException { +- checkAccess(); ++ checkPermission(); + synchronized (treeLock) { + levelObject = newLevel; + updateEffectiveLevel(); +@@ -1200,7 +1200,7 @@ + public synchronized void addHandler(Handler handler) throws SecurityException { + // Check for null handler + handler.getClass(); +- checkAccess(); ++ checkPermission(); + if (handlers == null) { + handlers = new ArrayList<Handler>(); + } +@@ -1217,7 +1217,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public synchronized void removeHandler(Handler handler) throws SecurityException { +- checkAccess(); ++ checkPermission(); + if (handler == null) { + return; + } +@@ -1251,7 +1251,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public synchronized void setUseParentHandlers(boolean useParentHandlers) { +- checkAccess(); ++ checkPermission(); + this.useParentHandlers = useParentHandlers; + } + +@@ -1388,7 +1388,7 @@ + if (parent == null) { + throw new NullPointerException(); + } +- manager.checkAccess(); ++ manager.checkPermission(); + doSetParent(parent); + } + +diff --git a/src/share/classes/java/util/logging/MemoryHandler.java b/src/share/classes/java/util/logging/MemoryHandler.java +--- openjdk/jdk/src/share/classes/java/util/logging/MemoryHandler.java ++++ openjdk/jdk/src/share/classes/java/util/logging/MemoryHandler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -238,7 +238,7 @@ + throw new NullPointerException(); + } + LogManager manager = LogManager.getLogManager(); +- checkAccess(); ++ checkPermission(); + pushLevel = newLevel; + } + +diff --git a/src/share/classes/java/util/logging/StreamHandler.java b/src/share/classes/java/util/logging/StreamHandler.java +--- openjdk/jdk/src/share/classes/java/util/logging/StreamHandler.java ++++ openjdk/jdk/src/share/classes/java/util/logging/StreamHandler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -249,7 +249,7 @@ + } + + private synchronized void flushAndClose() throws SecurityException { +- checkAccess(); ++ checkPermission(); + if (writer != null) { + try { + if (!doneHeader) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7169888.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,125 @@ +# HG changeset patch +# User dbuck +# Date 1342799616 25200 +# Node ID 39b599e90c7b33435ca42ae96ed673812a8be3d7 +# Parent 47e7c8e33cd82dade3e84af94bff125cdbdae062 +7169888: Narrowing resource definitions in JMX RMI connector +Summary: see bugdb 13932219 for details +Reviewed-by: fparain, vikram + +diff --git a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +--- openjdk/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java ++++ openjdk/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2002, 2012, 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 +@@ -39,11 +39,17 @@ + import java.rmi.MarshalledObject; + import java.rmi.UnmarshalException; + import java.rmi.server.Unreferenced; ++ + import java.security.AccessControlContext; + import java.security.AccessController; ++import java.security.Permission; ++import java.security.PermissionCollection; ++import java.security.Permissions; + import java.security.PrivilegedAction; + import java.security.PrivilegedActionException; + import java.security.PrivilegedExceptionAction; ++import java.security.ProtectionDomain; ++ + import java.util.Arrays; + import java.util.Collections; + import java.util.Map; +@@ -60,6 +66,7 @@ + import javax.management.MBeanException; + import javax.management.MBeanInfo; + import javax.management.MBeanRegistrationException; ++import javax.management.MBeanPermission; + import javax.management.MBeanServer; + import javax.management.NotCompliantMBeanException; + import javax.management.NotificationFilter; +@@ -144,15 +151,20 @@ + this.mbeanServer = rmiServer.getMBeanServer(); + + final ClassLoader dcl = defaultClassLoader; ++ + this.classLoaderWithRepository = + AccessController.doPrivileged( + new PrivilegedAction<ClassLoaderWithRepository>() { + public ClassLoaderWithRepository run() { + return new ClassLoaderWithRepository( +- getClassLoaderRepository(), ++ mbeanServer.getClassLoaderRepository(), + dcl); + } +- }); ++ }, ++ ++ withPermissions( new MBeanPermission("*", "getClassLoaderRepository"), ++ new RuntimePermission("createClassLoader")) ++ ); + + serverCommunicatorAdmin = new + RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); +@@ -160,6 +172,17 @@ + this.env = env; + } + ++ private static AccessControlContext withPermissions(Permission ... perms){ ++ Permissions col = new Permissions(); ++ ++ for (Permission thePerm : perms ) { ++ col.add(thePerm); ++ } ++ ++ final ProtectionDomain pd = new ProtectionDomain(null, col); ++ return new AccessControlContext( new ProtectionDomain[] { pd }); ++ } ++ + private synchronized ServerNotifForwarder getServerNotifFwd() { + // Lazily created when first use. Mainly when + // addNotificationListener is first called. +@@ -1314,16 +1337,6 @@ + // private methods + //------------------------------------------------------------------------ + +- private ClassLoaderRepository getClassLoaderRepository() { +- return +- AccessController.doPrivileged( +- new PrivilegedAction<ClassLoaderRepository>() { +- public ClassLoaderRepository run() { +- return mbeanServer.getClassLoaderRepository(); +- } +- }); +- } +- + private ClassLoader getClassLoader(final ObjectName name) + throws InstanceNotFoundException { + try { +@@ -1333,7 +1346,9 @@ + public ClassLoader run() throws InstanceNotFoundException { + return mbeanServer.getClassLoader(name); + } +- }); ++ }, ++ withPermissions(new MBeanPermission("*", "getClassLoader")) ++ ); + } catch (PrivilegedActionException pe) { + throw (InstanceNotFoundException) extractException(pe); + } +@@ -1348,7 +1363,9 @@ + public Object run() throws InstanceNotFoundException { + return mbeanServer.getClassLoaderFor(name); + } +- }); ++ }, ++ withPermissions(new MBeanPermission("*", "getClassLoaderFor")) ++ ); + } catch (PrivilegedActionException pe) { + throw (InstanceNotFoundException) extractException(pe); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7172522.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,36 @@ +# HG changeset patch +# User coffeys +# Date 1340096399 -3600 +# Node ID 88243aa6e67b6b84ff529ccdfd3b476410f60057 +# Parent 39b599e90c7b33435ca42ae96ed673812a8be3d7 +7172522: Improve DomainCombiner checking +Reviewed-by: mullan + +diff --git a/src/share/classes/java/security/AccessController.java b/src/share/classes/java/security/AccessController.java +--- openjdk/jdk/src/share/classes/java/security/AccessController.java ++++ openjdk/jdk/src/share/classes/java/security/AccessController.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1997, 2012, 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 +@@ -293,7 +293,7 @@ + DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); + if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action); ++ return AccessController.doPrivileged(action, acc); + } + return AccessController.doPrivileged(action, preserveCombiner(dc)); + } +@@ -389,7 +389,7 @@ + DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); + if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action); ++ return AccessController.doPrivileged(action, acc); + } + return AccessController.doPrivileged(action, preserveCombiner(dc)); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7176337.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,29 @@ +# HG changeset patch +# User asaha +# Date 1340145914 25200 +# Node ID a148157cd348fe4c251063db7d3973a83cfcf483 +# Parent fde4cc8479824449b03abedd5357500aec92e990 +7176337: Additional changes needed for 7158801 fix +Reviewed-by: kvn + +diff --git a/src/share/vm/compiler/compilerOracle.cpp b/src/share/vm/compiler/compilerOracle.cpp +--- openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp ++++ openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp +@@ -573,7 +573,7 @@ + char token[1024]; + int pos = 0; + int c = getc(stream); +- while(c != EOF && pos < (sizeof(token)-1)) { ++ while(c != EOF && pos < (int)(sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_from_line(token); +@@ -594,7 +594,7 @@ + int pos = 0; + const char* sp = str; + int c = *sp++; +- while (c != '\0' && pos < (sizeof(token)-1)) { ++ while (c != '\0' && pos < (int)(sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_line(token);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7186286.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,552 @@ +# HG changeset patch +# User xuelei +# Date 1343546404 25200 +# Node ID a6294da5a21f609b67a0d4d216028dda9f56e689 +# Parent 88243aa6e67b6b84ff529ccdfd3b476410f60057 +7186286: TLS implementation to better adhere to RFC +Summary: also reviewed by Alexander Fomin <Alexander.Fomin@Oracle.COM>, Andrew Gross<Andrew.Gross@Oracle.COM>, Sean Coffey<Sean.Coffey@Oracle.COM> +Reviewed-by: valeriep, wetmore + +diff --git a/src/share/classes/sun/security/pkcs11/P11Cipher.java b/src/share/classes/sun/security/pkcs11/P11Cipher.java +--- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java ++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 +@@ -650,7 +650,7 @@ + // see JCE spec + protected int engineGetKeySize(Key key) throws InvalidKeyException { + int n = P11SecretKeyFactory.convertKey +- (token, key, keyAlgorithm).keyLength(); ++ (token, key, keyAlgorithm).length(); + return n; + } + } +diff --git a/src/share/classes/sun/security/pkcs11/P11Key.java b/src/share/classes/sun/security/pkcs11/P11Key.java +--- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Key.java ++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Key.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 static sun.security.pkcs11.wrapper.PKCS11Constants.*; + + import sun.security.util.DerValue; ++import sun.security.util.Length; + + /** + * Key implementation classes. +@@ -61,7 +62,7 @@ + * @author Andreas Sterbenz + * @since 1.5 + */ +-abstract class P11Key implements Key { ++abstract class P11Key implements Key, Length { + + private final static String PUBLIC = "public"; + private final static String PRIVATE = "private"; +@@ -212,7 +213,11 @@ + return s1; + } + +- int keyLength() { ++ /** ++ * Return bit length of the key. ++ */ ++ @Override ++ public int length() { + return keyLength; + } + +diff --git a/src/share/classes/sun/security/pkcs11/P11RSACipher.java b/src/share/classes/sun/security/pkcs11/P11RSACipher.java +--- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java ++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 +@@ -201,7 +201,7 @@ + } else { + throw new InvalidKeyException("Unknown key type: " + p11Key); + } +- int n = (p11Key.keyLength() + 7) >> 3; ++ int n = (p11Key.length() + 7) >> 3; + outputSize = n; + buffer = new byte[n]; + maxInputSize = encrypt ? (n - PKCS1_MIN_PADDING_LENGTH) : n; +@@ -458,7 +458,7 @@ + + // see JCE spec + protected int engineGetKeySize(Key key) throws InvalidKeyException { +- int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength(); ++ int n = P11KeyFactory.convertKey(token, key, algorithm).length(); + return n; + } + } +diff --git a/src/share/classes/sun/security/pkcs11/P11Signature.java b/src/share/classes/sun/security/pkcs11/P11Signature.java +--- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java ++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 +@@ -274,7 +274,7 @@ + if (keyAlgorithm.equals("DSA")) { + signature = new byte[40]; + } else { +- signature = new byte[(p11Key.keyLength() + 7) >> 3]; ++ signature = new byte[(p11Key.length() + 7) >> 3]; + } + if (type == T_UPDATE) { + token.p11.C_VerifyFinal(session.id(), signature); +@@ -359,7 +359,7 @@ + if (keyAlgorithm.equals("RSA") && publicKey != p11Key) { + int keyLen; + if (publicKey instanceof P11Key) { +- keyLen = ((P11Key) publicKey).keyLength(); ++ keyLen = ((P11Key) publicKey).length(); + } else { + keyLen = ((RSAKey) publicKey).getModulus().bitLength(); + } +@@ -620,7 +620,7 @@ + + private byte[] pkcs1Pad(byte[] data) { + try { +- int len = (p11Key.keyLength() + 7) >> 3; ++ int len = (p11Key.length() + 7) >> 3; + RSAPadding padding = RSAPadding.getInstance + (RSAPadding.PAD_BLOCKTYPE_1, len); + byte[] padded = padding.pad(data); +diff --git a/src/share/classes/sun/security/ssl/HandshakeInStream.java b/src/share/classes/sun/security/ssl/HandshakeInStream.java +--- openjdk/jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java ++++ openjdk/jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -190,6 +190,7 @@ + + byte[] getBytes8() throws IOException { + int len = getInt8(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); +@@ -198,6 +199,7 @@ + + byte[] getBytes16() throws IOException { + int len = getInt16(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); +@@ -206,10 +208,19 @@ + + byte[] getBytes24() throws IOException { + int len = getInt24(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); + return b; + } + ++ // Is a length greater than available bytes in the record? ++ private void verifyLength(int len) throws SSLException { ++ if (len > available()) { ++ throw new SSLException( ++ "Not enough data to fill declared vector size"); ++ } ++ } ++ + } +diff --git a/src/share/classes/sun/security/ssl/Handshaker.java b/src/share/classes/sun/security/ssl/Handshaker.java +--- openjdk/jdk/src/share/classes/sun/security/ssl/Handshaker.java ++++ openjdk/jdk/src/share/classes/sun/security/ssl/Handshaker.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -776,9 +776,9 @@ + if (debug != null && Debug.isOn("handshake")) { + System.out.println("RSA master secret generation error:"); + e.printStackTrace(System.out); +- System.out.println("Generating new random premaster secret"); + } +- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion); ++ preMasterSecret = ++ RSAClientKeyExchange.generateDummySecret(protocolVersion); + // recursive call with new premaster secret + return calculateMasterSecret(preMasterSecret, null); + } +@@ -821,9 +821,9 @@ + System.out.println("RSA PreMasterSecret version error: expected" + + protocolVersion + " or " + requestedVersion + ", decrypted: " + + premasterVersion); +- System.out.println("Generating new random premaster secret"); + } +- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion); ++ preMasterSecret = ++ RSAClientKeyExchange.generateDummySecret(protocolVersion); + // recursive call with new premaster secret + return calculateMasterSecret(preMasterSecret, null); + } +diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +--- openjdk/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java ++++ openjdk/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -36,6 +36,7 @@ + import javax.net.ssl.*; + + import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; ++import sun.security.util.KeyLength; + + /** + * This is the client key exchange message (CLIENT --> SERVER) used with +@@ -85,7 +86,8 @@ + * it, using its RSA private key. Result is the same size as the + * server's public key, and uses PKCS #1 block format 02. + */ +- RSAClientKeyExchange(ProtocolVersion protocolVersion, ProtocolVersion maxVersion, ++ RSAClientKeyExchange(ProtocolVersion protocolVersion, ++ ProtocolVersion maxVersion, + SecureRandom generator, PublicKey publicKey) throws IOException { + if (publicKey.getAlgorithm().equals("RSA") == false) { + throw new SSLKeyException("Public key not of type RSA"); +@@ -120,7 +122,8 @@ + * Server gets the PKCS #1 (block format 02) data, decrypts + * it with its private key. + */ +- RSAClientKeyExchange(ProtocolVersion currentVersion, HandshakeInStream input, ++ RSAClientKeyExchange(ProtocolVersion currentVersion, ++ ProtocolVersion maxVersion, HandshakeInStream input, + int messageSize, PrivateKey privateKey) throws IOException { + + if (privateKey.getAlgorithm().equals("RSA") == false) { +@@ -143,28 +146,119 @@ + cipher.init(Cipher.UNWRAP_MODE, privateKey); + preMaster = (SecretKey)cipher.unwrap(encrypted, + "TlsRsaPremasterSecret", Cipher.SECRET_KEY); ++ ++ // polish the premaster secret ++ preMaster = polishPreMasterSecretKey( ++ currentVersion, maxVersion, preMaster, null); + } catch (Exception e) { +- /* +- * Bogus decrypted ClientKeyExchange? If so, conjure a +- * a random preMaster secret that will fail later during +- * Finished message processing. This is a countermeasure against +- * the "interactive RSA PKCS#1 encryption envelop attack" reported +- * in June 1998. Preserving the executation path will +- * mitigate timing attacks and force consistent error handling +- * that will prevent an attacking client from differentiating +- * different kinds of decrypted ClientKeyExchange bogosities. +- */ +- if (debug != null && Debug.isOn("handshake")) { +- System.out.println("Error decrypting premaster secret:"); +- e.printStackTrace(System.out); +- System.out.println("Generating random secret"); ++ // polish the premaster secret ++ preMaster = polishPreMasterSecretKey( ++ currentVersion, maxVersion, preMaster, e); ++ } ++ } ++ ++ /** ++ * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246, ++ * treating incorrectly formatted message blocks and/or mismatched ++ * version numbers in a manner indistinguishable from correctly ++ * formatted RSA blocks. ++ * ++ * RFC 5246 describes the approach as : ++ * ++ * 1. Generate a string R of 46 random bytes ++ * ++ * 2. Decrypt the message to recover the plaintext M ++ * ++ * 3. If the PKCS#1 padding is not correct, or the length of message ++ * M is not exactly 48 bytes: ++ * pre_master_secret = ClientHello.client_version || R ++ * else If ClientHello.client_version <= TLS 1.0, and version ++ * number check is explicitly disabled: ++ * pre_master_secret = M ++ * else: ++ * pre_master_secret = ClientHello.client_version || M[2..47] ++ * ++ * Note that although TLS 1.2 is not supported in this release, we still ++ * want to make use of the above approach to provide better protection. ++ */ ++ private SecretKey polishPreMasterSecretKey( ++ ProtocolVersion currentVersion, ProtocolVersion clientHelloVersion, ++ SecretKey secretKey, Exception failoverException) { ++ ++ if (failoverException == null && secretKey != null) { ++ // check the length ++ byte[] encoded = secretKey.getEncoded(); ++ if (encoded == null) { // unable to get the encoded key ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "unable to get the plaintext of the premaster secret"); ++ } ++ ++ int keySize = KeyLength.getKeySize(secretKey); ++ if (keySize > 0 && keySize != 384) { // 384 = 48 * 8 ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "incorrect length of premaster secret: " + ++ (keySize/8)); ++ } ++ ++ return generateDummySecret(currentVersion); ++ } ++ ++ // The key size is exactly 48 bytes or not accessible. ++ // ++ // Conservatively, pass the checking to master secret ++ // calculation. ++ return secretKey; ++ } else if (encoded.length == 48) { ++ // check the version ++ if (clientHelloVersion.major == encoded[0] && ++ clientHelloVersion.minor == encoded[1]) { ++ ++ return secretKey; ++ } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v && ++ currentVersion.major == encoded[0] && ++ currentVersion.minor == encoded[1]) { ++ /* ++ * For compatibility, we maintain the behavior that the ++ * version in pre_master_secret can be the negotiated ++ * version for TLS v1.0 and SSL v3.0. ++ */ ++ return secretKey; ++ } ++ ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println("Mismatching Protocol Versions, " + ++ "ClientHello.client_version is " + clientHelloVersion + ++ ", while PreMasterSecret.client_version is " + ++ ProtocolVersion.valueOf(encoded[0], encoded[1])); ++ } ++ return generateDummySecret(currentVersion); ++ } else { ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "incorrect length of premaster secret: " + ++ encoded.length); ++ } ++ return generateDummySecret(currentVersion); + } +- preMaster = generateDummySecret(currentVersion); + } ++ ++ if (debug != null && Debug.isOn("handshake") && ++ failoverException != null) { ++ System.out.println("Error decrypting premaster secret:"); ++ failoverException.printStackTrace(System.out); ++ } ++ ++ return generateDummySecret(currentVersion); + } + + // generate a premaster secret with the specified version number + static SecretKey generateDummySecret(ProtocolVersion version) { ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println("Generating a random fake premaster secret"); ++ } ++ + try { + KeyGenerator kg = + JsseJce.getKeyGenerator("SunTlsRsaPremasterSecret"); +diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java +--- openjdk/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java ++++ openjdk/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -190,8 +190,9 @@ + * temporary one used for non-export or signing-only + * certificates/keys. + */ +- RSAClientKeyExchange pms = new RSAClientKeyExchange +- (protocolVersion, input, message_len, privateKey); ++ RSAClientKeyExchange pms = new RSAClientKeyExchange( ++ protocolVersion, clientRequestedVersion, ++ input, message_len, privateKey); + preMasterSecret = this.clientKeyExchange(pms); + break; + case K_KRB5: +diff --git a/src/share/classes/sun/security/util/KeyLength.java b/src/share/classes/sun/security/util/KeyLength.java +new file mode 100644 +--- /dev/null ++++ openjdk/jdk/src/share/classes/sun/security/util/KeyLength.java +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (c) 2012, 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 ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++package sun.security.util; ++ ++import java.security.Key; ++import java.security.PrivilegedAction; ++import java.security.AccessController; ++import java.security.interfaces.ECKey; ++import java.security.interfaces.RSAKey; ++import java.security.interfaces.DSAKey; ++import javax.crypto.SecretKey; ++import javax.crypto.interfaces.DHKey; ++ ++/** ++ * A utility class to get key length ++ */ ++public final class KeyLength { ++ ++ /** ++ * Returns the key size of the given key object in bits. ++ * ++ * @param key the key object, cannot be null ++ * @return the key size of the given key object in bits, or -1 if the ++ * key size is not accessible ++ */ ++ final public static int getKeySize(Key key) { ++ int size = -1; ++ ++ if (key instanceof Length) { ++ try { ++ Length ruler = (Length)key; ++ size = ruler.length(); ++ } catch (UnsupportedOperationException usoe) { ++ // ignore the exception ++ } ++ ++ if (size >= 0) { ++ return size; ++ } ++ } ++ ++ // try to parse the length from key specification ++ if (key instanceof SecretKey) { ++ SecretKey sk = (SecretKey)key; ++ String format = sk.getFormat(); ++ if ("RAW".equals(format) && sk.getEncoded() != null) { ++ size = (sk.getEncoded().length * 8); ++ } // Otherwise, it may be a unextractable key of PKCS#11, or ++ // a key we are not able to handle. ++ } else if (key instanceof RSAKey) { ++ RSAKey pubk = (RSAKey)key; ++ size = pubk.getModulus().bitLength(); ++ } else if (key instanceof ECKey) { ++ ECKey pubk = (ECKey)key; ++ size = pubk.getParams().getOrder().bitLength(); ++ } else if (key instanceof DSAKey) { ++ DSAKey pubk = (DSAKey)key; ++ size = pubk.getParams().getP().bitLength(); ++ } else if (key instanceof DHKey) { ++ DHKey pubk = (DHKey)key; ++ size = pubk.getParams().getP().bitLength(); ++ } // Otherwise, it may be a unextractable key of PKCS#11, or ++ // a key we are not able to handle. ++ ++ return size; ++ } ++} ++ +diff --git a/src/share/classes/sun/security/util/Length.java b/src/share/classes/sun/security/util/Length.java +new file mode 100644 +--- /dev/null ++++ openjdk/jdk/src/share/classes/sun/security/util/Length.java +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 2012, 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 ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++package sun.security.util; ++ ++/** ++ * The Length interface defines the length of an object ++ */ ++public interface Length { ++ ++ /** ++ * Gets the length of this object ++ * <p> ++ * Note that if a class of java.security.Key implements this interfaces, ++ * the length should be measured in bits. ++ * ++ * @return the length of this object ++ * @throws UnsupportedOperationException if the operation is not supported ++ */ ++ public int length(); ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7189103.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,39 @@ +# HG changeset patch +# User coffeys +# Date 1345121690 -3600 +# Node ID b6a7a661db8a2141ebb2e79ba5739722d1be7bfd +# Parent a6294da5a21f609b67a0d4d216028dda9f56e689 +7189103: Executors needs to maintain state +Reviewed-by: chegar + +diff --git a/src/share/classes/java/util/concurrent/Executors.java b/src/share/classes/java/util/concurrent/Executors.java +--- openjdk/jdk/src/share/classes/java/util/concurrent/Executors.java ++++ openjdk/jdk/src/share/classes/java/util/concurrent/Executors.java +@@ -530,18 +530,17 @@ + return AccessController.doPrivileged( + new PrivilegedExceptionAction<T>() { + public T run() throws Exception { +- ClassLoader savedcl = null; + Thread t = Thread.currentThread(); +- try { +- ClassLoader cl = t.getContextClassLoader(); +- if (ccl != cl) { +- t.setContextClassLoader(ccl); +- savedcl = cl; ++ ClassLoader cl = t.getContextClassLoader(); ++ if (ccl == cl) { ++ return task.call(); ++ } else { ++ t.setContextClassLoader(ccl); ++ try { ++ return task.call(); ++ } finally { ++ t.setContextClassLoader(cl); + } +- return task.call(); +- } finally { +- if (savedcl != null) +- t.setContextClassLoader(savedcl); + } + } + }, acc);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7189490.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,55 @@ +# HG changeset patch +# User coffeys +# Date 1345121553 -3600 +# Node ID 7fe230af5036c83eb337b3560821b97c6dec08c9 +# Parent b6a7a661db8a2141ebb2e79ba5739722d1be7bfd +7189490: More improvements to DomainCombiner checking +Reviewed-by: mullan + +diff --git a/src/share/classes/java/security/AccessController.java b/src/share/classes/java/security/AccessController.java +--- openjdk/jdk/src/share/classes/java/security/AccessController.java ++++ openjdk/jdk/src/share/classes/java/security/AccessController.java +@@ -290,11 +290,11 @@ + */ + public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { + +- DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); +- if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action, acc); ++ if (acc == null) { ++ return AccessController.doPrivileged(action); + } ++ DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc)); + } + +@@ -386,11 +386,11 @@ + public static <T> T doPrivilegedWithCombiner + (PrivilegedExceptionAction<T> action) throws PrivilegedActionException { + +- DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); +- if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action, acc); ++ if (acc == null) { ++ return AccessController.doPrivileged(action); + } ++ DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc)); + } + +@@ -417,7 +417,12 @@ + // perform 'combine' on the caller of doPrivileged, + // even if the caller is from the bootclasspath + ProtectionDomain[] pds = new ProtectionDomain[] {callerPd}; +- return new AccessControlContext(combiner.combine(pds, null), combiner); ++ if (combiner == null) { ++ return new AccessControlContext(pds); ++ } else { ++ return new AccessControlContext(combiner.combine(pds, null), ++ combiner); ++ } + } + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7189567.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,95 @@ +# HG changeset patch +# User robm +# Date 1347900712 -3600 +# Node ID aa1fa3f96d77541a3bafd767001f3100fe6b8a5a +# Parent 7fe230af5036c83eb337b3560821b97c6dec08c9 +7189567: java net obselete protocol +Reviewed-by: chegar + +diff --git a/src/share/classes/java/net/URL.java b/src/share/classes/java/net/URL.java +--- openjdk/jdk/src/share/classes/java/net/URL.java ++++ openjdk/jdk/src/share/classes/java/net/URL.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1995, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1995, 2012, 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 +@@ -28,6 +28,8 @@ + import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; ++import java.security.AccessController; ++import java.security.PrivilegedAction; + import java.util.Hashtable; + import java.util.StringTokenizer; + import sun.security.util.SecurityConstants; +@@ -1110,6 +1112,21 @@ + static Hashtable handlers = new Hashtable(); + private static Object streamHandlerLock = new Object(); + ++ // special case the gopher protocol, disabled by default ++ private static final String GOPHER = "gopher"; ++ private static final String ENABLE_GOPHER_PROP = "jdk.net.registerGopherProtocol"; ++ private static final boolean enableGopher = AccessController.doPrivileged( ++ new PrivilegedAction<Boolean>() { ++ public Boolean run() { ++ String prop = System.getProperty(ENABLE_GOPHER_PROP); ++ return prop == null ? false : ++ (prop.equalsIgnoreCase("false") ? false : true); ++ } ++ }); ++ ++ // package name of the JDK implementation protocol handlers ++ private static final String JDK_PACKAGE_PREFIX = "sun.net.www.protocol"; ++ + /** + * Returns the Stream Handler. + * @param protocol the protocol to use +@@ -1141,7 +1158,7 @@ + + // REMIND: decide whether to allow the "null" class prefix + // or not. +- packagePrefixList += "sun.net.www.protocol"; ++ packagePrefixList += JDK_PACKAGE_PREFIX; + + StringTokenizer packagePrefixIter = + new StringTokenizer(packagePrefixList, "|"); +@@ -1151,6 +1168,15 @@ + + String packagePrefix = + packagePrefixIter.nextToken().trim(); ++ ++ // do not try to instantiate the JDK gopher handler ++ // unless the system property had been explicitly set ++ if (protocol.equalsIgnoreCase(GOPHER) && ++ packagePrefix.equals(JDK_PACKAGE_PREFIX) && ++ !enableGopher) { ++ continue; ++ } ++ + try { + String clsName = packagePrefix + "." + protocol + + ".Handler"; +diff --git a/test/java/net/URL/Test.java b/test/java/net/URL/Test.java +--- openjdk/jdk/test/java/net/URL/Test.java ++++ openjdk/jdk/test/java/net/URL/Test.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2001, 2012, 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 +@@ -322,10 +322,6 @@ + test("ftp://ftp.is.co.za/rfc/rfc1808.txt") + .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z(); + +- test("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles") +- .s("gopher").h("spinaltap.micro.umn.edu") +- .p("/00/Weather/California/Los%20Angeles").z(); +- + test("http://www.math.uio.no/faq/compression-faq/part1.html") + .s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z(); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7192975.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,35 @@ +# HG changeset patch +# User asaha +# Date 1349309813 25200 +# Node ID d77bc9151c1dea1a4a396fb59d58ba7c8d77fd88 +# Parent aa1fa3f96d77541a3bafd767001f3100fe6b8a5a +7192975: Conditional usage check is wrong +Reviewed-by: dsamersoff +Contributed-by: andreas.eriksson@oracle.com + +diff --git a/src/share/classes/javax/management/modelmbean/DescriptorSupport.java b/src/share/classes/javax/management/modelmbean/DescriptorSupport.java +--- openjdk/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java ++++ openjdk/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -1239,13 +1239,12 @@ + return s.substring(1, s.length() - 1); + } + final String className = s.substring(1, slash); ++ + final Constructor<?> constr; + try { ++ ReflectUtil.checkPackageAccess(className); + final ClassLoader contextClassLoader = + Thread.currentThread().getContextClassLoader(); +- if (contextClassLoader == null) { +- ReflectUtil.checkPackageAccess(className); +- } + final Class<?> c = + Class.forName(className, false, contextClassLoader); + constr = c.getConstructor(new Class[] {String.class});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7195194.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,29 @@ +# HG changeset patch +# User andrew +# Date 1349974205 -3600 +# Node ID 6a383aef225ab7bb99b723bbb29786e29747a4f0 +# Parent d77bc9151c1dea1a4a396fb59d58ba7c8d77fd88 +7195194: Better data validation for Swing +Reviewed-by: art, ahgross + +diff --git a/src/share/classes/javax/swing/text/DefaultFormatter.java b/src/share/classes/javax/swing/text/DefaultFormatter.java +--- openjdk/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java ++++ openjdk/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java +@@ -24,6 +24,8 @@ + */ + package javax.swing.text; + ++import sun.reflect.misc.ConstructorUtil; ++ + import java.io.Serializable; + import java.lang.reflect.*; + import java.text.ParseException; +@@ -245,7 +247,7 @@ + Constructor cons; + + try { +- cons = vc.getConstructor(new Class[] { String.class }); ++ cons = ConstructorUtil.getConstructor(vc, new Class[]{String.class}); + + } catch (NoSuchMethodException nsme) { + cons = null;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7195917.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,88 @@ +# HG changeset patch +# User malenkov +# Date 1348148080 -14400 +# Node ID 074f132d65c91231ca989e4c757207e1cf25a476 +# Parent 6a383aef225ab7bb99b723bbb29786e29747a4f0 +7195917: XMLDecoder parsing at close-time should be improved +Reviewed-by: art, ahgross + +diff --git a/src/share/classes/java/beans/XMLDecoder.java b/src/share/classes/java/beans/XMLDecoder.java +--- openjdk/jdk/src/share/classes/java/beans/XMLDecoder.java ++++ openjdk/jdk/src/share/classes/java/beans/XMLDecoder.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 2012, 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 +@@ -32,6 +32,10 @@ + import java.lang.ref.Reference; + import java.lang.ref.WeakReference; + ++import java.security.AccessControlContext; ++import java.security.AccessController; ++import java.security.PrivilegedAction; ++ + import org.xml.sax.SAXException; + + import javax.xml.parsers.SAXParserFactory; +@@ -66,6 +70,7 @@ + * @author Philip Milne + */ + public class XMLDecoder { ++ private final AccessControlContext acc = AccessController.getContext(); + private InputStream in; + private Object owner; + private ExceptionListener exceptionListener; +@@ -248,25 +253,33 @@ + */ + private ObjectHandler getHandler() { + if ( handler == null ) { +- SAXParserFactory factory = SAXParserFactory.newInstance(); +- try { +- SAXParser parser = factory.newSAXParser(); +- handler = new ObjectHandler( this, getClassLoader() ); +- parser.parse( in, handler ); ++ if ((this.acc == null) && (null != System.getSecurityManager())) { ++ throw new SecurityException("AccessControlContext is not set"); + } +- catch ( ParserConfigurationException e ) { +- getExceptionListener().exceptionThrown( e ); +- } +- catch ( SAXException se ) { +- Exception e = se.getException(); +- if ( e == null ) { +- e = se; ++ handler = AccessController.doPrivileged(new PrivilegedAction<ObjectHandler>() { ++ public ObjectHandler run() { ++ ObjectHandler handler = new ObjectHandler(XMLDecoder.this, getClassLoader()); ++ SAXParserFactory factory = SAXParserFactory.newInstance(); ++ try { ++ SAXParser parser = factory.newSAXParser(); ++ parser.parse( in, handler ); ++ } ++ catch ( ParserConfigurationException e ) { ++ getExceptionListener().exceptionThrown( e ); ++ } ++ catch ( SAXException se ) { ++ Exception e = se.getException(); ++ if ( e == null ) { ++ e = se; ++ } ++ getExceptionListener().exceptionThrown( e ); ++ } ++ catch ( IOException ioe ) { ++ getExceptionListener().exceptionThrown( ioe ); ++ } ++ return handler; + } +- getExceptionListener().exceptionThrown( e ); +- } +- catch ( IOException ioe ) { +- getExceptionListener().exceptionThrown( ioe ); +- } ++ }, this.acc); + } + return handler; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7195919.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,63 @@ +# HG changeset patch +# User dmeetry +# Date 1347313661 -14400 +# Node ID 5352a40bb0ff7e8a6e826478d7687fff695d9805 +# Parent 074f132d65c91231ca989e4c757207e1cf25a476 +7195919: (sl) ServiceLoader can throw CCE without needing to create instance +Reviewed-by: smarks + +diff --git a/src/share/classes/java/util/ServiceLoader.java b/src/share/classes/java/util/ServiceLoader.java +--- openjdk/jdk/src/share/classes/java/util/ServiceLoader.java ++++ openjdk/jdk/src/share/classes/java/util/ServiceLoader.java +@@ -358,14 +358,21 @@ + } + String cn = nextName; + nextName = null; ++ Class<?> c = null; + try { +- S p = service.cast(Class.forName(cn, true, loader) +- .newInstance()); +- providers.put(cn, p); +- return p; ++ c = Class.forName(cn, false, loader); + } catch (ClassNotFoundException x) { + fail(service, + "Provider " + cn + " not found"); ++ } ++ if (!service.isAssignableFrom(c)) { ++ fail(service, ++ "Provider " + cn + " not a subtype"); ++ } ++ try { ++ S p = service.cast(c.newInstance()); ++ providers.put(cn, p); ++ return p; + } catch (Throwable x) { + fail(service, + "Provider " + cn + " could not be instantiated: " + x, +diff --git a/src/share/classes/sun/misc/Service.java b/src/share/classes/sun/misc/Service.java +--- openjdk/jdk/src/share/classes/sun/misc/Service.java ++++ openjdk/jdk/src/share/classes/sun/misc/Service.java +@@ -284,12 +284,20 @@ + } + String cn = nextName; + nextName = null; ++ Class<?> c = null; + try { +- return Class.forName(cn, true, loader).newInstance(); ++ c = Class.forName(cn, false, loader); + } catch (ClassNotFoundException x) { + fail(service, + "Provider " + cn + " not found"); +- } catch (Exception x) { ++ } ++ if (!service.isAssignableFrom(c)) { ++ fail(service, ++ "Provider " + cn + " not a subtype"); ++ } ++ try { ++ return service.cast(c.newInstance()); ++ } catch (Throwable x) { + fail(service, + "Provider " + cn + " could not be instantiated: " + x, + x);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7198296.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,114 @@ +# HG changeset patch +# User asaha +# Date 1349309940 25200 +# Node ID a66bba985c2c46743d6780879278092c0fa5cf2b +# Parent 5352a40bb0ff7e8a6e826478d7687fff695d9805 +7198296: Refactor classloader usage +Reviewed-by: dsamersoff +Contributed-by: andreas.eriksson@oracle.com + +diff --git a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +--- openjdk/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java ++++ openjdk/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +@@ -165,9 +165,17 @@ + withPermissions( new MBeanPermission("*", "getClassLoaderRepository"), + new RuntimePermission("createClassLoader")) + ); +- +- serverCommunicatorAdmin = new +- RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); ++ this.defaultContextClassLoader = ++ AccessController.doPrivileged( ++ new PrivilegedAction<ClassLoader>() { ++ @Override ++ public ClassLoader run() { ++ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), ++ dcl); ++ } ++ }); ++ serverCommunicatorAdmin = new ++ RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); + + this.env = env; + } +@@ -529,7 +537,7 @@ + "connectionId=" + connectionId + +" unwrapping query with defaultClassLoader."); + +- queryValue = unwrap(query, defaultClassLoader, QueryExp.class); ++ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class); + + try { + final Object params[] = new Object[] { name, queryValue }; +@@ -563,7 +571,7 @@ + "connectionId=" + connectionId + +" unwrapping query with defaultClassLoader."); + +- queryValue = unwrap(query, defaultClassLoader, QueryExp.class); ++ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class); + + try { + final Object params[] = new Object[] { name, queryValue }; +@@ -1592,7 +1600,8 @@ + ClassLoader orderCL = AccessController.doPrivileged( + new PrivilegedExceptionAction<ClassLoader>() { + public ClassLoader run() throws Exception { +- return new OrderClassLoaders(cl1, cl2); ++ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), ++ new OrderClassLoaders(cl1, cl2)); + } + } + ); +@@ -1684,6 +1693,8 @@ + + private final ClassLoader defaultClassLoader; + ++ private final ClassLoader defaultContextClassLoader; ++ + private final ClassLoaderWithRepository classLoaderWithRepository; + + private boolean terminated = false; +@@ -1768,4 +1779,43 @@ + + private static final ClassLogger logger = + new ClassLogger("javax.management.remote.rmi", "RMIConnectionImpl"); ++ ++ private static final class CombinedClassLoader extends ClassLoader { ++ ++ private final static class ClassLoaderWrapper extends ClassLoader { ++ ClassLoaderWrapper(ClassLoader cl) { ++ super(cl); ++ } ++ ++ @Override ++ protected Class<?> loadClass(String name, boolean resolve) ++ throws ClassNotFoundException { ++ return super.loadClass(name, resolve); ++ } ++ }; ++ ++ final ClassLoaderWrapper defaultCL; ++ ++ private CombinedClassLoader(ClassLoader parent, ClassLoader defaultCL) { ++ super(parent); ++ this.defaultCL = new ClassLoaderWrapper(defaultCL); ++ } ++ ++ @Override ++ protected Class<?> loadClass(String name, boolean resolve) ++ throws ClassNotFoundException { ++ try { ++ super.loadClass(name, resolve); ++ } catch(Exception e) { ++ for(Throwable t = e; t != null; t = t.getCause()) { ++ if(t instanceof SecurityException) { ++ throw t==e?(SecurityException)t:new SecurityException(t.getMessage(), e); ++ } ++ } ++ } ++ final Class<?> cl = defaultCL.loadClass(name, resolve); ++ return cl; ++ } ++ ++ } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20121016/7198606.patch Thu Oct 11 21:32:13 2012 +0100 @@ -0,0 +1,28 @@ +# HG changeset patch +# User andrew +# Date 1349974451 -3600 +# Node ID 8319efc7c840d099832e06db7a50dcfb95bfd4aa +# Parent a148157cd348fe4c251063db7d3973a83cfcf483 +7198606: Improve VM optimization +Reviewed-by: roland, twisti + +diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp +--- openjdk/hotspot/src/share/vm/opto/loopTransform.cpp ++++ openjdk/hotspot/src/share/vm/opto/loopTransform.cpp +@@ -2721,6 +2721,8 @@ + result_mem = new (C, 1) ProjNode(call,TypeFunc::Memory); + _igvn.register_new_node_with_optimizer(result_mem); + ++/* Disable following optimization until proper fix (add missing checks). ++ + // If this fill is tightly coupled to an allocation and overwrites + // the whole body, allow it to take over the zeroing. + AllocateNode* alloc = AllocateNode::Ideal_allocation(base, this); +@@ -2744,6 +2746,7 @@ + #endif + } + } ++*/ + + // Redirect the old control and memory edges that are outside the loop. + Node* exit = head->loopexit()->proj_out(0);