diff -r 13a63d4a3f8d -r 840ad2a9015a src/java.base/share/classes/java/security/AccessController.java --- a/src/java.base/share/classes/java/security/AccessController.java Wed Sep 12 10:27:03 2018 -0700 +++ b/src/java.base/share/classes/java/security/AccessController.java Wed Sep 19 14:47:37 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,9 +25,13 @@ package java.security; +import java.lang.ref.Reference; import sun.security.util.Debug; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.DontInline; +import jdk.internal.vm.annotation.ForceInline; +import jdk.internal.vm.annotation.ReservedStackAccess; /** *

The AccessController class is used for access control operations @@ -296,7 +300,10 @@ */ @CallerSensitive - public static native T doPrivileged(PrivilegedAction action); + public static T doPrivileged(PrivilegedAction action) + { + return executePrivileged(action, null, Reflection.getCallerClass()); + } /** * Performs the specified {@code PrivilegedAction} with privileges @@ -369,8 +376,13 @@ * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) */ @CallerSensitive - public static native T doPrivileged(PrivilegedAction action, - AccessControlContext context); + public static T doPrivileged(PrivilegedAction action, + AccessControlContext context) + { + Class caller = Reflection.getCallerClass(); + context = checkContext(context, caller); + return executePrivileged(action, context, caller); + } /** @@ -524,10 +536,20 @@ * @see java.security.DomainCombiner */ @CallerSensitive - public static native T + public static T doPrivileged(PrivilegedExceptionAction action) - throws PrivilegedActionException; - + throws PrivilegedActionException + { + AccessControlContext context = null; + Class caller = Reflection.getCallerClass(); + try { + return executePrivileged(action, context, caller); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw wrapException(e); + } + } /** * Performs the specified {@code PrivilegedExceptionAction} with @@ -603,6 +625,7 @@ private static class AccHolder { // An AccessControlContext with no granted permissions. // Only initialized on demand when getInnocuousAcc() is called. +// TODO: set isAuthorized static final AccessControlContext innocuousAcc = new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, null) }); @@ -611,6 +634,8 @@ return AccHolder.innocuousAcc; } + private static native ProtectionDomain getProtectionDomain(final Class caller); + private static ProtectionDomain getCallerPD(final Class caller) { ProtectionDomain callerPd = doPrivileged (new PrivilegedAction<>() { @@ -659,11 +684,86 @@ * @see #doPrivileged(PrivilegedAction,AccessControlContext) */ @CallerSensitive - public static native T + public static T doPrivileged(PrivilegedExceptionAction action, AccessControlContext context) - throws PrivilegedActionException; + throws PrivilegedActionException + { + Class caller = Reflection.getCallerClass(); + context = checkContext(context, caller); + try { + return executePrivileged(action, context, caller); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw wrapException(e); + } + } + + private static AccessControlContext checkContext(AccessControlContext context, + Class caller) + { + // check if caller is authorized to create context + if (context != null && !context.isAuthorized() && + context != getInnocuousAcc() && + System.getSecurityManager() != null) + { + ProtectionDomain callerPD = getProtectionDomain(caller); + if (callerPD != null && !callerPD.impliesCreateAccessControlContext()) { + return getInnocuousAcc(); + } + } + return context; + } + @ForceInline + private static T + executePrivileged(PrivilegedAction action, + AccessControlContext context, + Class caller) + { +{ +AccessControlContext ctx = getStackAccessControlContext(); +assert ctx == null || ctx.isPrivileged(); +} + T result = action.run(); +{ +AccessControlContext ctx = getStackAccessControlContext(); +assert ctx == null || ctx.isPrivileged(); +} + Reference.reachabilityFence(context); + Reference.reachabilityFence(caller); + Reference.reachabilityFence(action); // FIXME: for debugging + return result; + } + + @ForceInline + private static T + executePrivileged(PrivilegedExceptionAction action, + AccessControlContext context, + Class caller) + throws Exception + { +{ +AccessControlContext ctx = getStackAccessControlContext(); +assert ctx == null || ctx.isPrivileged(); +} + T result = action.run(); +{ +AccessControlContext ctx = getStackAccessControlContext(); +assert ctx == null || ctx.isPrivileged(); +} + Reference.reachabilityFence(context); + Reference.reachabilityFence(caller); + Reference.reachabilityFence(action); // FIXME: for debugging + return result; + } + + @ForceInline + @ReservedStackAccess + private static PrivilegedActionException wrapException(Exception e) { + return new PrivilegedActionException(e); + } /** * Performs the specified {@code PrivilegedExceptionAction} with