Bug 1417712

Summary: [GSS] (6.4.z) Custom java security permission does not work
Product: [JBoss] JBoss Enterprise Application Platform 6 Reporter: dhorton
Component: jbossasAssignee: Jiri Ondrusek <jondruse>
Status: CLOSED CURRENTRELEASE QA Contact: Peter Mackay <pmackay>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.4.10CC: bmaxwell, fnasser, jason.greene, jbilek, jondruse, pmackay, rstancel
Target Milestone: CR1   
Target Release: EAP 6.4.16   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-06-22 09:23:31 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1434495, 1448486    

Description dhorton 2017-01-30 17:47:46 UTC
Description of problem:

We have a custom permission (extends java.security.Permission) that we want to check at runtime.

The permission should be granted to a user with a specific Principal (org.jboss.security.SimplePrincipal "admin") in my testing:

  grant principal org.jboss.security.SimplePrincipal "admin" {
    permission org.jboss.example.CustomPermission "/Hello";
  };

We have coded our servlet to check this permission at run time with code that looks like the following:


    javax.security.auth.Subject subj = (javax.security.auth.Subject) javax.security.jacc.PolicyContext.getContext("javax.security.auth.Subject.container");  

    org.jboss.example.CustomPermission permission = new org.jboss.example.CustomPermission("/Hello");

    try {
      Subject.doAsPrivileged(subj, new PrivilegedAction() {
        public Object run() {
          AccessController.checkPermission(p);
          return null;
        }
      }, null);
      return true;
    } catch (SecurityException se) {
      log.warn("AuthUtils.permitted(): Subject " + subj + " not authorized for permission " + p);
      return false;
    }

The subj above contains a org.jboss.security.SimplePrincipal instance with the username of "admin" in its principal set.




Actual results:

The permission check always returns "denied".

Expected results:

The permission check should return "granted" when the subject contains a SimplePrincipal instance with "admin" as the username.

Comment 1 dhorton 2017-01-30 17:48:07 UTC
KCS is here:  https://access.redhat.com/solutions/2893361

Comment 2 dhorton 2017-01-30 17:49:28 UTC
I was able to get this to work on JBoss EAP 6.4.10 using Oracle's 1.7.0_79 jvm (i did not set SECMGR=true though I don't think it matters). This issue seems to be dependent on the version of the jvm that is used. Java 1.8 appears to break this on 6.4.10. It looks to me like there is a code change in the jvm's javax.security.auth.SubjectDomainCombiner class between 1.7 and 1.8. Specifically, in java 1.8, the principal is not getting sent to the ProtectionDomain during processing.

Here is the code that appears to be triggering the issue (from the OpenJDK 1.8 code):


                if (subjectPd == null) {
                    if (pdAccess.getStaticPermissionsField(pd)) {
                        // Need to keep static ProtectionDomain objects static
                        subjectPd = new ProtectionDomain(pd.getCodeSource(),
                                                pd.getPermissions());
                    } else {
                        subjectPd = new ProtectionDomain(pd.getCodeSource(),
                                                pd.getPermissions(),
                                                pd.getClassLoader(),
                                                principals);
                    }

Notice the principals variable in not passed to the ProtectionDomain in the first part of the if statement. Here is the same section of code from the OpenJDK 1.7 codebase:

                if (subjectPd == null) {
                    subjectPd = new ProtectionDomain(pd.getCodeSource(),
                                                pd.getPermissions(),
                                                pd.getClassLoader(),
                                                principals);
                    cachedPDs.putValue(pd, subjectPd);
                } else {

In the 1.7 code, the principal is always passed to the ProtectionDomain. However, in the 1.8 code, the principal does not get sent to the ProtectionDomain's constructor. This appears to be causing the issue.

Comment 3 Jiri Ondrusek 2017-04-19 13:06:27 UTC
Works fine both on EAP 7.1 and WildFly

Comment 6 Peter Mackay 2017-06-16 22:10:28 UTC
Verified with EAP 6.4.16.CP.CR1

Comment 7 Petr Penicka 2017-06-22 09:23:31 UTC
Released on June 20 2017 as part of the EAP 6.4.16 maintenance release.