JDK-8129575 : Equal DelegationPermission instances may return different hash codes
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.security
  • Affected Version: 9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-06-23
  • Updated: 2016-08-24
  • Resolved: 2015-06-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b71Fixed
Related Reports
Relates :  
Description
A string which contains a number of principals can be passed to constructor of DelegationPermission. The class parses this string, and extracts principals. But hashCode() method in DelegationPermission uses Permission.getName() to calculate a hash:

http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/467094c6081b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/DelegationPermission.java#l182

...
    public int hashCode() {
        return getName().hashCode();
    }
...

Permission.getName() method returns the original string which was passed to constructor. As a result, semantically equal instances of DelegationPermission may return different hash codes. A test in the webrev below reproduces the problem.

When JDK-8065942 was integrated, a problem may occur during permission check. If code has an appropriate DelegationPermission in policy file, AccessController may not take it into account because KrbDelegationPermissionCollection.implies() now uses ConcurrentHashMap.containsKey():

http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/467094c6081b

...
+    @Override
     public boolean implies(Permission permission) {
         if (! (permission instanceof DelegationPermission))
-                return false;
+            return false;
 
-        synchronized (this) {
-            for (Permission x : perms) {
-                if (x.implies(permission))
-                    return true;
-            }
-        }
-        return false;
-
+        // if map contains key, then it automatically implies it
+        return perms.containsKey(permission);
     }
... 

As a result, ACE may be thrown even if code has a correct permission in policy file.

The following patch seems to fix the issue:

http://cr.openjdk.java.net/~asmotrak/delegation_permission/webrev.00/
Comments
The suggested fix is fine. Is it possible to refactor implies() and equals() so that the former calls the latter? This way it will be more clear that hashCode() and equals() are consistent.
24-06-2015