--- old/src/share/classes/java/net/InetAddress.java 2014-06-25 13:41:08.631137593 +0200 +++ new/src/share/classes/java/net/InetAddress.java 2014-06-25 13:41:08.546139054 +0200 @@ -252,8 +252,91 @@ return holder; } - /* Used to store the name service provider */ - private static List nameServices = null; + /* Used to store the name service providers */ + private static final class NameServices { + private static final List nameServices = new ArrayList<>(); + + static { + // get name service if provided and requested + String propPrefix = "sun.net.spi.nameservice.provider."; + int n = 1; + String provider = AccessController.doPrivileged( + new GetPropertyAction(propPrefix + n)); + while (provider != null) { + NameService ns = createNSProvider(provider); + if (ns != null) + nameServices.add(ns); + + n++; + provider = AccessController.doPrivileged( + new GetPropertyAction(propPrefix + n)); + } + + // if not designate any name services provider, + // create a default one + if (nameServices.size() == 0) { + NameService ns = createNSProvider("default"); + nameServices.add(ns); + } + } + + private static NameService createNSProvider(String provider) { + if (provider == null) + return null; + + NameService nameService = null; + if (provider.equals("default")) { + // initialize the default name service + nameService = new NameService() { + public InetAddress[] lookupAllHostAddr(String host) + throws UnknownHostException { + return impl.lookupAllHostAddr(host); + } + public String getHostByAddr(byte[] addr) + throws UnknownHostException { + return impl.getHostByAddr(addr); + } + }; + } else { + final String providerName = provider; + try { + nameService = java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public NameService run() { + Iterator itr = + ServiceLoader.load(NameServiceDescriptor.class) + .iterator(); + while (itr.hasNext()) { + NameServiceDescriptor nsd = itr.next(); + if (providerName. + equalsIgnoreCase(nsd.getType()+"," + +nsd.getProviderName())) { + try { + return nsd.createNameService(); + } catch (Exception e) { + e.printStackTrace(); + System.err.println( + "Cannot create name service:" + +providerName+": " + e); + } + } + } + + return null; + } + } + ); + } catch (java.security.PrivilegedActionException e) { + } + } + + return nameService; + } + + static List get() { + return nameServices; + } + } /* Used to store the best available hostname */ private transient String canonicalHostName = null; @@ -590,7 +673,7 @@ */ private static String getHostFromNameService(InetAddress addr, boolean check) { String host = null; - for (NameService nameService : nameServices) { + for (NameService nameService : NameServices.get()) { try { // first lookup the hostname host = nameService.getHostByAddr(addr.getAddress()); @@ -894,86 +977,9 @@ return null; } - private static NameService createNSProvider(String provider) { - if (provider == null) - return null; - - NameService nameService = null; - if (provider.equals("default")) { - // initialize the default name service - nameService = new NameService() { - public InetAddress[] lookupAllHostAddr(String host) - throws UnknownHostException { - return impl.lookupAllHostAddr(host); - } - public String getHostByAddr(byte[] addr) - throws UnknownHostException { - return impl.getHostByAddr(addr); - } - }; - } else { - final String providerName = provider; - try { - nameService = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public NameService run() { - Iterator itr = - ServiceLoader.load(NameServiceDescriptor.class) - .iterator(); - while (itr.hasNext()) { - NameServiceDescriptor nsd = itr.next(); - if (providerName. - equalsIgnoreCase(nsd.getType()+"," - +nsd.getProviderName())) { - try { - return nsd.createNameService(); - } catch (Exception e) { - e.printStackTrace(); - System.err.println( - "Cannot create name service:" - +providerName+": " + e); - } - } - } - - return null; - } - } - ); - } catch (java.security.PrivilegedActionException e) { - } - } - - return nameService; - } - static { // create the impl impl = InetAddressImplFactory.create(); - - // get name service if provided and requested - String provider = null;; - String propPrefix = "sun.net.spi.nameservice.provider."; - int n = 1; - nameServices = new ArrayList(); - provider = AccessController.doPrivileged( - new GetPropertyAction(propPrefix + n)); - while (provider != null) { - NameService ns = createNSProvider(provider); - if (ns != null) - nameServices.add(ns); - - n++; - provider = AccessController.doPrivileged( - new GetPropertyAction(propPrefix + n)); - } - - // if not designate any name services provider, - // create a default one - if (nameServices.size() == 0) { - NameService ns = createNSProvider("default"); - nameServices.add(ns); - } } /** @@ -1291,7 +1297,7 @@ // This is the first thread which looks up the addresses // this host or the cache entry for this host has been // expired so this thread should do the lookup. - for (NameService nameService : nameServices) { + for (NameService nameService : NameServices.get()) { try { /* * Do not put the call to lookup() inside the --- old/src/share/classes/java/net/NetworkInterface.java 2014-06-25 13:41:08.878133349 +0200 +++ new/src/share/classes/java/net/NetworkInterface.java 2014-06-25 13:41:08.793134810 +0200 @@ -452,6 +452,11 @@ } } } + return getHardwareAddress0(); + } + + // the same as getHardwareAddress(), but without security checks + byte[] getHardwareAddress0() throws SocketException { for (InetAddress addr : addrs) { if (addr instanceof Inet4Address) { return getMacAddr0(((Inet4Address)addr).getAddress(), name, index); --- old/src/share/classes/java/net/URLClassLoader.java 2014-06-25 13:41:09.103129483 +0200 +++ new/src/share/classes/java/net/URLClassLoader.java 2014-06-25 13:41:09.019130926 +0200 @@ -762,6 +762,10 @@ public URLClassPath getURLClassPath (URLClassLoader u) { return u.ucp; } + public byte[] getHardwareAddress0(NetworkInterface ni) + throws SocketException { + return ni.getHardwareAddress0(); + } } ); ClassLoader.registerAsParallelCapable(); --- old/src/share/classes/java/util/SplittableRandom.java 2014-06-25 13:41:09.329125599 +0200 +++ new/src/share/classes/java/util/SplittableRandom.java 2014-06-25 13:41:09.245127043 +0200 @@ -25,7 +25,13 @@ package java.util; +import sun.misc.JavaNetAccess; +import sun.misc.SharedSecrets; + import java.net.NetworkInterface; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; import java.util.concurrent.atomic.AtomicLong; import java.util.function.IntConsumer; import java.util.function.LongConsumer; @@ -230,8 +236,22 @@ String pp = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction( "java.util.secureRandomSeed")); - if (pp != null && pp.equalsIgnoreCase("true")) { - byte[] seedBytes = java.security.SecureRandom.getSeed(8); + if (pp != null) { + SecureRandom sr; + if (pp.equalsIgnoreCase("true")) { + sr = new SecureRandom(); + } else { + String[] args = pp.split(",", 2); + try { + sr = args.length > 1 + ? SecureRandom.getInstance(args[0], args[1]) + : SecureRandom.getInstance(args[0]); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + throw new IllegalArgumentException( + "Invalid java.util.secureRandomSeed property: " + pp, e); + } + } + byte[] seedBytes = sr.generateSeed(8); long s = (long)(seedBytes[0]) & 0xffL; for (int i = 1; i < 8; ++i) s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); @@ -241,11 +261,12 @@ try { Enumeration ifcs = NetworkInterface.getNetworkInterfaces(); + JavaNetAccess jna = SharedSecrets.getJavaNetAccess(); boolean retry = false; // retry once if getHardwareAddress is null while (ifcs.hasMoreElements()) { NetworkInterface ifc = ifcs.nextElement(); if (!ifc.isVirtual()) { // skip fake addresses - byte[] bs = ifc.getHardwareAddress(); + byte[] bs = jna.getHardwareAddress0(ifc); if (bs != null) { int n = bs.length; int m = Math.min(n >>> 1, 4); --- old/src/share/classes/java/util/concurrent/ThreadLocalRandom.java 2014-06-25 13:41:09.576121355 +0200 +++ new/src/share/classes/java/util/concurrent/ThreadLocalRandom.java 2014-06-25 13:41:09.490122832 +0200 @@ -35,8 +35,14 @@ package java.util.concurrent; +import sun.misc.JavaNetAccess; +import sun.misc.SharedSecrets; + import java.io.ObjectStreamField; import java.net.NetworkInterface; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; import java.util.Enumeration; import java.util.Random; import java.util.Spliterator; @@ -140,8 +146,22 @@ String pp = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction( "java.util.secureRandomSeed")); - if (pp != null && pp.equalsIgnoreCase("true")) { - byte[] seedBytes = java.security.SecureRandom.getSeed(8); + if (pp != null) { + SecureRandom sr; + if (pp.equalsIgnoreCase("true")) { + sr = new SecureRandom(); + } else { + String[] args = pp.split(",", 2); + try { + sr = args.length > 1 + ? SecureRandom.getInstance(args[0], args[1]) + : SecureRandom.getInstance(args[0]); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + throw new IllegalArgumentException( + "Invalid java.util.secureRandomSeed property: " + pp, e); + } + } + byte[] seedBytes = sr.generateSeed(8); long s = (long)(seedBytes[0]) & 0xffL; for (int i = 1; i < 8; ++i) s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); @@ -151,11 +171,12 @@ try { Enumeration ifcs = NetworkInterface.getNetworkInterfaces(); + JavaNetAccess jna = SharedSecrets.getJavaNetAccess(); boolean retry = false; // retry once if getHardwareAddress is null while (ifcs.hasMoreElements()) { NetworkInterface ifc = ifcs.nextElement(); if (!ifc.isVirtual()) { // skip fake addresses - byte[] bs = ifc.getHardwareAddress(); + byte[] bs = jna.getHardwareAddress0(ifc); if (bs != null) { int n = bs.length; int m = Math.min(n >>> 1, 4); --- old/src/share/classes/sun/misc/JavaNetAccess.java 2014-06-25 13:41:09.827117042 +0200 +++ new/src/share/classes/sun/misc/JavaNetAccess.java 2014-06-25 13:41:09.739118554 +0200 @@ -25,6 +25,8 @@ package sun.misc; +import java.net.NetworkInterface; +import java.net.SocketException; import java.net.URLClassLoader; public interface JavaNetAccess { @@ -32,4 +34,15 @@ * return the URLClassPath belonging to the given loader */ URLClassPath getURLClassPath (URLClassLoader u); + + /** + * Returns the hardware address (usually MAC) of the interface if it + * has one. No security checks are performed. + * + * @return a byte array containing the address, or {@code null} if + * the address doesn't exist + * + * @exception SocketException if an I/O error occurs. + */ + byte[] getHardwareAddress0(NetworkInterface ni) throws SocketException; }