Skip to content

Commit

Permalink
HV-1280 Use privileged actions to manipulate the class loader
Browse files Browse the repository at this point in the history
  • Loading branch information
gsmet committed Mar 15, 2017
1 parent 27370d3 commit 72c638d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.EnumSet;
import java.util.HashMap;
Expand All @@ -27,7 +28,9 @@

import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader;
import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext;
import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader;
import org.hibernate.validator.internal.util.privilegedactions.Unmarshal;

/**
Expand Down Expand Up @@ -69,10 +72,10 @@ public final BootstrapConfiguration parseValidationXml() {
return BootstrapConfigurationImpl.getDefaultBootstrapConfiguration();
}

ClassLoader previousTccl = Thread.currentThread().getContextClassLoader();
ClassLoader previousTccl = run( GetClassLoader.fromContext() );

try {
Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() );
run( SetContextClassLoader.action( ValidationXmlParser.class.getClassLoader() ) );

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

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

/**
* Runs the given privileged action, using a privileged block if required.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
import java.util.List;
Expand All @@ -37,7 +38,9 @@
import org.hibernate.validator.internal.metadata.raw.ConstrainedType;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader;
import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext;
import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader;
import org.hibernate.validator.internal.util.privilegedactions.Unmarshal;

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

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

try {
Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() );
run( SetContextClassLoader.action( XmlMappingParser.class.getClassLoader() ) );

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

Expand Down Expand Up @@ -382,6 +385,16 @@ private String getSchemaResourceName(String schemaVersion) {
return schemaResource;
}

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

/**
* Runs the given privileged action, using a privileged block if required.
* <p>
Expand Down

0 comments on commit 72c638d

Please sign in to comment.