[jdk17] RFR: 8269034: AccessControlException for SunPKCS11 daemon threads

Peter Firmstone peter.firmstone at zeus.net.au
Thu Jun 24 00:18:31 UTC 2021


Thanks Seán,

A good explanation. :)

Solaris was a very good platform for exposing and debugging race 
conditions, of course we have very good static analysis now.

Regards,

Peter.

On 23/06/2021 5:10 pm, Seán Coffey wrote:
> Thank for the feedback Peter. Comments inline.
>
> On 22/06/2021 22:40, Peter Firmstone wrote:
>> Was ever to run with SecurityManager?
> I found the issue while porting to jdk8u where Solaris uses a 
> configuration file with the SunPKCS11 Provider by default - We have 
> tests to register Providers while SecurityManager is in place. This 
> failed for SunPKCS11.
>>
>> When you see an AccessControlException, I'd recommend setting the 
>> following security debug property, so you can capture the 
>> ProtectionDomain that failed the access check: 
>> -Djava.security.debug=access:failure  Clearly there's a 
>> ProtectionDomain on the calling threads stack that doesn't have the 
>> necessary permission.  If you knew which one it was, you could just 
>> grant it java.lang.RuntimePermission "setContextClassLoader" 
>> permission in the policy file.
> Yes - that was one of my first actions. [1]. The jdk.crypto.cryptoki 
> ProtectionDomain lacks the permission and rightly so IMO. The default 
> policy doesn't grant "setContextClassLoader" permission to any JDK 
> module. It's not required when we use InnocuousThread.
>>
>> In NativeResourceCleaner the original constructor is setting the 
>> Context ClassLoader of the calling thread to null, prior to calling 
>> the Thread superclass constructor, so that both the calling thread 
>> and new thread will nave a null context ClassLoader.  In your new 
>> implementation, you are asserting the context class loader of the 
>> created thread is null, without setting the context ClassLoader of 
>> the original calling thread, is that the intended behaviour?
>>
>> Alternatively you could set the context ClassLoader of the calling 
>> thread to null using a PrivilegedAction, prior to creating the new 
>> thread and restore it?
> Use of InnocuousThread is made in various JDK classes for similar 
> purpose where daemon threads need to be run with limited privilege. 
> Similar use seen in networking and ldap classes.
>
>>
>> If the original intent was to set the context ClassLoader of the new 
>> thread to null, then why not just do that, rather than use an assertion?
> InnocuousThread sets this to null. The assert is just a belt and 
> braces approach which is a useful check during test runs. Again, 
> similar approach done in other JDK libraries.
>>
>> If assertions are not enabled it may run with a non null context 
>> ClassLoader?   What are the consequences?  It appears to me, the fix 
>> has created a bigger problem, rather than fixed it.  Just my 2 cents.
>
> see above. We shouldn't have an issue. A non-null classloader would 
> lead to classloader memory leak in some environments.
>
> regards,
> Sean.
>
>>
>> We use SecurityManager by default following principles of least 
>> privilege (only the code paths we need to execute), and the original 
>> reported bug is a non problem for us, we would capture the missing 
>> permission and grant it, these are permission grants for Java 16:
>>
>> grant codebase "jrt:/jdk.crypto.cryptoki"
>> {
>>     permission java.lang.RuntimePermission 
>> "accessClassInPackage.sun.security.util";
>> };
>>
>> grant codebase "jrt:/jdk.crypto.ec"
>> {
>>     permission java.security.SecurityPermission 
>> "putProviderProperty.SunEC";
>>     permission java.lang.RuntimePermission 
>> "accessClassInPackage.sun.security.jca";
>>     permission java.lang.RuntimePermission 
>> "accessClassInPackage.sun.security.pkcs";
>>     permission java.lang.RuntimePermission 
>> "accessClassInPackage.sun.security.util";
>>     permission java.lang.RuntimePermission 
>> "accessClassInPackage.sun.security.util.math";
>>     permission java.lang.RuntimePermission 
>> "accessClassInPackage.sun.security.util.math.intpoly";
>>     permission java.lang.RuntimePermission 
>> "accessClassInPackage.sun.security.x509";
>> };
>>
>> Good call making NativeResourceCleaner implement Runnable instead of 
>> extending Thread though.
>
>
> [1]
>
> access: domain that failed ProtectionDomain (jrt:/jdk.crypto.cryptoki 
> <no signer certificates>)
>  jdk.internal.loader.ClassLoaders$PlatformClassLoader at 5433274e
>  <no principals>
>  java.security.Permissions at 7006c658 (
>  ("java.io.FilePermission" "<<ALL FILES>>" "read")
>  ("java.net.SocketPermission" "localhost:0" "listen,resolve")
>  ("java.security.SecurityPermission" "clearProviderProperties.*")
>  ("java.security.SecurityPermission" 
> "getProperty.auth.login.defaultCallbackHandler")
>  ("java.security.SecurityPermission" "putProviderProperty.*")
>  ("java.security.SecurityPermission" "authProvider.*")
>  ("java.security.SecurityPermission" "removeProviderProperty.*")
>  ("java.util.PropertyPermission" "java.specification.version" "read")
>  ("java.util.PropertyPermission" "java.vm.vendor" "read")
>  ("java.util.PropertyPermission" "path.separator" "read")
>  ("java.util.PropertyPermission" "os.version" "read")
>  ("java.util.PropertyPermission" "java.vendor.url" "read")
>  ("java.util.PropertyPermission" "java.vm.name" "read")
>  ("java.util.PropertyPermission" "java.vm.specification.version" "read")
>  ("java.util.PropertyPermission" "os.name" "read")
>  ("java.util.PropertyPermission" 
> "sun.security.pkcs11.allowSingleThreadedModules" "read")
>  ("java.util.PropertyPermission" 
> "sun.security.pkcs11.disableKeyExtraction" "read")
>  ("java.util.PropertyPermission" "java.version" "read")
>  ("java.util.PropertyPermission" "os.arch" "read")
>  ("java.util.PropertyPermission" "java.specification.vendor" "read")
>  ("java.util.PropertyPermission" "java.vm.specification.name" "read")
>  ("java.util.PropertyPermission" "file.separator" "read")
>  ("java.util.PropertyPermission" "line.separator" "read")
>  ("java.util.PropertyPermission" "java.vm.specification.vendor" "read")
>  ("java.util.PropertyPermission" "java.specification.name" "read")
>  ("java.util.PropertyPermission" "java.vendor" "read")
>  ("java.util.PropertyPermission" "java.vm.version" "read")
>  ("java.util.PropertyPermission" "jdk.crypto.KeyAgreement.legacyKDF" 
> "read")
>  ("java.util.PropertyPermission" "java.class.version" "read")
>  ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.beans.*")
>  ("java.lang.RuntimePermission" "accessClassInPackage.sun.security.*")
>  ("java.lang.RuntimePermission" 
> "accessClassInPackage.com.sun.crypto.provider")
>  ("java.lang.RuntimePermission" "accessClassInPackage.com.apple.*")
>  ("java.lang.RuntimePermission" 
> "accessClassInPackage.com.sun.java.swing.plaf.*")
>  ("java.lang.RuntimePermission" "accessSystemModules")
>  ("java.lang.RuntimePermission" "accessClassInPackage.sun.nio.ch")
>  ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.beans")
>  ("java.lang.RuntimePermission" "loadLibrary.j2pkcs11")
> )
>
> Exception in thread "main" java.security.ProviderException: 
> Initialization failed
>         at 
> jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:386)
>         at 
> jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11$1.run(SunPKCS11.java:117)
>         at 
> jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11$1.run(SunPKCS11.java:114)
>         at 
> java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
>         at 
> jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11.configure(SunPKCS11.java:114)
>         at 
> java.base/sun.security.jca.ProviderConfig$3.run(ProviderConfig.java:257)
>         at 
> java.base/sun.security.jca.ProviderConfig$3.run(ProviderConfig.java:248)
>         at 
> java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
>         at 
> java.base/sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:248)
>         at 
> java.base/sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:226)
>         at 
> java.base/sun.security.jca.ProviderList.loadAll(ProviderList.java:317)
>         at 
> java.base/sun.security.jca.ProviderList.removeInvalid(ProviderList.java:334)
>         at 
> java.base/sun.security.jca.Providers.getFullProviderList(Providers.java:175)
>         at 
> java.base/java.security.Security.getProviders(Security.java:458)
>         at DefaultPKCS11.main(DefaultPKCS11.java:13)
> Caused by: java.security.AccessControlException: access denied 
> ("java.lang.RuntimePermission" "setContextClassLoader")
>         at 
> java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:485)
>         at 
> java.base/java.security.AccessController.checkPermission(AccessController.java:1068)
>         at 
> java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:416)
>         at 
> java.base/java.lang.Thread.setContextClassLoader(Thread.java:1525)
>         at 
> jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11$NativeResourceCleaner.<init>(SunPKCS11.java:982)
>         at 
> jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11.initToken(SunPKCS11.java:1193)
>         at 
> jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:377)
>         ... 14 more
>



More information about the security-dev mailing list