Merge pull request #10962 from rmuir/lockdown2
Remove JNI permissions, improve JNI testing.
This commit is contained in:
commit
54d361259e
3
pom.xml
3
pom.xml
|
@ -635,6 +635,9 @@
|
|||
<tests.security.manager>${tests.security.manager}</tests.security.manager>
|
||||
<tests.compatibility>${tests.compatibility}</tests.compatibility>
|
||||
<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 -->
|
||||
<java.security.policy>${basedir}/src/main/resources/org/elasticsearch/bootstrap/security.policy</java.security.policy>
|
||||
</systemProperties>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.bootstrap;
|
||||
|
||||
import org.apache.lucene.util.StringHelper;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.Version;
|
||||
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.spi.Message;
|
||||
import org.elasticsearch.common.io.PathUtils;
|
||||
import org.elasticsearch.common.jna.Kernel32Library;
|
||||
import org.elasticsearch.common.jna.Natives;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
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.NodeBuilder;
|
||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
||||
import org.hyperic.sigar.Sigar;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
@ -57,24 +60,16 @@ public class Bootstrap {
|
|||
private static volatile Thread keepAliveThread;
|
||||
private static volatile CountDownLatch keepAliveLatch;
|
||||
private static Bootstrap bootstrap;
|
||||
|
||||
private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception {
|
||||
if (settings.getAsBoolean("bootstrap.mlockall", false)) {
|
||||
|
||||
/** initialize native resources */
|
||||
public static void initializeNatives(boolean mlockAll, boolean ctrlHandler) {
|
||||
// mlockall if requested
|
||||
if (mlockAll) {
|
||||
Natives.tryMlockall();
|
||||
}
|
||||
|
||||
NodeBuilder nodeBuilder = NodeBuilder.nodeBuilder().settings(settings).loadConfigSettings(false);
|
||||
node = nodeBuilder.build();
|
||||
if (addShutdownHook) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
node.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (settings.getAsBoolean("bootstrap.ctrlhandler", true)) {
|
||||
// listener for windows close event
|
||||
if (ctrlHandler) {
|
||||
Natives.addConsoleCtrlHandler(new ConsoleCtrlHandler() {
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.bootstrap;
|
||||
|
||||
import org.apache.lucene.util.StringHelper;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
||||
import java.io.*;
|
||||
|
@ -49,9 +48,6 @@ class Security {
|
|||
* Can only happen once!
|
||||
*/
|
||||
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.
|
||||
URI template = Security.class.getResource(POLICY_RESOURCE).toURI();
|
||||
Policy.setPolicy(new ESPolicy(template, createPermissions(environment)));
|
||||
|
|
|
@ -22,6 +22,8 @@ package org.elasticsearch.common.jna;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.win32.StdCallLibrary;
|
||||
|
||||
import org.apache.lucene.util.Constants;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
|
||||
|
@ -46,13 +48,15 @@ public class Kernel32Library {
|
|||
}
|
||||
|
||||
private Kernel32Library() {
|
||||
try {
|
||||
Native.register("kernel32");
|
||||
logger.debug("windows/Kernel32 library loaded");
|
||||
} catch (NoClassDefFoundError e) {
|
||||
logger.warn("JNA not found. native methods and handlers will be disabled.");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
logger.warn("unable to link Windows/Kernel32 library. native methods and handlers will be disabled.");
|
||||
if (Constants.WINDOWS) {
|
||||
try {
|
||||
Native.register("kernel32");
|
||||
logger.debug("windows/Kernel32 library loaded");
|
||||
} catch (NoClassDefFoundError e) {
|
||||
logger.warn("JNA not found. native methods and handlers will be disabled.");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
logger.warn("unable to link Windows/Kernel32 library. native methods and handlers will be disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,9 +79,6 @@ grant {
|
|||
// needed by groovy scripting
|
||||
permission java.lang.RuntimePermission "getProtectionDomain";
|
||||
|
||||
// needed for natives calls
|
||||
permission java.lang.RuntimePermission "loadLibrary.*";
|
||||
|
||||
// reflection hacks:
|
||||
// needed for Striped64 (what is this doing), also enables unmap hack
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
|
||||
|
|
|
@ -20,83 +20,31 @@
|
|||
package org.elasticsearch.common.jna;
|
||||
|
||||
import org.apache.lucene.util.Constants;
|
||||
import org.elasticsearch.common.jna.Kernel32Library.ConsoleCtrlHandler;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
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
|
||||
public void testTryMlockall() {
|
||||
Natives.tryMlockall();
|
||||
|
||||
public void testMlockall() {
|
||||
if (Constants.WINDOWS) {
|
||||
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
|
||||
public void testAddConsoleCtrlHandler() {
|
||||
ConsoleCtrlHandler handler = new ConsoleCtrlHandler() {
|
||||
@Override
|
||||
public boolean handle(int code) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Natives.addConsoleCtrlHandler(handler);
|
||||
|
||||
public void testConsoleCtrlHandler() {
|
||||
if (Constants.WINDOWS) {
|
||||
assertNotNull(Kernel32Library.getInstance());
|
||||
assertThat(Kernel32Library.getInstance().getCallbacks().size(), equalTo(1));
|
||||
|
||||
} else {
|
||||
assertNotNull(Kernel32Library.getInstance());
|
||||
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;
|
||||
|
||||
import org.apache.lucene.util.TestSecurityManager;
|
||||
import org.elasticsearch.bootstrap.Bootstrap;
|
||||
|
||||
import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean;
|
||||
|
||||
|
@ -33,6 +34,8 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAs
|
|||
class SecurityHack {
|
||||
|
||||
static {
|
||||
// just like bootstrap, initialize natives, then SM
|
||||
Bootstrap.initializeNatives(true, true);
|
||||
// for IDEs, we check that security.policy is set
|
||||
if (systemPropertyAsBoolean("tests.security.manager", true) &&
|
||||
System.getProperty("java.security.policy") != null) {
|
||||
|
|
Loading…
Reference in New Issue