Fix security bug with use of thread context class loader.
diff --git a/build/solaris/makefiles/Defs.gmk b/build/solaris/makefiles/Defs.gmk index 3028ac7..6a041b7 100644 --- a/build/solaris/makefiles/Defs.gmk +++ b/build/solaris/makefiles/Defs.gmk
@@ -29,9 +29,9 @@ # Default JAVAHOME # ifeq ($(ARCH), sparc) - _JAVAHOME = /java/re/jdk/1.4.2/archive/fcs/binaries/solaris-sparc + _JAVAHOME = /java/re/jdk/1.5.0/archive/fcs/binaries/solaris-sparc else - _JAVAHOME = /java/re/jdk/1.4.2/archive/fcs/binaries/solaris-i586 + _JAVAHOME = /java/re/jdk/1.5.0/archive/fcs/binaries/solaris-i586 endif # @@ -183,7 +183,7 @@ # # Invoking the Java compiler # -JAVAC_CMD = $(JAVAC) -source 1.4 +JAVAC_CMD = $(JAVAC) -source 1.5 # # Set opt level to ALT_OPT if set otherwise _OPT
diff --git a/src/share/classes/javax/activation/CommandMap.java b/src/share/classes/javax/activation/CommandMap.java index 7da1e2a..79a2cbc 100644 --- a/src/share/classes/javax/activation/CommandMap.java +++ b/src/share/classes/javax/activation/CommandMap.java
@@ -40,6 +40,9 @@ package javax.activation; +import java.util.Map; +import java.util.WeakHashMap; + /** * The CommandMap class provides an interface to a registry of @@ -51,6 +54,8 @@ */ public abstract class CommandMap { private static CommandMap defaultCommandMap = null; + private static Map<ClassLoader,CommandMap> map = + new WeakHashMap<ClassLoader,CommandMap>(); /** * Get the default CommandMap. @@ -69,11 +74,18 @@ * * @return the CommandMap */ - public static CommandMap getDefaultCommandMap() { - if (defaultCommandMap == null) - defaultCommandMap = new MailcapCommandMap(); + public static synchronized CommandMap getDefaultCommandMap() { + if (defaultCommandMap != null) + return defaultCommandMap; - return defaultCommandMap; + // fetch per-thread-context-class-loader default + ClassLoader tccl = SecuritySupport.getContextClassLoader(); + CommandMap def = map.get(tccl); + if (def == null) { + def = new MailcapCommandMap(); + map.put(tccl, def); + } + return def; } /** @@ -84,7 +96,7 @@ * @exception SecurityException if the caller doesn't have permission * to change the default */ - public static void setDefaultCommandMap(CommandMap commandMap) { + public static synchronized void setDefaultCommandMap(CommandMap commandMap) { SecurityManager security = System.getSecurityManager(); if (security != null) { try { @@ -92,13 +104,16 @@ security.checkSetFactory(); } catch (SecurityException ex) { // otherwise, we also allow it if this code and the - // factory come from the same class loader (e.g., + // factory come from the same (non-system) class loader (e.g., // the JAF classes were loaded with the applet classes). - if (CommandMap.class.getClassLoader() != + if (CommandMap.class.getClassLoader() == null || + CommandMap.class.getClassLoader() != commandMap.getClass().getClassLoader()) throw ex; } } + // remove any per-thread-context-class-loader CommandMap + map.remove(SecuritySupport.getContextClassLoader()); defaultCommandMap = commandMap; }
diff --git a/src/share/classes/javax/activation/DataHandler.java b/src/share/classes/javax/activation/DataHandler.java index 901a93f..22b941d 100644 --- a/src/share/classes/javax/activation/DataHandler.java +++ b/src/share/classes/javax/activation/DataHandler.java
@@ -381,7 +381,10 @@ // if it's not set, set it... if (transferFlavors == emptyFlavors) transferFlavors = getDataContentHandler().getTransferDataFlavors(); - return transferFlavors; + if (transferFlavors == emptyFlavors) + return transferFlavors; + else + return (DataFlavor[])transferFlavors.clone(); } /**
diff --git a/src/share/classes/javax/activation/FileTypeMap.java b/src/share/classes/javax/activation/FileTypeMap.java index 8b7079e..1050590 100644 --- a/src/share/classes/javax/activation/FileTypeMap.java +++ b/src/share/classes/javax/activation/FileTypeMap.java
@@ -41,6 +41,8 @@ package javax.activation; import java.io.File; +import java.util.Map; +import java.util.WeakHashMap; /** * The FileTypeMap is an abstract class that provides a data typing @@ -61,6 +63,8 @@ public abstract class FileTypeMap { private static FileTypeMap defaultMap = null; + private static Map<ClassLoader,FileTypeMap> map = + new WeakHashMap<ClassLoader,FileTypeMap>(); /** * The default constructor. @@ -95,7 +99,7 @@ * @exception SecurityException if the caller doesn't have permission * to change the default */ - public static void setDefaultFileTypeMap(FileTypeMap map) { + public static synchronized void setDefaultFileTypeMap(FileTypeMap map) { SecurityManager security = System.getSecurityManager(); if (security != null) { try { @@ -103,9 +107,10 @@ security.checkSetFactory(); } catch (SecurityException ex) { // otherwise, we also allow it if this code and the - // factory come from the same class loader (e.g., + // factory come from the same (non-system) class loader (e.g., // the JAF classes were loaded with the applet classes). - if (FileTypeMap.class.getClassLoader() != + if (FileTypeMap.class.getClassLoader() == null || + FileTypeMap.class.getClassLoader() != map.getClass().getClassLoader()) throw ex; } @@ -122,10 +127,17 @@ * @return The default FileTypeMap * @see javax.activation.FileTypeMap#setDefaultFileTypeMap */ - public static FileTypeMap getDefaultFileTypeMap() { - // XXX - probably should be synchronized - if (defaultMap == null) - defaultMap = new MimetypesFileTypeMap(); - return defaultMap; + public static synchronized FileTypeMap getDefaultFileTypeMap() { + if (defaultMap != null) + return defaultMap; + + // fetch per-thread-context-class-loader default + ClassLoader tccl = SecuritySupport.getContextClassLoader(); + FileTypeMap def = map.get(tccl); + if (def == null) { + def = new MimetypesFileTypeMap(); + map.put(tccl, def); + } + return def; } }
diff --git a/src/share/classes/javax/activation/MailcapCommandMap.java b/src/share/classes/javax/activation/MailcapCommandMap.java index 5f2c319..2c83938 100644 --- a/src/share/classes/javax/activation/MailcapCommandMap.java +++ b/src/share/classes/javax/activation/MailcapCommandMap.java
@@ -133,11 +133,7 @@ public class MailcapCommandMap extends CommandMap { /* * We manage a collection of databases, searched in order. - * The default database is shared between all instances - * of this class. - * XXX - Can we safely share more databases between instances? */ - private static MailcapFile defDB = null; private MailcapFile[] DB; private static final int PROG = 0; // programmatically added entries @@ -177,14 +173,10 @@ loadAllResources(dbv, "META-INF/mailcap"); LogSupport.log("MailcapCommandMap: load DEF"); - synchronized (MailcapCommandMap.class) { - // see if another instance has created this yet. - if (defDB == null) - defDB = loadResource("/META-INF/mailcap.default"); - } + mf = loadResource("/META-INF/mailcap.default"); - if (defDB != null) - dbv.add(defDB); + if (mf != null) + dbv.add(mf); DB = new MailcapFile[dbv.size()]; DB = (MailcapFile[])dbv.toArray(DB);
diff --git a/src/share/classes/javax/activation/MimetypesFileTypeMap.java b/src/share/classes/javax/activation/MimetypesFileTypeMap.java index eef6c5f..0d9fbd4 100644 --- a/src/share/classes/javax/activation/MimetypesFileTypeMap.java +++ b/src/share/classes/javax/activation/MimetypesFileTypeMap.java
@@ -82,11 +82,7 @@ public class MimetypesFileTypeMap extends FileTypeMap { /* * We manage a collection of databases, searched in order. - * The default database is shared between all instances - * of this class. - * XXX - Can we safely share more databases between instances? */ - private static MimeTypeFile defDB = null; private MimeTypeFile[] DB; private static final int PROG = 0; // programmatically added entries @@ -127,14 +123,10 @@ loadAllResources(dbv, "META-INF/mime.types"); LogSupport.log("MimetypesFileTypeMap: load DEF"); - synchronized (MimetypesFileTypeMap.class) { - // see if another instance has created this yet. - if (defDB == null) - defDB = loadResource("/META-INF/mimetypes.default"); - } + mf = loadResource("/META-INF/mimetypes.default"); - if (defDB != null) - dbv.addElement(defDB); + if (mf != null) + dbv.addElement(mf); DB = new MimeTypeFile[dbv.size()]; dbv.copyInto(DB);