Skip to content

Commit 5e5e346

Browse files
committed
Fix classes that can exit
In a previous change, we locked down the classes that can exit by specifying explicit classes rather than packages than can exit. Alas, there was a bug in the sense that the class that we exit from in the case of an uncaught exception is not ElasticsearchUncaughtExceptionHandler but rather an anonymous nested class of ElasticsearchUncaughtExceptionHandler. To address this, we replace this anonymous class with a bonafide nested class ElasticsearchUncaughtExceptionHandler$PrivilegedHaltAction. Note that if we try to get this class name we have a $ in the middle of the string which is a special regular expression character; as such, we have to escape it. Relates #27518
1 parent 8aaba9f commit 5e5e346

File tree

2 files changed

+24
-14
lines changed

2 files changed

+24
-14
lines changed

core/src/main/java/org/elasticsearch/bootstrap/ElasticsearchUncaughtExceptionHandler.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,37 +65,43 @@ public void uncaughtException(Thread t, Throwable e) {
6565
}
6666
}
6767

68-
// visible for testing
6968
static boolean isFatalUncaught(Throwable e) {
7069
return e instanceof Error;
7170
}
7271

73-
// visible for testing
7472
void onFatalUncaught(final String threadName, final Throwable t) {
7573
final Logger logger = Loggers.getLogger(ElasticsearchUncaughtExceptionHandler.class, loggingPrefixSupplier.get());
7674
logger.error(
7775
(org.apache.logging.log4j.util.Supplier<?>)
7876
() -> new ParameterizedMessage("fatal error in thread [{}], exiting", threadName), t);
7977
}
8078

81-
// visible for testing
8279
void onNonFatalUncaught(final String threadName, final Throwable t) {
8380
final Logger logger = Loggers.getLogger(ElasticsearchUncaughtExceptionHandler.class, loggingPrefixSupplier.get());
8481
logger.warn((org.apache.logging.log4j.util.Supplier<?>)
8582
() -> new ParameterizedMessage("uncaught exception in thread [{}]", threadName), t);
8683
}
8784

88-
// visible for testing
8985
void halt(int status) {
90-
AccessController.doPrivileged(new PrivilegedAction<Void>() {
91-
@SuppressForbidden(reason = "halt")
92-
@Override
93-
public Void run() {
94-
// we halt to prevent shutdown hooks from running
95-
Runtime.getRuntime().halt(status);
96-
return null;
97-
}
98-
});
86+
AccessController.doPrivileged(new PrivilegedHaltAction(status));
87+
}
88+
89+
static class PrivilegedHaltAction implements PrivilegedAction<Void> {
90+
91+
private final int status;
92+
93+
private PrivilegedHaltAction(final int status) {
94+
this.status = status;
95+
}
96+
97+
@SuppressForbidden(reason = "halt")
98+
@Override
99+
public Void run() {
100+
// we halt to prevent shutdown hooks from running
101+
Runtime.getRuntime().halt(status);
102+
return null;
103+
}
104+
99105
}
100106

101107
}

core/src/main/java/org/elasticsearch/bootstrap/Security.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ static void configure(Environment environment, boolean filterBadDefaults) throws
119119
Policy.setPolicy(new ESPolicy(createPermissions(environment), getPluginPermissions(environment), filterBadDefaults));
120120

121121
// enable security manager
122-
final String[] classesThatCanExit = new String[]{ElasticsearchUncaughtExceptionHandler.class.getName(), Command.class.getName()};
122+
final String[] classesThatCanExit =
123+
new String[]{
124+
// SecureSM matches class names as regular expressions so we escape the $ that arises from the nested class name
125+
ElasticsearchUncaughtExceptionHandler.PrivilegedHaltAction.class.getName().replace("$", "\\$"),
126+
Command.class.getName()};
123127
System.setSecurityManager(new SecureSM(classesThatCanExit));
124128

125129
// do some basic tests

0 commit comments

Comments
 (0)