From 56d9abae14a71f1e9b31cb76cde38ad364b43d02 Mon Sep 17 00:00:00 2001
From: maminjie <maminjie1@huawei.com>
Date: Sat, 19 Sep 2020 12:39:06 +0800
Subject: [PATCH] Fix privilege escalation when running under the security
 manager (CVE-2017-7536)

refers to https://github.com/hibernate/hibernate-validator/commit/0ed45f37c4680998167179e631113a2c9cb5d113
---
 documentation/src/main/asciidoc/ch01.asciidoc |  2 ++
 .../HibernateValidatorPermission.java         | 29 +++++++++++++++++++
 .../internal/engine/ValidatorImpl.java        |  6 ++++
 .../privilegedactions/GetDeclaredField.java   |  1 -
 tck-runner/src/test/resources/test.policy     |  5 ++++
 5 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java

diff --git a/documentation/src/main/asciidoc/ch01.asciidoc b/documentation/src/main/asciidoc/ch01.asciidoc
index 59b5ef3..67f7598 100644
--- a/documentation/src/main/asciidoc/ch01.asciidoc
+++ b/documentation/src/main/asciidoc/ch01.asciidoc
@@ -105,6 +105,8 @@ grant codeBase "file:path/to/hibernate-validator-{hvVersion}.jar" {
     permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
     permission java.lang.RuntimePermission "accessDeclaredMembers";
 
+    permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers";
+
     // Only needed when working with XML descriptors (validation.xml or XML constraint mappings)
     permission java.util.PropertyPermission "mapAnyUriToUri", "read";
 };
diff --git a/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java b/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java
new file mode 100644
index 0000000..fa90ed1
--- /dev/null
+++ b/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java
@@ -0,0 +1,29 @@
+/*
+ * Hibernate Validator, declare and validate application constraints
+ *
+ * License: Apache License, Version 2.0
+ * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
+ */
+package org.hibernate.validator;
+
+import java.security.BasicPermission;
+
+/**
+ * Our specific implementation of {@link BasicPermission} as we cannot define additional {@link RuntimePermission}.
+ * <p>
+ * {@code HibernateValidatorPermission} is thread-safe and immutable.
+ *
+ * @author Guillaume Smet
+ */
+public class HibernateValidatorPermission extends BasicPermission {
+
+   public static final HibernateValidatorPermission ACCESS_PRIVATE_MEMBERS = new HibernateValidatorPermission( "accessPrivateMembers" );
+
+   public HibernateValidatorPermission(String name) {
+       super( name );
+   }
+
+   public HibernateValidatorPermission(String name, String actions) {
+       super( name, actions );
+   }
+}
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java
index ced6804..d4e160c 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java
@@ -35,6 +35,7 @@
 import javax.validation.groups.Default;
 import javax.validation.metadata.BeanDescriptor;
 
+import org.hibernate.validator.HibernateValidatorPermission;
 import org.hibernate.validator.internal.engine.ValidationContext.ValidationContextBuilder;
 import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
 import org.hibernate.validator.internal.engine.groups.Group;
@@ -1734,6 +1735,11 @@ private Member getAccessible(Member original) {
 		if ( member != null ) {
 			return member;
 		}
+    
+        SecurityManager sm = System.getSecurityManager();
+        if ( sm != null ) {
+            sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS );
+        }
 
 		Class<?> clazz = original.getDeclaringClass();
 
diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java
index 2169571..5bc6285 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java
@@ -31,7 +31,6 @@ private GetDeclaredField(Class<?> clazz, String fieldName) {
 	public Field run() {
 		try {
 			final Field field = clazz.getDeclaredField( fieldName );
-			field.setAccessible( true );
 			return field;
 		}
 		catch ( NoSuchFieldException e ) {
diff --git a/tck-runner/src/test/resources/test.policy b/tck-runner/src/test/resources/test.policy
index 7c7b72e..ac9cb25 100644
--- a/tck-runner/src/test/resources/test.policy
+++ b/tck-runner/src/test/resources/test.policy
@@ -27,6 +27,8 @@ grant codeBase "file:${localRepository}/org/hibernate/hibernate-validator/${proj
     permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
     permission java.lang.RuntimePermission "accessDeclaredMembers";
 
+    permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers";
+
     // JAXB
     permission java.util.PropertyPermission "mapAnyUriToUri", "read";
 };
@@ -37,6 +39,8 @@ grant codeBase "file:${basedir}/../engine/target/hibernate-validator-${project.v
     permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
     permission java.lang.RuntimePermission "accessDeclaredMembers";
 
+    permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers";
+
     // JAXB
     permission java.util.PropertyPermission "mapAnyUriToUri", "read";
 };
@@ -75,6 +79,7 @@ grant codeBase "file:${project.build.directory}/classes" {
     permission java.util.PropertyPermission "validation.provider", "read";
     permission java.io.FilePermission "${localRepository}/org/hibernate/beanvalidation/tck/beanvalidation-tck-tests/${tck.version}/beanvalidation-tck-tests-${tck.version}.jar", "read";
     permission java.util.PropertyPermission "user.language", "write";
+    permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers";
 };
 
 grant codeBase "file:${project.build.directory}/test-classes" {
-- 
2.23.0

