May 22, 2011, 11:26 p.m.
posted by superj
Performance Issues in the Java 2 Access-Control Model
The Java 2 access-control model is certainly very powerful. It offers a strong security mechanism embedded into the runtime. It is clear, however, that all the access-control checks performed during the execution of a program may add a significant overhead to the performance of the program itself. This should not be a surprise. Security has a price, but it is better to have reduced performance than to be attacked by malicious programs. To reduce the performance hit, the access-control mechanism adopts three optimization measures.
8.9.1 Removal of Duplicate ProtectionDomains
When it obtains the ProtectionDomains traversed by the thread of execution, AccessController.checkPermission() considers each single ProtectionDomain only once. If a ProtectionDomain appears more than one time, its implies() method will be invoked only once. This offers a good improvement because the ProtectionDomain.implies() method is very expensive in terms of performance (see Section 8.5.1 on page 266).
In Figure on page 284, the same application domain is traversed twice by the thread of execution, with classes MyPrivilegedExceptionAction and CountFile1. However, when AccessController.checkPermission() walks back through the stack frames, obtaining the ProtectionDomains for all the classes on the thread's stack, the first application domain class encountered is MyPrivilegedExceptionAction (see step 5 on page 284). At this point, AccessController.checkPermission() invokes the implies() method on the application domain. When CountFile1 is encountered (see step 7 on page 285), the application domain is not interrogated again.
2 Filtering Out of the System Domain
A significant improvement in the performance of the access-control mechanism comes from the fact that the system domain is never interrogated to see whether it implies a particular Permission. The system domain, being fully trusted, automatically implies AllPermission (see Section 8.2 on page 258). Therefore, there would be no point in calling its implies() method.
From an implementation standpoint, it should be noted also that the system domain is null. Therefore, it would be even impossible to call implies() on it. When it encounters the system domain on the thread's stack, AccessController.checkPermission() moves directly to the next frame on the stack. In Figure on page 284, steps 1, 2, 3, 4, and 6 are filtered out because they involve the system domain.
3 Verification Stopped at the First Privileged Stack Frame
When it encounters a call to AccessController.doPrivileged(), AccessController.checkPermission() stops the verification process with the doPrivileged() caller. The ProtectionDomains for the class calling doPrivileged() is checked for the Permission, but the callers of that class are not (see Figure on page 276). This may result in several Permission checkings being filtered out.
In Figure on page 284, the ProtectionDomain for CountFile1 is checked, but because CountFile1 calls doPrivileged(), the ProtectionDomain of its caller, CountFileCaller1, is not interrogated at all.