Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7119959

Rhino modifies return value of reflection methods requiring checkMemberAccess()

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Withdrawn
    • Affects Version/s: 6u20
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:

      Description

      FULL PRODUCT VERSION :
      java version "1.6.0_20"
      OpenJDK Runtime Environment (IcedTea6 1.9.10) (fedora-55.1.9.10.fc14-i386)
      OpenJDK Server VM (build 19.0-b09, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux localhost.localdomain 2.6.35.14-103.fc14.i686.PAE #1 SMP Thu Oct 27 15:58:03 UTC 2011 i686 i686 i386 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      On line 92 of src/share/classes/com/sun/script/javascript/RhinoWrapFactory.java, the return value of a method is modified to be null *if there is a security manager present* and the return value is a non-public member.

      This gives *very* surprising behaviour in scripts:

      var cls = java.lang.class.forName("java.util.ArrayList");
      var sizeField = cls.getDeclaredField("size");

      the sizeField in the above example is assigned a null, even though the Class.getDeclaredField(String) is documented to never return null. No exception or log message is emitted to hint the user about what actually happened.

      In my opinion the handling of Member return objects is a bit simplistic in the RhinoWrapFactory.
      Member interface has just 3 impls (and won't be getting any new I suppose?) - Constructor, Method and Field. The code in the RhinoWrapFactory should specialize for those cases and try to call the SecurityManager.checkMemberAccess() appropriately:

      if (member instanceof Field) {
          //just call this to get the member access checked by the security manager
          member.getDeclaringClass().getDeclaredField(member.getName());
      } else if (member instanceof Method) {
      ...


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the code from the test case with the following system props:

      -Djava.security.manager -Djava.security.policy==security.file


      where the security.file contains these permission definitions:

      grant {
          permission java.security.AllPermission;
      };



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      private int java.util.ArrayList.size
      private int java.util.ArrayList.size

      ACTUAL -
      null
      private int java.util.ArrayList.size


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.script.ScriptEngineManager;

      public class Test {

          public static void main(String[] args) throws Exception {
              test();
              System.setSecurityManager(null);
              test();
          }
          
          private static void test() throws Exception {
              new ScriptEngineManager().getEngineByName("JavaScript").eval(""
                  + "var cls = java.lang.Class.forName(\"java.util.ArrayList\");"
                  + "var field = cls.getDeclaredField(\"size\");"
                  + "println(field);");
          }
      }

      ---------- END SOURCE ----------

        Attachments

          Activity

            People

            • Assignee:
              sundar Sundararajan Athijegannathan
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:
                Indexed: