Skip to content

Commit

Permalink
Update doPrivilegedWithCombinerHelper function
Browse files Browse the repository at this point in the history
When we try to invoke doPrivilegedWithCombiner function to
perform a privileged action under an existing context
environment, we are used to construct a new context but ignore
the parent context.

We should take consideration of a combination of the current
and parent context, rather than just choose either the current
or the parent.

This patch solves a failed case in issue #19499.

Issue: #19499

Signed-off-by: Jinhang Zhang <[email protected]>
  • Loading branch information
JinhangZhang committed Nov 20, 2024
1 parent 48709bf commit 18ae5e8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
*/
package java.security;

import com.ibm.oti.util.Msg;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
Expand Down Expand Up @@ -351,6 +350,36 @@ public AccessControlContext(ProtectionDomain[] fromContext) {
this.containPrivilegedContext = true;
}

AccessControlContext(ProtectionDomain[] pdArray, AccessControlContext parent, AccessControlContext acc, int authorizeState) {
super();
switch (authorizeState) {
default:
// authorizeState can't be STATE_UNKNOWN, callerPD always is NULL
throw new IllegalArgumentException();
case STATE_AUTHORIZED:
if (null != acc) {
// when parent combiner is not null, use parent combiner to combine the current context
if (parent.getCombiner() != null) {
this.context = parent.getCombiner().combine(pdArray, acc.context);
this.domainCombiner = parent.getCombiner();
} else {
this.context = combinePDObjs(pdArray, acc.context);
this.domainCombiner = acc.domainCombiner;
}
} else {
this.domainCombiner = parent.domainCombiner;
this.context = pdArray;
this.nextStackAcc = parent;
}
break;
case STATE_NOT_AUTHORIZED:
break;
}
this.doPrivilegedAcc = acc;
this.authorizeState = authorizeState;
this.containPrivilegedContext = true;
}

/**
* Constructs a new instance of this class given a context
* and a DomainCombiner
Expand Down Expand Up @@ -497,7 +526,6 @@ static Permission[] combinePermObjs(Permission[] checked, Permission[] toBeCombi
return (Permission[]) combineObjs(false, checked, toBeCombined, start, len, justCombine);
}

/*[IF JAVA_SPEC_VERSION < 24]*/
/**
* Perform ProtectionDomain.implies(permission) with known ProtectionDomain objects already implied
*
Expand Down Expand Up @@ -663,7 +691,7 @@ static boolean checkPermissionWithCache(
}
}
/*[MSG "K002c", "Access denied {0}"]*/
throw new AccessControlException(Msg.getString("K002c", perm), perm); //$NON-NLS-1$
throw new AccessControlException(com.ibm.oti.util.Msg.getString("K002c", perm), perm); //$NON-NLS-1$
}
}
if (null != accCurrent
Expand Down Expand Up @@ -699,7 +727,6 @@ static boolean checkPermissionWithCache(
}
return true;
}
/*[ENDIF] JAVA_SPEC_VERSION < 24 */

/**
* Helper to print debug information for checkPermission().
Expand Down Expand Up @@ -733,10 +760,6 @@ private boolean debugHelper(Permission perm) {
* if perm is null
*/
public void checkPermission(Permission perm) throws AccessControlException {
/*[IF JAVA_SPEC_VERSION >= 24]*/
/*[MSG "K002e", "checking permissions is not supported"]*/
throw new AccessControlException(Msg.getString("K002e")); //$NON-NLS-1$
/*[ELSE] JAVA_SPEC_VERSION >= 24 */
if (perm == null) throw new NullPointerException();
if (null != context && (STATE_AUTHORIZED != authorizeState) && containPrivilegedContext && null != System.getSecurityManager()) {
// only check SecurityPermission "createAccessControlContext" when context is not null, not authorized and containPrivilegedContext.
Expand All @@ -750,7 +773,7 @@ public void checkPermission(Permission perm) throws AccessControlException {
}
if (STATE_NOT_AUTHORIZED == authorizeState) {
/*[MSG "K002d", "Access denied {0} due to untrusted AccessControlContext since {1} is denied"]*/
throw new AccessControlException(Msg.getString("K002d", perm, SecurityConstants.CREATE_ACC_PERMISSION), perm); //$NON-NLS-1$
throw new AccessControlException(com.ibm.oti.util.Msg.getString("K002d", perm, SecurityConstants.CREATE_ACC_PERMISSION), perm); //$NON-NLS-1$
}
}

Expand All @@ -759,7 +782,6 @@ public void checkPermission(Permission perm) throws AccessControlException {
debug = debugHelper(perm);
}
checkPermissionWithCache(perm, null, this.context, debug ? DEBUG_ENABLED | DEBUG_ACCESS_DENIED : DEBUG_DISABLED, this.doPrivilegedAcc,this.isLimitedContext, this.limitedPerms, this.nextStackAcc, new AccessCache());
/*[ENDIF] JAVA_SPEC_VERSION >= 24 */
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1044,13 +1044,9 @@ public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action
private static AccessControlContext doPrivilegedWithCombinerHelper(AccessControlContext context) {
ProtectionDomain domain = getCallerPD(2);
ProtectionDomain[] pdArray = (domain == null) ? null : new ProtectionDomain[] { domain };
AccessControlContext fixedContext = new AccessControlContext(context, pdArray, getNewAuthorizedState(context, domain));
if (context == null) {
AccessControlContext parentContext = getContextHelper(true);
fixedContext.domainCombiner = parentContext.domainCombiner;
fixedContext.nextStackAcc = parentContext;
}
return fixedContext;
AccessControlContext parentContext = getContextHelper(context == null);

return new AccessControlContext(pdArray, parentContext, context, getNewAuthorizedState(context, domain));
}

}

0 comments on commit 18ae5e8

Please sign in to comment.