8269034: AccessControlException for SunPKCS11 daemon threads
Reviewed-by: valeriep
This commit is contained in:
parent
d042029509
commit
0d745ae8fd
@ -199,6 +199,7 @@ module java.base {
|
|||||||
jdk.attach,
|
jdk.attach,
|
||||||
jdk.charsets,
|
jdk.charsets,
|
||||||
jdk.compiler,
|
jdk.compiler,
|
||||||
|
jdk.crypto.cryptoki,
|
||||||
jdk.incubator.vector,
|
jdk.incubator.vector,
|
||||||
jdk.jfr,
|
jdk.jfr,
|
||||||
jdk.jshell,
|
jdk.jshell,
|
||||||
|
@ -128,6 +128,7 @@ grant codeBase "jrt:/jdk.crypto.ec" {
|
|||||||
grant codeBase "jrt:/jdk.crypto.cryptoki" {
|
grant codeBase "jrt:/jdk.crypto.cryptoki" {
|
||||||
permission java.lang.RuntimePermission
|
permission java.lang.RuntimePermission
|
||||||
"accessClassInPackage.com.sun.crypto.provider";
|
"accessClassInPackage.com.sun.crypto.provider";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
|
||||||
permission java.lang.RuntimePermission
|
permission java.lang.RuntimePermission
|
||||||
"accessClassInPackage.sun.security.*";
|
"accessClassInPackage.sun.security.*";
|
||||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
|
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
|
||||||
|
@ -42,6 +42,7 @@ import javax.security.auth.callback.PasswordCallback;
|
|||||||
|
|
||||||
import com.sun.crypto.provider.ChaCha20Poly1305Parameters;
|
import com.sun.crypto.provider.ChaCha20Poly1305Parameters;
|
||||||
|
|
||||||
|
import jdk.internal.misc.InnocuousThread;
|
||||||
import sun.security.util.Debug;
|
import sun.security.util.Debug;
|
||||||
import sun.security.util.ResourcesMgr;
|
import sun.security.util.ResourcesMgr;
|
||||||
import static sun.security.util.SecurityConstants.PROVIDER_VER;
|
import static sun.security.util.SecurityConstants.PROVIDER_VER;
|
||||||
@ -907,15 +908,11 @@ public final class SunPKCS11 extends AuthProvider {
|
|||||||
// background thread that periodically checks for token insertion
|
// background thread that periodically checks for token insertion
|
||||||
// if no token is present. We need to do that in a separate thread because
|
// if no token is present. We need to do that in a separate thread because
|
||||||
// the insertion check may block for quite a long time on some tokens.
|
// the insertion check may block for quite a long time on some tokens.
|
||||||
private static class TokenPoller extends Thread {
|
private static class TokenPoller implements Runnable {
|
||||||
private final SunPKCS11 provider;
|
private final SunPKCS11 provider;
|
||||||
private volatile boolean enabled;
|
private volatile boolean enabled;
|
||||||
|
|
||||||
private TokenPoller(SunPKCS11 provider) {
|
private TokenPoller(SunPKCS11 provider) {
|
||||||
super((ThreadGroup)null, "Poller-" + provider.getName());
|
|
||||||
setContextClassLoader(null);
|
|
||||||
setDaemon(true);
|
|
||||||
setPriority(Thread.MIN_PRIORITY);
|
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
@ -944,12 +941,20 @@ public final class SunPKCS11 extends AuthProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the poller thread, if not already active
|
// create the poller thread, if not already active
|
||||||
|
@SuppressWarnings("removal")
|
||||||
private void createPoller() {
|
private void createPoller() {
|
||||||
if (poller != null) {
|
if (poller != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
poller = new TokenPoller(this);
|
poller = new TokenPoller(this);
|
||||||
poller.start();
|
Thread t = InnocuousThread.newSystemThread(
|
||||||
|
"Poller-" + getName(),
|
||||||
|
poller,
|
||||||
|
Thread.MIN_PRIORITY);
|
||||||
|
assert t.getContextClassLoader() == null;
|
||||||
|
t.setDaemon(true);
|
||||||
|
t.start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy the poller thread, if active
|
// destroy the poller thread, if active
|
||||||
@ -972,18 +977,11 @@ public final class SunPKCS11 extends AuthProvider {
|
|||||||
return (token != null) && token.isValid();
|
return (token != null) && token.isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NativeResourceCleaner extends Thread {
|
private class NativeResourceCleaner implements Runnable {
|
||||||
private long sleepMillis = config.getResourceCleanerShortInterval();
|
private long sleepMillis = config.getResourceCleanerShortInterval();
|
||||||
private int count = 0;
|
private int count = 0;
|
||||||
boolean keyRefFound, sessRefFound;
|
boolean keyRefFound, sessRefFound;
|
||||||
|
|
||||||
private NativeResourceCleaner() {
|
|
||||||
super((ThreadGroup)null, "Cleanup-SunPKCS11");
|
|
||||||
setContextClassLoader(null);
|
|
||||||
setDaemon(true);
|
|
||||||
setPriority(Thread.MIN_PRIORITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The cleaner.shortInterval and cleaner.longInterval properties
|
* The cleaner.shortInterval and cleaner.longInterval properties
|
||||||
* may be defined in the pkcs11 config file and are specified in milliseconds
|
* may be defined in the pkcs11 config file and are specified in milliseconds
|
||||||
@ -1001,7 +999,7 @@ public final class SunPKCS11 extends AuthProvider {
|
|||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
sleep(sleepMillis);
|
Thread.sleep(sleepMillis);
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1022,6 +1020,19 @@ public final class SunPKCS11 extends AuthProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create the cleaner thread, if not already active
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
private void createCleaner() {
|
||||||
|
cleaner = new NativeResourceCleaner();
|
||||||
|
Thread t = InnocuousThread.newSystemThread(
|
||||||
|
"Cleanup-SunPKCS11",
|
||||||
|
cleaner,
|
||||||
|
Thread.MIN_PRIORITY);
|
||||||
|
assert t.getContextClassLoader() == null;
|
||||||
|
t.setDaemon(true);
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
|
||||||
// destroy the token. Called if we detect that it has been removed
|
// destroy the token. Called if we detect that it has been removed
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
synchronized void uninitToken(Token token) {
|
synchronized void uninitToken(Token token) {
|
||||||
@ -1190,8 +1201,7 @@ public final class SunPKCS11 extends AuthProvider {
|
|||||||
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
if (cleaner == null) {
|
if (cleaner == null) {
|
||||||
cleaner = new NativeResourceCleaner();
|
createCleaner();
|
||||||
cleaner.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,10 +31,9 @@ import javax.security.auth.callback.UnsupportedCallbackException;
|
|||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.security.KeyStore;
|
import java.security.*;
|
||||||
import java.security.Provider;
|
|
||||||
import java.security.Security;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.PropertyPermission;
|
||||||
import java.util.ServiceConfigurationError;
|
import java.util.ServiceConfigurationError;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
@ -44,19 +43,28 @@ public class MultipleLogins {
|
|||||||
private static final String KS_TYPE = "PKCS11";
|
private static final String KS_TYPE = "PKCS11";
|
||||||
private static final int NUM_PROVIDERS = 20;
|
private static final int NUM_PROVIDERS = 20;
|
||||||
private static final SunPKCS11[] providers = new SunPKCS11[NUM_PROVIDERS];
|
private static final SunPKCS11[] providers = new SunPKCS11[NUM_PROVIDERS];
|
||||||
|
static final Policy DEFAULT_POLICY = Policy.getPolicy();
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
String nssConfig = PKCS11Test.getNssConfig();
|
||||||
|
if (nssConfig == null) {
|
||||||
|
// No test framework support yet. Ignore
|
||||||
|
System.out.println("No NSS config found. Skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i =0; i < NUM_PROVIDERS; i++) {
|
for (int i =0; i < NUM_PROVIDERS; i++) {
|
||||||
String nssConfig = PKCS11Test.getNssConfig();
|
// loop to set up test without security manger
|
||||||
if (nssConfig == null) {
|
providers[i] = (SunPKCS11)PKCS11Test.newPKCS11Provider();
|
||||||
// No test framework support yet. Ignore
|
}
|
||||||
System.out.println("No NSS config found. Skipping.");
|
|
||||||
return;
|
if (args.length > 0) {
|
||||||
}
|
Policy.setPolicy(new SimplePolicy());
|
||||||
providers[i] =
|
System.setSecurityManager(new SecurityManager());
|
||||||
(SunPKCS11)PKCS11Test.newPKCS11Provider()
|
}
|
||||||
.configure(nssConfig);
|
|
||||||
|
for (int i =0; i < NUM_PROVIDERS; i++) {
|
||||||
|
providers[i] = (SunPKCS11)providers[i].configure(nssConfig);
|
||||||
Security.addProvider(providers[i]);
|
Security.addProvider(providers[i]);
|
||||||
test(providers[i]);
|
test(providers[i]);
|
||||||
}
|
}
|
||||||
@ -92,7 +100,6 @@ public class MultipleLogins {
|
|||||||
|
|
||||||
private static void test(SunPKCS11 p) throws Exception {
|
private static void test(SunPKCS11 p) throws Exception {
|
||||||
KeyStore ks = KeyStore.getInstance(KS_TYPE, p);
|
KeyStore ks = KeyStore.getInstance(KS_TYPE, p);
|
||||||
|
|
||||||
p.setCallbackHandler(new PasswordCallbackHandler());
|
p.setCallbackHandler(new PasswordCallbackHandler());
|
||||||
try {
|
try {
|
||||||
ks.load(null, (char[]) null);
|
ks.load(null, (char[]) null);
|
||||||
@ -117,6 +124,23 @@ public class MultipleLogins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final class SimplePolicy extends Policy {
|
||||||
|
|
||||||
|
final Permissions perms = new Permissions();
|
||||||
|
SimplePolicy() {
|
||||||
|
perms.add(new PropertyPermission("*", "read, write"));
|
||||||
|
perms.add(new SecurityPermission("authProvider.*"));
|
||||||
|
perms.add(new SecurityPermission("insertProvider.*"));
|
||||||
|
perms.add(new SecurityPermission("removeProvider.*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean implies(ProtectionDomain domain, Permission permission) {
|
||||||
|
return perms.implies(permission) ||
|
||||||
|
DEFAULT_POLICY.implies(domain, permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class PasswordCallbackHandler implements CallbackHandler {
|
public static class PasswordCallbackHandler implements CallbackHandler {
|
||||||
public void handle(Callback[] callbacks)
|
public void handle(Callback[] callbacks)
|
||||||
throws IOException, UnsupportedCallbackException {
|
throws IOException, UnsupportedCallbackException {
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# @test
|
# @test
|
||||||
# @bug 7777777
|
# @bug 8240256 8269034
|
||||||
# @summary
|
# @summary
|
||||||
# @library /test/lib/
|
# @library /test/lib/
|
||||||
# @build jdk.test.lib.util.ForceGC
|
# @build jdk.test.lib.util.ForceGC
|
||||||
@ -114,9 +114,7 @@ ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
|
|||||||
${TESTSRC}${FS}MultipleLogins.java \
|
${TESTSRC}${FS}MultipleLogins.java \
|
||||||
${TESTSRC}${FS}..${FS}PKCS11Test.java
|
${TESTSRC}${FS}..${FS}PKCS11Test.java
|
||||||
|
|
||||||
# run test
|
TEST_ARGS="${TESTVMOPTS} -classpath ${TESTCLASSPATH} \
|
||||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \
|
|
||||||
-classpath ${TESTCLASSPATH} \
|
|
||||||
--add-modules jdk.crypto.cryptoki \
|
--add-modules jdk.crypto.cryptoki \
|
||||||
--add-exports jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED \
|
--add-exports jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED \
|
||||||
-DCUSTOM_DB_DIR=${TESTCLASSES} \
|
-DCUSTOM_DB_DIR=${TESTCLASSES} \
|
||||||
@ -125,11 +123,13 @@ ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \
|
|||||||
-DNO_DEIMOS=true \
|
-DNO_DEIMOS=true \
|
||||||
-Dtest.src=${TESTSRC} \
|
-Dtest.src=${TESTSRC} \
|
||||||
-Dtest.classes=${TESTCLASSES} \
|
-Dtest.classes=${TESTCLASSES} \
|
||||||
-Djava.security.debug=${DEBUG} \
|
-Djava.security.debug=${DEBUG}"
|
||||||
MultipleLogins
|
|
||||||
|
|
||||||
# save error status
|
# run test without security manager
|
||||||
status=$?
|
${TESTJAVA}${FS}bin${FS}java ${TEST_ARGS} MultipleLogins || exit 10
|
||||||
|
|
||||||
# return
|
# run test with security manager
|
||||||
exit $status
|
${TESTJAVA}${FS}bin${FS}java ${TEST_ARGS} MultipleLogins useSimplePolicy || exit 11
|
||||||
|
|
||||||
|
echo Done
|
||||||
|
exit 0
|
||||||
|
Loading…
Reference in New Issue
Block a user