40
40
import java .security .Provider ;
41
41
import java .security .SecureRandom ;
42
42
import java .util .ArrayDeque ;
43
- import java .util .ArrayList ;
43
+ import java .util .HashMap ;
44
44
import java .util .List ;
45
45
import java .util .Map ;
46
46
import java .util .Objects ;
49
49
50
50
import jdk .vm .ci .meta .MetaAccessProvider ;
51
51
import jdk .vm .ci .meta .ResolvedJavaField ;
52
- import org .graalvm .collections .Pair ;
53
52
import org .graalvm .compiler .serviceprovider .JavaVersionUtil ;
54
53
import org .graalvm .nativeimage .Platform ;
55
54
import org .graalvm .nativeimage .Platforms ;
@@ -135,16 +134,11 @@ private static ProtectionDomain getProtectionDomain(final Class<?> caller) {
135
134
136
135
@ Substitute
137
136
@ TargetElement (onlyWith = JDK14OrLater .class )
138
- @ SuppressWarnings ("deprecation" ) // deprecated starting JDK 17
139
137
static <T > T executePrivileged (PrivilegedExceptionAction <T > action , AccessControlContext context , Class <?> caller ) throws Throwable {
140
138
if (action == null ) {
141
139
throw new NullPointerException ("Null action" );
142
140
}
143
141
144
- if (context != null && context .equals (AccessControllerUtil .NO_CONTEXT_SINGLETON )) {
145
- VMError .shouldNotReachHere ("Invoked AccessControlContext was replaced at build time but wasn't reinitialized at run time." );
146
- }
147
-
148
142
AccessControllerUtil .PrivilegedStack .push (context , caller );
149
143
try {
150
144
return action .run ();
@@ -157,17 +151,11 @@ static <T> T executePrivileged(PrivilegedExceptionAction<T> action, AccessContro
157
151
158
152
@ Substitute
159
153
@ TargetElement (onlyWith = JDK14OrLater .class )
160
- @ SuppressWarnings ("deprecation" ) // deprecated starting JDK 17
161
154
static <T > T executePrivileged (PrivilegedAction <T > action , AccessControlContext context , Class <?> caller ) throws Throwable {
162
155
if (action == null ) {
163
156
throw new NullPointerException ("Null action" );
164
157
}
165
158
166
- if (context != null && context .equals (AccessControllerUtil .NO_CONTEXT_SINGLETON )) {
167
- VMError .shouldNotReachHere ("Invoked AccessControlContext was replaced at build time but wasn't reinitialized at run time.\n " +
168
- "This might be an indicator of improper build time initialization, or of a non-compatible JDK version." );
169
- }
170
-
171
159
AccessControllerUtil .PrivilegedStack .push (context , caller );
172
160
try {
173
161
return action .run ();
@@ -180,11 +168,21 @@ static <T> T executePrivileged(PrivilegedAction<T> action, AccessControlContext
180
168
181
169
@ Substitute
182
170
@ TargetElement (onlyWith = JDK14OrLater .class )
183
- @ SuppressWarnings ("unused" )
171
+ @ SuppressWarnings ({ "unused" , "deprecation" } )
184
172
static AccessControlContext checkContext (AccessControlContext context , Class <?> caller ) {
173
+
174
+ if (context != null && context .equals (AccessControllerUtil .NO_CONTEXT_SINGLETON )) {
175
+ VMError .shouldNotReachHere ("Non-allowed AccessControlContext that was replaced with a blank one at build time was invoked without being reinitialized at run time.\n " +
176
+ "This might be an indicator of improper build time initialization, or of a non-compatible JDK version.\n " +
177
+ "In order to fix this you can either:\n " +
178
+ " * Annotate the offending context's field with @RecomputeFieldValue\n " +
179
+ " * Implement a custom runtime accessor and annotate said field with @InjectAccessors\n " +
180
+ " * If this context originates from the JDK, and it doesn't leak sensitive info, you can allow it in 'AccessControlContextFeature.duringSetup'" );
181
+ }
182
+
185
183
// check if caller is authorized to create context
186
184
if (System .getSecurityManager () != null ) {
187
- throw VMError .shouldNotReachHere ( "Needs to be implemented when SecurityManager is supported" );
185
+ throw VMError .unsupportedFeature ( " SecurityManager isn't supported" );
188
186
}
189
187
return context ;
190
188
}
@@ -224,7 +222,7 @@ public Class<?> getCaller() {
224
222
}
225
223
}
226
224
227
- @ SuppressWarnings ("rawtypes" ) private static final FastThreadLocalObject <ArrayDeque > stack = FastThreadLocalFactory .createObject (ArrayDeque .class , "accStack " );
225
+ @ SuppressWarnings ("rawtypes" ) private static final FastThreadLocalObject <ArrayDeque > stack = FastThreadLocalFactory .createObject (ArrayDeque .class , "AccessControlContextStack " );
228
226
229
227
@ SuppressWarnings ("unchecked" )
230
228
private static ArrayDeque <StackElement > getStack () {
@@ -270,7 +268,7 @@ static Throwable wrapCheckedException(Throwable ex) {
270
268
@ SuppressWarnings ({"unused" })
271
269
class AccessControlContextFeature implements Feature {
272
270
273
- static List < Pair < String , AccessControlContext >> allowedContexts = new ArrayList <>();
271
+ static Map < String , AccessControlContext > allowedContexts = new HashMap <>();
274
272
275
273
static void allowContextIfExists (String className , String fieldName ) {
276
274
try {
@@ -280,7 +278,7 @@ static void allowContextIfExists(String className, String fieldName) {
280
278
String description = className + "." + fieldName ;
281
279
try {
282
280
AccessControlContext acc = ReflectionUtil .readStaticField (clazz , fieldName );
283
- allowedContexts .add ( Pair . create ( description , acc ) );
281
+ allowedContexts .put ( description , acc );
284
282
} catch (ReflectionUtil .ReflectionUtilError e ) {
285
283
VMError .shouldNotReachHere ("Following field isn't present in JDK" + JavaVersionUtil .JAVA_SPEC + ": " + description );
286
284
}
@@ -323,7 +321,7 @@ public void duringSetup(DuringSetupAccess access) {
323
321
324
322
private static Object replaceAccessControlContext (Object obj ) {
325
323
if (obj instanceof AccessControlContext && obj != AccessControllerUtil .NO_CONTEXT_SINGLETON ) {
326
- if (allowedContexts .stream (). anyMatch (( e ) -> obj . equals ( e . getRight ()) )) {
324
+ if (allowedContexts .containsValue ( obj )) {
327
325
return obj ;
328
326
} else {
329
327
return AccessControllerUtil .NO_CONTEXT_SINGLETON ;
0 commit comments