Skip to content

Commit 7cb8cbb

Browse files
committed
Bug 38139257 - [38041090->25.03.3] Failed to restart services: java.lang.SecurityException due to Subject is not inherited from the parent thread
Redo //dev/coherence-ce/release/coherence-ce-v25.03/prj/... changelist 117247 + ce-main -> ce-v25.03 @117390 [git-p4: depot-paths = "//dev/coherence-ce/release/coherence-ce-v25.03/": change = 117400]
1 parent 748d510 commit 7cb8cbb

File tree

12 files changed

+386
-32
lines changed

12 files changed

+386
-32
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Universal Permissive License v 1.0 as shown at
5+
* https://oss.oracle.com/licenses/upl.
6+
*/
7+
package com.tangosol.net.security;
8+
9+
import java.security.PrivilegedAction;
10+
11+
import javax.security.auth.Subject;
12+
13+
/**
14+
* A helper class to expose the {@link Subject#doAs} call as a privileged action.
15+
* <p>
16+
* This is a Java21 version of this class which replaces the {@link Subject#doAs},
17+
* which is deprecated with {@link Subject#callAs} in the coherence-core-21
18+
* module and is built into the multi-release coherence.jar.
19+
*
20+
* Note: In case of Exception, Subject.callAs() wraps the Exception
21+
* returned by action::run with the java.util.concurrent.CompletionException.
22+
*/
23+
public class DoAsAction<T>
24+
implements PrivilegedAction<T>
25+
{
26+
/**
27+
* Construct a privileged action.
28+
*
29+
* @param action the action to run with privileges of the current subject
30+
*
31+
* @since 14.1.2.0.4
32+
*/
33+
public DoAsAction(PrivilegedAction<T> action)
34+
{
35+
this(Subject.current(), action);
36+
}
37+
/**
38+
* Construct a privileged action.
39+
*
40+
* @param subject the subject that the specified action will run as
41+
* @param action the action to run with privileges of the specified subject
42+
*/
43+
public DoAsAction(Subject subject, PrivilegedAction<T> action)
44+
{
45+
m_subject = subject;
46+
m_action = action;
47+
}
48+
49+
@Override
50+
public T run()
51+
{
52+
return Subject.callAs(m_subject, m_action::run);
53+
}
54+
55+
56+
// ----- data members ---------------------------------------------------
57+
58+
/**
59+
* The subject that the specified action will run as.
60+
*/
61+
private Subject m_subject;
62+
63+
/**
64+
* The privileged action to be run as the specified subject.
65+
*/
66+
private PrivilegedAction<T> m_action;
67+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Universal Permissive License v 1.0 as shown at
5+
* https://oss.oracle.com/licenses/upl.
6+
*/
7+
8+
package com.tangosol.net.security;
9+
10+
import javax.security.auth.Subject;
11+
12+
import java.security.AccessController;
13+
import java.security.Permission;
14+
import java.security.PrivilegedAction;
15+
import java.security.PrivilegedActionException;
16+
import java.security.PrivilegedExceptionAction;
17+
18+
import java.util.function.Supplier;
19+
20+
/**
21+
* A wrapper to handle the removal of Java's SecurityManger class.
22+
* <p>
23+
* This is a Java21 version of this class in the coherence-core-21
24+
* module and is built into the multi-release coherence.jar.
25+
*
26+
* Note, In case of Exception, Subject.callAs() wraps the Exception
27+
* returned by action::run with the java.util.concurrent.CompletionException.
28+
*
29+
* @author Jonathan Knight, lh 26/06/2025
30+
* @since 14.1.2.0.4
31+
*/
32+
@SuppressWarnings("removal")
33+
public class SecurityManagerWrapperImpl
34+
implements SecurityManagerWrapper
35+
{
36+
SecurityManagerWrapperImpl()
37+
{
38+
}
39+
40+
@Override
41+
public Subject getCurrentSubject()
42+
{
43+
return Subject.current();
44+
}
45+
46+
@Override
47+
public boolean hasSecurityManager()
48+
{
49+
return System.getSecurityManager() != null;
50+
}
51+
52+
@Override
53+
public <T> T doIfSecure(PrivilegedAction<T> action)
54+
{
55+
if (hasSecurityManager())
56+
{
57+
if (action instanceof DoAsAction)
58+
{
59+
return AccessController.doPrivileged(action);
60+
}
61+
62+
Subject subject = getCurrentSubject();
63+
return AccessController.doPrivileged((PrivilegedAction<T>) () ->
64+
Subject.callAs(subject, action::run));
65+
}
66+
return action.run();
67+
}
68+
69+
@Override
70+
public <T> T doIfSecure(PrivilegedExceptionAction<T> action) throws Exception
71+
{
72+
if (hasSecurityManager())
73+
{
74+
if (action instanceof DoAsAction)
75+
{
76+
return AccessController.doPrivileged(action);
77+
}
78+
79+
Subject subject = getCurrentSubject();
80+
return AccessController.doPrivileged((PrivilegedExceptionAction<T>) () ->
81+
Subject.callAs(subject, action::run));
82+
}
83+
return action.run();
84+
}
85+
86+
@Override
87+
public void doIfSecure(PrivilegedAction<?> action, Runnable fallback)
88+
{
89+
if (hasSecurityManager())
90+
{
91+
if (action instanceof DoAsAction)
92+
{
93+
AccessController.doPrivileged(action);
94+
}
95+
else
96+
{
97+
Subject subject = getCurrentSubject();
98+
AccessController.doPrivileged((PrivilegedAction) () ->
99+
Subject.callAs(subject, action::run));
100+
}
101+
}
102+
else
103+
{
104+
fallback.run();
105+
}
106+
}
107+
108+
@Override
109+
public <T> T doIfSecure(PrivilegedAction<T> action, Supplier<T> fallback)
110+
{
111+
if (hasSecurityManager())
112+
{
113+
if (action instanceof DoAsAction)
114+
{
115+
return AccessController.doPrivileged(action);
116+
}
117+
Subject subject = getCurrentSubject();
118+
return AccessController.doPrivileged((PrivilegedAction<T>) () ->
119+
Subject.callAs(subject, action::run));
120+
}
121+
return fallback.get();
122+
}
123+
124+
@Override
125+
public <T> T doPrivileged(PrivilegedAction<T> action)
126+
{
127+
if (action instanceof DoAsAction)
128+
{
129+
return AccessController.doPrivileged(action);
130+
}
131+
132+
Subject subject = getCurrentSubject();
133+
return AccessController.doPrivileged((PrivilegedAction<T>) () ->
134+
Subject.callAs(subject, action::run));
135+
}
136+
137+
@Override
138+
public <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws PrivilegedActionException
139+
{
140+
if (action instanceof DoAsAction)
141+
{
142+
return AccessController.doPrivileged(action);
143+
}
144+
145+
Subject subject = getCurrentSubject();
146+
return AccessController.doPrivileged((PrivilegedExceptionAction<T>) () ->
147+
Subject.callAs(subject, action::run));
148+
}
149+
150+
@Override
151+
public void checkPermission(Supplier<Permission> supplier)
152+
{
153+
checkPermission(supplier.get());
154+
}
155+
156+
@Override
157+
public void checkPermission(Permission permission)
158+
{
159+
SecurityManager security = System.getSecurityManager();
160+
if (security != null)
161+
{
162+
if (permission != null)
163+
{
164+
security.checkPermission(permission);
165+
}
166+
}
167+
}
168+
}

prj/coherence-core/src/main/java/com/tangosol/net/security/SecurityManagerWrapperImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* @author Jonathan Knight 25/01/2025
3030
*/
3131
@SuppressWarnings("removal")
32-
class SecurityManagerWrapperImpl
32+
public class SecurityManagerWrapperImpl
3333
implements SecurityManagerWrapper
3434
{
3535
SecurityManagerWrapperImpl()
@@ -71,7 +71,7 @@ public <T> T doIfSecure(PrivilegedExceptionAction<T> action) throws Exception
7171
{
7272
if (hasSecurityManager())
7373
{
74-
AccessController.doPrivileged(action);
74+
return AccessController.doPrivileged(action);
7575
}
7676
return action.run();
7777
}
@@ -83,7 +83,10 @@ public void doIfSecure(PrivilegedAction<?> action, Runnable fallback)
8383
{
8484
AccessController.doPrivileged(action);
8585
}
86-
fallback.run();
86+
else
87+
{
88+
fallback.run();
89+
}
8790
}
8891

8992
@Override

prj/coherence-core/src/main/java/com/tangosol/util/Unsafe.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import com.oracle.coherence.common.base.Logger;
1212
import com.tangosol.coherence.config.Config;
1313

14-
import com.tangosol.net.security.SecurityHelper;
14+
import com.tangosol.net.security.SecurityManagerWrapperImpl;
1515

1616
import java.security.CodeSource;
1717

@@ -62,7 +62,7 @@ public static Unsafe getUnsafe()
6262
{
6363
String sClassName = aStack[i].getClassName();
6464
// skip frames pertinent to use of Unsafe within a security block
65-
if (!sClassName.startsWith("java.security"))
65+
if (!sClassName.startsWith("java.security") && !sClassName.startsWith("javax.security"))
6666
{
6767
sCallingClass = sClassName;
6868
break;
@@ -98,7 +98,7 @@ public static Unsafe getUnsafe()
9898

9999
CodeSource srcUnsafe = Unsafe.class.getProtectionDomain().getCodeSource();
100100
CodeSource srcCaller = clzCaller.getProtectionDomain().getCodeSource();
101-
CodeSource srcSecurity = SecurityHelper.getCodeSource();
101+
CodeSource srcSecurity = SecurityManagerWrapperImpl.class.getProtectionDomain().getCodeSource();
102102
if (Base.equals(srcCaller, srcUnsafe) || Base.equals(srcCaller, srcSecurity))
103103
{
104104
return INSTANCE;

0 commit comments

Comments
 (0)