Skip to content

Commit 494ffaa

Browse files
Fix review feedback
1 parent 539ba73 commit 494ffaa

File tree

5 files changed

+195
-104
lines changed

5 files changed

+195
-104
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,16 @@
5555
import java.util.Set;
5656
import java.util.StringJoiner;
5757

58+
import com.oracle.svm.core.BaseProcessPropertiesSupport;
5859
import org.graalvm.compiler.core.common.NumUtil;
5960
import org.graalvm.compiler.core.common.SuppressFBWarnings;
6061
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
61-
import org.graalvm.nativeimage.ImageInfo;
62+
import org.graalvm.nativeimage.ImageSingletons;
6263
import org.graalvm.nativeimage.Platform;
6364
import org.graalvm.nativeimage.Platforms;
6465
import org.graalvm.nativeimage.ProcessProperties;
6566
import org.graalvm.nativeimage.c.function.CFunctionPointer;
67+
import org.graalvm.nativeimage.impl.ProcessPropertiesSupport;
6668
import org.graalvm.util.DirectAnnotationAccess;
6769

6870
import com.oracle.svm.core.RuntimeAssertionsSupport;
@@ -327,7 +329,6 @@ public void setModule(Object module) {
327329
this.module = module;
328330
}
329331

330-
static final boolean IS_EXECUTABLE = ImageInfo.isExecutable();
331332
/**
332333
* Final fields in substituted classes are treated as implicitly RecomputeFieldValue even when
333334
* not annotated with @RecomputeFieldValue. Their name must not match a field in the original
@@ -336,21 +337,19 @@ public void setModule(Object module) {
336337
static final LazyFinalReference<java.security.ProtectionDomain> allPermDomainReference = new LazyFinalReference<>(() -> {
337338
java.security.Permissions perms = new java.security.Permissions();
338339
perms.add(SecurityConstants.ALL_PERMISSION);
339-
URL url = null;
340+
CodeSource cs = null;
340341

341-
if (IS_EXECUTABLE) {
342+
if (ImageSingletons.lookup(ProcessPropertiesSupport.class) instanceof BaseProcessPropertiesSupport) {
342343
// Try to use executable image's name as code source for the class.
343344
// The file location can be used by Java code to determine its location on disk, similar
344345
// to argv[0].
345346
try {
346-
url = new File(ProcessProperties.getExecutableName()).toURI().toURL();
347+
cs = new CodeSource(new File(ProcessProperties.getExecutableName()).toURI().toURL(), (Certificate[]) null);
347348
} catch (MalformedURLException e) {
348349
// This should not really happen; the file is cannonicalized, absolute, so it should
349350
// always have file:// URL.
350351
}
351352
}
352-
353-
CodeSource cs = new CodeSource(url, (Certificate[]) null);
354353
return new java.security.ProtectionDomain(cs, perms);
355354
});
356355

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/AccessControllerUtil.java

Lines changed: 67 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -35,70 +35,90 @@
3535
import java.util.ArrayDeque;
3636
import java.util.Objects;
3737

38-
@InternalVMMethod
39-
@SuppressWarnings({"unused"})
40-
public class AccessControllerUtil {
38+
/**
39+
* Stack for storing AccessControlContexts. Used in conjunction with
40+
* {@code StackAccessControlContextVisitor}.
41+
*/
42+
class PrivilegedStack {
4143

42-
public static final AccessControlContext DISALLOWED_CONTEXT_MARKER;
44+
public static class StackElement {
45+
protected AccessControlContext context;
46+
protected Class<?> caller;
4347

44-
static {
45-
try {
46-
DISALLOWED_CONTEXT_MARKER = ReflectionUtil.lookupConstructor(AccessControlContext.class, ProtectionDomain[].class, boolean.class).newInstance(new ProtectionDomain[0], true);
47-
} catch (ReflectiveOperationException ex) {
48-
throw VMError.shouldNotReachHere(ex);
48+
StackElement(AccessControlContext context, Class<?> caller) {
49+
this.context = context;
50+
this.caller = caller;
51+
}
52+
53+
public AccessControlContext getContext() {
54+
return context;
55+
}
56+
57+
public Class<?> getCaller() {
58+
return caller;
4959
}
5060
}
5161

52-
public static class PrivilegedStack {
62+
/* Local AccessControlContext stack */
63+
private static final FastThreadLocalObject<ArrayDeque<StackElement>> stack;
5364

54-
public static class StackElement {
55-
protected AccessControlContext context;
56-
protected Class<?> caller;
65+
static {
5766

58-
StackElement(AccessControlContext context, Class<?> caller) {
59-
this.context = context;
60-
this.caller = caller;
61-
}
67+
@SuppressWarnings("unchecked")
68+
Class<ArrayDeque<StackElement>> cls = (Class<ArrayDeque<StackElement>>) (Object) ArrayDeque.class;
69+
stack = FastThreadLocalFactory.createObject(cls, "AccessControlContextStack");
70+
}
6271

63-
public AccessControlContext getContext() {
64-
return context;
65-
}
72+
@SuppressWarnings("unchecked")
73+
private static ArrayDeque<StackElement> getStack() {
74+
ensureInitialized();
75+
return stack.get();
76+
}
6677

67-
public Class<?> getCaller() {
68-
return caller;
69-
}
78+
private static void ensureInitialized() {
79+
if (stack.get() == null) {
80+
ArrayDeque<StackElement> tmp = new ArrayDeque<>();
81+
stack.set(tmp);
7082
}
83+
}
7184

72-
@SuppressWarnings("rawtypes") private static final FastThreadLocalObject<ArrayDeque> stack = FastThreadLocalFactory.createObject(ArrayDeque.class, "AccessControlContextStack");
85+
public static void push(AccessControlContext context, Class<?> caller) {
86+
getStack().push(new StackElement(context, caller));
87+
}
7388

74-
@SuppressWarnings("unchecked")
75-
private static ArrayDeque<StackElement> getStack() {
76-
ArrayDeque<StackElement> tmp = stack.get();
77-
if (tmp == null) {
78-
tmp = new ArrayDeque<>();
79-
stack.set(tmp);
80-
}
81-
return tmp;
82-
}
89+
public static void pop() {
90+
getStack().pop();
91+
}
8392

84-
public static void push(AccessControlContext context, Class<?> caller) {
85-
getStack().push(new StackElement(context, caller));
86-
}
93+
public static AccessControlContext peekContext() {
94+
return Objects.requireNonNull(getStack().peek()).getContext();
95+
}
8796

88-
public static void pop() {
89-
getStack().pop();
90-
}
97+
public static Class<?> peekCaller() {
98+
return Objects.requireNonNull(getStack().peek()).getCaller();
99+
}
91100

92-
public static AccessControlContext peekContext() {
93-
return Objects.requireNonNull(getStack().peek()).getContext();
94-
}
101+
public static int length() {
102+
return getStack().size();
103+
}
104+
}
95105

96-
public static Class<?> peekCaller() {
97-
return Objects.requireNonNull(getStack().peek()).getCaller();
98-
}
106+
@InternalVMMethod
107+
@SuppressWarnings({"unused"})
108+
public class AccessControllerUtil {
109+
110+
/**
111+
* Instance that is used to mark contexts that were disallowed in
112+
* {@code AccessControlContextReplacerFeature.replaceAccessControlContext()} If this marker is
113+
* passed to {@code AccessController.doPrivileged()} a runtime error will be thrown.
114+
*/
115+
public static final AccessControlContext DISALLOWED_CONTEXT_MARKER;
99116

100-
public static int length() {
101-
return getStack().size();
117+
static {
118+
try {
119+
DISALLOWED_CONTEXT_MARKER = ReflectionUtil.lookupConstructor(AccessControlContext.class, ProtectionDomain[].class, boolean.class).newInstance(new ProtectionDomain[0], true);
120+
} catch (ReflectiveOperationException ex) {
121+
throw VMError.shouldNotReachHere(ex);
102122
}
103123
}
104124

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecuritySubstitutions.java

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,24 @@
2424
*/
2525
package com.oracle.svm.core.jdk;
2626

27-
import static com.oracle.svm.core.snippets.KnownIntrinsics.readCallerStackPointer;
27+
import com.oracle.svm.core.SubstrateUtil;
28+
import com.oracle.svm.core.annotate.Alias;
29+
import com.oracle.svm.core.annotate.Delete;
30+
import com.oracle.svm.core.annotate.InjectAccessors;
31+
import com.oracle.svm.core.annotate.NeverInline;
32+
import com.oracle.svm.core.annotate.RecomputeFieldValue;
33+
import com.oracle.svm.core.annotate.Substitute;
34+
import com.oracle.svm.core.annotate.TargetClass;
35+
import com.oracle.svm.core.annotate.TargetElement;
36+
import com.oracle.svm.core.graal.snippets.CEntryPointSnippets;
37+
import com.oracle.svm.core.thread.Target_java_lang_Thread;
38+
import com.oracle.svm.core.util.VMError;
39+
import jdk.vm.ci.meta.MetaAccessProvider;
40+
import jdk.vm.ci.meta.ResolvedJavaField;
41+
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
42+
import org.graalvm.nativeimage.Platform;
43+
import org.graalvm.nativeimage.Platforms;
44+
import org.graalvm.word.Pointer;
2845

2946
import java.net.URL;
3047
import java.security.AccessControlContext;
@@ -43,24 +60,7 @@
4360
import java.util.concurrent.atomic.AtomicReference;
4461
import java.util.function.Predicate;
4562

46-
import jdk.vm.ci.meta.MetaAccessProvider;
47-
import jdk.vm.ci.meta.ResolvedJavaField;
48-
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
49-
import org.graalvm.nativeimage.Platform;
50-
import org.graalvm.nativeimage.Platforms;
51-
import org.graalvm.word.Pointer;
52-
53-
import com.oracle.svm.core.SubstrateUtil;
54-
import com.oracle.svm.core.annotate.Alias;
55-
import com.oracle.svm.core.annotate.Delete;
56-
import com.oracle.svm.core.annotate.InjectAccessors;
57-
import com.oracle.svm.core.annotate.NeverInline;
58-
import com.oracle.svm.core.annotate.RecomputeFieldValue;
59-
import com.oracle.svm.core.annotate.Substitute;
60-
import com.oracle.svm.core.annotate.TargetClass;
61-
import com.oracle.svm.core.annotate.TargetElement;
62-
import com.oracle.svm.core.thread.Target_java_lang_Thread;
63-
import com.oracle.svm.core.util.VMError;
63+
import static com.oracle.svm.core.snippets.KnownIntrinsics.readCallerStackPointer;
6464

6565
// Checkstyle: stop
6666
import sun.security.jca.ProviderList;
@@ -109,6 +109,17 @@ static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlCont
109109

110110
@Substitute
111111
static AccessControlContext getStackAccessControlContext() {
112+
if (!CEntryPointSnippets.isIsolateInitialized()) {
113+
/*
114+
* If isolate still isn't initialized, we can assume that we are so early in the JDK
115+
* initialization that any attempt at stalk walk will fail as not even the basic
116+
* PrintWriter/Logging is available yet. This manifested when
117+
* UseDedicatedVMOperationThread hosted option was set, triggering a runtime crash.
118+
*/
119+
Permissions perms = new Permissions();
120+
perms.add(SecurityConstants.ALL_PERMISSION);
121+
return new AccessControlContext(new ProtectionDomain[]{new ProtectionDomain(null, perms)});
122+
}
112123
return StackAccessControlContextVisitor.getFromStack();
113124
}
114125

@@ -118,47 +129,47 @@ static AccessControlContext getInheritedAccessControlContext() {
118129
}
119130

120131
@Substitute
121-
@TargetElement(onlyWith = JDK14OrLater.class)
132+
@TargetElement(onlyWith = JDK17OrLater.class)
122133
private static ProtectionDomain getProtectionDomain(final Class<?> caller) {
123134
return caller.getProtectionDomain();
124135
}
125136

126137
@Substitute
127-
@TargetElement(onlyWith = JDK14OrLater.class)
138+
@TargetElement(onlyWith = JDK17OrLater.class)
128139
static <T> T executePrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context, Class<?> caller) throws Throwable {
129140
if (action == null) {
130141
throw new NullPointerException("Null action");
131142
}
132143

133-
AccessControllerUtil.PrivilegedStack.push(context, caller);
144+
PrivilegedStack.push(context, caller);
134145
try {
135146
return action.run();
136147
} catch (Exception e) {
137148
throw AccessControllerUtil.wrapCheckedException(e);
138149
} finally {
139-
AccessControllerUtil.PrivilegedStack.pop();
150+
PrivilegedStack.pop();
140151
}
141152
}
142153

143154
@Substitute
144-
@TargetElement(onlyWith = JDK14OrLater.class)
155+
@TargetElement(onlyWith = JDK17OrLater.class)
145156
static <T> T executePrivileged(PrivilegedAction<T> action, AccessControlContext context, Class<?> caller) throws Throwable {
146157
if (action == null) {
147158
throw new NullPointerException("Null action");
148159
}
149160

150-
AccessControllerUtil.PrivilegedStack.push(context, caller);
161+
PrivilegedStack.push(context, caller);
151162
try {
152163
return action.run();
153164
} catch (Exception e) {
154165
throw AccessControllerUtil.wrapCheckedException(e);
155166
} finally {
156-
AccessControllerUtil.PrivilegedStack.pop();
167+
PrivilegedStack.pop();
157168
}
158169
}
159170

160171
@Substitute
161-
@TargetElement(onlyWith = JDK14OrLater.class)
172+
@TargetElement(onlyWith = JDK17OrLater.class)
162173
@SuppressWarnings({"unused", "deprecation"})
163174
static AccessControlContext checkContext(AccessControlContext context, Class<?> caller) {
164175

@@ -182,15 +193,19 @@ static AccessControlContext checkContext(AccessControlContext context, Class<?>
182193
@TargetClass(java.security.AccessControlContext.class)
183194
@SuppressWarnings({"unused"})
184195
final class Target_java_security_AccessControlContext {
185-
@Alias protected boolean isPrivileged;
186-
@Alias protected boolean isAuthorized;
196+
@Alias public boolean isPrivileged;
197+
@Alias public boolean isAuthorized;
187198

188199
@Alias
189200
Target_java_security_AccessControlContext(ProtectionDomain[] context, AccessControlContext privilegedContext) {
190201
}
191202

192203
@Substitute
193204
static Debug getDebug() {
205+
/*
206+
* We want to prevent Debug class from being reachable, as this method would return null
207+
* anyways
208+
*/
194209
return null;
195210
}
196211
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/StackTraceUtils.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
import java.security.AccessControlContext;
2828
import java.security.AccessController;
29-
import java.security.Permissions;
3029
import java.security.ProtectionDomain;
3130
import java.util.ArrayList;
3231

@@ -39,8 +38,6 @@
3938
import com.oracle.svm.core.SubstrateUtil;
4039
import com.oracle.svm.core.annotate.NeverInline;
4140
import com.oracle.svm.core.code.FrameInfoQueryResult;
42-
import com.oracle.svm.core.graal.snippets.CEntryPointSnippets;
43-
import com.oracle.svm.core.jdk.AccessControllerUtil.PrivilegedStack;
4441
import com.oracle.svm.core.snippets.KnownIntrinsics;
4542
import com.oracle.svm.core.stack.JavaStackFrameVisitor;
4643
import com.oracle.svm.core.stack.JavaStackWalker;
@@ -51,10 +48,6 @@
5148
import jdk.vm.ci.meta.ResolvedJavaMethod;
5249
import jdk.vm.ci.meta.ResolvedJavaType;
5350

54-
// Checkstyle: stop
55-
import sun.security.util.SecurityConstants;
56-
// Checkstyle: resume
57-
5851
public class StackTraceUtils {
5952

6053
private static final Class<?>[] NO_CLASSES = new Class<?>[0];
@@ -370,11 +363,6 @@ public boolean visitFrame(final FrameInfoQueryResult frameInfo) {
370363
@NeverInline("Starting a stack walk in the caller frame")
371364
@SuppressWarnings({"deprecation"}) // deprecated starting JDK 17
372365
public static AccessControlContext getFromStack() {
373-
if (!CEntryPointSnippets.isIsolateInitialized()) {
374-
Permissions perms = new Permissions();
375-
perms.add(SecurityConstants.ALL_PERMISSION);
376-
return new AccessControlContext(new ProtectionDomain[]{new ProtectionDomain(null, perms)});
377-
}
378366
StackAccessControlContextVisitor visitor = new StackAccessControlContextVisitor();
379367
JavaStackWalker.walkCurrentThread(KnownIntrinsics.readCallerStackPointer(), visitor);
380368
Target_java_security_AccessControlContext wrapper;

0 commit comments

Comments
 (0)