Tim Blackman wrote:
On Jul 31, 2010, at 11:53 PM, Peter Firmstone wrote:

<snip>
A RevokeableDynamicPolicy supports the addition or removal of PermissionGrant's
<snip>

Hmmm.

I remember talking with Bob and Mike Warres about this.  The problem with 
removing permission grants is that  when code is granted a permission, it can 
very likely squirrel away something -- an object, or another capability 
available through the granted permission -- that will permit it to perform the 
same operation again without the JVM checking for the permission again.  Our 
conclusion was that there was probably no effective way to implement removal of 
permission grants.

Perhaps there is something about the particulars of what you have done here to 
negate this argument -- and I have not had the time to check the details of 
your stuff myself to be sure -- but my guess is that it will be difficult or 
impossible to do this in an airtight manner.

First I'd better point out that this is still an experiment and may not make a release, but I'm glad you've responded, as security is a difficult issue and all help is appreciated.

The SecurityDelegate's I mentioned earlier, are of course a compromise, many existing security guards on existing Java classes are on constructors or methods that return object's, however object's such as OutputStream and the likes, have unguarded methods, so once these objects have been released, the reference can be stored, by what may later become untrusted, and the methods called by untrusted objects.

The SecurityDelegate is a wrapper class that implements the same interface as the guarded object, but once notified of a Permission revocation ensures the next thread to access the guarded object, through the SecurityDelegate has AccessController.checkPermission called again.

Because of the cost of the Permission check, it's too expensive to call on every method invocation.

However there is still a flaw in this, consider for a moment an object protected by a SecurityDelegate, permission's are revoked, the policy notifies all SecurityDelegate's of a revocation, they ensure the next method call rechecks permission. The flaw is that once the SecurityDelegate, containing the protected object is in untrusted hands, we don't know how many references to it exist. The next call might have permission, however there is no guarantee that another following will. The mixing of untrusted and trusted code is the risk.

While it cannot be eliminated entirely, every method requiring protection, should execute a private method something like the following (Constructors and methods excluded for clarity):

class ProtectedOutputStream extends OutputStream implements SecurityDelegate {

   private final OutputStream protected;
   private volatile boolean check = true;
   private volatile Thread currentThread = null;

   public void notify(){
      check = true;
   }

   private void check(){
      if ( check == true) {
         AccessController.checkPermission(perm);
         currentThread = Thread.currentThread();
         check = false;
         return;
      }
      if ( currentThread != null ) {
         if (Thread.currentThread() == currentThread ) {
            return;
         }
      }
       AccessController.checkPermission(perm);
       currentThread = Thread.currentThread();
       return;
   }
public void write(byte[] b) {
       check();
       protected.write(b);
   }

}

Still, I'm not sure if this is enough to protect the object, there are some Thread timing issues I've ignored here, but those aside, I don't want to call the AccessController every invocation, for obvious efficiency reasons.

Thought's and ideas?

Cheers,

Peter.

Reply via email to