Closed Bug 199051 Opened 22 years ago Closed 22 years ago

Invoker optimization does not work with security manager

Categories

(Rhino Graveyard :: Core, defect)

defect
Not set
normal

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: igor, Assigned: norrisboyd)

Details

Attachments

(2 files, 3 obsolete files)

To speedup invocation of Java methods via reflection Rhino generates special classes that calls the reflected method directly. It requires to create a class loader to load the generated byte code for the class but currently Rhino does not check for a possible SecurityException during loader creation/class load. It can happen, for example, if a system security policy disable creation of class loaders or a currently executed script does not have sufficient privileges even if Rhino classes are allowed to do that. The problem was initially reported in netscape.public.mozilla.jseng, see http://groups.google.com/groups?dq=&hl=en&lr=&ie=UTF-8&threadm=3E708F75.2020108%40icesoft.com&prev=/groups%3Fdq%3D%26num%3D25%26hl%3Den%26lr%3D%26ie%3DUTF-8%26group%3Dnetscape.public.mozilla.jseng%26start%3D25 Here is a way to reproduce the problem based on that: 1. Create the policy file test.policy that prevents Rhino from creating class loaders with the following body: grant codeBase "file:${user.home}/path-to-js-jar" { permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.io.FilePermission "<<ALL FILES>>", "read"; permission java.util.PropertyPermission "*", "read"; }; where ${user.home}/path-to-js-jar should be adjusted accordingly (on windows one may use something like file:/d:/rhino1_5/js.jar 2. Put the following 2 lines into the file test.js in the same directory as test.policy: var x = new java.lang.Integer(2); print(x.intValue()); 3. Run Rhino shell in the interpreted mode (if creation of class loaders is disabled, the optimizer would not work): java -Djava.security.manager -Djava.security.policy=test.policy org.mozilla.javascript.tools.shell.Main -opt -1 test.js It gives instead of expected printed number 2 an exception stack trace: Exception in thread "main" java.security.AccessControlException: access denied (java.lang.RuntimePermission createClassLoader) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:272) at java.security.AccessController.checkPermission(AccessController.java:399) at java.lang.SecurityManager.checkPermission(SecurityManager.java:545) at java.lang.SecurityManager.checkCreateClassLoader(SecurityManager.java:610) at java.lang.ClassLoader.<init>(ClassLoader.java:234) at org.mozilla.javascript.DefiningClassLoader.<init>(DefiningClassLoader.java:55) More complex test case would be to grant the createClassLoader permission to Rhino classes and use optimizer. In this case the generated classes does not sufficient privileges and triggers AccessControlException as well: test.policy: grant codeBase "file:${user.home}/path-to-js-jar" { permission java.lang.RuntimePermission "createClassLoader"; permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.io.FilePermission "<<ALL FILES>>", "read"; permission java.util.PropertyPermission "*", "read"; }; invocation: java -Djava.security.manager -Djava.security.policy=test.policy org.mozilla.javascript.tools.shell.Main -opt 9 test.js leads to exactly the same exception.
The patch adds a public API to enable/disable on per Context basis the invoker optimization and disables it for any Context instance that has seen SecurityException during invoker invocation. The patch also disables invoker optimization in case of var-arg methods since there any speedup in method invocation is berried under the need to create/unwrap additional argument arrays.
A simple way to resolve the issue is to create an invoker object in FunctionObject constructor instead of doing this lazily during script call. In typical applications FunctionObject instances are constructed during initialization when there is no script or other code on Java stack with restricted permissions, so as long as Rhino classes have enough permissions, Invoker optimization should be available. And if it is not, the patch catches SecurityException to disable the optimization in this case which will happen only once and not during each call, so the performance impact should be minimal even in this case.
Attachment #118361 - Attachment is obsolete: true
Attachment #118908 - Attachment is obsolete: true
I committed the above patch.
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Verified FIXED. I followed the steps that Igor outlined above in the Rhino1_5R4 shell vs. the Rhino1_5R5pre shell. I got the same exception as Igor in R4, but no exception in R5pre. I tried both variations of the test (opt -1 and opt 9) which Igor explained above. I will attach my opt -1 results below -
Status: RESOLVED → VERIFIED
Targeting as resolved against 1.5R5
Target Milestone: --- → 1.5R5
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: