Mark initialization of selector as privileged
Motivation: Instrumenting the NIO selector implementation requires special permissions. Yet, the code for performing this instrumentation is executed in a manner that would require all code leading up to the initialization to have the requisite permissions. In a restrictive environment (e.g., under a security policy that only grants the requisite permissions the Netty transport jar but not to application code triggering the Netty initialization), then instrumeting the selector will not succeed even if the security policy would otherwise permit it. Modifications: This commit marks the necessary blocks as privileged. This enables access to the necessary resources for instrumenting the selector. The idea is that we are saying the Netty code is trusted, and as long as the Netty code has been granted the necessary permissions, then we will allow the caller access to these resources even though the caller itself might not have the requisite permissions. Result: The selector can be instrumented in a restrictive security environment.
This commit is contained in:
parent
74567548c2
commit
9a3576f926
@ -162,31 +162,64 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
||||
return selector;
|
||||
}
|
||||
|
||||
try {
|
||||
SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
|
||||
final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
|
||||
|
||||
Class<?> selectorImplClass =
|
||||
Class.forName("sun.nio.ch.SelectorImpl", false, PlatformDependent.getSystemClassLoader());
|
||||
|
||||
// Ensure the current selector implementation is what we can instrument.
|
||||
if (!selectorImplClass.isAssignableFrom(selector.getClass())) {
|
||||
return selector;
|
||||
Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
return Class.forName(
|
||||
"sun.nio.ch.SelectorImpl",
|
||||
false,
|
||||
PlatformDependent.getSystemClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
return e;
|
||||
} catch (SecurityException e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
|
||||
Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
|
||||
if (!(maybeSelectorImplClass instanceof Class) ||
|
||||
// ensure the current selector implementation is what we can instrument.
|
||||
!((Class<?>) maybeSelectorImplClass).isAssignableFrom(selector.getClass())) {
|
||||
if (maybeSelectorImplClass instanceof Exception) {
|
||||
Exception e = (Exception) maybeSelectorImplClass;
|
||||
logger.trace("failed to instrument a special java.util.Set into: {}", selector, e);
|
||||
}
|
||||
return selector;
|
||||
}
|
||||
|
||||
selectedKeysField.setAccessible(true);
|
||||
publicSelectedKeysField.setAccessible(true);
|
||||
final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
|
||||
|
||||
selectedKeysField.set(selector, selectedKeySet);
|
||||
publicSelectedKeysField.set(selector, selectedKeySet);
|
||||
Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
|
||||
Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
|
||||
|
||||
selectedKeys = selectedKeySet;
|
||||
logger.trace("Instrumented an optimized java.util.Set into: {}", selector);
|
||||
} catch (Throwable t) {
|
||||
selectedKeysField.setAccessible(true);
|
||||
publicSelectedKeysField.setAccessible(true);
|
||||
|
||||
selectedKeysField.set(selector, selectedKeySet);
|
||||
publicSelectedKeysField.set(selector, selectedKeySet);
|
||||
return null;
|
||||
} catch (NoSuchFieldException e) {
|
||||
return e;
|
||||
} catch (IllegalAccessException e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (maybeException instanceof Exception) {
|
||||
selectedKeys = null;
|
||||
logger.trace("Failed to instrument an optimized java.util.Set into: {}", selector, t);
|
||||
Exception e = (Exception) maybeException;
|
||||
logger.trace("failed to instrument a special java.util.Set into: {}", selector, e);
|
||||
} else {
|
||||
selectedKeys = selectedKeySet;
|
||||
logger.trace("instrumented a special java.util.Set into: {}", selector);
|
||||
}
|
||||
|
||||
return selector;
|
||||
|
Loading…
x
Reference in New Issue
Block a user