[logback-user] SecurityManager issue using logback

Ralph Goers rgoers at apache.org
Sun Nov 6 02:47:26 CET 2011


What I find interesting is that IntelliJ says getClassLoaderAsPrivileged isn't even used by anything in Logback.

Ralph

On Nov 5, 2011, at 5:32 PM, Joern Huxhorn wrote:

> There is one issue with the code in http://goo.gl/zASBm, though:
> It checks for getClassLoader permission in a static code block only, i.e. when the class is initially loaded by the classloader,  and saves that information for later reference.
> 
> I don't think that this is a valid optimization for precisely the reason that this permission can change during runtime (according to http://download.oracle.com/javase/1.4.2/docs/api/java/security/AccessController.html even per thread), for example if a different SecurityManager is installed.
> 
> The method using the statically initialized boolean should probably look like this instead:
> 
> public static ClassLoader getClassLoaderAsPrivileged(final Class clazz) {
>  try {
>    AccessController.checkPermission(new RuntimePermission("getClassLoader"));
>    return AccessController.doPrivileged(
>        new PrivilegedAction<ClassLoader>() {
>          public ClassLoader run() {
>            return clazz.getClassLoader();
>          }
>        });
>  } catch (AccessControlException e) {
>    return null;
>  }
> }
> 
> Not sure if this would solve the problem at hand...
> 
> Joern.
> 
> On 05.11.2011, at 16:25, ceki wrote:
> 
>> 
>> Thanks for the sample project. I can confirm that I observe a
>> AccessControlException when logback is present. The
>> AccessControlException is not thrown if slf4j-nop, slf4j-simple or
>> slf4j-log4j are used as the slf4j binding.
>> 
>> Although logback does not install its own SecurityManager or modify
>> the security configuration, it does attempt to determine whether it
>> has "getClassLoader" permission. See http://goo.gl/zASBm
>> 
>> Here is the code in question:
>> 
>> AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
>>    public Boolean run() {
>>      try {
>>        AccessController.checkPermission(
>>                    new RuntimePermission("getClassLoader"));
>>        return true;
>>      } catch (AccessControlException e) {
>>        return false;
>>      }
>>    }
>> });
>> 
>> 
>> If the privileged block above code is removed, then the
>> AccessControlException goes away. The privileged block looks quite
>> legitimate to me so I don't think it's a bug in logback.
>> 
>> To convince yourself the the privileged block is key, you can remove
>> all logging related calls and all logging related dependencies, add
>> the privileged block at the beginning of the test. You should observe
>> an AccessControlException being thrown.
>> 
>> -- 
>> Ceki
>> http://twitter.com/#!/ceki
>> 
>> 
>> 
>> On 11/5/2011 1:42 PM, Andrew Bourgeois wrote:
>>> Ceki,
>>> 
>>> I redid the test in a clean Maven project. I don't know if attachments
>>> will pass through, so:
>>> 
>>> 1) pom.xml:
>>> 
>>> <project xmlns="http://maven.apache.org/POM/4.0.0"
>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
>>> http://maven.apache.org/maven-v4_0_0.xsd">
>>> <modelVersion>4.0.0</modelVersion>
>>> <name>test</name>
>>> <groupId>be.test.fun</groupId>
>>> <artifactId>test</artifactId>
>>> <version>0.1.0-RC1</version>
>>> <dependencies>
>>> <dependency>
>>> <groupId>org.slf4j</groupId>
>>> <artifactId>slf4j-api</artifactId>
>>> <version>1.6.0</version>
>>> </dependency>
>>> 
>>> <dependency>
>>> <groupId>log4j</groupId>
>>> <artifactId>log4j</artifactId>
>>> <version>1.2.16</version>
>>> </dependency>
>>> <dependency>
>>> <groupId>org.slf4j</groupId>
>>> <artifactId>slf4j-log4j12</artifactId>
>>> <version>1.6.0</version>
>>> </dependency>
>>> 
>>> <!--dependency>
>>> <groupId>ch.qos.logback</groupId>
>>> <artifactId>logback-core</artifactId>
>>> <version>1.0.0</version>
>>> </dependency>
>>> <dependency>
>>> <groupId>ch.qos.logback</groupId>
>>> <artifactId>logback-classic</artifactId>
>>> <version>1.0.0</version>
>>> </dependency-->
>>> 
>>> <dependency>
>>> <groupId>junit</groupId>
>>> <artifactId>junit</artifactId>
>>> <version>4.4</version>
>>> <scope>test</scope>
>>> </dependency>
>>> </dependencies>
>>> <build>
>>> <resources>
>>> </resources>
>>> <plugins>
>>> <plugin>
>>> <artifactId>maven-compiler-plugin</artifactId>
>>> <configuration>
>>> <source>1.6</source>
>>> <target>1.6</target>
>>> <verbose>true</verbose>
>>> </configuration>
>>> </plugin>
>>> </plugins>
>>> </build>
>>> </project>
>>> 
>>> 2) The JUnit test:
>>> 
>>> package be.test.fun;
>>> 
>>> import org.junit.Test;
>>> import java.rmi.RMISecurityManager;
>>> import org.slf4j.Logger;
>>> import org.slf4j.LoggerFactory;
>>> 
>>> public class SecurityManagerTest {
>>> 
>>> @Test
>>> public void securityManagerWithLogs() {
>>> Logger logger = LoggerFactory.getLogger(SecurityManagerTest.class);
>>> 
>>> System.setProperty("java.security.policy",
>>> "./src/test/resources/java.policy");
>>> logger.debug("Policy location: {}",
>>> System.getProperty("java.security.policy"));
>>> if (System.getSecurityManager() == null) {
>>> System.setSecurityManager(new RMISecurityManager());
>>> }
>>> System.setProperty("java.security.policy",
>>> "./src/test/resources/java.policy");
>>> }
>>> 
>>> // @Test
>>> // public void securityManagerWithoutLogs() {
>>> // System.setProperty("java.security.policy",
>>> "./src/test/resources/java.policy");
>>> // if (System.getSecurityManager() == null) {
>>> // System.setSecurityManager(new RMISecurityManager());
>>> // }
>>> // System.setProperty("java.security.policy",
>>> "./src/test/resources/java.policy");
>>> // }
>>> }
>>> 
>>> 3) java.policy that you put into src/test.resources:
>>> 
>>> grant {
>>> permission java.security.AllPermission;
>>> };
>>> 
>>> So.... if you run this:
>>> -------------------------------------------------------
>>> T E S T S
>>> -------------------------------------------------------
>>> Running be.test.fun.SecurityManagerTest
>>> 2011-11-05 13:36:33,828 [main] DEBUG - (be.test.fun.SecurityManagerTest)
>>> - Policy location: ./src/test/resources/java.policy
>>> Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.201 sec
>>> 
>>> Results :
>>> 
>>> Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
>>> 
>>> Now, comment the 2 LOG4J-related dependencies inside the POM, and
>>> uncomment the logback ones:
>>> -------------------------------------------------------
>>> T E S T S
>>> -------------------------------------------------------
>>> Running be.test.fun.SecurityManagerTest
>>> 13:38:04.222 [main] DEBUG be.test.fun.SecurityManagerTest - Policy
>>> location: ./src/test/resources/java.policy
>>> java.security.AccessControlException: access denied
>>> (java.lang.RuntimePermission setContextClassLoader)
>>> at
>>> java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
>>> 
>>> at
>>> java.security.AccessController.checkPermission(AccessController.java:546)
>>> at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
>>> at java.lang.Thread.setContextClassLoader(Thread.java:1394)
>>> at
>>> org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:366)
>>> 
>>> at
>>> org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
>>> 
>>> [INFO]
>>> ------------------------------------------------------------------------
>>> [INFO] BUILD FAILURE
>>> [INFO]
>>> ------------------------------------------------------------------------
>>> [INFO] Total time: 2.202s
>>> 
>>> And now comment the "securityManagerWithLogs" test method, and uncomment
>>> the "securityManagerWithoutLogs" one:
>>> -------------------------------------------------------
>>> T E S T S
>>> -------------------------------------------------------
>>> Running be.test.fun.SecurityManagerTest
>>> Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.105 sec
>>> 
>>> Results :
>>> 
>>> Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
>>> 
>>> Do you have the same output?
>>> 
>>> FYI:
>>> 
>>> [xvepak at localhost test]$ mvn -version
>>> Apache Maven 3.0.1 (r1038046; 2010-11-23 11:58:32+0100)
>>> Java version: 1.6.0_23
>>> Java home: /home/xvepak/software/jdk1.6.0_23/jre
>>> Default locale: en_US, platform encoding: UTF-8
>>> OS name: "linux" version: "2.6.18-238.12.1.el5" arch: "i386" Family: "unix"
>>> 
>>> Thank you for trying to help out!!
>>> 
>>> Best regards
>>> 
>>> Andrew Bourgeois
>>> 
>>> -----Original Message----- From: ceki
>>> Sent: Saturday, November 05, 2011 1:03 AM
>>> To: logback users list
>>> Subject: Re: [logback-user] SecurityManager issue using logback
>>> 
>>> On 05/11/2011 12:47 PM, Andrew Bourgeois wrote:
>>> 
>>>> So to reformulate:
>>>> The exception IS thrown when we have SLF4J code
>>>> The exception ISN'T thrown when we remove the SLF4J.
>>> 
>>> That's not what I observe. An exception is thrown in both cases.
>> 
>> 
>> 
>> _______________________________________________
>> Logback-user mailing list
>> Logback-user at qos.ch
>> http://mailman.qos.ch/mailman/listinfo/logback-user
> 
> _______________________________________________
> Logback-user mailing list
> Logback-user at qos.ch
> http://mailman.qos.ch/mailman/listinfo/logback-user



More information about the Logback-user mailing list