6

I'm building a SWING application and also need to write a custom SecurityManager. If I write an empty class which extends SecurityManager like this

public class Sandbox extends SecurityManager {}

it works fine, meaning that the GUI is rendered correctly and all privileges like I/O are revoked. However I need to customize the checkPermission method and whenever I override it nothing works anymore... Why even something like this shouldn't work??

public class Sandbox extends SecurityManager {
  @Overide
  public void checkPermission(Permission perm) {
    super.checkPermission(perm);
  }
}

Update: a very basic example that shows the problem is this

public static void main(String[] args) {

    System.setSecurityManager(new SecurityManager() {
        @Override
        public void checkPermission(Permission p) {
            if (some_condition_here) {
              // Do something here
            } else {
              // Resort to default implementation
              super.checkPermission(p);
            }
        }
    });

    new JFrame().setVisible(true);

}

Removing the "checkPermission" method the application works correctly, but I really can't get my head around this.

Flavio
  • 846
  • 1
  • 9
  • 21

2 Answers2

1

The permissions are granted based on all the code on the stack. All callers must have the required permission. If you override the method and call the superclass method, your code is on the stack as well which implies that your codebase (where your custom SecurityManager belongs to) must have the permission you (your callers) ask for.

That’s the difference between overriding or not. If you don’t override that method only the (possibly privileged) caller’s code is on the stack and it will get the requested permission. If you override that method your code is also on the stack and must have the permission as well.

So if you want to implement a custom SecurityManager which invokes the inherited check method you must configure the inherited (policy based) logic to give your SecurityManager all permissions it should be able to grant. It’s recommended to separate the SecurityManager from the rest of the application into a different codebase so only the SecurityManager and nothing else gets the generous permissions.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • So he basically needs to cover all the possible requests to the security manager. But your answer sounds more professional! +1 – mike Sep 04 '13 at 12:52
  • Still, from Oracle documentation they suggest calling (for example) super.checkRead() from public void checkRead(String file). And I keep getting the same exception being thrown – Flavio Sep 04 '13 at 20:06
  • As Holger said, everything on the stack gets checked for the permission. So you need to implement them in the subclass as well. – mike Sep 05 '13 at 00:18
  • It doesn’t matter which check… method you override. All these methods delegate to `checkPermission(Permission)` anyway. They are there for historical reasons only. You can control the entire security with that single checkPermission method. However, if you override any of these methods and call its super implementation your code is on the stack and the codebase of your custom security manager must have the permission as well for this check to succeed. – Holger Sep 05 '13 at 08:48
  • Just to recall: if you haven’t configured policies for the default security manager the default is to grant (almost) no permissions to any code outside the JVM at all. The only permissions you might get are "exitVM" if your code is the main application and file access to resources belonging to your own codebase. – Holger Sep 05 '13 at 08:52
0

If you call the superclass' checkPermission(p) you didn't have to override the class in the first place. Comment it out, then it works.

The superclas' calls java.security.AccessController.checkPermission(perm) and that seems to throw a java.security.AccessControlException, when not invoked by java.lang.SecurityManager

in my case it says:

Could not load Logmanager "null"
java.security.AccessControlException: access denied (java.util.PropertyPermission java.util.logging.manager read)

etc.

public class SecurityManagerExample
{
  public static void main(String[] args)
  {
    System.setSecurityManager(new SecurityManager()
    {
      @Override
      public void checkPermission(Permission p)
      {
        //super.checkPermission(p);
      }
    });

    new JFrame().setVisible(true);
  }
}

I found a tutorial on how to write a security manager. I'd also recommend you to go through the java doc and the examples provided by oracle.


UPDATE

Take a look at the method summary and override the functionality you want to forbid. As I found out you also need to explicitly allow the functionality you want to have.

Here an example:

public class SecurityManagerExample
{

  public static void main(String[] args)
  {
    System.setSecurityManager(new SecurityManager()
    {
      @Override
      public void checkWrite(String file) {
        // no exception is thrown, i. e. creating files is allowed in general
      }

      @Override
      public void checkDelete(String file)
      {
        if (file.equals("test.xml"))
        {
          throw new SecurityException("Not allowed to delete test.xml!");
        }
      }
    });

    File f = new File("test.xml");
    try
    {
      f.createNewFile();
    }
    catch (IOException e)
    {
    }

    f.delete();

  }
}

OUTPUT

Exception in thread "main" java.lang.SecurityException: Not allowed to delete test.xml!
    at main.SecurityManagerExample$1.checkDelete(SecurityManagerExample.java:60)
    at java.io.File.delete(File.java:902)
    at main.SecurityManagerExample.main(SecurityManagerExample.java:74)
mike
  • 4,929
  • 4
  • 40
  • 80
  • Thanks mike, I already went through that tutorial but unfortunately it wasn't helpful :( Anyway I've updated my code snippet so as to make clear that I don't simply need to call super.checkPermission(p); inside that method, but my example what just a simplification. And btw "commenting it out" has the same effect of running the program with no SecurityManager at all – Flavio Sep 04 '13 at 11:57
  • Then check the other link I posted under your question. Plus the java doc and there also is another tutorial on oracle http://docs.oracle.com/javase/tutorial/essential/environment/security.html – mike Sep 04 '13 at 12:01
  • Since you updated your comment: What I'm saying is, if you want to use the the functionality of the base class, don't extend it. If you want to extend it, then write you own policies on what is allowed or not. If you just want to forbid a special case. You need to override another method. Since all methods finally call `checkPermission`, it is not easy to override it appropiate. – mike Sep 04 '13 at 12:03