8333344: JMX attaching of Subject does not work when security manager not allowed
Reviewed-by: weijun, dfuchs
This commit is contained in:
parent
856931d01f
commit
bcf4bb4882
@ -165,6 +165,7 @@ module java.base {
|
||||
java.desktop,
|
||||
java.logging,
|
||||
java.management,
|
||||
java.management.rmi,
|
||||
java.naming,
|
||||
java.rmi,
|
||||
jdk.charsets,
|
||||
|
@ -46,6 +46,7 @@ import javax.management.*;
|
||||
import javax.management.remote.JMXServerErrorException;
|
||||
import javax.management.remote.NotificationResult;
|
||||
import javax.security.auth.Subject;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
import static javax.management.remote.rmi.RMIConnector.Util.cast;
|
||||
@ -108,14 +109,19 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
|
||||
this.rmiServer = rmiServer;
|
||||
this.connectionId = connectionId;
|
||||
this.defaultClassLoader = defaultClassLoader;
|
||||
|
||||
this.subject = subject;
|
||||
|
||||
if (subject == null) {
|
||||
this.acc = null;
|
||||
} else {
|
||||
// An authenticated Subject was provided.
|
||||
// Subject Delegation has been removed.
|
||||
if (SharedSecrets.getJavaLangAccess().allowSecurityManager()) {
|
||||
// SM is allowed. Will use ACC created with Subject:
|
||||
this.acc = JMXSubjectDomainCombiner.getContext(subject);
|
||||
} else {
|
||||
this.acc = null;
|
||||
}
|
||||
}
|
||||
this.mbeanServer = rmiServer.getMBeanServer();
|
||||
|
||||
@ -1292,10 +1298,21 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
|
||||
return getServerNotifFwd().fetchNotifs(csn, t, mn);
|
||||
}
|
||||
};
|
||||
if (acc == null)
|
||||
if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) {
|
||||
// Modern case
|
||||
if (subject == null) {
|
||||
return action.run();
|
||||
else
|
||||
} else {
|
||||
return Subject.doAs(subject, action);
|
||||
}
|
||||
} else {
|
||||
// SM permitted
|
||||
if (acc == null) {
|
||||
return action.run(); // No Subject or ACC
|
||||
} else {
|
||||
return AccessController.doPrivileged(action, acc);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
serverCommunicatorAdmin.rspOutgoing();
|
||||
}
|
||||
@ -1411,17 +1428,37 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
|
||||
serverCommunicatorAdmin.reqIncoming();
|
||||
try {
|
||||
PrivilegedOperation op = new PrivilegedOperation(operation, params);
|
||||
if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) {
|
||||
// Modern case
|
||||
if (subject == null) {
|
||||
try {
|
||||
return op.run();
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new PrivilegedActionException(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Subject.doAs(subject, op);
|
||||
}
|
||||
} else {
|
||||
// SM permitted
|
||||
if (acc == null) {
|
||||
try {
|
||||
return op.run();
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException)
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new PrivilegedActionException(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return AccessController.doPrivileged(op, acc);
|
||||
}
|
||||
}
|
||||
} catch (Error e) {
|
||||
throw new JMXServerErrorException(e.toString(),e);
|
||||
} finally {
|
||||
@ -1585,15 +1622,25 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
|
||||
}
|
||||
try {
|
||||
final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl));
|
||||
try{
|
||||
try {
|
||||
if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) {
|
||||
// Modern case
|
||||
if (subject != null) {
|
||||
return Subject.doAs(subject, (PrivilegedExceptionAction<T>) () -> wrappedClass.cast(mo.get()));
|
||||
} else {
|
||||
return wrappedClass.cast(mo.get());
|
||||
}
|
||||
} else {
|
||||
// SM permitted
|
||||
if (acc != null) {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedExceptionAction<T>) () ->
|
||||
wrappedClass.cast(mo.get()), acc);
|
||||
}else{
|
||||
} else {
|
||||
return wrappedClass.cast(mo.get());
|
||||
}
|
||||
}finally{
|
||||
}
|
||||
} finally {
|
||||
AccessController.doPrivileged(new SetCcl(old));
|
||||
}
|
||||
} catch (PrivilegedActionException pe) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -343,10 +343,9 @@ public class ServerNotifForwarder {
|
||||
//----------------
|
||||
// PRIVATE METHODS
|
||||
//----------------
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private Subject getSubject() {
|
||||
return Subject.getSubject(AccessController.getContext());
|
||||
return Subject.current();
|
||||
}
|
||||
|
||||
private void checkState() throws IOException {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,6 +42,7 @@ import java.util.regex.Pattern;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
import javax.security.auth.Subject;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
||||
/**
|
||||
* <p>An object of this class implements the MBeanServerAccessController
|
||||
@ -300,16 +301,19 @@ public class MBeanServerFileAccessController
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private synchronized void checkAccess(AccessType requiredAccess, String arg) {
|
||||
@SuppressWarnings("removal")
|
||||
Subject s = null;
|
||||
if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) {
|
||||
s = Subject.current();
|
||||
} else {
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
@SuppressWarnings("removal")
|
||||
final Subject s =
|
||||
AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
s = AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
public Subject run() {
|
||||
return Subject.getSubject(acc);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (s == null) return; /* security has not been enabled */
|
||||
final Set<Principal> principals = s.getPrincipals();
|
||||
String newPropertyValue = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,6 +60,8 @@ import javax.management.MBeanServerConnection;
|
||||
import javax.management.NotificationBroadcasterSupport;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.ReflectionException;
|
||||
import javax.security.auth.Subject;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import static javax.management.monitor.MonitorNotification.*;
|
||||
|
||||
/**
|
||||
@ -169,8 +171,9 @@ public abstract class Monitor
|
||||
new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* AccessControlContext of the Monitor.start() caller.
|
||||
* Subject and possibly AccessControlContext of the Monitor.start() caller.
|
||||
*/
|
||||
private volatile Subject subject;
|
||||
@SuppressWarnings("removal")
|
||||
private static final AccessControlContext noPermissionsACC =
|
||||
new AccessControlContext(
|
||||
@ -713,10 +716,14 @@ public abstract class Monitor
|
||||
//
|
||||
cleanupIsComplexTypeAttribute();
|
||||
|
||||
// Cache the AccessControlContext of the Monitor.start() caller.
|
||||
// Cache the Subject or AccessControlContext of the Monitor.start() caller.
|
||||
// The monitor tasks will be executed within this context.
|
||||
//
|
||||
if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) {
|
||||
subject = Subject.current();
|
||||
} else {
|
||||
acc = AccessController.getContext();
|
||||
}
|
||||
|
||||
// Start the scheduler.
|
||||
//
|
||||
@ -747,8 +754,9 @@ public abstract class Monitor
|
||||
//
|
||||
cleanupFutures();
|
||||
|
||||
// Reset the AccessControlContext.
|
||||
// Reset the Subject and AccessControlContext.
|
||||
//
|
||||
subject = null;
|
||||
acc = noPermissionsACC;
|
||||
|
||||
// Reset the complex type attribute information
|
||||
@ -1512,9 +1520,11 @@ public abstract class Monitor
|
||||
@SuppressWarnings("removal")
|
||||
public void run() {
|
||||
final ScheduledFuture<?> sf;
|
||||
final Subject s;
|
||||
final AccessControlContext ac;
|
||||
synchronized (Monitor.this) {
|
||||
sf = Monitor.this.schedulerFuture;
|
||||
s = Monitor.this.subject;
|
||||
ac = Monitor.this.acc;
|
||||
}
|
||||
PrivilegedAction<Void> action = new PrivilegedAction<>() {
|
||||
@ -1531,10 +1541,20 @@ public abstract class Monitor
|
||||
return null;
|
||||
}
|
||||
};
|
||||
if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) {
|
||||
// No SecurityManager permitted:
|
||||
if (s == null) {
|
||||
action.run();
|
||||
} else {
|
||||
Subject.doAs(s, action);
|
||||
}
|
||||
} else {
|
||||
if (ac == null) {
|
||||
throw new SecurityException("AccessControlContext cannot be null");
|
||||
}
|
||||
// ACC means SM is permitted.
|
||||
AccessController.doPrivileged(action, ac);
|
||||
}
|
||||
synchronized (Monitor.this) {
|
||||
if (Monitor.this.isActive() &&
|
||||
Monitor.this.schedulerFuture == sf) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,9 +32,17 @@
|
||||
*
|
||||
* @run clean StartStopTest
|
||||
* @run build StartStopTest
|
||||
*
|
||||
* @run main/othervm/timeout=300 StartStopTest 1
|
||||
* @run main/othervm/timeout=300 StartStopTest 2
|
||||
* @run main/othervm/timeout=300 StartStopTest 3
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow StartStopTest 1
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow StartStopTest 2
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow StartStopTest 3
|
||||
* @run main/othervm/timeout=300/policy=all.policy StartStopTest 1
|
||||
* @run main/othervm/timeout=300/policy=all.policy StartStopTest 2
|
||||
* @run main/othervm/timeout=300/policy=all.policy StartStopTest 3
|
||||
*
|
||||
* @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 StartStopTest 1
|
||||
* @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 StartStopTest 2
|
||||
* @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 StartStopTest 3
|
||||
|
@ -30,13 +30,19 @@
|
||||
*
|
||||
* @run clean ThreadPoolAccTest
|
||||
* @run build ThreadPoolAccTest
|
||||
*
|
||||
* @run main/othervm ThreadPoolAccTest
|
||||
* @run main/othervm -Djava.security.manager=allow ThreadPoolAccTest
|
||||
* @run main/othervm -Djava.security.manager=allow -DThreadPoolAccTest.useGetSubjectACC=true ThreadPoolAccTest
|
||||
* @run main/othervm/policy=all.policy ThreadPoolAccTest
|
||||
* @run main/othervm/policy=all.policy -DThreadPoolAccTest.useGetSubjectACC=true ThreadPoolAccTest
|
||||
*/
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerFactory;
|
||||
import javax.management.ObjectName;
|
||||
@ -67,7 +73,9 @@ public class ThreadPoolAccTest {
|
||||
return "";
|
||||
}
|
||||
private void setPrincipal() {
|
||||
Subject subject = Subject.getSubject(AccessController.getContext());
|
||||
// Use Subject.current() unless test Property is set.
|
||||
Subject subject = Boolean.getBoolean("ThreadPoolAccTest.useGetSubjectACC") ?
|
||||
Subject.getSubject(AccessController.getContext()) : Subject.current();
|
||||
Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
|
||||
principal = principals.iterator().next().getName();
|
||||
}
|
||||
@ -136,7 +144,9 @@ public class ThreadPoolAccTest {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Subject.doAs(subject, action);
|
||||
// Subject.doAs(subject, action);
|
||||
Callable<Void> c = (Callable<Void>) () -> action.run();
|
||||
Subject.callAs(subject, c);
|
||||
}
|
||||
|
||||
sleep(500); // wait for getX method to be called, which calls setPrincipal
|
||||
|
3
test/jdk/javax/management/monitor/all.policy
Normal file
3
test/jdk/javax/management/monitor/all.policy
Normal file
@ -0,0 +1,3 @@
|
||||
grant {
|
||||
permission java.security.AllPermission;
|
||||
};
|
@ -30,6 +30,8 @@
|
||||
* java.management/com.sun.jmx.remote.security
|
||||
* @run clean NotificationAccessControllerTest
|
||||
* @run build NotificationAccessControllerTest
|
||||
*
|
||||
* @run main/othervm NotificationAccessControllerTest
|
||||
* @run main/othervm -Djava.security.manager=allow NotificationAccessControllerTest
|
||||
*/
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,7 +31,9 @@
|
||||
*
|
||||
* @run clean NotificationEmissionTest
|
||||
* @run build NotificationEmissionTest
|
||||
*
|
||||
* @run main NotificationEmissionTest 1
|
||||
* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 1
|
||||
* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 2
|
||||
* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 3
|
||||
* @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 4
|
||||
|
@ -30,6 +30,7 @@
|
||||
*
|
||||
* @run clean NonJMXPrincipalsTest SimpleStandard SimpleStandardMBean
|
||||
* @run build NonJMXPrincipalsTest SimpleStandard SimpleStandardMBean
|
||||
* @run main/othervm NonJMXPrincipalsTest
|
||||
* @run main/othervm -Djava.security.manager=allow NonJMXPrincipalsTest
|
||||
*/
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
*
|
||||
* @run clean PasswordAccessFileTest SimpleStandard SimpleStandardMBean
|
||||
* @run build PasswordAccessFileTest SimpleStandard SimpleStandardMBean
|
||||
*
|
||||
* @run main/othervm PasswordAccessFileTest
|
||||
* @run main/othervm -Djava.security.manager=allow PasswordAccessFileTest
|
||||
*/
|
||||
|
||||
|
@ -30,7 +30,10 @@
|
||||
* java.management/com.sun.jmx.remote.security
|
||||
* @run clean RMIAltAuthTest
|
||||
* @run build RMIAltAuthTest SimpleStandard SimpleStandardMBean
|
||||
*
|
||||
* @run main/othervm RMIAltAuthTest
|
||||
* @run main/othervm -Djava.security.manager=allow RMIAltAuthTest
|
||||
* @run main/othervm -Djava.security.manager=allow -DSimpleStandard.useGetSubjectACC=true RMIAltAuthTest
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
|
@ -30,7 +30,10 @@
|
||||
* java.management/com.sun.jmx.remote.security
|
||||
* @run clean RMIPasswdAuthTest
|
||||
* @run build RMIPasswdAuthTest SimpleStandard SimpleStandardMBean
|
||||
*
|
||||
* @run main/othervm RMIPasswdAuthTest
|
||||
* @run main/othervm -Djava.security.manager=allow RMIPasswdAuthTest
|
||||
* @run main/othervm -Djava.security.manager=allow -DSimpleStandard.useGetSubjectACC=true RMIPasswdAuthTest
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -152,8 +152,8 @@ public class SimpleStandard
|
||||
* type JMXPrincipal and refers to the "monitorRole" identity.
|
||||
*/
|
||||
private void checkSubject() {
|
||||
AccessControlContext acc = AccessController.getContext();
|
||||
Subject subject = Subject.getSubject(acc);
|
||||
Subject subject = Boolean.getBoolean("SimpleStandard.useGetSubjectACC") ?
|
||||
Subject.getSubject(AccessController.getContext()) : Subject.current();
|
||||
Set principals = subject.getPrincipals();
|
||||
Principal principal = (Principal) principals.iterator().next();
|
||||
if (!(principal instanceof JMXPrincipal))
|
||||
|
@ -29,9 +29,15 @@
|
||||
* @modules java.management.rmi
|
||||
* @library /test/lib
|
||||
* @compile Simple.java
|
||||
*
|
||||
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
|
||||
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
|
||||
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
|
||||
*
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
|
||||
*
|
||||
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials
|
||||
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedGetException
|
||||
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
|
||||
|
@ -61,6 +61,7 @@ import java.util.Set;
|
||||
*
|
||||
* @library /test/lib
|
||||
*
|
||||
* @run main/othervm/timeout=300 RmiBootstrapTest .*_test.*.in
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow RmiBootstrapTest .*_test.*.in
|
||||
* */
|
||||
|
||||
@ -72,6 +73,7 @@ import java.util.Set;
|
||||
*
|
||||
* @library /test/lib
|
||||
*
|
||||
* @run main/othervm/timeout=300 RmiBootstrapTest .*_ssltest.*.in
|
||||
* @run main/othervm/timeout=300 -Djava.security.manager=allow RmiBootstrapTest .*_ssltest.*.in
|
||||
* */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user