Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/java.base/share/classes/java/security/AccessController.java
12513 views
1
/*[INCLUDE-IF Sidecar18-SE]*/
2
/*******************************************************************************
3
* Copyright (c) 1998, 2021 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
22
*******************************************************************************/
23
package java.security;
24
25
import java.security.AccessControlContext.AccessCache;
26
import sun.security.util.SecurityConstants;
27
28
/*[IF Sidecar19-SE]
29
import jdk.internal.reflect.CallerSensitive;
30
/*[ELSE]*/
31
import sun.reflect.CallerSensitive;
32
/*[ENDIF]*/
33
34
/**
35
* Checks access to system resources. Supports marking of code
36
* as privileged. Makes context snapshots to allow checking from
37
* other contexts.
38
*
39
* @author OTI
40
* @version initial
41
*/
42
/*[IF JAVA_SPEC_VERSION >= 17]*/
43
@Deprecated(since="17", forRemoval=true)
44
/*[ENDIF] JAVA_SPEC_VERSION >= 17 */
45
public final class AccessController {
46
static {
47
// Initialize vm-internal caches
48
initializeInternal();
49
}
50
51
static final int OBJS_INDEX_ACC = 0;
52
static final int OBJS_INDEX_PDS = 1;
53
static final int OBJS_ARRAY_SIZE = 3;
54
static final int OBJS_INDEX_PERMS_OR_CACHECHECKED = 2;
55
56
private static native void initializeInternal();
57
58
/* [PR CMVC 188787] Enabling -Djava.security.debug option within WAS keeps JVM busy */
59
static final class DebugRecursionDetection {
60
private static ThreadLocal<String> tlDebug = new ThreadLocal<>();
61
static ThreadLocal<String> getTlDebug() {
62
return tlDebug;
63
}
64
}
65
66
/*[PR 1FDIC6B] J9JCL:WIN95 - AccessController missing private no-arg constructor */
67
/**
68
* Prevents this class from being instantiated.
69
*/
70
private AccessController() {
71
super();
72
}
73
74
/**
75
* The object array returned has following format:
76
*
77
* Pre-JEP140 format: AccessControlContext/ProtectionDomain..., and the length of the object array is NOT divisible by OBJS_ARRAY_SIZE
78
* First element is an AccessControlContext object which might be null, either from a full permission privileged frame or from current thread if there is no such privileged frames
79
* ProtectionDomain elements after AccessControlContext object could be in one of following two formats:
80
* For doPrivileged methods - flag forDoPrivilegedWithCombiner is false:
81
* the ProtectionDomain element might be null, first ProtectionDomain element is a duplicate of the ProtectionDomain of the caller of doPrivileged
82
* rest of ProtectionDomain elements are from the callers discovered during stack walking
83
* the start index of the actual ProtectionDomain element is 2 of the object array returned
84
* For doPrivilegedWithCombiner methods - flag forDoPrivilegedWithCombiner is true:
85
* there are only two ProtectionDomain elements, first one is the ProtectionDomain of the caller of doPrivileged
86
* and the other is the ProtectionDomain of the caller of doPrivilegedWithCombiner
87
* the fourth element of the object array is NULL for padding to ensure that the length of the object array is NOT divisible by OBJS_ARRAY_SIZE either
88
*
89
* JEP 140 format: AccessControlContext/ProtectionDomain[]/Permission[]
90
* The length of the object array is always divisible by OBJS_ARRAY_SIZE.
91
* Depends on number of limited permission privileged frames, the result are in following format:
92
* First element is an AccessControlContext object
93
* Second element could be in one of following two formats:
94
* For doPrivileged methods - flag forDoPrivilegedWithCombiner is false:
95
* an array of ProtectionDomain objects in which first ProtectionDomain element is a duplicate of the ProtectionDomain of the caller of doPrivileged
96
* the start index of the actual ProtectionDomain element is 1 of this ProtectionDomain objects array
97
* For doPrivilegedWithCombiner methods - flag forDoPrivilegedWithCombiner is true:
98
* an array of ProtectionDomain objects with only two elements
99
* first one is the ProtectionDomain of the caller of doPrivileged
100
* and the other is the ProtectionDomain of the caller of doPrivilegedWithCombiner
101
* Third element is an array of Limited Permission objects
102
* Repeating this format:
103
* AccessControlContext object,
104
* ProtectionDomain objects array with same format above when flag forDoPrivilegedWithCombiner is false
105
* or just the ProtectionDomain of the caller of doPrivileged in case of flag forDoPrivilegedWithCombiner is true
106
* Permission object array
107
* Until a full permission privileged frame or the end of the stack reached.
108
*
109
* Note: 1. The reason to have Pre-JEP140 and JEP 140 format is to keep similar format and processing logic
110
* when there is no limited doPrivileged method (JEP 140 implementation) involved.
111
* This helped to address performance issue raised by JAZZ 66091: Perf work for LIR 28261 (Limited doPrivileged / JEP 140)
112
* 2. The reason to duplicate the ProtectionDomain object of the caller of doPrivileged is to avoid creating a new object array
113
* without NULL and duplicate ProtectionDomain objects discovered during stack walking while still keeping same order of
114
* those objects.
115
*
116
* A full permission privileged frame is any frame running one of the following methods:
117
*
118
* <code><ul>
119
* <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedAction;)Ljava/lang/Object;</li>
120
* <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;</li>
121
* <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;</li>
122
* <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;</li>
123
* </ul></code>
124
*
125
* A limited permission privileged frame is any frame running one of the following methods:
126
*
127
* <code><ul>
128
* <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;[Ljava/security/Permission;)Ljava/lang/Object;</li>
129
* <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;[Ljava/security/Permission;)Ljava/lang/Object;</li>
130
* </ul></code>
131
*
132
* @param depth The stack depth at which to start. Depth 0 is the current frame (the caller of this native).
133
* @param forDoPrivilegedWithCombiner The flag to indicate if it is for doPrivilegedWithCombiner method
134
*
135
* @return an Object[] as description above
136
*/
137
private static native Object[] getAccSnapshot(int depth, boolean forDoPrivilegedWithCombiner);
138
139
/**
140
* This native retrieves the ProtectionDomain object of the non-reflection/MethodHandleInvoke caller as per depth specified.
141
* For example, when depth is set to 1 for method doPrivilegedWithCombiner, the ProtectionDomain object of the caller of doPrivilegedWithCombiner is returned
142
* Note: it is only for limited doPrivilegedWithCombiner methods for now.
143
*
144
* @param depth The stack depth at which to start.
145
*
146
* @return a ProtectionDomain object as per description above
147
*/
148
private static native ProtectionDomain getCallerPD(int depth);
149
150
/**
151
* provide debug info according to debug settings before throwing AccessControlException
152
*
153
* @param debug overall debug flag returned from DebugRecursionDetection.getTlDebug()
154
* @param perm the permission to check
155
* @param pDomain the pDomain to check
156
* @param createACCdenied if true, actual cause of this ACE was SecurityPermission("createAccessControlContext") denied
157
* @exception AccessControlException always throw an AccessControlException
158
*/
159
private static void throwACE(boolean debug, Permission perm, ProtectionDomain pDomain, boolean createACCdenied) {
160
if (debug) {
161
DebugRecursionDetection.getTlDebug().set(""); //$NON-NLS-1$
162
AccessControlContext.debugPrintAccess();
163
if (createACCdenied) {
164
System.err.println("access denied " + perm + " due to untrusted AccessControlContext since " + SecurityConstants.CREATE_ACC_PERMISSION + " is denied."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
165
} else {
166
System.err.println("access denied " + perm); //$NON-NLS-1$
167
}
168
DebugRecursionDetection.getTlDebug().remove();
169
}
170
if (debug && ((AccessControlContext.debugSetting() & AccessControlContext.DEBUG_ACCESS_FAILURE) != 0)) {
171
DebugRecursionDetection.getTlDebug().set(""); //$NON-NLS-1$
172
new Exception("Stack trace").printStackTrace(); //$NON-NLS-1$
173
if (createACCdenied) {
174
System.err.println("domain that failed " + SecurityConstants.CREATE_ACC_PERMISSION + " check " + pDomain); //$NON-NLS-1$ //$NON-NLS-2$
175
} else {
176
System.err.println("domain that failed " + pDomain); //$NON-NLS-1$
177
}
178
DebugRecursionDetection.getTlDebug().remove();
179
}
180
if (createACCdenied) {
181
/*[MSG "K002d", "Access denied {0} due to untrusted AccessControlContext since {1} is denied"]*/
182
throw new AccessControlException(com.ibm.oti.util.Msg.getString("K002d", perm, SecurityConstants.CREATE_ACC_PERMISSION), perm); //$NON-NLS-1$
183
} else {
184
/*[MSG "K002c", "Access denied {0}"]*/
185
throw new AccessControlException(com.ibm.oti.util.Msg.getString("K002c", perm), perm); //$NON-NLS-1$
186
}
187
}
188
189
/**
190
* Helper method to check whether the running program is allowed to access the resource
191
* being guarded by the given Permission argument
192
* Assuming perm is not null.
193
*
194
* @param perm the permission to be checked
195
* @param activeDC the DomainCombiner to be invoked
196
* @param acc the AccessControlContext to be checked
197
* @param objects the object array returned from native getAccSnapshot
198
* @param frame the doPrivileged frame are being checked
199
* @param checked the cached check result
200
* @param objPDomains the object array containing ProtectionDomain objects
201
* @param debug the debug flag
202
* @param startPos the start index of the actual ProtectionDomain objects
203
* 1 is JEP140 format, 2 is Pre-JEP140 format
204
*
205
* @return true if access is granted by a limited permission, otherwise return false
206
*/
207
private static boolean checkPermissionHelper(Permission perm, AccessControlContext acc, DomainCombiner activeDC, Object[] objects, int frame, AccessCache checked, Object[] objPDomains, int debug, int startPos) {
208
boolean limitedPermImplied = false;
209
boolean debugEnabled = (debug & AccessControlContext.DEBUG_ENABLED) != 0;
210
ProtectionDomain[] pDomains = generatePDarray(activeDC, acc, objPDomains, debugEnabled, startPos);
211
if (debugEnabled && (0 != (AccessControlContext.debugSetting() & AccessControlContext.DEBUG_ACCESS_DOMAIN))) {
212
DebugRecursionDetection.getTlDebug().set(""); //$NON-NLS-1$
213
AccessControlContext.debugPrintAccess();
214
if (null == pDomains || 0 == pDomains.length) {
215
System.err.println("domain (context is null)"); //$NON-NLS-1$
216
} else {
217
/*[PR 121690] -Djava.security.debug=access:domain should print domains in checkPermission() */
218
for (int i = 0; i < pDomains.length; ++i) {
219
System.err.println("domain " + i + " " + pDomains[i]); //$NON-NLS-1$ //$NON-NLS-2$
220
}
221
}
222
DebugRecursionDetection.getTlDebug().remove();
223
}
224
int length = pDomains == null ? 0 : pDomains.length;
225
if ((null != acc)
226
&& (null != acc.context)
227
&& (AccessControlContext.STATE_AUTHORIZED != acc.authorizeState)
228
&& (null != System.getSecurityManager())
229
) {
230
/*[PR JAZZ 72492] PMR 24367,001,866: Unexpected Security Permission "createAccessControlContext" exception thrown from 1.6SR14 onwards */
231
// startPos: 1 is JEP140 format, 2 is Pre-JEP140 format
232
ProtectionDomain callerPD = (ProtectionDomain) objPDomains[startPos - 1];
233
if (null != callerPD && !callerPD.implies(SecurityConstants.CREATE_ACC_PERMISSION)) {
234
/*[PR CMVC 197399] Improve checking order */
235
// new behavior introduced by this fix
236
// an ACE is thrown if there is a untrusted PD but without SecurityPermission createAccessControlContext
237
throwACE((debug & AccessControlContext.DEBUG_ACCESS_DENIED) != 0, perm, callerPD, true);
238
}
239
}
240
241
if (2 == startPos) { // Pre-JEP140 format
242
if (null != acc && (null != acc.doPrivilegedAcc || null != acc.nextStackAcc || acc.isLimitedContext)) {
243
checked = new AccessCache(); /* checked was null initially when Pre-JEP140 format */
244
return AccessControlContext.checkPermissionWithCache(perm, activeDC, pDomains, debug, acc, false, null, null, checked);
245
} else {
246
if (pDomains != null) {
247
for (int i = 0; i < length ; ++i) {
248
// invoke PD within acc.context first
249
/*[IF Sidecar19-SE]*/
250
if ((pDomains[length - i - 1] != null) && !pDomains[length - i - 1].impliesWithAltFilePerm(perm)) {
251
/*[ELSE]*/
252
if ((pDomains[length - i - 1] != null) && !pDomains[length - i - 1].implies(perm)) {
253
/*[ENDIF] Sidecar19-SE*/
254
throwACE((debug & AccessControlContext.DEBUG_ACCESS_DENIED) != 0, perm, pDomains[length - i - 1], false);
255
}
256
}
257
}
258
}
259
} else {
260
if (AccessControlContext.checkPermissionWithCache(perm, activeDC,
261
pDomains, debug, (AccessControlContext)objects[frame * OBJS_ARRAY_SIZE],
262
(null != objects[frame * OBJS_ARRAY_SIZE + OBJS_INDEX_PERMS_OR_CACHECHECKED]),
263
(Permission[])objects[frame * OBJS_ARRAY_SIZE + OBJS_INDEX_PERMS_OR_CACHECHECKED],
264
null, checked)
265
) {
266
limitedPermImplied = true;
267
}
268
}
269
return limitedPermImplied;
270
}
271
272
/**
273
* Helper to print debug stack information for checkPermission().
274
*
275
* @param debug the debug flags in effect
276
* @param perm the permission to check
277
*/
278
private static void debugPrintStack(boolean debug, Permission perm) {
279
if (debug && ((AccessControlContext.debugSetting() & AccessControlContext.DEBUG_ACCESS_STACK) != 0)) {
280
DebugRecursionDetection.getTlDebug().set(""); //$NON-NLS-1$
281
new Exception("Stack trace for " + perm).printStackTrace(); //$NON-NLS-1$
282
DebugRecursionDetection.getTlDebug().remove();
283
}
284
}
285
286
/**
287
* Helper to print debug information for checkPermission() when in the pre JEP 140 format.
288
*
289
* @param objects the AccessControlContext and ProtectionDomain array obtained from the stack
290
* @param perm the permission to check
291
* @return if debugging is enabled
292
*/
293
private static boolean debugHelperPreJEP140(Object[] objects, Permission perm) {
294
boolean debug = true;
295
if (AccessControlContext.debugCodeBaseArray != null) {
296
debug = false;
297
for (int i = 2; i < objects.length; ++i) {
298
Object pd = objects[i];
299
if (pd != null) {
300
CodeSource cs = ((ProtectionDomain) pd).getCodeSource();
301
if ((cs != null) && AccessControlContext.debugCodeBase(cs.getLocation())) {
302
debug = true;
303
break;
304
}
305
}
306
}
307
AccessControlContext acc = (AccessControlContext) objects[0];
308
if (!debug) {
309
debug = (acc != null) && acc.hasDebugCodeBase();
310
}
311
}
312
313
if (debug && !AccessControlContext.debugPermission(perm)) {
314
debug = false;
315
}
316
317
debugPrintStack(debug, perm);
318
return debug;
319
}
320
321
/**
322
* Helper to print debug information for checkPermission() when in the JEP 140 format.
323
*
324
* @param objects the AccessControlContext and ProtectionDomain array obtained from the stack
325
* @param perm the permission to check
326
* @return if debugging is enabled
327
*/
328
private static boolean debugHelperJEP140(Object[] objects, Permission perm) {
329
boolean debug = true;
330
if (AccessControlContext.debugCodeBaseArray != null) {
331
debug = false;
332
done:
333
for (int j = 0; j < objects.length / OBJS_ARRAY_SIZE; ++j) {
334
AccessControlContext acc = (AccessControlContext) objects[j * OBJS_ARRAY_SIZE];
335
Object[] objPDomains = (Object[]) objects[j * OBJS_ARRAY_SIZE + OBJS_INDEX_PDS];
336
for (int i = 1; i < objPDomains.length; ++i) {
337
Object pd = objPDomains[i];
338
if (pd != null) {
339
CodeSource cs = ((ProtectionDomain) pd).getCodeSource();
340
if ((cs != null) && AccessControlContext.debugCodeBase(cs.getLocation())) {
341
debug = true;
342
break done;
343
}
344
}
345
}
346
if ((acc != null) && acc.hasDebugCodeBase()) {
347
debug = true;
348
break;
349
}
350
}
351
}
352
353
if (debug) {
354
debug = AccessControlContext.debugPermission(perm);
355
}
356
357
debugPrintStack(debug, perm);
358
return debug;
359
}
360
361
/**
362
* Checks whether the running program is allowed to
363
* access the resource being guarded by the given
364
* Permission argument.
365
*
366
* @param perm the permission to check
367
* @exception AccessControlException if access is not allowed.
368
* NullPointerException if perm is null
369
*/
370
public static void checkPermission(Permission perm) throws AccessControlException {
371
if (perm == null) {
372
throw new NullPointerException();
373
}
374
// DEBUG_ENABLED is set if there is nothing to match, or if there is a matching codebase or permission object
375
int debug = AccessControlContext.DEBUG_DISABLED;
376
if (AccessControlContext.debugSetting() != 0) {
377
if (null == DebugRecursionDetection.getTlDebug().get()) {
378
debug = AccessControlContext.DEBUG_ACCESS_DENIED | AccessControlContext.DEBUG_ENABLED;
379
}
380
}
381
382
Object[] objects = getAccSnapshot(1, false);
383
boolean isPreJEP140Format = (0 == objects.length % OBJS_ARRAY_SIZE) ? false : true;
384
385
DomainCombiner activeDC = null;
386
AccessControlContext topACC = (AccessControlContext) objects[0];
387
if ((topACC != null)
388
&& (topACC.domainCombiner != null)
389
) {
390
/* only AccessControlContext with STATE_AUTHORIZED authorizeState could have non-null domainCombiner
391
* the domainCombiner from the closest doPrivileged is used for all later ProtectionDomain combine() calls
392
*/
393
activeDC = topACC.domainCombiner;
394
}
395
396
if (isPreJEP140Format) {
397
if ((debug != AccessControlContext.DEBUG_DISABLED) && !debugHelperPreJEP140(objects, perm)) {
398
debug = AccessControlContext.DEBUG_ACCESS_DENIED; // Disable DEBUG_ENABLED
399
}
400
401
checkPermissionHelper(perm, topACC, activeDC, null, 0, null, objects, debug, 2); // the actual ProtectionDomain element starts at index 2
402
} else {
403
int frameNbr = objects.length / OBJS_ARRAY_SIZE;
404
405
if ((debug != AccessControlContext.DEBUG_DISABLED) && !debugHelperJEP140(objects, perm)) {
406
debug = AccessControlContext.DEBUG_ACCESS_DENIED; // Disable DEBUG_ENABLED
407
}
408
409
AccessCache checked = new AccessCache();
410
for (int j = 0; j < frameNbr; ++j) {
411
AccessControlContext acc = (AccessControlContext) objects[j * OBJS_ARRAY_SIZE];
412
Object[] objPDomains = (Object[]) objects[j * OBJS_ARRAY_SIZE + OBJS_INDEX_PDS];
413
if (checkPermissionHelper(perm, acc, activeDC, objects, j, checked, objPDomains, debug, 1)) { // the actual ProtectionDomain element starts at index 1
414
break;
415
}
416
}
417
}
418
if ((debug & AccessControlContext.DEBUG_ENABLED) != 0) {
419
DebugRecursionDetection.getTlDebug().set(""); //$NON-NLS-1$
420
AccessControlContext.debugPrintAccess();
421
System.err.println("access allowed " + perm); //$NON-NLS-1$
422
DebugRecursionDetection.getTlDebug().remove();
423
}
424
}
425
426
/**
427
* Used to keep the context live during doPrivileged().
428
*
429
* @param context the context to retain
430
*
431
* @see #doPrivileged(PrivilegedAction, AccessControlContext)
432
*/
433
private static void keepalive(AccessControlContext context) {
434
return;
435
}
436
437
/**
438
* @param perms the permissions to retain
439
*/
440
private static void keepalive(Permission... perms) {
441
return;
442
}
443
444
/**
445
* Answers the access controller context of the current thread,
446
* including the inherited ones. It basically retrieves all the
447
* protection domains from the calling stack and creates an
448
* <code>AccessControlContext</code> with them.
449
*
450
* @return an AccessControlContext which captures the current state
451
*
452
* @see AccessControlContext
453
*/
454
public static AccessControlContext getContext() {
455
return getContextHelper(false);
456
}
457
458
/**
459
* This is a helper method for getContext() and doPrivilegedWithCombiner methods.
460
* Answers the access controller context of the current thread including the inherited ones.
461
* Refer native getAccSnapshot() for return data format accordingly to the flag forDoPrivilegedWithCombiner.
462
*
463
* @param forDoPrivilegedWithCombiner The flag to indicate if it is for doPrivilegedWithCombiner method
464
* @return an AccessControlContext which captures the current state
465
*/
466
@CallerSensitive
467
private static AccessControlContext getContextHelper(boolean forDoPrivilegedWithCombiner) {
468
Object[] domains = getAccSnapshot(2, forDoPrivilegedWithCombiner);
469
boolean isPreJEP140Format = (0 == domains.length % OBJS_ARRAY_SIZE) ? false : true;
470
DomainCombiner activeDC = null;
471
AccessControlContext topACC = (AccessControlContext) domains[0];
472
if ((topACC != null)
473
&& (topACC.domainCombiner != null)
474
) {
475
/* only AccessControlContext with STATE_AUTHORIZED authorizeState could have non-null domainCombiner
476
* the domainCombiner from the closest doPrivileged is used for all later ProtectionDomain combine() calls
477
*/
478
activeDC = topACC.domainCombiner;
479
}
480
if (isPreJEP140Format) {
481
/*[PR JAZZ 66930] j.s.AccessControlContext.checkPermission() invoke untrusted ProtectionDomain.implies */
482
// The actual ProtectionDomain element starts at index 2
483
ProtectionDomain[] pDomains = generatePDarray(activeDC, topACC, domains, false, 2);
484
AccessControlContext accTmp;
485
int newAuthorizedState = getNewAuthorizedState(topACC, (ProtectionDomain) domains[1]);
486
if ((topACC != null) && ((topACC.doPrivilegedAcc != null) || (topACC.nextStackAcc != null) || topACC.isLimitedContext)) {
487
accTmp = new AccessControlContext(topACC, pDomains, newAuthorizedState);
488
} else {
489
accTmp = new AccessControlContext(pDomains, newAuthorizedState);
490
}
491
if ((topACC != null) && (topACC.domainCombiner != null)) {
492
accTmp.domainCombiner = topACC.domainCombiner;
493
}
494
return accTmp;
495
}
496
int frameNbr = domains.length / OBJS_ARRAY_SIZE;
497
AccessControlContext accContext = null;
498
AccessControlContext accLower = null;
499
for (int j = 0; j < frameNbr; ++j) {
500
AccessControlContext acc = (AccessControlContext) domains[j * OBJS_ARRAY_SIZE];
501
/*[PR JAZZ 66930] j.s.AccessControlContext.checkPermission() invoke untrusted ProtectionDomain.implies */
502
// the actual ProtectionDomain element starts at index 1
503
ProtectionDomain[] pDomains = generatePDarray(activeDC, acc, (Object[]) domains[j * OBJS_ARRAY_SIZE + OBJS_INDEX_PDS], false, 1);
504
AccessControlContext accTmp;
505
int newAuthorizedState = getNewAuthorizedState(acc, (ProtectionDomain)((Object[]) domains[j * OBJS_ARRAY_SIZE + OBJS_INDEX_PDS])[0]);
506
if (((null != acc) && acc.isLimitedContext) || (1 < frameNbr)) {
507
// there is a limited doPrivilege frame
508
accTmp = new AccessControlContext(acc, pDomains, newAuthorizedState);
509
} else {
510
// not set doPrivilegedAcc for non limited doPrivilege
511
// all ProtectionDomains already included within pDomains
512
accTmp = new AccessControlContext(pDomains, newAuthorizedState);
513
}
514
if (null != acc && null != acc.domainCombiner) {
515
accTmp.domainCombiner = acc.domainCombiner;
516
if (activeDC == null) {
517
// This activeDC will be set to accContext.domainCombiner.
518
activeDC = acc.domainCombiner;
519
}
520
}
521
if (null != domains[j * OBJS_ARRAY_SIZE + OBJS_INDEX_PERMS_OR_CACHECHECKED]) {
522
// this is frame with limited permissions
523
accTmp.isLimitedContext = true;
524
accTmp.limitedPerms = (Permission[]) domains[j * OBJS_ARRAY_SIZE + OBJS_INDEX_PERMS_OR_CACHECHECKED];
525
}
526
527
if (null == accLower) {
528
accContext = accTmp;
529
} else {
530
accLower.nextStackAcc = accTmp;
531
}
532
accLower = accTmp;
533
}
534
if ((accContext != null) && (accContext.domainCombiner == null) && (activeDC != null)) {
535
// the domainCombiner from the closest doPrivileged is set for returning AccessControlContext object, otherwise null is set.
536
accContext.domainCombiner = activeDC;
537
}
538
return accContext;
539
}
540
541
/**
542
* Helper method to generate ProtectionDomain array for a new AccessControlContext object
543
*
544
* @param activeDC the DomainCombiner to be invoked
545
* @param acc the AccessControlContext object to be checked
546
* @param domains the incoming ProtectionDomain object array
547
* @param debug the debug flag
548
* @param startPos the start index of the actual ProtectionDomain object
549
*
550
* @return a ProtectionDomain object array
551
*/
552
private static ProtectionDomain[] generatePDarray(DomainCombiner activeDC, AccessControlContext acc, Object[] domains, boolean debug, int startPos) {
553
ProtectionDomain[] pDomains = null;
554
/*[PR JAZZ 66930] j.s.AccessControlContext.checkPermission() invoke untrusted ProtectionDomain.implies */
555
DomainCombiner actDC = null;
556
if (activeDC != null) {
557
actDC = activeDC;
558
} else {
559
if ((acc != null)
560
&& (acc.domainCombiner != null)
561
) {
562
// only AccessControlContext with STATE_AUTHORIZED authorizeState could have non-null domainCombiner
563
actDC = acc.domainCombiner;
564
}
565
}
566
567
if (actDC != null) {
568
if (debug) {
569
DebugRecursionDetection.getTlDebug().set(""); //$NON-NLS-1$
570
AccessControlContext.debugPrintAccess();
571
System.err.println("AccessController invoking the Combiner"); //$NON-NLS-1$
572
DebugRecursionDetection.getTlDebug().remove();
573
}
574
ProtectionDomain[] pds = null;
575
if (acc != null) {
576
pds = acc.context;
577
}
578
pDomains = actDC.combine(toArrayOfProtectionDomains(domains, null, startPos), pds);
579
} else {
580
pDomains = toArrayOfProtectionDomains(domains, acc, startPos);
581
}
582
if (null != pDomains && 0 == pDomains.length) {
583
pDomains = null;
584
}
585
return pDomains;
586
}
587
588
/**
589
* Helper method to determine the newAuthorizedState according to incoming acc and callerPD.
590
*
591
* @param acc the AccessControlContext object to be checked
592
* @param callerPD the caller's ProtectionDomain object
593
*
594
* @return AccessControlContext.STATE_AUTHORIZED or STATE_NOT_AUTHORIZED (can't be STATE_UNKNOWN)
595
*/
596
private static int getNewAuthorizedState(AccessControlContext acc, ProtectionDomain callerPD) {
597
int newAuthorizedState;
598
/*[PR JAZZ 87596] PMR 18839,756,000 - Need to trust AccessControlContext created without active SecurityManager */
599
if ((null != acc) && (null != System.getSecurityManager())) {
600
newAuthorizedState = acc.authorizeState;
601
if (AccessControlContext.STATE_UNKNOWN == newAuthorizedState) {
602
// only change AccessControlContext.authorizeState when it is unknown initially
603
if (null == callerPD || callerPD.implies(SecurityConstants.CREATE_ACC_PERMISSION)) {
604
newAuthorizedState = AccessControlContext.STATE_AUTHORIZED;
605
} else {
606
newAuthorizedState = AccessControlContext.STATE_NOT_AUTHORIZED;
607
}
608
}
609
} else {
610
newAuthorizedState = AccessControlContext.STATE_AUTHORIZED;
611
}
612
return newAuthorizedState;
613
}
614
615
/**
616
* Helper method to combine the ProtectionDomain objects
617
*
618
* @param domains the incoming ProtectionDomain object array
619
* @param acc the AccessControlContext whose context is an ProtectionDomain object array
620
* @param startPos the start index of the domains
621
*
622
* @return an ProtectionDomain object array
623
*/
624
static ProtectionDomain[] toArrayOfProtectionDomains(Object[] domains, AccessControlContext acc, int startPos) {
625
final ProtectionDomain[] accDomains = acc == null ? null : acc.context;
626
ProtectionDomain[] answer = null;
627
628
if (domains == null) {
629
if (accDomains != null && accDomains.length != 0) {
630
answer = accDomains;
631
}
632
} else if (accDomains == null) {
633
int domainCount = domains.length - startPos;
634
for (int i = 0; i < domainCount; ++i) {
635
if (domains[startPos + i] == null) {
636
domainCount = i;
637
break;
638
}
639
}
640
if (domainCount > 0) {
641
answer = new ProtectionDomain[domainCount];
642
System.arraycopy(domains, startPos, answer, 0, domainCount);
643
}
644
} else {
645
final int domainCount = domains.length;
646
final int accDomainCount = accDomains.length;
647
int newDomainCount = 0;
648
answer = new ProtectionDomain[domainCount + accDomainCount];
649
for (int i = startPos; i < domainCount; ++i) {
650
Object domain = domains[i];
651
if (domain == null) {
652
break;
653
}
654
for (int j = accDomainCount;;) {
655
j -= 1;
656
if (j < 0) {
657
answer[newDomainCount] = (ProtectionDomain) domain;
658
newDomainCount += 1;
659
break;
660
} else if (accDomains[j] == domain) {
661
break;
662
}
663
}
664
}
665
if (newDomainCount + accDomainCount == 0) {
666
answer = null;
667
} else if (newDomainCount == 0) {
668
answer = accDomains;
669
} else {
670
if (newDomainCount < domainCount) {
671
ProtectionDomain[] copy = new ProtectionDomain[newDomainCount + accDomainCount];
672
System.arraycopy(answer, 0, copy, 0, newDomainCount);
673
answer = copy;
674
}
675
System.arraycopy(accDomains, 0, answer, newDomainCount, accDomainCount);
676
}
677
}
678
679
return answer;
680
}
681
682
/**
683
* Performs the privileged action specified by <code>action</code>.
684
* <p>
685
* When permission checks are made, if the permission has been granted by all
686
* frames below and including the one representing the call to this method,
687
* then the permission is granted. In other words, the check stops here.
688
*
689
* Any unchecked exception generated by this method will propagate up the chain.
690
* @param <T> the type of value returned by PrivilegedAction.run
691
*
692
* @param action The PrivilegedAction to performed
693
*
694
* @return the result of the PrivilegedAction
695
*
696
* @exception NullPointerException if action is null
697
*
698
* @see #doPrivileged(PrivilegedAction)
699
*/
700
/*[PR 1GO8C5O] required for initializeInternal */
701
@CallerSensitive
702
public static <T> T doPrivileged(PrivilegedAction<T> action) {
703
return action.run();
704
}
705
706
/**
707
* Performs the privileged action specified by <code>action</code>.
708
* <p>
709
* When permission checks are made, if the permission has been granted by all
710
* frames below and including the one representing the call to this method,
711
* then the permission is granted iff it is granted by the AccessControlContext
712
* <code>context</code>. In other words, no more checking of the current stack
713
* is performed. Instead, the passed in context is checked.
714
*
715
* Any unchecked exception generated by this method will propagate up the chain.
716
* @param <T> the type of value returned by PrivilegedAction.run
717
*
718
* @param action The PrivilegedAction to performed
719
* @param context The AccessControlContext to check
720
*
721
* @return the result of the PrivilegedAction
722
*
723
* @exception NullPointerException if action is null
724
*
725
* @see #doPrivileged(PrivilegedAction)
726
*/
727
@CallerSensitive
728
public static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context) {
729
T result = action.run();
730
/*[PR 108112] context is not kept alive*/
731
keepalive(context);
732
return result;
733
}
734
735
/**
736
* Performs the privileged action specified by <code>action</code>.
737
* <p>
738
* When permission checks are made, if the permission has been granted by all
739
* frames below and including the one representing the call to this method,
740
* then the permission is granted. In other words, the check stops here.
741
*
742
* Any unchecked exception generated by this method will propagate up the chain.
743
* However, checked exceptions will be caught an re-thrown as PrivilegedActionExceptions
744
* @param <T> the type of value returned by PrivilegedExceptionAction.run
745
*
746
* @param action The PrivilegedExceptionAction to performed
747
*
748
* @return the result of the PrivilegedExceptionAction
749
*
750
* @throws PrivilegedActionException when a checked exception occurs when performing the action
751
* NullPointerException if action is null
752
*
753
* @see #doPrivileged(PrivilegedAction)
754
*/
755
@CallerSensitive
756
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action)
757
throws PrivilegedActionException
758
{
759
try {
760
return action.run();
761
} catch (RuntimeException ex) {
762
throw ex;
763
} catch (Exception ex) {
764
throw new PrivilegedActionException(ex);
765
}
766
}
767
768
/**
769
* Performs the privileged action specified by <code>action</code>.
770
* <p>
771
* When permission checks are made, if the permission has been granted by all
772
* frames below and including the one representing the call to this method,
773
* then the permission is granted iff it is granted by the AccessControlContext
774
* <code>context</code>. In other words, no more checking of the current stack
775
* is performed. Instead, the passed in context is checked.
776
*
777
* Any unchecked exception generated by this method will propagate up the chain.
778
* However, checked exceptions will be caught an re-thrown as PrivilegedActionExceptions
779
* @param <T> the type of value returned by PrivilegedExceptionAction.run
780
*
781
* @param action The PrivilegedExceptionAction to performed
782
* @param context The AccessControlContext to check
783
*
784
* @return the result of the PrivilegedExceptionAction
785
*
786
* @throws PrivilegedActionException when a checked exception occurs when performing the action
787
* NullPointerException if action is null
788
*
789
* @see #doPrivileged(PrivilegedAction)
790
*/
791
@CallerSensitive
792
public static <T> T doPrivileged (PrivilegedExceptionAction<T> action, AccessControlContext context)
793
throws PrivilegedActionException
794
{
795
try {
796
T result = action.run();
797
/*[PR 108112] context is not kept alive*/
798
keepalive(context);
799
return result;
800
} catch (RuntimeException ex) {
801
throw ex;
802
} catch (Exception ex) {
803
throw new PrivilegedActionException(ex);
804
}
805
}
806
807
/**
808
* Performs the privileged action specified by <code>action</code>, retaining
809
* any current DomainCombiner.
810
* <p>
811
* When permission checks are made, if the permission has been granted by all
812
* frames below and including the one representing the call to this method,
813
* then the permission is granted. In other words, the check stops here.
814
*
815
* Any unchecked exception generated by this method will propagate up the chain.
816
* @param <T> the type of value returned by PrivilegedAction.run
817
*
818
* @param action The PrivilegedAction to performed
819
*
820
* @return the result of the PrivilegedAction
821
*
822
* @see #doPrivileged(PrivilegedAction)
823
*/
824
@CallerSensitive
825
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
826
return doPrivileged(action, getContextHelper(true));
827
}
828
829
/**
830
* Performs the privileged action specified by <code>action</code>, retaining
831
* any current DomainCombiner.
832
* <p>
833
* When permission checks are made, if the permission has been granted by all
834
* frames below and including the one representing the call to this method,
835
* then the permission is granted. In other words, the check stops here.
836
*
837
* Any unchecked exception generated by this method will propagate up the chain.
838
* However, checked exceptions will be caught an re-thrown as PrivilegedActionExceptions
839
* @param <T> the type of value returned by PrivilegedExceptionAction.run
840
*
841
* @param action The PrivilegedExceptionAction to performed
842
*
843
* @return the result of the PrivilegedExceptionAction
844
*
845
* @throws PrivilegedActionException when a checked exception occurs when performing the action
846
*
847
* @see #doPrivileged(PrivilegedAction)
848
*/
849
@CallerSensitive
850
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
851
throws PrivilegedActionException
852
{
853
return doPrivileged(action, getContextHelper(true));
854
}
855
856
/**
857
* Helper method to check if any permission is null
858
*
859
* @param perms The Permission arguments to limit the scope of the caller's privileges.
860
*
861
* @exception NullPointerException if any perm is null
862
*
863
*/
864
private static void checkPermsNPE(Permission... perms) {
865
for (int i = 0; i < perms.length; ++i) {
866
if (null == perms[i]) {
867
throw new NullPointerException();
868
}
869
}
870
}
871
872
/**
873
* Performs the privileged action specified by <code>action</code>.
874
* <p>
875
* When permission checks are made, if the permission has been granted by all
876
* frames below and including the one representing the call to this method,
877
* then the permission is granted iff it is granted by the AccessControlContext
878
* <code>context</code> and also granted by one of the permissions arguments.
879
*
880
* Any unchecked exception generated by this method will propagate up the chain.
881
* @param <T> the type of value returned by PrivilegedAction.run
882
*
883
* @param action The PrivilegedAction to performed
884
* @param context The AccessControlContext to check
885
* @param perms The Permission arguments to limit the scope of the caller's privileges.
886
*
887
* @return the result of the PrivilegedAction
888
* @since 1.8
889
*
890
* @exception NullPointerException if action is null
891
*
892
* @see #doPrivileged(PrivilegedAction)
893
* @see #doPrivileged(PrivilegedAction, AccessControlContext)
894
*/
895
@CallerSensitive
896
public static <T> T doPrivileged(PrivilegedAction<T> action,
897
AccessControlContext context, Permission... perms)
898
{
899
checkPermsNPE(perms);
900
T result = action.run();
901
keepalive(context);
902
keepalive(perms);
903
return result;
904
}
905
906
/**
907
* Performs the privileged action specified by <code>action</code>, retaining
908
* any current DomainCombiner.
909
* <p>
910
* When permission checks are made, if the permission has been granted by all
911
* frames below and including the one representing the call to this method,
912
* then the permission is granted iff it is granted by one of the permissions arguments.
913
*
914
* Any unchecked exception generated by this method will propagate up the chain.
915
* @param <T> the type of value returned by PrivilegedAction.run
916
*
917
* @param action The PrivilegedAction to performed
918
* @param context The AccessControlContext to check
919
* @param perms The Permission arguments to limit the scope of the caller's privileges.
920
*
921
* @return the result of the PrivilegedAction
922
* @since 1.8
923
*
924
* @see #doPrivileged(PrivilegedAction)
925
* @see #doPrivileged(PrivilegedAction, AccessControlContext)
926
*/
927
@CallerSensitive
928
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
929
AccessControlContext context, Permission... perms)
930
{
931
checkPermsNPE(perms);
932
ProtectionDomain domain = getCallerPD(1);
933
ProtectionDomain[] pdArray = (domain == null) ? null : new ProtectionDomain[] { domain };
934
return doPrivileged(action, new AccessControlContext(context, pdArray, getNewAuthorizedState(context, domain)), perms);
935
}
936
937
/**
938
* Performs the privileged action specified by <code>action</code>.
939
* <p>
940
* When permission checks are made, if the permission has been granted by all
941
* frames below and including the one representing the call to this method,
942
* then the permission is granted iff it is granted by the AccessControlContext
943
* <code>context</code> and also granted by one of the permissions arguments.
944
*
945
* Any unchecked exception generated by this method will propagate up the chain.
946
* However, checked exceptions will be caught an re-thrown as PrivilegedActionExceptions
947
* @param <T> the type of value returned by PrivilegedExceptionAction.run
948
*
949
* @param action The PrivilegedExceptionAction to performed
950
* @param context The AccessControlContext to check
951
* @param perms The Permission arguments to limit the scope of the caller's privileges.
952
*
953
* @return the result of the PrivilegedExceptionAction
954
* @since 1.8
955
*
956
* @throws PrivilegedActionException when a checked exception occurs when performing the action
957
* NullPointerException if action is null
958
*
959
* @see #doPrivileged(PrivilegedAction)
960
* @see #doPrivileged(PrivilegedAction, AccessControlContext)
961
*/
962
@CallerSensitive
963
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
964
AccessControlContext context, Permission... perms)
965
throws PrivilegedActionException
966
{
967
try {
968
checkPermsNPE(perms);
969
T result = action.run();
970
keepalive(context);
971
keepalive(perms);
972
return result;
973
} catch (RuntimeException ex) {
974
throw ex;
975
} catch (Exception ex) {
976
throw new PrivilegedActionException(ex);
977
}
978
}
979
980
/**
981
* Performs the privileged action specified by <code>action</code>, retaining
982
* any current DomainCombiner.
983
* <p>
984
* When permission checks are made, if the permission has been granted by all
985
* frames below and including the one representing the call to this method,
986
* then the permission is granted and also granted by one of the permissions arguments.
987
*
988
* Any unchecked exception generated by this method will propagate up the chain.
989
* However, checked exceptions will be caught an re-thrown as PrivilegedActionExceptions
990
* @param <T> the type of value returned by PrivilegedExceptionAction.run
991
*
992
* @param action The PrivilegedExceptionAction to performed
993
* @param context The AccessControlContext to check
994
* @param perms The Permission arguments to limit the scope of the caller's privileges.
995
*
996
* @return the result of the PrivilegedExceptionAction
997
* @since 1.8
998
*
999
* @throws PrivilegedActionException when a checked exception occurs when performing the action
1000
*
1001
* @see #doPrivileged(PrivilegedAction)
1002
* @see #doPrivileged(PrivilegedAction, AccessControlContext)
1003
*/
1004
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
1005
AccessControlContext context, Permission... perms)
1006
throws PrivilegedActionException
1007
{
1008
checkPermsNPE(perms);
1009
ProtectionDomain domain = getCallerPD(1);
1010
ProtectionDomain[] pdArray = (domain == null) ? null : new ProtectionDomain[] { domain };
1011
return doPrivileged(action, new AccessControlContext(context, pdArray, getNewAuthorizedState(context, domain)), perms);
1012
}
1013
1014
}
1015
1016