Skip to content

Commit 72c638d

Browse files
committed
HV-1280 Use privileged actions to manipulate the class loader
1 parent 27370d3 commit 72c638d

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java

+16-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.io.IOException;
1010
import java.io.InputStream;
1111
import java.security.AccessController;
12+
import java.security.PrivilegedAction;
1213
import java.security.PrivilegedExceptionAction;
1314
import java.util.EnumSet;
1415
import java.util.HashMap;
@@ -27,7 +28,9 @@
2728

2829
import org.hibernate.validator.internal.util.logging.Log;
2930
import org.hibernate.validator.internal.util.logging.LoggerFactory;
31+
import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader;
3032
import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext;
33+
import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader;
3134
import org.hibernate.validator.internal.util.privilegedactions.Unmarshal;
3235

3336
/**
@@ -69,10 +72,10 @@ public final BootstrapConfiguration parseValidationXml() {
6972
return BootstrapConfigurationImpl.getDefaultBootstrapConfiguration();
7073
}
7174

72-
ClassLoader previousTccl = Thread.currentThread().getContextClassLoader();
75+
ClassLoader previousTccl = run( GetClassLoader.fromContext() );
7376

7477
try {
75-
Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() );
78+
run( SetContextClassLoader.action( ValidationXmlParser.class.getClassLoader() ) );
7679

7780
// HV-970 The parser helper is only loaded if there actually is a validation.xml file;
7881
// this avoids accessing javax.xml.stream.* (which does not exist on Android) when not actually
@@ -87,7 +90,7 @@ public final BootstrapConfiguration parseValidationXml() {
8790
return createBootstrapConfiguration( validationConfig );
8891
}
8992
finally {
90-
Thread.currentThread().setContextClassLoader( previousTccl );
93+
run( SetContextClassLoader.action( previousTccl ) );
9194
closeStream( inputStream );
9295
}
9396
}
@@ -196,6 +199,16 @@ private EnumSet<ExecutableType> getValidatedExecutableTypes(DefaultValidatedExec
196199
return executableTypes;
197200
}
198201

202+
/**
203+
* Runs the given privileged action, using a privileged block if required.
204+
* <p>
205+
* <b>NOTE:</b> This must never be changed into a publicly available method to avoid execution of arbitrary
206+
* privileged actions within HV's protection domain.
207+
*/
208+
private static <T> T run(PrivilegedAction<T> action) {
209+
return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run();
210+
}
211+
199212
/**
200213
* Runs the given privileged action, using a privileged block if required.
201214
* <p>

engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java

+16-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.io.InputStream;
1212
import java.lang.annotation.Annotation;
1313
import java.security.AccessController;
14+
import java.security.PrivilegedAction;
1415
import java.security.PrivilegedExceptionAction;
1516
import java.util.Collections;
1617
import java.util.List;
@@ -37,7 +38,9 @@
3738
import org.hibernate.validator.internal.metadata.raw.ConstrainedType;
3839
import org.hibernate.validator.internal.util.logging.Log;
3940
import org.hibernate.validator.internal.util.logging.LoggerFactory;
41+
import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader;
4042
import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext;
43+
import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader;
4144
import org.hibernate.validator.internal.util.privilegedactions.Unmarshal;
4245

4346
import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList;
@@ -173,10 +176,10 @@ public final void parse(Set<InputStream> mappingStreams) {
173176
}
174177

175178
private ConstraintMappingsType unmarshal(JAXBContext jc, InputStream in) throws JAXBException {
176-
ClassLoader previousTccl = Thread.currentThread().getContextClassLoader();
179+
ClassLoader previousTccl = run( GetClassLoader.fromContext() );
177180

178181
try {
179-
Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() );
182+
run( SetContextClassLoader.action( XmlMappingParser.class.getClassLoader() ) );
180183

181184
XMLEventReader xmlEventReader = xmlParserHelper.createXmlEventReader( "constraint mapping file", new CloseIgnoringInputStream( in ) );
182185
String schemaVersion = xmlParserHelper.getSchemaVersion( "constraint mapping file", xmlEventReader );
@@ -189,7 +192,7 @@ private ConstraintMappingsType unmarshal(JAXBContext jc, InputStream in) throws
189192
return getValidationConfig( xmlEventReader, unmarshaller );
190193
}
191194
finally {
192-
Thread.currentThread().setContextClassLoader( previousTccl );
195+
run( SetContextClassLoader.action( previousTccl ) );
193196
}
194197
}
195198

@@ -382,6 +385,16 @@ private String getSchemaResourceName(String schemaVersion) {
382385
return schemaResource;
383386
}
384387

388+
/**
389+
* Runs the given privileged action, using a privileged block if required.
390+
* <p>
391+
* <b>NOTE:</b> This must never be changed into a publicly available method to avoid execution of arbitrary
392+
* privileged actions within HV's protection domain.
393+
*/
394+
private static <T> T run(PrivilegedAction<T> action) {
395+
return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run();
396+
}
397+
385398
/**
386399
* Runs the given privileged action, using a privileged block if required.
387400
* <p>

0 commit comments

Comments
 (0)