This relates to my other post about a non blocking policy.
Basically the two argument constructor was designed around applets and
granting permission to code, not subjects, the access decisions were
made at ProtectionDomain construction time , the policy is never consulted.
Inside Java 2 Platform Security, 2nd Edition, discusses
ProtectionDomain's in chapter 5:
"The first constructor creates a ProtectionDomain with the specified
CodeSource and PermissionColllection, a null ClassLoader, and an empty
Principal array. If a non-null PermissionColleciton is supplied, it is
made immutable by setting it to read-only, to ensure its integrity and
consistency. When we first developed Java 2, we made this design
decision as an added integrity precaution; in retrospect, however, it
complicated our ability to make security policy more flexible. When the
PermissionCollection is not null, the permissions are statically granted
to ProtectionDomain and therefore the security Policy will not be
consulted on subsequent permission checks against this
ProtectionDomain. This behaviour is consistent across all releases of
J2SE. Only this first constructor existed when the Java 2 platform was
introduced. In the releases prior to J2SE 1.4, permissions were granted
to code soley on the basis of the characteristics encapsulate in a
CodeSource. This constructor remains in order to maintain backward
compatiblity with versions prior to J2SE 1.4."
The book also goes on to discuss JAAS and it's subsequent integration
into J2SE 1.4. The creation of ProtectionDomain's 4 argument
constructor, was to support JAAS and more flexible policy decisions.
So the current way ProtectionDomain.implies(Permission) performs a
security check:
1. If PermissionCollection supplied at construction has
AllPermission, return true.
2. If PermissionCollecition was constructed using the 4 argument
constructor, get the Policy and ask it.
3. If the policy returned false, check any Permissions granted at
construction.
Note that the policy merges the ProtectionDomain permissions, so 3 above
gets checked twice.
What I'm thinking is:
When the SecurityManager is instantiated, get the policy and maintain a
volatile reference to it.
Then instead of asking a ProtectionDomain if it implies, ask the policy
directly if the ProtectionDomain has permission.
When the policy is replaced, a Permission check is performed by the
security manager, if permission is granted, it could schedule a task to
update the reference. If the task fails, the old policy is still in
force, log message. This could either mean that instantiation of the
new Policy failed, or someone just checked to see if they had permission
to update the policy without updating it.
This would make the security manager and underlying policies non
blocking, potentially avoiding cache misses and allowing security checks
to be performed even in the most scalability critical areas of code.
I've posted to the concurrency interest list, so am interested about
their thoughts on limits to scalability.
Even though it is just one synchronized lock to access a reference,
every security check thread calls it and the new SecurityManager can
parallelise the access control context permission check into multiple
threads, currently ProtectionDomains in a context are processed in
series, so if we've got an average of 10 protection domains on the
stack, we've just increased concurrency by 10 times. Every library, jar
file etc, has it's own ProtectionDomain.
Cheers,
Peter.
Dan Creswell wrote:
Can you explain a bit more of the motivation for asking the questions below?
On 8 January 2012 11:49, Peter Firmstone <[email protected]> wrote:
Does anyone rely on static ProtectionDomain's?
new ProtectionDomain(codeSource, permissions)
Static domains do not consult the Policy, ever.
Does anyone rely on a ProtectionDomain that doesn't consult the installed
policy for security decisions?
Regards,
Peter.