37 import java.util.Map; |
37 import java.util.Map; |
38 import java.util.Set; |
38 import java.util.Set; |
39 import java.util.List; |
39 import java.util.List; |
40 import java.util.WeakHashMap; |
40 import java.util.WeakHashMap; |
41 import sun.misc.ProxyGenerator; |
41 import sun.misc.ProxyGenerator; |
|
42 import sun.misc.VM; |
|
43 import sun.reflect.CallerSensitive; |
42 import sun.reflect.Reflection; |
44 import sun.reflect.Reflection; |
43 import sun.reflect.misc.ReflectUtil; |
45 import sun.reflect.misc.ReflectUtil; |
44 import sun.security.util.SecurityConstants; |
46 import sun.security.util.SecurityConstants; |
45 |
47 |
46 /** |
48 /** |
406 * parameters that may be passed to {@code getProxyClass} |
408 * parameters that may be passed to {@code getProxyClass} |
407 * are violated |
409 * are violated |
408 * @throws NullPointerException if the {@code interfaces} array |
410 * @throws NullPointerException if the {@code interfaces} array |
409 * argument or any of its elements are {@code null} |
411 * argument or any of its elements are {@code null} |
410 */ |
412 */ |
|
413 @CallerSensitive |
411 public static Class<?> getProxyClass(ClassLoader loader, |
414 public static Class<?> getProxyClass(ClassLoader loader, |
412 Class<?>... interfaces) |
415 Class<?>... interfaces) |
413 throws IllegalArgumentException |
416 throws IllegalArgumentException |
414 { |
417 { |
415 return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor |
|
416 } |
|
417 |
|
418 private static void checkProxyLoader(ClassLoader ccl, |
|
419 ClassLoader loader) |
|
420 { |
|
421 SecurityManager sm = System.getSecurityManager(); |
418 SecurityManager sm = System.getSecurityManager(); |
422 if (sm != null) { |
419 if (sm != null) { |
423 if (loader == null && ccl != null) { |
420 checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); |
424 if (!ProxyAccessHelper.allowNullLoader) { |
421 } |
425 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); |
422 |
426 } |
423 return getProxyClass0(loader, interfaces); |
427 } |
|
428 } |
|
429 } |
424 } |
430 |
425 |
431 /* |
426 /* |
432 * Generate a proxy class (caller-sensitive). |
427 * Check permissions required to create a Proxy class. |
433 * |
428 * |
434 * To define a proxy class, it performs the access checks as in |
429 * To define a proxy class, it performs the access checks as in |
435 * Class.forName (VM will invoke ClassLoader.checkPackageAccess): |
430 * Class.forName (VM will invoke ClassLoader.checkPackageAccess): |
436 * 1. "getClassLoader" permission check if loader == null |
431 * 1. "getClassLoader" permission check if loader == null |
437 * 2. checkPackageAccess on the interfaces it implements |
432 * 2. checkPackageAccess on the interfaces it implements |
444 * the defining loader of the interface. If the caller's class loader |
439 * the defining loader of the interface. If the caller's class loader |
445 * is not the same as the defining loader of the interface, the VM |
440 * is not the same as the defining loader of the interface, the VM |
446 * will throw IllegalAccessError when the generated proxy class is |
441 * will throw IllegalAccessError when the generated proxy class is |
447 * being defined via the defineClass0 method. |
442 * being defined via the defineClass0 method. |
448 */ |
443 */ |
|
444 private static void checkProxyAccess(Class<?> caller, |
|
445 ClassLoader loader, |
|
446 Class<?>... interfaces) |
|
447 { |
|
448 SecurityManager sm = System.getSecurityManager(); |
|
449 if (sm != null) { |
|
450 ClassLoader ccl = caller.getClassLoader(); |
|
451 if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) { |
|
452 if (!ProxyAccessHelper.allowNullLoader) { |
|
453 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); |
|
454 } |
|
455 } |
|
456 ReflectUtil.checkProxyPackageAccess(ccl, interfaces); |
|
457 } |
|
458 } |
|
459 |
|
460 /** |
|
461 * Generate a proxy class. Must call the checkProxyAccess method |
|
462 * to perform permission checks before calling this. |
|
463 */ |
449 private static Class<?> getProxyClass0(ClassLoader loader, |
464 private static Class<?> getProxyClass0(ClassLoader loader, |
450 Class<?>... interfaces) { |
465 Class<?>... interfaces) { |
451 SecurityManager sm = System.getSecurityManager(); |
|
452 if (sm != null) { |
|
453 final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller |
|
454 final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME); |
|
455 final ClassLoader ccl = caller.getClassLoader(); |
|
456 checkProxyLoader(ccl, loader); |
|
457 ReflectUtil.checkProxyPackageAccess(ccl, interfaces); |
|
458 } |
|
459 |
|
460 if (interfaces.length > 65535) { |
466 if (interfaces.length > 65535) { |
461 throw new IllegalArgumentException("interface limit exceeded"); |
467 throw new IllegalArgumentException("interface limit exceeded"); |
462 } |
468 } |
463 |
469 |
464 Class<?> proxyClass = null; |
470 Class<?> proxyClass = null; |
696 * @throws NullPointerException if the {@code interfaces} array |
702 * @throws NullPointerException if the {@code interfaces} array |
697 * argument or any of its elements are {@code null}, or |
703 * argument or any of its elements are {@code null}, or |
698 * if the invocation handler, {@code h}, is |
704 * if the invocation handler, {@code h}, is |
699 * {@code null} |
705 * {@code null} |
700 */ |
706 */ |
|
707 @CallerSensitive |
701 public static Object newProxyInstance(ClassLoader loader, |
708 public static Object newProxyInstance(ClassLoader loader, |
702 Class<?>[] interfaces, |
709 Class<?>[] interfaces, |
703 InvocationHandler h) |
710 InvocationHandler h) |
704 throws IllegalArgumentException |
711 throws IllegalArgumentException |
705 { |
712 { |
706 if (h == null) { |
713 if (h == null) { |
707 throw new NullPointerException(); |
714 throw new NullPointerException(); |
708 } |
715 } |
709 |
716 |
|
717 final SecurityManager sm = System.getSecurityManager(); |
|
718 if (sm != null) { |
|
719 checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); |
|
720 } |
|
721 |
710 /* |
722 /* |
711 * Look up or generate the designated proxy class. |
723 * Look up or generate the designated proxy class. |
712 */ |
724 */ |
713 Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor |
725 Class<?> cl = getProxyClass0(loader, interfaces); |
714 |
726 |
715 /* |
727 /* |
716 * Invoke its constructor with the designated invocation handler. |
728 * Invoke its constructor with the designated invocation handler. |
717 */ |
729 */ |
718 try { |
730 try { |
719 final Constructor<?> cons = cl.getConstructor(constructorParams); |
731 final Constructor<?> cons = cl.getConstructor(constructorParams); |
720 final InvocationHandler ih = h; |
732 final InvocationHandler ih = h; |
721 SecurityManager sm = System.getSecurityManager(); |
|
722 if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { |
733 if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { |
723 // create proxy instance with doPrivilege as the proxy class may |
734 // create proxy instance with doPrivilege as the proxy class may |
724 // implement non-public interfaces that requires a special permission |
735 // implement non-public interfaces that requires a special permission |
725 return AccessController.doPrivileged(new PrivilegedAction<Object>() { |
736 return AccessController.doPrivileged(new PrivilegedAction<Object>() { |
726 public Object run() { |
737 public Object run() { |