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();
}
}