3 Replies Latest reply on Apr 1, 2008 11:44 AM by Adrian Brock

    Annotation hash check with security enabled

    Ales Justin Master

      With my recent changes of INSTANCE scope inspection, I have the following code to check if there is some other non-annotation metadata present:

       Set<Object> checkSet = new HashSet<Object>();
       Object[] allMetaData = levelMetaData.getMetaData();
       Annotation[] annotations = levelMetaData.getAnnotations();
       // all meta data is not null, since instance metadata is not empty
       checkSet.addAll(Arrays.asList(allMetaData));
       checkSet.removeAll(Arrays.asList(annotations));
      
       // do we have something else than annotations
       if (checkSet.isEmpty() == false)
       return true;
      

      but I already stumbled upon this
      7828 ERROR [AbstractKernelController] Error installing to Instantiated: name=SimpleBean state=Described
      java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
       at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
       at java.security.AccessController.checkPermission(AccessController.java:427)
       at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
       at java.lang.SecurityManager.checkMemberAccess(SecurityManager.java:1662)
       at java.lang.Class.checkMemberAccess(Class.java:2125)
       at java.lang.Class.getDeclaredMethods(Class.java:1762)
       at sun.reflect.annotation.AnnotationInvocationHandler.getMemberMethods(AnnotationInvocationHandler.java:257)
       at sun.reflect.annotation.AnnotationInvocationHandler.equalsImpl(AnnotationInvocationHandler.java:169)
       at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:40)
       at $Proxy34.equals(Unknown Source)
       at java.util.Arrays$ArrayList.indexOf(Arrays.java:2384)
       at java.util.Arrays$ArrayList.contains(Arrays.java:2391)
       at java.util.AbstractSet.removeAll(AbstractSet.java:146)
       at org.jboss.aop.microcontainer.integration.AOPConstructorJoinpoint.hasMetaDataAtLevel(AOPConstructorJoinpoint.java:213)
       at org.jboss.aop.microcontainer.integration.AOPConstructorJoinpoint.checkForMetaDataAtSubInstanceLevel(AOPConstructorJoinpoint.java:189)
       at org.jboss.aop.microcontainer.integration.AOPConstructorJoinpoint.methodHasSubInstanceMetaData(AOPConstructorJoinpoint.java:166)
       at org.jboss.aop.microcontainer.integration.AOPConstructorJoinpoint.rootHasMethodWithSubInstanceMetaData(AOPConstructorJoinpoint.java:142)
       at org.jboss.aop.microcontainer.integration.AOPConstructorJoinpoint.rootHasSubInstanceMetaData(AOPConstructorJoinpoint.java:122)
      

      which I think is somehow too strict to require security check, since is a simple equals/hash call made by HashSet to remove annotation metadata.

        • 1. Re: Annotation hash check with security enabled
          Ales Justin Master

           

          "alesj" wrote:
          which I think is somehow too strict to require security check, since is a simple equals/hash call made by HashSet to remove annotation metadata.

          Doing direct '==' would probably do the trick, but that's too impl specific.
          Not to mention the horrible code that would come out of it. ;-)

          • 2. Re: Annotation hash check with security enabled
            Ales Justin Master

             

            "alesj" wrote:
            "alesj" wrote:
            which I think is somehow too strict to require security check, since is a simple equals/hash call made by HashSet to remove annotation metadata.

            Doing direct '==' would probably do the trick, but that's too impl specific.
            Not to mention the horrible code that would come out of it. ;-)

            Like Adrian said yesterday on the jboss-dev list, think before you shoot. :-)
            This does the trick, and it doesn't require any hash/equals:
             Object[] allMetaData = levelMetaData.getMetaData();
             Annotation[] annotations = levelMetaData.getAnnotations();
             // all meta data is not null, since level metadata is not empty
             int allSize = allMetaData.length;
             int annotationsSize = annotations != null ? annotations.length : 0;
            
             // do we have something else than annotations
             if (allSize > annotationsSize)
             {
             return true;
             }
            

            ;-)

            • 3. Re: Annotation hash check with security enabled
              Adrian Brock Master

               

              "alesj" wrote:

              7828 ERROR [AbstractKernelController] Error installing to Instantiated: name=SimpleBean state=Described
              java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
               at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
               at java.security.AccessController.checkPermission(AccessController.java:427)
               at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
               at java.lang.SecurityManager.checkMemberAccess(SecurityManager.java:1662)
               at java.lang.Class.checkMemberAccess(Class.java:2125)
               at java.lang.Class.getDeclaredMethods(Class.java:1762)
               at sun.reflect.annotation.AnnotationInvocationHandler.getMemberMethods(AnnotationInvocationHandler.java:257)
               at sun.reflect.annotation.AnnotationInvocationHandler.equalsImpl(AnnotationInvocationHandler.java:169)
               at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:40)
               at $Proxy34.equals(Unknown Source)
              



              This looks like a bug in the JDK.

              Looking at the open jdk source, the invocation of getDeclaredMembers()
              should be in a privileged block.

              
               /**
               * Returns the member methods for our annotation type. These are
               * obtained lazily and cached, as they're expensive to obtain
               * and we only need them if our equals method is invoked (which should
               * be rare).
               */
               private Method[] getMemberMethods() {
               if (memberMethods == null) {
               final Method[] mm = type.getDeclaredMethods(); // This fails if the calling context of the annotation.equals() doesn't have accessDelcaredMembers for the annotation class
               AccessController.doPrivileged(new PrivilegedAction() {
               public Object run() {
               AccessibleObject.setAccessible(mm, true);
               return null;
               }
               });
               memberMethods = mm;
               }
               return memberMethods;
               }
               private transient volatile Method[] memberMethods = null;