Remove JNI permissions, improve JNI testing.
This commit is contained in:
parent
02da246b10
commit
b8efa8ea21
3
pom.xml
3
pom.xml
|
@ -635,6 +635,9 @@
|
||||||
<tests.security.manager>${tests.security.manager}</tests.security.manager>
|
<tests.security.manager>${tests.security.manager}</tests.security.manager>
|
||||||
<tests.compatibility>${tests.compatibility}</tests.compatibility>
|
<tests.compatibility>${tests.compatibility}</tests.compatibility>
|
||||||
<java.awt.headless>true</java.awt.headless>
|
<java.awt.headless>true</java.awt.headless>
|
||||||
|
<!-- true if we are running tests from maven (as opposed to IDE, etc).
|
||||||
|
allows us to assert certain things work, like libsigar -->
|
||||||
|
<tests.maven>true</tests.maven>
|
||||||
<!-- security manager / test.policy -->
|
<!-- security manager / test.policy -->
|
||||||
<java.security.policy>${basedir}/src/main/resources/org/elasticsearch/bootstrap/security.policy</java.security.policy>
|
<java.security.policy>${basedir}/src/main/resources/org/elasticsearch/bootstrap/security.policy</java.security.policy>
|
||||||
</systemProperties>
|
</systemProperties>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.bootstrap;
|
package org.elasticsearch.bootstrap;
|
||||||
|
|
||||||
|
import org.apache.lucene.util.StringHelper;
|
||||||
import org.elasticsearch.ExceptionsHelper;
|
import org.elasticsearch.ExceptionsHelper;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.PidFile;
|
import org.elasticsearch.common.PidFile;
|
||||||
|
@ -27,6 +28,7 @@ import org.elasticsearch.common.collect.Tuple;
|
||||||
import org.elasticsearch.common.inject.CreationException;
|
import org.elasticsearch.common.inject.CreationException;
|
||||||
import org.elasticsearch.common.inject.spi.Message;
|
import org.elasticsearch.common.inject.spi.Message;
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
|
import org.elasticsearch.common.jna.Kernel32Library;
|
||||||
import org.elasticsearch.common.jna.Natives;
|
import org.elasticsearch.common.jna.Natives;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
@ -38,6 +40,7 @@ import org.elasticsearch.monitor.process.JmxProcessProbe;
|
||||||
import org.elasticsearch.node.Node;
|
import org.elasticsearch.node.Node;
|
||||||
import org.elasticsearch.node.NodeBuilder;
|
import org.elasticsearch.node.NodeBuilder;
|
||||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
||||||
|
import org.hyperic.sigar.Sigar;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -58,23 +61,15 @@ public class Bootstrap {
|
||||||
private static volatile CountDownLatch keepAliveLatch;
|
private static volatile CountDownLatch keepAliveLatch;
|
||||||
private static Bootstrap bootstrap;
|
private static Bootstrap bootstrap;
|
||||||
|
|
||||||
private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception {
|
/** initialize native resources */
|
||||||
if (settings.getAsBoolean("bootstrap.mlockall", false)) {
|
public static void initializeNatives(boolean mlockAll, boolean ctrlHandler) {
|
||||||
|
// mlockall if requested
|
||||||
|
if (mlockAll) {
|
||||||
Natives.tryMlockall();
|
Natives.tryMlockall();
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeBuilder nodeBuilder = NodeBuilder.nodeBuilder().settings(settings).loadConfigSettings(false);
|
// listener for windows close event
|
||||||
node = nodeBuilder.build();
|
if (ctrlHandler) {
|
||||||
if (addShutdownHook) {
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
node.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.getAsBoolean("bootstrap.ctrlhandler", true)) {
|
|
||||||
Natives.addConsoleCtrlHandler(new ConsoleCtrlHandler() {
|
Natives.addConsoleCtrlHandler(new ConsoleCtrlHandler() {
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(int code) {
|
public boolean handle(int code) {
|
||||||
|
@ -89,7 +84,36 @@ public class Bootstrap {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// install SM after natives, JNA can require strange permissions
|
Kernel32Library.getInstance();
|
||||||
|
|
||||||
|
// initialize sigar explicitly
|
||||||
|
try {
|
||||||
|
Sigar.load();
|
||||||
|
Loggers.getLogger(Bootstrap.class).trace("sigar libraries loaded successfully");
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Loggers.getLogger(Bootstrap.class).trace("failed to load sigar libraries", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init lucene random seed. it will use /dev/urandom where available:
|
||||||
|
StringHelper.randomId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception {
|
||||||
|
initializeNatives(settings.getAsBoolean("bootstrap.mlockall", false),
|
||||||
|
settings.getAsBoolean("bootstrap.ctrlhandler", true));
|
||||||
|
|
||||||
|
NodeBuilder nodeBuilder = NodeBuilder.nodeBuilder().settings(settings).loadConfigSettings(false);
|
||||||
|
node = nodeBuilder.build();
|
||||||
|
if (addShutdownHook) {
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
node.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// install SM after natives, shutdown hooks, etc.
|
||||||
setupSecurity(settings, environment);
|
setupSecurity(settings, environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.bootstrap;
|
package org.elasticsearch.bootstrap;
|
||||||
|
|
||||||
import org.apache.lucene.util.StringHelper;
|
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -49,9 +48,6 @@ class Security {
|
||||||
* Can only happen once!
|
* Can only happen once!
|
||||||
*/
|
*/
|
||||||
static void configure(Environment environment) throws Exception {
|
static void configure(Environment environment) throws Exception {
|
||||||
// init lucene random seed. it will use /dev/urandom where available:
|
|
||||||
StringHelper.randomId();
|
|
||||||
|
|
||||||
// enable security policy: union of template and environment-based paths.
|
// enable security policy: union of template and environment-based paths.
|
||||||
URI template = Security.class.getResource(POLICY_RESOURCE).toURI();
|
URI template = Security.class.getResource(POLICY_RESOURCE).toURI();
|
||||||
Policy.setPolicy(new ESPolicy(template, createPermissions(environment)));
|
Policy.setPolicy(new ESPolicy(template, createPermissions(environment)));
|
||||||
|
|
|
@ -22,6 +22,8 @@ package org.elasticsearch.common.jna;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.sun.jna.Native;
|
import com.sun.jna.Native;
|
||||||
import com.sun.jna.win32.StdCallLibrary;
|
import com.sun.jna.win32.StdCallLibrary;
|
||||||
|
|
||||||
|
import org.apache.lucene.util.Constants;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
|
||||||
|
@ -46,6 +48,7 @@ public class Kernel32Library {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Kernel32Library() {
|
private Kernel32Library() {
|
||||||
|
if (Constants.WINDOWS) {
|
||||||
try {
|
try {
|
||||||
Native.register("kernel32");
|
Native.register("kernel32");
|
||||||
logger.debug("windows/Kernel32 library loaded");
|
logger.debug("windows/Kernel32 library loaded");
|
||||||
|
@ -55,6 +58,7 @@ public class Kernel32Library {
|
||||||
logger.warn("unable to link Windows/Kernel32 library. native methods and handlers will be disabled.");
|
logger.warn("unable to link Windows/Kernel32 library. native methods and handlers will be disabled.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Kernel32Library getInstance() {
|
public static Kernel32Library getInstance() {
|
||||||
return Holder.instance;
|
return Holder.instance;
|
||||||
|
|
|
@ -82,9 +82,6 @@ grant {
|
||||||
// needed by groovy scripting
|
// needed by groovy scripting
|
||||||
permission java.lang.RuntimePermission "getProtectionDomain";
|
permission java.lang.RuntimePermission "getProtectionDomain";
|
||||||
|
|
||||||
// needed for natives calls
|
|
||||||
permission java.lang.RuntimePermission "loadLibrary.*";
|
|
||||||
|
|
||||||
// reflection hacks:
|
// reflection hacks:
|
||||||
// needed for Striped64 (what is this doing), also enables unmap hack
|
// needed for Striped64 (what is this doing), also enables unmap hack
|
||||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
|
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
|
||||||
|
|
|
@ -20,83 +20,31 @@
|
||||||
package org.elasticsearch.common.jna;
|
package org.elasticsearch.common.jna;
|
||||||
|
|
||||||
import org.apache.lucene.util.Constants;
|
import org.apache.lucene.util.Constants;
|
||||||
import org.elasticsearch.common.jna.Kernel32Library.ConsoleCtrlHandler;
|
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class NativesTests extends ElasticsearchTestCase {
|
public class NativesTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
/**
|
|
||||||
* Those properties are set by the JNA Api and if not ignored,
|
|
||||||
* lead to tests failure (see AbstractRandomizedTest#IGNORED_INVARIANT_PROPERTIES)
|
|
||||||
*/
|
|
||||||
private static final String[] JNA_INVARIANT_PROPERTIES = {
|
|
||||||
"jna.platform.library.path",
|
|
||||||
"jnidispatch.path"
|
|
||||||
};
|
|
||||||
|
|
||||||
private Map<String, String> properties = new HashMap<>();
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void saveProperties() {
|
|
||||||
assumeTrue("Natives can't load libraries from path if security manager is enabled.", System.getSecurityManager() == null);
|
|
||||||
for (String p : JNA_INVARIANT_PROPERTIES) {
|
|
||||||
properties.put(p, System.getProperty(p));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void restoreProperties() {
|
|
||||||
for (String p : JNA_INVARIANT_PROPERTIES) {
|
|
||||||
if (properties.get(p) != null) {
|
|
||||||
System.setProperty(p, properties.get(p));
|
|
||||||
} else {
|
|
||||||
System.clearProperty(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTryMlockall() {
|
public void testMlockall() {
|
||||||
Natives.tryMlockall();
|
|
||||||
|
|
||||||
if (Constants.WINDOWS) {
|
if (Constants.WINDOWS) {
|
||||||
assertFalse("Memory locking is not available on Windows platforms", Natives.LOCAL_MLOCKALL);
|
assertFalse("Memory locking is not available on Windows platforms", Natives.LOCAL_MLOCKALL);
|
||||||
}
|
}
|
||||||
|
if (Constants.MAC_OS_X) {
|
||||||
|
assertFalse("Memory locking is not available on OS X platforms", Natives.LOCAL_MLOCKALL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddConsoleCtrlHandler() {
|
public void testConsoleCtrlHandler() {
|
||||||
ConsoleCtrlHandler handler = new ConsoleCtrlHandler() {
|
|
||||||
@Override
|
|
||||||
public boolean handle(int code) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Natives.addConsoleCtrlHandler(handler);
|
|
||||||
|
|
||||||
if (Constants.WINDOWS) {
|
if (Constants.WINDOWS) {
|
||||||
assertNotNull(Kernel32Library.getInstance());
|
assertNotNull(Kernel32Library.getInstance());
|
||||||
assertThat(Kernel32Library.getInstance().getCallbacks().size(), equalTo(1));
|
assertThat(Kernel32Library.getInstance().getCallbacks().size(), equalTo(1));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assertNotNull(Kernel32Library.getInstance());
|
assertNotNull(Kernel32Library.getInstance());
|
||||||
assertThat(Kernel32Library.getInstance().getCallbacks().size(), equalTo(0));
|
assertThat(Kernel32Library.getInstance().getCallbacks().size(), equalTo(0));
|
||||||
|
|
||||||
try {
|
|
||||||
Kernel32Library.getInstance().addConsoleCtrlHandler(handler);
|
|
||||||
fail("should have thrown an unsupported operation exception");
|
|
||||||
} catch (UnsatisfiedLinkError e) {
|
|
||||||
// UnsatisfiedLinkError is expected
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.monitor;
|
||||||
|
|
||||||
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
|
import org.hyperic.sigar.Sigar;
|
||||||
|
|
||||||
|
public class SigarTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
assumeTrue("we can only ensure sigar is working when running from maven",
|
||||||
|
Boolean.parseBoolean(System.getProperty("tests.maven")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSigarLoads() throws Exception {
|
||||||
|
Sigar.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSigarWorks() throws Exception {
|
||||||
|
Sigar sigar = new Sigar();
|
||||||
|
assertNotNull(sigar.getCpu());
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.test;
|
package org.elasticsearch.test;
|
||||||
|
|
||||||
import org.apache.lucene.util.TestSecurityManager;
|
import org.apache.lucene.util.TestSecurityManager;
|
||||||
|
import org.elasticsearch.bootstrap.Bootstrap;
|
||||||
|
|
||||||
import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean;
|
import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean;
|
||||||
|
|
||||||
|
@ -33,6 +34,8 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAs
|
||||||
class SecurityHack {
|
class SecurityHack {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
// just like bootstrap, initialize natives, then SM
|
||||||
|
Bootstrap.initializeNatives(true, true);
|
||||||
// for IDEs, we check that security.policy is set
|
// for IDEs, we check that security.policy is set
|
||||||
if (systemPropertyAsBoolean("tests.security.manager", true) &&
|
if (systemPropertyAsBoolean("tests.security.manager", true) &&
|
||||||
System.getProperty("java.security.policy") != null) {
|
System.getProperty("java.security.policy") != null) {
|
||||||
|
|
Loading…
Reference in New Issue