From 6dcb4cbb44b982da85376501910a277fcdedfcfa Mon Sep 17 00:00:00 2001 From: Scott Marlow Date: Wed, 21 Sep 2022 11:49:31 -0400 Subject: [PATCH] HHH-15514 EntityTestCase Test failures with Hibernate ORM when run under security manager Signed-off-by: Scott Marlow --- .../internal/bytebuddy/ByteBuddyState.java | 92 +++++++++---------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java index d19949699ce8..e66df715cd20 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java @@ -59,6 +59,8 @@ public final class ByteBuddyState { private static final boolean DEBUG = false; private final ByteBuddy byteBuddy; + private final ForDeclaredMethods getDeclaredMethodMemberSubstitution; + private final ForDeclaredMethods getMethodMemberSubstitution; private static final ProxyDefinitionHelpers proxyDefinitionHelpers = new ProxyDefinitionHelpers(); @@ -84,9 +86,13 @@ public final class ByteBuddyState { this.basicProxyCache = new TypeCache( TypeCache.Sort.WEAK ); if ( SystemSecurityManager.isSecurityManagerEnabled() ) { - this.classRewriter = new SecurityManagerClassRewriter(); + this.getDeclaredMethodMemberSubstitution = getDeclaredMethodMemberSubstitution(); + this.getMethodMemberSubstitution = getMethodMemberSubstitution(); + this.classRewriter = null; } else { + this.getDeclaredMethodMemberSubstitution = null; + this.getMethodMemberSubstitution = null; this.classRewriter = new StandardClassRewriter(); } } @@ -199,7 +205,13 @@ private Unloaded make(DynamicType.Builder builder) { } private Unloaded make(TypePool typePool, DynamicType.Builder builder) { - classRewriter.installReflectionMethodVisitors( builder ); + if ( SystemSecurityManager.isSecurityManagerEnabled() ) { + builder = builder.visit( getDeclaredMethodMemberSubstitution ); + builder = builder.visit( getMethodMemberSubstitution ); + } + else { + classRewriter.installReflectionMethodVisitors( builder ); + } Unloaded unloadedClass; if ( typePool != null ) { @@ -217,12 +229,39 @@ private Unloaded make(TypePool typePool, DynamicType.Builder builder) { LOG.warn( "Unable to save generated class %1$s", unloadedClass.getTypeDescription().getName(), e ); } } - - classRewriter.registerAuthorizedClass( unloadedClass ); + if ( SystemSecurityManager.isSecurityManagerEnabled() ) { + // we authorize the proxy class to access the method lookup dispatcher + HibernateMethodLookupDispatcher.registerAuthorizedClass( unloadedClass.getTypeDescription().getName() ); + } + else { + classRewriter.registerAuthorizedClass( unloadedClass ); + } return unloadedClass; } + private static ForDeclaredMethods getDeclaredMethodMemberSubstitution() { + // this should only be called if the security manager is enabled, thus the privileged calls + return MemberSubstitution.relaxed() + .method( ElementMatchers.is( AccessController.doPrivileged( new GetDeclaredMethodAction( Class.class, + "getDeclaredMethod", String.class, Class[].class ) ) ) ) + .replaceWith( + AccessController.doPrivileged( new GetDeclaredMethodAction( HibernateMethodLookupDispatcher.class, + "getDeclaredMethod", Class.class, String.class, Class[].class ) ) ) + .on( ElementMatchers.isTypeInitializer() ); + } + + private static ForDeclaredMethods getMethodMemberSubstitution() { + // this should only be called if the security manager is enabled, thus the privileged calls + return MemberSubstitution.relaxed() + .method( ElementMatchers.is( AccessController.doPrivileged( new GetDeclaredMethodAction( Class.class, + "getMethod", String.class, Class[].class ) ) ) ) + .replaceWith( + AccessController.doPrivileged( new GetDeclaredMethodAction( HibernateMethodLookupDispatcher.class, + "getMethod", Class.class, String.class, Class[].class ) ) ) + .on( ElementMatchers.isTypeInitializer() ); + } + private static class GetDeclaredMethodAction implements PrivilegedAction { private final Class clazz; private final String methodName; @@ -323,51 +362,6 @@ private interface ClassRewriter { void registerAuthorizedClass(Unloaded unloadedClass); } - private static class SecurityManagerClassRewriter implements ClassRewriter { - - private final ForDeclaredMethods getDeclaredMethodMemberSubstitution; - private final ForDeclaredMethods getMethodMemberSubstitution; - - private SecurityManagerClassRewriter() { - this.getDeclaredMethodMemberSubstitution = getDeclaredMethodMemberSubstitution(); - this.getMethodMemberSubstitution = getMethodMemberSubstitution(); - } - - @Override - public void installReflectionMethodVisitors(DynamicType.Builder builder) { - builder = builder.visit( getDeclaredMethodMemberSubstitution ); - builder = builder.visit( getMethodMemberSubstitution ); - } - - @Override - public void registerAuthorizedClass(Unloaded unloadedClass) { - // we authorize the proxy class to access the method lookup dispatcher - HibernateMethodLookupDispatcher.registerAuthorizedClass( unloadedClass.getTypeDescription().getName() ); - } - - private static ForDeclaredMethods getDeclaredMethodMemberSubstitution() { - // this should only be called if the security manager is enabled, thus the privileged calls - return MemberSubstitution.relaxed() - .method( ElementMatchers.is( AccessController.doPrivileged( new GetDeclaredMethodAction( Class.class, - "getDeclaredMethod", String.class, Class[].class ) ) ) ) - .replaceWith( - AccessController.doPrivileged( new GetDeclaredMethodAction( HibernateMethodLookupDispatcher.class, - "getDeclaredMethod", Class.class, String.class, Class[].class ) ) ) - .on( ElementMatchers.isTypeInitializer() ); - } - - private static ForDeclaredMethods getMethodMemberSubstitution() { - // this should only be called if the security manager is enabled, thus the privileged calls - return MemberSubstitution.relaxed() - .method( ElementMatchers.is( AccessController.doPrivileged( new GetDeclaredMethodAction( Class.class, - "getMethod", String.class, Class[].class ) ) ) ) - .replaceWith( - AccessController.doPrivileged( new GetDeclaredMethodAction( HibernateMethodLookupDispatcher.class, - "getMethod", Class.class, String.class, Class[].class ) ) ) - .on( ElementMatchers.isTypeInitializer() ); - } - } - private static class StandardClassRewriter implements ClassRewriter { @Override