You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2014/09/08 00:39:06 UTC

[27/32] git commit: Add better security support in LoaderUtil.

Add better security support in LoaderUtil.

  - Now, instead of failing due to lack of the getClassLoader RuntimePermission, this class falls back to the ClassLoader of LoaderUtil.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2423e44b
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2423e44b
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2423e44b

Branch: refs/heads/master
Commit: 2423e44b1330c090b453e82b18118d2b3bacbaa7
Parents: 86fe4ca
Author: Matt Sicker <ma...@apache.org>
Authored: Sun Sep 7 16:43:53 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Sun Sep 7 16:43:53 2014 -0500

----------------------------------------------------------------------
 .../apache/logging/log4j/util/LoaderUtil.java   | 30 ++++++++++++++++----
 1 file changed, 25 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2423e44b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
index ed77589..374a458 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
@@ -23,34 +23,53 @@ import java.security.PrivilegedAction;
 /**
  * <em>Consider this class private.</em> Utility class for ClassLoaders.
  * @see ClassLoader
+ * @see RuntimePermission
  * @see Thread#getContextClassLoader()
+ * @see ClassLoader#getSystemClassLoader()
  */
-// TODO: migrate any other useful methods from Loader in log4j-core
 public final class LoaderUtil {
     private LoaderUtil() {}
 
     public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";
 
+    private static final SecurityManager SECURITY_MANAGER = System.getSecurityManager();
+
     // this variable must be lazily loaded; otherwise, we get a nice circular class loading problem where LoaderUtil
     // wants to use PropertiesUtil, but then PropertiesUtil wants to use LoaderUtil.
     private static Boolean ignoreTCCL;
 
+    private static final boolean GET_CLASS_LOADER_DISABLED;
+
     private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new ThreadContextClassLoaderGetter();
 
     static {
-        final SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new RuntimePermission("getClassLoader"));
+        if (SECURITY_MANAGER != null) {
+            boolean getClassLoaderDisabled;
+            try {
+                SECURITY_MANAGER.checkPermission(new RuntimePermission("getClassLoader"));
+                getClassLoaderDisabled = false;
+            } catch (final SecurityException ignored) {
+                getClassLoaderDisabled = true;
+            }
+            GET_CLASS_LOADER_DISABLED = getClassLoaderDisabled;
+        } else {
+            GET_CLASS_LOADER_DISABLED = false;
         }
     }
 
     /**
      * Gets the current Thread ClassLoader. Returns the system ClassLoader if the TCCL is {@code null}.
+     * If running with a {@link SecurityManager} that does not allow access to the Thread ClassLoader or system
+     * ClassLoader, then the ClassLoader for this class is returned.
      *
      * @return the current ThreadContextClassLoader.
      */
     public static ClassLoader getThreadContextClassLoader() {
-        return System.getSecurityManager() == null
+        if (GET_CLASS_LOADER_DISABLED) {
+            // we can at least get this class's ClassLoader regardless of security context
+            return LoaderUtil.class.getClassLoader();
+        }
+        return SECURITY_MANAGER == null
             ? TCCL_GETTER.run()
             : AccessController.doPrivileged(TCCL_GETTER);
     }
@@ -101,6 +120,7 @@ public final class LoaderUtil {
         try {
             return clazz.getConstructor().newInstance();
         } catch (final NoSuchMethodException e) {
+            // FIXME: looking at the code for Class.newInstance(), this seems to do the same thing as above
             return clazz.newInstance();
         }
     }