[logback-user] SecurityManager issue using logback

Joern Huxhorn jhuxhorn at googlemail.com
Sun Nov 6 01:32:36 CET 2011


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



More information about the Logback-user mailing list