8214583: AccessController.getContext may return wrong value after JDK-8212605
Reviewed-by: mchung, redestad
This commit is contained in:
parent
ad47b4c4cc
commit
57dc039131
src
hotspot/share
java.base/share
test/jdk
@ -625,6 +625,15 @@ JVM_GetMethodParameters(JNIEnv *env, jobject method);
|
||||
JNIEXPORT jobject JNICALL
|
||||
JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls);
|
||||
|
||||
/*
|
||||
* Ensure that code doing a stackwalk and using javaVFrame::locals() to
|
||||
* get the value will see a materialized value and not a scalar-replaced
|
||||
* null value.
|
||||
*/
|
||||
#define JVM_EnsureMaterializedForStackWalk(env, value) \
|
||||
do {} while(0) // Nothing to do. The fact that the value escaped
|
||||
// through a native method is enough.
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls);
|
||||
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/jfieldIDWorkaround.hpp"
|
||||
@ -1245,8 +1246,12 @@ JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
|
||||
javaVFrame *priv = vfst.asJavaVFrame(); // executePrivileged
|
||||
|
||||
StackValueCollection* locals = priv->locals();
|
||||
privileged_context = locals->obj_at(1);
|
||||
Handle caller = locals->obj_at(2);
|
||||
StackValue* ctx_sv = locals->at(1); // AccessControlContext context
|
||||
StackValue* clr_sv = locals->at(2); // Class<?> caller
|
||||
assert(!ctx_sv->obj_is_scalar_replaced(), "found scalar-replaced object");
|
||||
assert(!clr_sv->obj_is_scalar_replaced(), "found scalar-replaced object");
|
||||
privileged_context = ctx_sv->get_obj();
|
||||
Handle caller = clr_sv->get_obj();
|
||||
|
||||
Klass *caller_klass = java_lang_Class::as_Klass(caller());
|
||||
protection_domain = caller_klass->protection_domain();
|
||||
|
@ -709,6 +709,13 @@ public final class AccessController {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value needs to be physically located in the frame, so that it
|
||||
* can be found by a stack walk.
|
||||
*/
|
||||
@Hidden
|
||||
private static native void ensureMaterializedForStackWalk(Object o);
|
||||
|
||||
/**
|
||||
* Sanity check that the caller context is indeed privileged.
|
||||
*
|
||||
@ -734,6 +741,11 @@ public final class AccessController {
|
||||
AccessControlContext context,
|
||||
Class<?> caller)
|
||||
{
|
||||
// Ensure context has a physical value in the frame
|
||||
if (context != null) {
|
||||
ensureMaterializedForStackWalk(context);
|
||||
}
|
||||
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
T result = action.run();
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
@ -742,7 +754,6 @@ public final class AccessController {
|
||||
// retrieved by getStackAccessControlContext().
|
||||
Reference.reachabilityFence(context);
|
||||
Reference.reachabilityFence(caller);
|
||||
Reference.reachabilityFence(action);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -761,6 +772,11 @@ public final class AccessController {
|
||||
Class<?> caller)
|
||||
throws Exception
|
||||
{
|
||||
// Ensure context has a physical value in the frame
|
||||
if (context != null) {
|
||||
ensureMaterializedForStackWalk(context);
|
||||
}
|
||||
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
T result = action.run();
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
@ -769,7 +785,6 @@ public final class AccessController {
|
||||
// retrieved by getStackAccessControlContext().
|
||||
Reference.reachabilityFence(context);
|
||||
Reference.reachabilityFence(caller);
|
||||
Reference.reachabilityFence(action);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -59,3 +59,12 @@ Java_java_security_AccessController_getInheritedAccessControlContext(
|
||||
{
|
||||
return JVM_GetInheritedAccessControlContext(env, this);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_java_security_AccessController_ensureMaterializedForStackWalk(
|
||||
JNIEnv *env,
|
||||
jclass cls,
|
||||
jobject value)
|
||||
{
|
||||
JVM_EnsureMaterializedForStackWalk(env, value);
|
||||
}
|
||||
|
68
test/jdk/java/security/AccessController/DoPriv.java
Normal file
68
test/jdk/java/security/AccessController/DoPriv.java
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8214583
|
||||
* @summary Check that getContext works after JIT compiler escape analysis.
|
||||
*/
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.DomainCombiner;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class DoPriv {
|
||||
|
||||
static void go(final DomainCombiner dc0, final AccessControlContext co, final int index) throws Exception {
|
||||
final AccessControlContext ci = new AccessControlContext(co, dc0);
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Integer>)() -> {
|
||||
AccessControlContext c1 = AccessController.getContext();
|
||||
DomainCombiner dc = c1.getDomainCombiner();
|
||||
if (dc != dc0 || dc == null) {
|
||||
throw new AssertionError("iteration " + index + " " + dc + " != " + dc0);
|
||||
}
|
||||
return 0;
|
||||
}, ci);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final DomainCombiner dc0 = new DomainCombiner() {
|
||||
public ProtectionDomain[] combine(ProtectionDomain[] currentDomains,
|
||||
ProtectionDomain[] assignedDomains) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
final AccessControlContext co = AccessController.getContext();
|
||||
|
||||
for (int i = 0; i < 500_000; ++i) {
|
||||
go(dc0, co, i);
|
||||
}
|
||||
}
|
||||
}
|
57
test/jdk/javax/security/auth/Subject/DoAs.java
Normal file
57
test/jdk/javax/security/auth/Subject/DoAs.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8214583
|
||||
* @summary Check that getSubject works after JIT compiler escape analysis.
|
||||
*/
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
public class DoAs {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final Set<String> outer = new HashSet<>(Arrays.asList("Outer"));
|
||||
final Subject subject = new Subject(true, Collections.EMPTY_SET, outer, Collections.EMPTY_SET);
|
||||
|
||||
for (int i = 0; i < 100_000; ++i) {
|
||||
final int index = i;
|
||||
Subject.doAs(subject, (PrivilegedExceptionAction<Integer>)() -> {
|
||||
AccessControlContext c1 = AccessController.getContext();
|
||||
Subject s = Subject.getSubject(c1);
|
||||
if (s != subject) {
|
||||
throw new AssertionError("outer Oops! " + "iteration " + index + " " + s + " != " + subject);
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user