diff options
author | nickl- <github@jigsoft.co.za> | 2017-10-27 07:55:08 +0200 |
---|---|---|
committer | nickl- <github@jigsoft.co.za> | 2017-11-12 23:49:21 +0200 |
commit | 4e81640868096321627deb064b3f63e48c9a9705 (patch) | |
tree | 63accf921af551eece5d2e128e7dad021970fc71 | |
parent | 7d5eb53d1241ca8bdd4624a9f5a61834bf4dc053 (diff) | |
download | javassist-4e81640868096321627deb064b3f63e48c9a9705.tar.gz javassist-4e81640868096321627deb064b3f63e48c9a9705.zip |
Add caller class checking.
The only thing remotely inforceable is caller class checking. You cannot
bypass an exception with setAccesible. Oracle went and removed
Reflection.getCallerClass() completely in favour of StackWalker. At least
we can share the SecurityManage ClassContext, SecurityActions seems the
appropriate venue for our stack trace peek to support the older versions
-rw-r--r-- | src/main/javassist/util/proxy/DefineClassHelper.java | 15 | ||||
-rwxr-xr-x | src/main/javassist/util/proxy/SecurityActions.java | 9 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/main/javassist/util/proxy/DefineClassHelper.java b/src/main/javassist/util/proxy/DefineClassHelper.java index 208a6f0c..b47f3b59 100644 --- a/src/main/javassist/util/proxy/DefineClassHelper.java +++ b/src/main/javassist/util/proxy/DefineClassHelper.java @@ -63,9 +63,14 @@ public class DefineClassHelper } } } + private final StackWalker stack = StackWalker + .getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); private final ReferencedUnsafe sunMiscUnsafe = getReferencedUnsafe(); private final ReferencedUnsafe getReferencedUnsafe() { + if (null != SecuredPrivileged.JAVA_9 + && stack.getCallerClass() != this.getClass()) + throw new IllegalAccessError("Access denied for caller."); try { Object usf = SecurityActions.getSunMiscUnsafeAnonymously(); MethodHandle meth = SecurityActions.getMethodHandle(ClassLoader.class, @@ -91,9 +96,13 @@ public class DefineClassHelper } }, JAVA_7 { + private final SecurityActions stack = SecurityActions.stack; private final MethodHandle defineClass = getDefineClassMethodHandle(); private final MethodHandle getDefineClassMethodHandle() { + if (null != SecuredPrivileged.JAVA_7 + && stack.getCallerClass() != this.getClass()) + throw new IllegalAccessError("Access denied for caller."); try { return SecurityActions.getMethodHandle(ClassLoader.class, "defineClass", new Class[] { @@ -109,6 +118,8 @@ public class DefineClassHelper protected Class<?> defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) throws ClassFormatError { + if (stack.getCallerClass() != DefineClassHelper.class) + throw new IllegalAccessError("Access denied for caller."); try { return (Class<?>) defineClass.invokeWithArguments( loader, name, b, off, len, protectionDomain); @@ -121,7 +132,11 @@ public class DefineClassHelper }, JAVA_OTHER { private final Method defineClass = getDefineClassMethod(); + private final SecurityActions stack = SecurityActions.stack; private final Method getDefineClassMethod() { + if (null != SecuredPrivileged.JAVA_OTHER + && stack.getCallerClass() != this.getClass()) + throw new IllegalAccessError("Access denied for caller."); try { return SecurityActions.getDeclaredMethod(ClassLoader.class, "defineClass", new Class[] { diff --git a/src/main/javassist/util/proxy/SecurityActions.java b/src/main/javassist/util/proxy/SecurityActions.java index ce0b5fa6..4bc10a8a 100755 --- a/src/main/javassist/util/proxy/SecurityActions.java +++ b/src/main/javassist/util/proxy/SecurityActions.java @@ -25,8 +25,15 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +class SecurityActions extends SecurityManager +{ + public static final SecurityActions stack = new SecurityActions(); + public Class<?> getCallerClass() + { + return getClassContext()[2]; + } + -class SecurityActions { static Method[] getDeclaredMethods(final Class<?> clazz) { if (System.getSecurityManager() == null) |