diff --git a/securesm/src/main/java/org/elasticsearch/SecureSM.java b/securesm/src/main/java/org/elasticsearch/SecureSM.java
index c0ad45c44d0..c8b4bee5262 100644
--- a/securesm/src/main/java/org/elasticsearch/SecureSM.java
+++ b/securesm/src/main/java/org/elasticsearch/SecureSM.java
@@ -63,7 +63,7 @@ import java.util.Objects;
*/
public class SecureSM extends SecurityManager {
- private final String[] packagesThatCanExit;
+ private final String[] classesThatCanExit;
/**
* Creates a new security manager where no packages can exit nor halt the virtual machine.
@@ -73,22 +73,24 @@ public class SecureSM extends SecurityManager {
}
/**
- * Creates a new security manager with the specified list of packages being the only packages
- * that can exit or halt the virtual machine.
+ * Creates a new security manager with the specified list of regular expressions as the those that class names will be tested against to
+ * check whether or not a class can exit or halt the virtual machine.
*
- * @param packagesThatCanExit the list of packages that can exit or halt the virtual machine
+ * @param classesThatCanExit the list of classes that can exit or halt the virtual machine
*/
- public SecureSM(final String[] packagesThatCanExit) {
- this.packagesThatCanExit = packagesThatCanExit;
+ public SecureSM(final String[] classesThatCanExit) {
+ this.classesThatCanExit = classesThatCanExit;
}
/**
- * Creates a new security manager with a standard set of test packages being the only packages
- * that can exit or halt the virtual machine. The packages that can exit are
+ * Creates a new security manager with a standard set of test packages being the only packages that can exit or halt the virtual machine.
+ * The packages that can exit are:
+ *
* org.apache.maven.surefire.booter.
* com.carrotsearch.ant.tasks.junit4.
* org.eclipse.internal.junit.runner.
* com.intellij.rt.execution.junit.
+ *
*
* @return an instance of SecureSM where test packages can halt or exit the virtual machine
*/
@@ -96,15 +98,15 @@ public class SecureSM extends SecurityManager {
return new SecureSM(TEST_RUNNER_PACKAGES);
}
- private static final String[] TEST_RUNNER_PACKAGES = new String[] {
+ static final String[] TEST_RUNNER_PACKAGES = new String[] {
// surefire test runner
- "org.apache.maven.surefire.booter.",
+ "org\\.apache\\.maven\\.surefire\\.booter\\..*",
// junit4 test runner
- "com.carrotsearch.ant.tasks.junit4.",
+ "com\\.carrotsearch\\.ant\\.tasks\\.junit4\\.slave\\..*",
// eclipse test runner
- "org.eclipse.jdt.internal.junit.runner.",
+ "org\\.eclipse.jdt\\.internal\\.junit\\.runner\\..*",
// intellij test runner
- "com.intellij.rt.execution.junit."
+ "com\\.intellij\\.rt\\.execution\\.junit\\..*"
};
// java.security.debug support
@@ -203,6 +205,8 @@ public class SecureSM extends SecurityManager {
/**
* The "Uwe Schindler" algorithm.
+ *
+ * @param status the exit status
*/
protected void innerCheckExit(final int status) {
AccessController.doPrivileged(new PrivilegedAction() {
@@ -222,14 +226,12 @@ public class SecureSM extends SecurityManager {
}
if (exitMethodHit != null) {
- if (packagesThatCanExit == null) {
+ if (classesThatCanExit == null) {
break;
}
- for (String packageThatCanExit : packagesThatCanExit) {
- if (className.startsWith(packageThatCanExit)) {
- // this exit point is allowed, we return normally from closure:
- return null;
- }
+ if (classCanExit(className, classesThatCanExit)) {
+ // this exit point is allowed, we return normally from closure:
+ return null;
}
// anything else in stack trace is not allowed, break and throw SecurityException below:
break;
@@ -248,4 +250,13 @@ public class SecureSM extends SecurityManager {
super.checkExit(status);
}
+ static boolean classCanExit(final String className, final String[] classesThatCanExit) {
+ for (final String classThatCanExit : classesThatCanExit) {
+ if (className.matches(classThatCanExit)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
diff --git a/securesm/src/test/java/org/elasticsearch/TestSecureSM.java b/securesm/src/test/java/org/elasticsearch/TestSecureSM.java
index 31c8d0ad4fb..99e376be847 100644
--- a/securesm/src/test/java/org/elasticsearch/TestSecureSM.java
+++ b/securesm/src/test/java/org/elasticsearch/TestSecureSM.java
@@ -55,6 +55,16 @@ public class TestSecureSM extends TestCase {
fail("did not hit expected exception");
} catch (SecurityException expected) {}
}
+
+ @Test
+ public void testClassCanExit() {
+ assertTrue(SecureSM.classCanExit("org.apache.maven.surefire.booter.CommandReader", SecureSM.TEST_RUNNER_PACKAGES));
+ assertTrue(SecureSM.classCanExit("com.carrotsearch.ant.tasks.junit4.slave.JvmExit", SecureSM.TEST_RUNNER_PACKAGES));
+ assertTrue(SecureSM.classCanExit("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner", SecureSM.TEST_RUNNER_PACKAGES));
+ assertTrue(SecureSM.classCanExit("com.intellij.rt.execution.junit.JUnitStarter", SecureSM.TEST_RUNNER_PACKAGES));
+ assertTrue(SecureSM.classCanExit("org.elasticsearch.Foo", new String[]{"org.elasticsearch.Foo"}));
+ assertFalse(SecureSM.classCanExit("org.elasticsearch.Foo", new String[]{"org.elasticsearch.Bar"}));
+ }
@Test
public void testCreateThread() throws Exception {