Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5034011

ProtectionDomain.toString() in Policy.implies() causes StackOverflowError

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 1.4.2
    • security-libs

      Name: js151677 Date: 04/19/2004


      FULL PRODUCT VERSION :
      java version "1.4.2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
      Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

      java version "1.5.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
      Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)

      FULL OS VERSION :
      SuSE Linux 7.1 (i386)
      VERSION = 7.1
      Kernel: 2.2.18

      Can be reproducible on WindowsXP,Solaris.

      A DESCRIPTION OF THE PROBLEM :
      The cause of the problem is a call to ProtectionDomain.toString() inside the method implies() of a custom java.security.Policy implementation. If this method returns false, then an infinite recursion starts:

      ProtectionDomain.toString() calls ProtectionDomain.seeAllp() which in turn checks permissions and thus ends up in calling Policy.implies().

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Compile PolicyTest.java
      2. Put PolicyTest.class and test.policy into one directory
      3. run:
         java -Djava.security.manager -Djava.security.auth.policy=test.policy PolicyTest

      wait for the StackOverflowError.

      Alternatively you can run this through a debugger, putting breakpoints at lines 17 and 28 (17: System.getProperty(), 28: ProtectionDomain.toString()) of PolicyTest.java.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Of course, an empty Policy implementation makes no sense, but I am planning to implement a custom Policy so I will need logging information. Calling toString() is quite natural for that purpose so it should be fail-safe in any case.
      ACTUAL -
      The result is a recursion between ProtectionDomain.toString() and Policy.implies() (and other methods inbetween).

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      This is the output from the debugger showing the stack with one recursion:

      implies():28, PolicyTest$EmptyPolicy
      implies():189, java.security.ProtectionDomain
      checkPermission():254, java.security.AccessControlContext
      checkPermission():401, java.security.AccessController
      checkPermission():524, java.lang.SecurityManager
      seeAllp():241, java.security.ProtectionDomain
      toString():220, java.security.ProtectionDomain
      valueOf():2131, java.lang.String
      append():361, java.lang.StringBuffer
      implies():28, PolicyTest$EmptyPolicy
      implies():189, java.security.ProtectionDomain
      checkPermission():254, java.security.AccessControlContext
      checkPermission():401, java.security.AccessController
      checkPermission():524, java.lang.SecurityManager
      checkPropertyAccess():1276, java.lang.SecurityManager
      getProperty():573, java.lang.System
      main():17, PolicyTest

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      You need PolicyTest.java and test.policy:

      /*
       * PolicyTest.java
       */
      import java.security.*;
      import java.io.*;

      /**
       * Calling ProtectionDomain.toString() on a Policy that returns false from
       * implies(), causes a stack overflow.
       */
      public class PolicyTest
      {
          public static void main(String[] args) throws Exception
          {
              EmptyPolicy.setPolicy(new EmptyPolicy());
              System.out.println("Installed empty policy");
              System.out.println("Your home directory is " + System.getProperty("user.home"));
          }

          static class EmptyPolicy extends Policy
          {
              public EmptyPolicy()
              {
              }

              public boolean implies(ProtectionDomain domain, Permission permission)
              {
                  System.out.println("implies called with ProtectionDomain " + domain + " Permission " + permission);
                  //return deferredPolicy.implies(domain, permission);
                  return false;
              }

              public PermissionCollection getPermissions(CodeSource codesource)
              {
                  System.out.println("getPermissions called for codesource " + codesource);
                  //PermissionCollection pc = deferredPolicy.getPermissions(codesource);
                  System.out.println("returning " + null);
                  return null;
              }

              public PermissionCollection getPermissions(ProtectionDomain domain)
              {
                  System.out.println("getPermissions called for ProtectionDomain " + domain);
                  //PermissionCollection pc = deferredPolicy.getPermissions(domain);
                  System.out.println("returning " + null);
                  return null;
              }

              public void refresh()
              {
                  System.out.println("refreshing policy (no implementation)");
              }
          }
      }

      --------------------------------------------------------------------------

      /*
       * test.policy
       */
      grant codeBase "file:."
      {
      permission java.security.SecurityPermission "setPolicy";
      };
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Don't call ProtectionDomain.toString():

      public boolean implies(ProtectionDomain domain, Permission permission)
      {
           // causes StackOverflowError:
           //System.out.println("ProtectionDomain " + domain
           // + " Permission " + permission);
           System.out.println("ProtectionDomain " + domain.getCodeSource()
                              + " Permission " + permission);
           return false;
      }
      (Incident Review ID: 191392)
      ======================================================================

            Unassigned Unassigned
            jssunw Jitender S (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: