Re: specifying revoked permissions at runtime
Alexey wrote:
I've written a prototype for an application that's going to allow 3rd
party jar files to be loaded at runtime (it's a game, where playing
the game consists of writing modules that get launched into the
runtime environment and interact with a set API). Obviously, I need
to protect the game engine from "cheating" libraries that might
somehow mess with the game engine itself or the runtime environment.
Naturally, I'm looking at the java.security framework. I found just
the thing I need in java.lang.RuntimePermission among some other ones,
but what I'm not understanding is how to tie it to a class loader
object in a "revoke this permission" kind of way. I'm able to grant
my own set of permissions for my own class loader, but how do I revoke
them? It appears RuntimePermission does not rely on actions. You can
only specify permission targets and by default, class loaders do not
include any RuntimePermission objects at all. So it appears it's wide
open (I imagine java.* package definitions are ensured at the runtime
level, not via this security model). One obvious thing I need to do
is restrict people loading classes within some packages because the
game engine API relies on package access protection in some places. I
could of course inspect all jar files prior to loading them, but I
think permissions would be a more graceful and reliable way of doing
this.
Package injection can be stopped by specifying the packages are sealed
within the jar file manifest. Access to packages can be removed by
adding to the "package.access" security property (see
SecurityManager.checkPackageAccess). As it happens java.* packages has
special code within java.lang.ClassLoader to stop tinkering, so it is no
t a good example.
The easiest way to specify code permissions is through the security
policy file. You can also do it programmatically, as for instance
WebStart does (the source is available).
The permissions available at any point in a thread execution is the
*intersection* of all frames on the stack. That is to say all code on
the stack must have the permission in order for it to be allowed. There
are a couple caveats. Threads also inherit the stack when they are
created (so the creating stack also gets checked). Checking of the stack
can be stopped, and optionally another context inserted, using
java.security.AccessController.doPrivileged.
It's really quite difficult to get right.
Tom Hawtin