From eed4ec4e8d76f4fa0dc25cd263582a2786849bcd Mon Sep 17 00:00:00 2001 From: JinhangZhang Date: Mon, 11 Nov 2024 14:18:22 -0500 Subject: [PATCH] Update doPrivilegedWithCombinerHelper function 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 --- .../java/security/AccessControlContext.java | 46 ++++++++++++------- .../java/security/AccessController.java | 16 +++---- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/jcl/src/java.base/share/classes/java/security/AccessControlContext.java b/jcl/src/java.base/share/classes/java/security/AccessControlContext.java index de86aff22a6..bbf75f625cd 100644 --- a/jcl/src/java.base/share/classes/java/security/AccessControlContext.java +++ b/jcl/src/java.base/share/classes/java/security/AccessControlContext.java @@ -318,37 +318,49 @@ public AccessControlContext(ProtectionDomain[] fromContext) { } AccessControlContext(ProtectionDomain[] context, int authorizeState) { - super(); - switch (authorizeState) { - default: - // authorizeState can't be STATE_UNKNOWN, callerPD always is NULL - throw new IllegalArgumentException(); - case STATE_AUTHORIZED: - case STATE_NOT_AUTHORIZED: - break; - } - this.context = context; - this.authorizeState = authorizeState; - this.containPrivilegedContext = true; + this(context, null, null, authorizeState); } AccessControlContext(AccessControlContext acc, ProtectionDomain[] context, int authorizeState) { + this(context, null, acc, authorizeState); +} + +AccessControlContext(ProtectionDomain[] context, AccessControlContext parentAcc, AccessControlContext acc, int authorizeState) { super(); switch (authorizeState) { default: - // authorizeState can't be STATE_UNKNOWN, callerPD always is NULL + // authorizeState can't be STATE_UNKNOWN, callerPD is always NULL throw new IllegalArgumentException(); case STATE_AUTHORIZED: - if (null != acc) { - // inherit the domain combiner when authorized - this.domainCombiner = acc.domainCombiner; + if (acc != null) { + if (parentAcc == null) { + // inherit the domain combiner when authorized + this.domainCombiner = acc.domainCombiner; + this.context = context; + } else { + // when parent combiner is not null, use parent combiner to combine the current context + DomainCombiner parentCombiner = parentAcc.getCombiner(); + if (parentCombiner != null) { + this.context = parentCombiner.combine(context, acc.context); + this.domainCombiner = parentCombiner; + } else { + this.context = combinePDObjs(context, acc.context); + this.domainCombiner = acc.domainCombiner; + } + } + } else { + if (parentAcc != null) { + this.domainCombiner = parentAcc.domainCombiner; + this.nextStackAcc = parentAcc; + } + this.context = context; } break; case STATE_NOT_AUTHORIZED: + this.context = context; break; } this.doPrivilegedAcc = acc; - this.context = context; this.authorizeState = authorizeState; this.containPrivilegedContext = true; } diff --git a/jcl/src/java.base/share/classes/java/security/AccessController.java b/jcl/src/java.base/share/classes/java/security/AccessController.java index 8bb613bccbb..4de7c41c813 100644 --- a/jcl/src/java.base/share/classes/java/security/AccessController.java +++ b/jcl/src/java.base/share/classes/java/security/AccessController.java @@ -1088,21 +1088,17 @@ public static T doPrivilegedWithCombiner(PrivilegedExceptionAction action /** * Helper method to construct an AccessControlContext for doPrivilegedWithCombiner methods. * - * @param context an AccessControlContext, if it is null, use getContextHelper() to construct a context. + * @param acc an AccessControlContext, if it is null, use getContextHelper() to construct a context. * * @return An AccessControlContext to be applied to the doPrivileged(action, context, perms). */ @CallerSensitive -private static AccessControlContext doPrivilegedWithCombinerHelper(AccessControlContext context) { +private static AccessControlContext doPrivilegedWithCombinerHelper(AccessControlContext acc) { 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; + ProtectionDomain[] context = (domain == null) ? null : new ProtectionDomain[] { domain }; + AccessControlContext parentAcc = getContextHelper(acc == null); + + return new AccessControlContext(context, parentAcc, acc, getNewAuthorizedState(acc, domain)); } /*[ENDIF] JAVA_SPEC_VERSION < 24 */