You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2012/08/30 14:54:07 UTC

svn commit: r1378914 - in /lucene/dev/trunk: lucene/ lucene/tools/junit4/ solr/core/src/java/org/apache/solr/core/ solr/core/src/test/org/apache/solr/cloud/ solr/core/src/test/org/apache/solr/core/

Author: uschindler
Date: Thu Aug 30 12:54:06 2012
New Revision: 1378914

URL: http://svn.apache.org/viewvc?rev=1378914&view=rev
Log:
LUCENE-4337: Add a SecurityManager to run tests using a custom policy file, disallowing write/delete access outside ${build.dir} and listening network sockets on any other address than 127.0.0.1:1024-. This also fixes failing Solr tests because of creating index in example folder or listening on 0.0.0.0 (JMX)

Added:
    lucene/dev/trunk/lucene/tools/junit4/tests.policy
Modified:
    lucene/dev/trunk/lucene/common-build.xml
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMultiCoreConfBootstrap.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java

Modified: lucene/dev/trunk/lucene/common-build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/common-build.xml?rev=1378914&r1=1378913&r2=1378914&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/common-build.xml (original)
+++ lucene/dev/trunk/lucene/common-build.xml Thu Aug 30 12:54:06 2012
@@ -796,6 +796,11 @@
             <sysproperty key="tempDir" value="." />
             <sysproperty key="java.io.tmpdir" value="." />
 
+            <!-- Restrict access to certain Java features and install security manager: -->
+            <sysproperty key="tests.sandbox.dir" value="${build.dir}" />
+            <sysproperty key="java.security.manager" value="java.lang.SecurityManager" />
+            <sysproperty key="java.security.policy" value="${common.dir}/tools/junit4/tests.policy" />
+
             <sysproperty key="lucene.version" value="${dev.version}"/>
 
             <sysproperty key="jetty.testMode" value="1"/>

