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

New policy sometimes has no effect with no indication given

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.2.1
    • security-libs
    • beta
    • generic
    • generic

      When a new policy is set at runtime ,by calling setPolicy, you would
      expect it to have immediate and full effect. However, protection domains
      from which classes where already loaded (via the SecureClassLoader)
      continue to have privileges derived from the old policy. If the new
      policy is stricter, a security hole may result without any indication
      given. This results from the fact that SecureClassLoader has
      a cache for protection domains, and so it consults the policy
      only once per code-source, for the first time it loads a class
      from that code source. Any changes in the policy afterwards
      will not be reflected in the cache, even if a NEW class is
      loaded from that code-source. Needless to say, classes which
      were already loaded before the policy-change - continue to have
      the old privileges. So actually there are 2 problems here:

      1. Even if a new class is loaded after the policy change, from a code-source
         from which another class has been loaded before the policy change - the new
         class would still get the old privileges. This stems from the cache
         in the SecureClassLoader. This is the more severe problem.

      2. A class which was loaded before the policy-change, would continue to have
         its privileges based on the old policy, because its protection domain
         was already computed and a reference to it put in its Class class.
         This is also a problem, and should either be fixed or at least
         documented.



      The following sources exemplify the first problem.


      DynamicPolicy.java implements the dynamic policy. It simply
      allows everything initially, and after it is refreshed -
      allows nothing.


      DynamicPolicy.java
      ------------------


      import java.security.*;
      import java.lang.*;

      public class DynamicPolicy extends Policy{

          static boolean refreshed=false;

          public DynamicPolicy() {
              System.out.println("Dynamic policy constructed...");
          }

          public PermissionCollection getPermissions(CodeSource cs) {
              System.out.println("DynamicPolicy consulted...");

              Permissions perms=new Permissions();

              // Everything is allowed in the beginning...
              // But after the refresh - everything should be prohibited...
              if (!refreshed)
                  perms.add(new AllPermission());

              return perms;
          }

          public void refresh() {
              refreshed=true;
          }
      }

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

      There are 2 code-sources used for this test. The first is a JAR file containing TryAllPermission and
      TryAllPermission1 classes (and their inner classes), and the second is a JAR file containing
      SecondTryAllPermission class (and its inner class).

      TestDynamicPolicy sets the new policy. It then causes TryAllPermission class to be called, and verifies
      that it has all permissions allowed to it. Then, it calls the refresh method of the dynamic policy, which
      now causes the policy to allow NOTHING. And indeed, for a new code-source - SecondTryAllPermission - which
      is now loaded - nothing is allowed. But for TryAllPermission1, whose protection-domain is already cached -
      still everything is allowed!! Note, that the launcher should be run with a security manager
      enabled, and with a policy that enables the code to set and get the policy. javatest.jar should be
      on the CLASSPATH.



      TestDynamicPolicy.java
      --------------------------------------

      import java.io.PrintStream;
      import java.io.IOException;
      import javasoft.sqe.harness.Status;
      import javasoft.sqe.harness.Test;
      import java.lang.System;
      import java.security.Policy;


      public class TestDynamicPolicy implements Test {

          public Status run(String args[], PrintStream log, PrintStream out) {

              // A security manager must be installed
              SecurityManager sm=System.getSecurityManager();
              if (sm==null)
                  return Status.failed("Test must be run with a security manager installed");

              // Instantiate and set the new policy
              DynamicPolicy dp = new DynamicPolicy();
      Policy.setPolicy(dp);

      // Verify that policy has been set
      if (dp != Policy.getPolicy())
      return Status.failed("Policy was not set!!");

      // Verify the TryALlPermission can do anything
      TryAllPermission tap=new TryAllPermission();
      if (tap.hasAllPermissions() != true)
      // This should not happen
      return Status.failed("Didn't get all permissions in the beginning!");

      // Now, make policy prohibit everything
      dp.refresh();

      // Verify that a class at another URL cannot do anything
      SecondTryAllPermission stap=new SecondTryAllPermission();
      if (stap.hasAllPermissions() != false)
      // This should not happen
      return Status.failed("Everything should be prohibited, but is allowed for second protection domain");

      // Now, verify that a class from a code source whose protection-domain
      // WAS ALREADY CACHED has no permissions
      TryAllPermission1 tap1=new TryAllPermission1();
      if (tap1.hasAllPermissions() != false)
      return Status.failed("Oops, a NEW class from first protection domain has all permissions which it shouldn't!");

              return Status.passed("Passed the test");
          }

          public static void main(String args[]) {
              Status s;
              TestDynamicPolicy jstest = new TestDynamicPolicy();
              s = jstest.run(args, System.err, System.out);
              s.exit();
          }
      }





      --------------------------------------------------------
      When TestDynamicPolicy is run, the result is:

      FAILED: Oops, a NEW class from first protection domain has all permissions which it shouldn't!


      TryAllPermission.java
      --------------------------------------------------------
      import java.security.*;
      import java.lang.System;

      public class TryAllPermission {

          public boolean hasAllPermissions() {

              final AllPermission ap=new AllPermission();

              final SecurityManager sm=System.getSecurityManager();

              try {
                  AccessController.doPrivileged(new PrivilegedAction() {
                            public Object run() {
                                  // privileged code goes here, for example:
                                  sm.checkPermission(ap);
                                  return null; // nothing to return
                            }
                        });
                  return true;
              } catch (SecurityException se) {
                  return false;
              }

          }
      }

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



      TryAllPermission1.java
      --------------------------------------------------------
      import java.security.*;
      import java.lang.System;

      public class TryAllPermission1 {

          public boolean hasAllPermissions() {

              final AllPermission ap=new AllPermission();

              final SecurityManager sm=System.getSecurityManager();

              try {
                  AccessController.doPrivileged(new PrivilegedAction() {
                            public Object run() {
                                  // privileged code goes here, for example:
                                  sm.checkPermission(ap);
                                  return null; // nothing to return
                            }
                        });
                  return true;
              } catch (SecurityException se) {
                  return false;
              }

          }
      }

      SecondTryAllPermission.java
      --------------------------------------------------------

      import java.security.*;
      import java.lang.System;

      public class SecondTryAllPermission {

          public boolean hasAllPermissions() {

              final AllPermission ap=new AllPermission();

              final SecurityManager sm=System.getSecurityManager();

              try {
                  AccessController.doPrivileged(new PrivilegedAction() {
                            public Object run() {
                                  // privileged code goes here, for example:
                                  sm.checkPermission(ap);
                                  return null; // nothing to return
                            }
                        });
                  return true;
              } catch (SecurityException se) {
                  return false;
              }
          }
      }


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

      The test should be given the following permissions:


      grant codeBase "file:testPath" {
              permission java.security.SecurityPermission "setPolicy";
              permission java.security.SecurityPermission "getPolicy";
      };




            gellisonsunw Gary Ellison (Inactive)
            dhendlersunw Danny Hendler (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: