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 <jaiki...@apache.org>
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>&lt;permissions&gt;</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
  */

Reply via email to