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

Seán Coffey sean.coffey at oracle.com
Wed Jun 23 07:10:45 UTC 2021


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