# HG changeset patch
# User jrose
# Date 1297757813 28800
# Node ID e1ba54c4360948b4a4a3f78e9c900b9e08917b60
# Parent 3b2ac15dfc1607cbc792f1b557a98e3e2a2ed6db
7014755: JSR 292 member lookup interaction with security manager
Summary: add security manager interactions for Lookup methods
Reviewed-by: twisti
diff -r 3b2ac15dfc16 -r e1ba54c43609 jdk/src/share/classes/java/dyn/MethodHandles.java
--- a/jdk/src/share/classes/java/dyn/MethodHandles.java Tue Feb 15 00:16:50 2011 -0800
+++ b/jdk/src/share/classes/java/dyn/MethodHandles.java Tue Feb 15 00:16:53 2011 -0800
@@ -198,6 +198,10 @@
* the lookup can still succeed.
* For example, lookups for {@code MethodHandle.invokeExact} and
* {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
+ *
If there is a security manager installed, it can forbid the lookup
+ * on various grounds (see below).
+ * By contrast, the {@code ldc} instruction is not subject to
+ * security manager checks.
*
*
* Access checking
@@ -255,6 +259,18 @@
* which can transform a lookup on {@code C.E} into one on any of those other
* classes, without special elevation of privilege.
*
+ * Although bytecode instructions can only refer to classes in
+ * a related class loader, this API can search for methods in any
+ * class, as long as a reference to its {@code Class} object is
+ * available. Such cross-loader references are also possible with the
+ * Core Reflection API, and are impossible to bytecode instructions
+ * such as {@code invokestatic} or {@code getfield}.
+ * There is a {@linkplain java.lang.SecurityManager security manager API}
+ * to allow applications to check such cross-loader references.
+ * These checks apply to both the {@code MethodHandles.Lookup} API
+ * and the Core Reflection API
+ * (as found on {@link java.lang.Class Class}).
+ *
* Access checks only apply to named and reflected methods,
* constructors, and fields.
* Other method handle creation methods, such as
@@ -262,6 +278,41 @@
* do not require any access checks, and are done
* with static methods of {@link MethodHandles},
* independently of any {@code Lookup} object.
+ *
+ *
Security manager interactions
+ *
+ * If a security manager is present, member lookups are subject to
+ * additional checks.
+ * From one to four calls are made to the security manager.
+ * Any of these calls can refuse access by throwing a
+ * {@link java.lang.SecurityException SecurityException}.
+ * Define {@code smgr} as the security manager,
+ * {@code refc} as the containing class in which the member
+ * is being sought, and {@code defc} as the class in which the
+ * member is actually defined.
+ * The calls are made according to the following rules:
+ *
+ * - In all cases, {@link SecurityManager#checkMemberAccess
+ * smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
+ *
- If the class loader of the lookup class is not
+ * the same as or an ancestor of the class loader of {@code refc},
+ * then {@link SecurityManager#checkPackageAccess
+ * smgr.checkPackageAccess(refcPkg)} is called,
+ * where {@code refcPkg} is the package of {@code refc}.
+ *
- If the retrieved member is not public,
+ * {@link SecurityManager#checkMemberAccess
+ * smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
+ * (Note that {@code defc} might be the same as {@code refc}.)
+ *
- If the retrieved member is not public,
+ * and if {@code defc} and {@code refc} are in different class loaders,
+ * and if the class loader of the lookup class is not
+ * the same as or an ancestor of the class loader of {@code defc},
+ * then {@link SecurityManager#checkPackageAccess
+ * smgr.checkPackageAccess(defcPkg)} is called,
+ * where {@code defcPkg} is the package of {@code defc}.
+ *
+ * In all cases, the requesting class presented to the security
+ * manager will be the lookup class from the current {@code Lookup} object.
*/
public static final
class Lookup {
@@ -518,6 +569,8 @@
* @return the desired method handle
* @throws NoSuchMethodException if the method does not exist
* @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public
@@ -558,6 +611,8 @@
* @return the desired method handle
* @throws NoSuchMethodException if the method does not exist
* @throws IllegalAccessException if access checking fails, or if the method is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle findVirtual(Class> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
@@ -587,6 +642,8 @@
* @return the desired method handle
* @throws NoSuchMethodException if the constructor does not exist
* @throws IllegalAccessException if access checking fails
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle findConstructor(Class> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
@@ -642,6 +699,8 @@
* @return the desired method handle
* @throws NoSuchMethodException if the method does not exist
* @throws IllegalAccessException if access checking fails
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle findSpecial(Class> refc, String name, MethodType type,
@@ -666,6 +725,8 @@
* @return a method handle which can load values from the field
* @throws NoSuchFieldException if the field does not exist
* @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle findGetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
@@ -685,6 +746,8 @@
* @return a method handle which can store values into the field
* @throws NoSuchFieldException if the field does not exist
* @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle findSetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
@@ -703,6 +766,8 @@
* @return a method handle which can load values from the field
* @throws NoSuchFieldException if the field does not exist
* @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle findStaticGetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
@@ -721,6 +786,8 @@
* @return a method handle which can store values into the field
* @throws NoSuchFieldException if the field does not exist
* @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle findStaticSetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
@@ -764,6 +831,8 @@
* @return the desired method handle
* @throws NoSuchMethodException if the method does not exist
* @throws IllegalAccessException if access checking fails
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
* @throws NullPointerException if any argument is null
*/
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
diff -r 3b2ac15dfc16 -r e1ba54c43609 jdk/src/share/classes/java/dyn/package-info.java
--- a/jdk/src/share/classes/java/dyn/package-info.java Tue Feb 15 00:16:50 2011 -0800
+++ b/jdk/src/share/classes/java/dyn/package-info.java Tue Feb 15 00:16:53 2011 -0800
@@ -127,6 +127,9 @@
* type is created. Any classes mentioned in this reification will be loaded if necessary,
* but not initialized, and access checking and error reporting performed as usual.
*
+ * Unlike the reflective {@code Lookup} API, there are no security manager calls made
+ * when these constants are resolved.
+ *
* The method handle itself will have a type and behavior determined by the subtag as follows:
*
*