Added: lucene/dev/trunk/lucene/tools/junit4/tests.policy
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/tools/junit4/tests.policy?rev=1378914&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/tools/junit4/tests.policy (added)
+++ lucene/dev/trunk/lucene/tools/junit4/tests.policy Thu Aug 30 12:54:06 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+// Policy file to prevent tests from writing outside the test sandbox directory
+// (must be given as a sysprop: tests.sandbox.dir)
+// This policy also disallows stuff like listening on network ports of interfaces
+// different than 127.0.0.1.
+
+// PLEASE NOTE: You may need to enable other permissions when new tests are added,
+// everything not allowed here is forbidden!
+
+grant { 
+  permission java.io.FilePermission "<<ALL FILES>>", "read,execute";
+  permission java.io.FilePermission "${tests.sandbox.dir}${/}-", "read,execute,write,delete";
+  permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+  permission java.net.SocketPermission "*", "connect,resolve";
+  permission java.util.PropertyPermission "*", "read,write";
+  permission java.lang.reflect.ReflectPermission "*";
+  permission java.lang.RuntimePermission "*";
+  
+  // Solr needs those:
+  permission java.net.NetPermission "*";
+  permission java.util.logging.LoggingPermission "control";
+  permission java.lang.management.ManagementPermission "monitor";
+  permission javax.management.MBeanPermission "*", "*";
+  permission javax.management.MBeanServerPermission "*";
+  permission javax.management.MBeanTrustPermission "*";
+  
+  // TIKA uses BouncyCastle and that registers new provider for PDF parsing + MSOffice parsing. Maybe report as bug!
+  permission java.security.SecurityPermission "putProviderProperty.BC";
+  permission java.security.SecurityPermission "insertProvider.BC";
+};

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java?rev=1378914&r1=1378913&r2=1378914&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java Thu Aug 30 12:54:06 2012
@@ -61,6 +61,13 @@ public class JmxMonitoredMap<K, V> exten
 
   public JmxMonitoredMap(String coreName, String coreHashCode,
                          final JmxConfiguration jmxConfig) {
+    this(coreName, coreHashCode, jmxConfig, null);
+  }
+  
+  // TODO: Make public? Move Map<String,?> env to environment?
+  // Currently the map is needed to bind to localhost
+  JmxMonitoredMap(String coreName, String coreHashCode,
+                         final JmxConfiguration jmxConfig, Map<String,?> env) {
     this.coreHashCode = coreHashCode;
     jmxRootName = (null != jmxConfig.rootName ?
                    jmxConfig.rootName
@@ -94,7 +101,7 @@ public class JmxMonitoredMap<K, V> exten
         server = MBeanServerFactory.newMBeanServer();
         JMXConnectorServer connector = JMXConnectorServerFactory
                 .newJMXConnectorServer(new JMXServiceURL(jmxConfig.serviceUrl),
-                        null, server);
+                        env, server);
         connector.start();
         LOG.info("JMX monitoring is enabled at " + jmxConfig.serviceUrl);
       } catch (Exception e) {

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMultiCoreConfBootstrap.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMultiCoreConfBootstrap.java?rev=1378914&r1=1378913&r2=1378914&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMultiCoreConfBootstrap.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMultiCoreConfBootstrap.java Thu Aug 30 12:54:06 2012
@@ -25,9 +25,7 @@ import org.apache.solr.core.CoreContaine
 import org.apache.solr.util.AbstractSolrTestCase;
 import org.apache.solr.util.ExternalPaths;
 import org.junit.After;
-import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,27 +34,25 @@ public class TestMultiCoreConfBootstrap 
   protected static Logger log = LoggerFactory.getLogger(TestMultiCoreConfBootstrap.class);
   protected CoreContainer cores = null;
   private String home;
-
-  protected static ZkTestServer zkServer;
-  protected static String zkDir;
-  
-  @BeforeClass
-  public static void beforeClass() {
-    createTempDir();
-  }
   
-  @AfterClass
-  public static void afterClass() {
-    zkServer = null;
-    zkDir = null;
-  }
+  protected File dataDir2;
+  protected ZkTestServer zkServer;
+  protected String zkDir;
   
   @Override
   @Before
   public void setUp() throws Exception {
     super.setUp();
+    
+    createTempDir();
+    dataDir2 = new File(TEMP_DIR, getSimpleClassName() + "-core1-"
+        + System.currentTimeMillis());
+    dataDir2.mkdirs();
+
     home = ExternalPaths.EXAMPLE_MULTICORE_HOME;
     System.setProperty("solr.solr.home", home);
+    System.setProperty( "solr.core0.data.dir", dataDir.getCanonicalPath() ); 
+    System.setProperty( "solr.core1.data.dir", dataDir2.getCanonicalPath() ); 
     
     zkDir = dataDir.getAbsolutePath() + File.separator
         + "zookeeper/server1/data";
@@ -82,14 +78,11 @@ public class TestMultiCoreConfBootstrap 
     
     zkServer.shutdown();
     
-    File dataDir1 = new File(home + File.separator + "core0","data");
-    File dataDir2 = new File(home + File.separator + "core1","data");
-
     String skip = System.getProperty("solr.test.leavedatadir");
     if (null != skip && 0 != skip.trim().length()) {
       log.info("NOTE: per solr.test.leavedatadir, dataDir will not be removed: " + dataDir.getAbsolutePath());
     } else {
-      if (!AbstractSolrTestCase.recurseDelete(dataDir1)) {
+      if (!AbstractSolrTestCase.recurseDelete(dataDir)) {
         log.warn("!!!! WARNING: best effort to remove " + dataDir.getAbsolutePath() + " FAILED !!!!!");
       }
       if (!AbstractSolrTestCase.recurseDelete(dataDir2)) {
@@ -97,6 +90,9 @@ public class TestMultiCoreConfBootstrap 
       }
     }
 
+    zkServer = null;
+    zkDir = null;
+
     super.tearDown();
   }
 

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java?rev=1378914&r1=1378913&r2=1378914&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java Thu Aug 30 12:54:06 2012
@@ -30,10 +30,15 @@ import javax.management.Query;
 import javax.management.remote.JMXConnector;
 import javax.management.remote.JMXConnectorFactory;
 import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
 import java.net.ServerSocket;
 import java.net.URL;
-import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
+import java.rmi.server.RMIServerSocketFactory;
+import java.util.Collections;
 import java.util.Set;
 
 import static org.hamcrest.CoreMatchers.allOf;
@@ -61,33 +66,38 @@ public class TestJmxMonitoredMap extends
   public void setUp() throws Exception {
 
     super.setUp();
-
-    int retries = 5;
-    for (int i = 0; i < retries; i++) {
-      try {
-        ServerSocket server = new ServerSocket(0);
-        try {
-          port = server.getLocalPort();
-        } finally {
-          server.close();
-        }
-        // System.out.println("Using port: " + port);
-        try {
-          LocateRegistry.createRegistry(port);
-        } catch (RemoteException e) {
-          throw e;
-        }
-        String url = "service:jmx:rmi:///jndi/rmi://:" + port + "/solrjmx";
-        JmxConfiguration config = new JmxConfiguration(true, null, url, null);
-        monitoredMap = new JmxMonitoredMap<String, SolrInfoMBean>("", "", config);
-        JMXServiceURL u = new JMXServiceURL(url);
-        connector = JMXConnectorFactory.connect(u);
-        mbeanServer = connector.getMBeanServerConnection();
-        break;
-      } catch (Exception e) {
-        if(retries == (i + 1)) {
-          throw e;
+    String oldHost = System.getProperty("java.rmi.server.hostname");
+    try {
+      // this stupid sysprop thing is needed, because remote stubs use the
+      // hostname to connect, which does not work with server bound to 127.0.0.1
+      // See: http://weblogs.java.net/blog/emcmanus/archive/2006/12/multihomed_comp.html
+      System.setProperty("java.rmi.server.hostname", "127.0.0.1");
+      class LocalhostRMIServerSocketFactory implements RMIServerSocketFactory {
+        ServerSocket socket;
+        
+        @Override
+        public ServerSocket createServerSocket(int port) throws IOException {
+          socket = new ServerSocket();
+          socket.bind(new InetSocketAddress("127.0.0.1", port));
+          return socket;
         }
+      };
+      LocalhostRMIServerSocketFactory factory = new LocalhostRMIServerSocketFactory();
+      LocateRegistry.createRegistry(0, null, factory);
+      port = factory.socket.getLocalPort();
+      //System.out.println("Using port: " + port);
+      String url = "service:jmx:rmi://127.0.0.1:"+port+"/jndi/rmi://127.0.0.1:"+port+"/solrjmx";
+      JmxConfiguration config = new JmxConfiguration(true, null, url, null);
+      monitoredMap = new JmxMonitoredMap<String, SolrInfoMBean>("", "", config,
+        Collections.singletonMap(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, factory));
+      JMXServiceURL u = new JMXServiceURL(url);
+      connector = JMXConnectorFactory.connect(u);
+      mbeanServer = connector.getMBeanServerConnection();
+    } finally {
+      if (oldHost == null) {
+        System.clearProperty("java.rmi.server.hostname");
+      } else {
+        System.setProperty("java.rmi.server.hostname", oldHost);
       }
     }
   }