Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8266459: Implement JEP 411: Deprecate the Security Manager for Removal #4073

Closed
wants to merge 14 commits into from
@@ -79,38 +79,37 @@
* permitted.
* <p>
* Environments using a security manager will typically set the security
* manager at startup. In the JDK implementation, this is done by setting
* the system property {@systemProperty java.security.manager} on the command
* line to the class name of the security manager. It can also be set to the
* empty String ("") or the special token "{@code default}" to use the
* manager at startup. In the JDK implementation, this is done by setting the
* system property {@systemProperty java.security.manager} on the command line
* to the class name of the security manager. It can also be set to the empty
* String ("") or the special token "{@code default}" to use the
* default {@code java.lang.SecurityManager}. If a class name is specified,
* it must be {@code java.lang.SecurityManager} or a public subclass and have
* a public no-arg constructor. The class is loaded by the
* {@linkplain ClassLoader#getSystemClassLoader() built-in system class loader}
* if it is not {@code java.lang.SecurityManager}.
* if it is not {@code java.lang.SecurityManager}. If the
* {@code java.security.manager} system property is not set, the default value
* is {@code null}, which means a security manager will not be set at startup.
* <p>
* The Java run-time may also allow, but is not required to allow, the security
* manager to be set dynamically by invoking the
* {@link System#setSecurityManager(SecurityManager) setSecurityManager} method.
* In the JDK implementation, the default value of the
* {@code java.security.manager} system property, if not set, is
* the special token "{@code disallow}". If the Java virtual machine is
* started with the {@code java.security.manager} system property
* not set or set to "{@code disallow}" then a security manager will not be
* set at startup and cannot be set dynamically (the
* In the JDK implementation, if the Java virtual machine is started with
* the {@code java.security.manager} system property set to the special token
* "{@code disallow}" then a security manager will not be set at startup and
* cannot be set dynamically (the
* {@link System#setSecurityManager(SecurityManager) setSecurityManager}
* method will throw an {@code UnsupportedOperationException}). If the
* {@code java.security.manager} system property is set to the
* {@code java.security.manager} system property is not set or is set to the
* special token "{@code allow}", then a security manager will not be set at
* startup but can be set dynamically. Finally, if the
* {@code java.security.manager} system property is set to the
* class name of the security manager, or to the empty String ("") or the
* special token "{@code default}", then a security manager is set at startup
* (as described previously) and can also be subsequently replaced (or
* disabled) dynamically (subject to the policy of the currently installed
* security manager). The following table illustrates the behavior of the JDK
* implementation for the different settings of the
* {@code java.security.manager} system property:
* {@code java.security.manager} system property is set to the class name of
* the security manager, or to the empty String ("") or the special token
* "{@code default}", then a security manager is set at startup (as described
* previously) and can also be subsequently replaced (or disabled) dynamically
* (subject to the policy of the currently installed security manager). The
* following table illustrates the behavior of the JDK implementation for the
* different settings of the {@code java.security.manager} system property:
* <table class="striped">
* <caption style="display:none">property value,
* the SecurityManager set at startup,
@@ -168,6 +167,8 @@
*
* </tbody>
* </table>
* <p> A future release of the JDK may change the default value of the
* {@code java.security.manager} system property to "{@code disallow}".
* <p>
* The current security manager is returned by the
* {@link System#getSecurityManager() getSecurityManager} method.
@@ -340,16 +340,10 @@ private static void checkIO() {
* security manager has been established, then no action is taken and
* the method simply returns.
*
* @implNote In the JDK implementation, the default value of the
* {@code java.security.manager} system property, if not set, is
* the special token "{@code disallow}". If the Java virtual machine is
* started with the {@code java.security.manager} system property
* set to the special token "{@code allow}", then a security manager can
* be set dynamically. If the Java virtual machine is started with the
* system property {@code java.security.manager} not set or set
* to "{@code disallow}" then a security manager cannot be set
* dynamically (the {@code setSecurityManager} method will throw an
* {@code UnsupportedOperationException}).
* @implNote In the JDK implementation, if the Java virtual machine is
* started with the system property {@code java.security.manager} set to
* the special token "{@code disallow}" then the {@code setSecurityManager}
* method cannot be used to set a security manager.
*
* @param sm the security manager or {@code null}
* @throws SecurityException
@@ -371,23 +365,9 @@ private static void checkIO() {
@Deprecated(since="17", forRemoval=true)
public static void setSecurityManager(@SuppressWarnings("removal") SecurityManager sm) {
if (allowSecurityManager()) {
if (security == null) {
// ensure image reader is initialized
Object.class.getResource("java/lang/ANY");
// ensure the default file system is initialized
DefaultFileSystemProvider.theFileSystem();
}
if (sm != null) {
try {
// pre-populates the SecurityManager.packageAccess cache
// to avoid recursive permission checking issues with custom
// SecurityManager implementations
sm.checkPackageAccess("java.lang");
} catch (Exception e) {
// no-op
}
}
setSecurityManager0(sm);
System.err.println("WARNING: java.lang.System::setSecurityManager" +
" is deprecated and will be removed in a future release.");
setSecurityManagerDirect(sm);
} else {
// security manager not allowed
if (sm != null) {
@@ -397,6 +377,27 @@ public static void setSecurityManager(@SuppressWarnings("removal") SecurityManag
}
}

private static void setSecurityManagerDirect(
@SuppressWarnings("removal") SecurityManager sm) {
if (security == null) {
// ensure image reader is initialized
Object.class.getResource("java/lang/ANY");
// ensure the default file system is initialized
DefaultFileSystemProvider.theFileSystem();
}
if (sm != null) {
try {
// pre-populates the SecurityManager.packageAccess cache
// to avoid recursive permission checking issues with custom
// SecurityManager implementations
sm.checkPackageAccess("java.lang");
} catch (Exception e) {
// no-op
}
}
setSecurityManager0(sm);
}

@SuppressWarnings("removal")
private static synchronized
void setSecurityManager0(final SecurityManager s) {
@@ -2149,6 +2150,7 @@ private static void initPhase3() {
Unsafe.getUnsafe().ensureClassInitialized(StringConcatFactory.class);

String smProp = System.getProperty("java.security.manager");
boolean needWarning = false;
if (smProp != null) {
switch (smProp) {
case "disallow":
@@ -2159,8 +2161,9 @@ private static void initPhase3() {
break;
case "":
case "default":
setSecurityManager(new SecurityManager());
setSecurityManagerDirect(new SecurityManager());
allowSecurityManager = MAYBE;
needWarning = true;
break;
default:
try {
@@ -2178,17 +2181,18 @@ private static void initPhase3() {
// custom security manager may be in non-exported package
ctor.setAccessible(true);
SecurityManager sm = (SecurityManager) ctor.newInstance();
setSecurityManager(sm);
setSecurityManagerDirect(sm);
needWarning = true;
} catch (Exception e) {
throw new InternalError("Could not create SecurityManager", e);
}
allowSecurityManager = MAYBE;
}
} else {
allowSecurityManager = NEVER;
allowSecurityManager = MAYBE;
}

if (allowSecurityManager != NEVER) {
if (needWarning) {
System.err.println("WARNING: The Security Manager is deprecated" +
" and will be removed in a future release.");
}
@@ -35,7 +35,7 @@

public static void main(String args[]) throws Exception {
String prop = System.getProperty("java.security.manager");
boolean disallow = !"allow".equals(prop);
boolean disallow = "disallow".equals(prop);
try {
System.setSecurityManager(new SecurityManager());
if (disallow) {
@@ -234,7 +234,14 @@ static LoggerFinder getLoggerFinder(Class<?> expectedClass,
}
}
} else if ("QUIET".equals(errorPolicy.toUpperCase(Locale.ROOT))) {
if (!ErrorStream.errorStream.peek().isEmpty()) {
String warning = ErrorStream.errorStream.peek();
String smDeprecationWarning
= "WARNING: java.lang.System::setSecurityManager is deprecated and will be removed in a future release."
+ System.getProperty("line.separator");
if (warning.startsWith(smDeprecationWarning)) {
warning = warning.substring(smDeprecationWarning.length());
}
if (!warning.isEmpty()) {
throw new RuntimeException("Unexpected error message found: "
+ ErrorStream.errorStream.peek());
}
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2021, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @bug 8266459
* @summary check various warnings
* @library /test/lib
*/

import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;

import java.security.Permission;

public class SecurityManagerWarnings {
public static void main(String args[]) throws Exception {
if (args.length == 0) {
run(null)
.shouldHaveExitValue(0)
.shouldContain("SM is enabled: false")
.shouldNotContain("Security Manager is deprecated")
.shouldContain("setSecurityManager is deprecated");
run("allow")
.shouldHaveExitValue(0)
.shouldContain("SM is enabled: false")
.shouldNotContain("Security Manager is deprecated")
.shouldContain("setSecurityManager is deprecated");
run("disallow")
.shouldNotHaveExitValue(0)
.shouldContain("SM is enabled: false")
.shouldNotContain("Security Manager is deprecated")
.shouldContain("UnsupportedOperationException");
run("SecurityManagerWarnings$MySM")
.shouldHaveExitValue(0)
.shouldContain("SM is enabled: true")
.shouldContain("Security Manager is deprecated")
.shouldContain("setSecurityManager is deprecated");
run("")
.shouldNotHaveExitValue(0)
.shouldContain("SM is enabled: true")
.shouldContain("Security Manager is deprecated")
.shouldContain("AccessControlException");
run("default")
.shouldNotHaveExitValue(0)
.shouldContain("SM is enabled: true")
.shouldContain("Security Manager is deprecated")
.shouldContain("AccessControlException");
} else {
System.out.println("SM is enabled: " + (System.getSecurityManager() != null));
System.setSecurityManager(new SecurityManager());
}
}

static OutputAnalyzer run(String prop) throws Exception {
if (prop == null) {
return ProcessTools.executeTestJvm(
"SecurityManagerWarnings", "run");
} else {
return ProcessTools.executeTestJvm(
"-Djava.security.manager=" + prop,
"SecurityManagerWarnings", "run");
}
}

// This SecurityManager allows everything!
public static class MySM extends SecurityManager {
@Override
public void checkPermission(Permission perm) {
}
}
}
@@ -147,7 +147,7 @@ public void testDumpDirNotExist() throws IOException {
"-Djdk.internal.lambda.dumpProxyClasses=notExist",
"com.example.TestLambda");
assertEquals(tr.testOutput.stream()
.filter(s -> !s.contains("Security Manager is deprecated"))
.filter(s -> !s.contains("setSecurityManager is deprecated"))
.filter(s -> s.startsWith("WARNING"))
.peek(s -> assertTrue(s.contains("does not exist")))
.count(),
@@ -164,7 +164,7 @@ public void testDumpDirIsFile() throws IOException {
"-Djdk.internal.lambda.dumpProxyClasses=file",
"com.example.TestLambda");
assertEquals(tr.testOutput.stream()
.filter(s -> !s.contains("Security Manager is deprecated"))
.filter(s -> !s.contains("setSecurityManager is deprecated"))
.filter(s -> s.startsWith("WARNING"))
.peek(s -> assertTrue(s.contains("not a directory")))
.count(),
@@ -224,7 +224,7 @@ public void testDumpDirNotWritable() throws IOException {
"-Djdk.internal.lambda.dumpProxyClasses=readOnly",
"com.example.TestLambda");
assertEquals(tr.testOutput.stream()
.filter(s -> !s.contains("Security Manager is deprecated"))
.filter(s -> !s.contains("setSecurityManager is deprecated"))
.filter(s -> s.startsWith("WARNING"))
.peek(s -> assertTrue(s.contains("not writable")))
.count(),