This is an automated email from the ASF dual-hosted git repository.
jaikiran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant.git
The following commit(s) were added to refs/heads/master by this push:
new 2821ba0d1 Throw BuildException when <permissions> is in use on Java 18
and higher
2821ba0d1 is described below
commit 2821ba0d14f932df056e89afa7217e09d5eab270
Author: Jaikiran Pai <[email protected]>
AuthorDate: Wed Aug 16 15:39:27 2023 +0530
Throw BuildException when <permissions> is in use on Java 18 and higher
---
manual/Types/permissions.html | 16 ++++++---
src/main/org/apache/tools/ant/MagicNames.java | 11 ++++++
.../org/apache/tools/ant/taskdefs/ExecuteJava.java | 4 ++-
.../org/apache/tools/ant/types/Permissions.java | 41 ++++++++++++++++++----
.../apache/tools/ant/util/SecurityManagerUtil.java | 27 ++++++++++++++
.../ant/util/optional/NoExitSecurityManager.java | 2 ++
6 files changed, 89 insertions(+), 12 deletions(-)
diff --git a/manual/Types/permissions.html b/manual/Types/permissions.html
index d0db0e327..b0c7e892d 100644
--- a/manual/Types/permissions.html
+++ b/manual/Types/permissions.html
@@ -25,11 +25,17 @@
<body>
<h2 id="permissions">Permissions</h2>
-<p><b>Note</b> <code>Permissions</code> requires the use of Java
SecurityManager.
- Java version 17 deprecated SecurityManager for removal and Java 18 by
default disallowed
- setting SecurityManager at runtime. <code>Permissions</code> is thus no
longer supported
- when used in Java 18 or higher versions. Using it in such Java runtime
versions won't provide the
- functionality that it originally provided.</p>
+<p><b>Note:</b> <code>Permissions</code> requires the use of Java
SecurityManager.
+ Java version 17 deprecated SecurityManager for removal and Java 18 and
higher versions, by
+ default, disallow setting SecurityManager at runtime.
<code>Permissions</code> is thus no longer
+ supported when used in Java 18 or higher versions. Using it in those Java
runtime versions
+ will throw a <code>org.apache.tools.ant.BuildException</code>. Throwing of
+ <code>BuildException</code> can be relaxed by setting the
+ <code>ant.securitymanager.usage.warn</code> system or Ant property to
<code>true</code>,
+ which will then cause a warning to be logged instead of the exception being
thrown. Even when
+ <code>ant.securitymanager.usage.warn</code> is set to <code>true</code>,
+ SecurityManager usage will still be disabled and no security checks will be
performed.
+ It is recommended to no longer use <code><permissions></code></p>
<p>Permissions represents a set of security permissions granted or revoked to
a specific part
code executed in the JVM where Apache Ant is running in. The actual
Permissions are specified
diff --git a/src/main/org/apache/tools/ant/MagicNames.java
b/src/main/org/apache/tools/ant/MagicNames.java
index 12fbcf731..4e3b8735e 100644
--- a/src/main/org/apache/tools/ant/MagicNames.java
+++ b/src/main/org/apache/tools/ant/MagicNames.java
@@ -359,5 +359,16 @@ public final class MagicNames {
*/
public static final String DISABLE_NASHORN_COMPAT =
"ant.disable.graal.nashorn.compat";
+ /**
+ * When running on Java 18 or higher runtime, Ant will throw a {@link
BuildException}
+ * if the {@linkplain org.apache.tools.ant.types.Permissions
<permissions>} type is used.
+ * Set this property to {@code true} to disable throwing an exception and
instead just log a
+ * warning message.
+ *
+ * Value: {@value}
+ * @since Ant 1.10.14
+ */
+ public static final String WARN_SECURITY_MANAGER_USAGE =
"ant.securitymanager.usage.warn";
+
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
index 0964c9132..cb0d1250f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
@@ -211,9 +211,11 @@ public class ExecuteJava implements Runnable,
TimeoutObserver {
@Override
public void run() {
final Object[] argument = {javaCommand.getArguments()};
+ boolean restoreSecMgr = false;
try {
if (perm != null) {
perm.setSecurityManager();
+ restoreSecMgr = true;
}
main.invoke(null, argument);
} catch (InvocationTargetException e) {
@@ -224,7 +226,7 @@ public class ExecuteJava implements Runnable,
TimeoutObserver {
} catch (Throwable t) {
caught = t;
} finally {
- if (perm != null) {
+ if (perm != null && restoreSecMgr) {
perm.restoreSecurityManager();
}
synchronized (this) {
diff --git a/src/main/org/apache/tools/ant/types/Permissions.java
b/src/main/org/apache/tools/ant/types/Permissions.java
index 703c8acc8..35144acf1 100644
--- a/src/main/org/apache/tools/ant/types/Permissions.java
+++ b/src/main/org/apache/tools/ant/types/Permissions.java
@@ -30,13 +30,13 @@ import java.util.StringTokenizer;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ExitException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.util.SecurityManagerUtil;
/**
* This class implements a security manager meant for usage by tasks that run
inside the
* Ant VM. An examples are the Java Task and JUnitTask.
- * <p>
- * Note: This class doesn't provide any functionality for Java 18 and higher
*
* <p>
* The basic functionality is that nothing (except for a base set of
permissions) is allowed, unless
@@ -46,9 +46,13 @@ import org.apache.tools.ant.util.SecurityManagerUtil;
* It is not permissible to add permissions (either granted or revoked) while
the Security Manager
* is active (after calling setSecurityManager() but before calling
restoreSecurityManager()).
*
+ * <p>
+ * Note: This class isn't supported in Java 18 and higher where {@link
SecurityManager} has been
+ * deprecated for removal.
+ *
* @since Ant 1.6
*/
-public class Permissions {
+public class Permissions extends ProjectComponent {
private final List<Permission> grantedPermissions = new LinkedList<>();
private final List<Permission> revokedPermissions = new LinkedList<>();
@@ -99,11 +103,24 @@ public class Permissions {
* subject to these Permissions. Note that setting the SecurityManager too
early may
* prevent your part from starting, as for instance changing classloaders
may be prohibited.
* The classloader for the new situation is supposed to be present.
+ * <p>
+ * This method is no longer supported in Java 18 and higher versions and
throws a
+ * {@link BuildException}. {@link
org.apache.tools.ant.MagicNames#WARN_SECURITY_MANAGER_USAGE}
+ * property can be set to {@code true} to log a warning message instead of
throwing the exception.
+ *
* @throws BuildException on error
*/
public synchronized void setSecurityManager() throws BuildException {
if (!SecurityManagerUtil.isSetSecurityManagerAllowed()) {
- return;
+ final String msg = "Use of <permissions> or " +
Permissions.class.getName()
+ + " is disallowed in current Java runtime version";
+ if (SecurityManagerUtil.warnOnSecurityManagerUsage(getProject())) {
+ // just log a warning
+ log("Security checks are disabled - " + msg, Project.MSG_WARN);
+ return;
+ } else {
+ throw new BuildException(msg);
+ }
}
origSm = System.getSecurityManager();
init();
@@ -174,10 +191,22 @@ public class Permissions {
/**
* To be used by tasks that just finished executing the parts subject to
these permissions.
+ * <p>
+ * This method is no longer supported in Java 18 and higher versions and
throws a
+ * {@link BuildException}. {@link
org.apache.tools.ant.MagicNames#WARN_SECURITY_MANAGER_USAGE}
+ * property can be set to {@code true} to log a warning message instead of
throwing the exception.
*/
- public synchronized void restoreSecurityManager() {
+ public synchronized void restoreSecurityManager() throws BuildException {
if (!SecurityManagerUtil.isSetSecurityManagerAllowed()) {
- return;
+ final String msg = "Use of <permissions> or " +
Permissions.class.getName()
+ + " is disallowed in current Java runtime version";
+ if (SecurityManagerUtil.warnOnSecurityManagerUsage(getProject())) {
+ // just log a warning
+ log("Security checks are disabled - " + msg, Project.MSG_WARN);
+ return;
+ } else {
+ throw new BuildException(msg);
+ }
}
active = false;
System.setSecurityManager(origSm);
diff --git a/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java
b/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java
index e27b14efb..836a7b872 100644
--- a/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java
+++ b/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java
@@ -17,14 +17,41 @@
*/
package org.apache.tools.ant.util;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+
+/**
+ * @since Ant 1.10.14
+ */
public final class SecurityManagerUtil {
private static final boolean isJava18OrHigher =
JavaEnvUtils.isAtLeastJavaVersion("18");
+ private static final boolean sysPropWarnOnSecMgrUsage =
+ Boolean.getBoolean(MagicNames.WARN_SECURITY_MANAGER_USAGE);
+ /**
+ * {@return true if {@code SecurityManager} usage is allowed in current
Java runtime. false
+ * otherwise}
+ */
public static boolean isSetSecurityManagerAllowed() {
if (isJava18OrHigher) {
return false;
}
return true;
}
+
+ /**
+ * {@return true if {@code SecurityManager} usage should only be logged as
a warning. false
+ * otherwise}
+ */
+ public static boolean warnOnSecurityManagerUsage(final Project project) {
+ if (project == null) {
+ return sysPropWarnOnSecMgrUsage;
+ }
+ final String val =
project.getProperty(MagicNames.WARN_SECURITY_MANAGER_USAGE);
+ if (val == null) {
+ return sysPropWarnOnSecMgrUsage;
+ }
+ return Boolean.parseBoolean(val);
+ }
}
diff --git
a/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
b/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
index 4df8ef099..f1559e9ab 100644
--- a/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
+++ b/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
@@ -26,6 +26,8 @@ import org.apache.tools.ant.ExitException;
* The goal is to intercept System.exit calls and make it throw an
* exception instead so that a System.exit in a task does not
* fully terminate Ant.
+ * <p>
+ * This class is no longer supported in Java runtime versions 18 and higher.
*
* @see ExitException
*/