You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by ch...@apache.org on 2014/11/20 16:22:36 UTC
svn commit: r1640754 - in /uima/sandbox/uima-ducc/trunk:
uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/
uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/
Author: challngr
Date: Thu Nov 20 15:22:36 2014
New Revision: 1640754
URL: http://svn.apache.org/r1640754
Log:
UIMA-4064 Add classpath poisoning test, and fix the bugs it revealed.
Added:
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ClassSeparation.java
Modified:
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/ClassManager.java
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/DuccEventHttpDispatcher.java
Added: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ClassSeparation.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ClassSeparation.java?rev=1640754&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ClassSeparation.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ClassSeparation.java Thu Nov 20 15:22:36 2014
@@ -0,0 +1,174 @@
+/*
+ * 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.
+*/
+
+package org.apache.uima.ducc.cli.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.uima.ducc.cli.DuccReservationCancel;
+import org.apache.uima.ducc.cli.DuccReservationSubmit;
+
+import com.google.gson.Gson;
+// Note: this is required for compilation but DO NOT put it into the runtime
+// classpath or the tests will fail.
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+/**
+ * Test CLI classpath separation
+ *
+ * To run this test, compile with the google Gson jar and the poisoned xstream class from the
+ * test package. Then run WITHOUT Gson, but still with the poisoned xstream.
+ *
+ * The CLI uses both gson and xstream. The gson test must throw to succeed, because the test tries
+ * to load it and gson should be on the other side of the classloader barrier.
+ *
+ * The reservation should go through becase the poisoned xstream is kept on "this" side of the
+ * classloader barrier and only the good one is used.
+ */
+public class ClassSeparation
+ extends ATestDriver
+{
+ public ClassSeparation()
+ {
+ }
+
+ public String[] testsToRun()
+ {
+ return new String[] {
+ "VerifyWrongXstream", // insure poisoned classes are provided by the "user"
+ "LoadGson", // Insure we can't get at any of the CLI's open source stuff
+ "PoisonedCLI", // Insure our poisoned classes don't leak into the CLI
+ };
+ }
+
+ public void testVerifyWrongXstream(String testid)
+ throws Exception
+ {
+ DomDriver dd = null;
+ try {
+ dd = new DomDriver();
+ } catch ( IllegalStateException e ) {
+ String msg = e.getMessage();
+ if ( msg.equals("I am not the DomDriver.") ) {
+ success(testid, "DomDriver is properly bogus.");
+ } else {
+ fail(testid, "DomDriver may not be bogus, test is invalid.");
+ }
+ }
+
+ try {
+ XStream xs = new XStream(dd);
+ } catch ( IllegalStateException e ) {
+ String msg = e.getMessage();
+ if ( msg.equals("I am not XStream.") ) {
+ success(testid, "XStream is properly bogus.");
+ } else {
+ fail(testid, "XStream may not be bogus, test is invalid.");
+ }
+ }
+
+ }
+
+ /**
+ * Try to load gson - it must fail. The CLI uses gson, which it will load, but across a
+ * classloader barrier so it can't "leak" back into here.
+ */
+ public void testLoadGson(String testid)
+ throws Exception
+ {
+ try {
+ Map<Integer, String> m = new HashMap<Integer, String>();
+ for ( int i = 0; i < 20; i++ ) {
+ m.put(i, ""+i);
+ }
+ Gson g = new Gson();
+ String gs = g.toJson(m);
+ System.out.println(gs);
+ fail(testid, "Loaded gson, should have failed.");
+ } catch ( NoClassDefFoundError e ) {
+ success("Test succeeded, gson did not leak from CLI into the test code:" + e.toString());
+ }
+ }
+
+ /**
+ * Try to poison the CLI. The CLI needs xstream. We'll put a deliberately poisoned xstream into
+ * the classpath when running this test. The CLI should succeed nonetheless.
+ */
+ public void testPoisonedCLI(String testid)
+ throws Exception
+ {
+
+ Properties reserve_props = new Properties();
+ DuccReservationSubmit reserve;
+ String resid = null;
+
+ reserve_props.setProperty("description", "Reserve And Cancel");
+ reserve_props.setProperty("instance_memory_size", "4");
+ reserve_props.setProperty("number_of_instances", "2");
+ reserve_props.setProperty("scheduling_class", "fixed");
+ try {
+ reserve = new DuccReservationSubmit(reserve_props);
+ if ( reserve.execute() ) {
+ resid = "" + reserve.getDuccId();
+ success(testid, "Reservation", resid, "successful, rc =", ""+reserve.getReturnCode(), ":", reserve.getHostsAsString());
+ String[] hosts = reserve.getHosts();
+ System.out.println("" + hosts.length + " hosts assigned");
+ if ( hosts.length > 0 ) {
+ for ( String h : reserve.getHosts() ) {
+ System.out.println(" " + h);
+ }
+ }
+ } else {
+ fail(testid, "Reservation failed, rc = " + reserve.getReturnCode());
+ }
+ } catch ( Throwable e ) {
+ fail(testid, "Reservation cannot execute.");
+ e.printStackTrace();
+ }
+
+ if ( resid == null ) {
+ fail(testid, "Bypass cancel because reserve failed.");
+ return;
+ }
+
+ Properties cancel_props = new Properties();
+ cancel_props.setProperty("id", resid);
+ try {
+ DuccReservationCancel cancel = new DuccReservationCancel(cancel_props);
+ if ( cancel.execute() ) {
+ success(testid, "Reservation " + ""+cancel.getDuccId() + " cancelled, rc = " + cancel.getReturnCode() + " " + cancel.getResponseMessage());
+ } else {
+ fail(testid, "Reservation " + ""+cancel.getDuccId() + " cancel failed, rc = " + cancel.getReturnCode() + " " + cancel.getResponseMessage());
+ }
+ } catch ( Throwable t ) {
+ fail(testid, "Cancel reseration cannot execute.");
+ }
+
+ }
+
+ public static void main(String[] args)
+ {
+ ClassSeparation tester = new ClassSeparation();
+ tester.runTests();
+ }
+
+}
Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/ClassManager.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/ClassManager.java?rev=1640754&r1=1640753&r2=1640754&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/ClassManager.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/ClassManager.java Thu Nov 20 15:22:36 2014
@@ -317,35 +317,25 @@ public class ClassManager
extends URLClassLoader
{
- ClassLoader parent;
HttpClassLoader(URL[] urls, ClassLoader parent)
{
super(urls, parent);
- this.parent = parent;
-
- //for ( URL u : urls ) {
- // System.out.println("XStreamClassLoader initializes from " + u);
- // }
}
- public Class<?> findClass(final String clname)
- throws ClassNotFoundException
+ public Class<?> loadClass(String clname, boolean resolve)
+ throws ClassNotFoundException
{
- if ( DEBUG ) System.out.println("--------- HttpClassLoader -- Finding class " + clname + " from " + this.getClass() + " " + clname);
- Class<?> ret = super.findClass(clname);
- if ( ret == null ) {
- if ( DEBUG ) {
- System.out.println(" Not found");
- }
- } else {
- if ( DEBUG ) {
- System.out.println(" " + ret.getProtectionDomain().getCodeSource().getLocation());
- System.out.println(" " + ret.getClassLoader());
- }
+
+ if ( DEBUG ) System.out.println("--------- HttpClassLoader ------- load class " + clname);
+ try {
+ Class<?> ret = super.loadClass(clname, resolve);
+ if ( DEBUG ) System.out.println("--------- HttpClassLoader ------- returns " + clname);
+ return ret;
+ } catch ( ClassNotFoundException e ) {
+ if ( DEBUG ) System.out.println("--------- HttpClassLoader ------- fails to find " + clname);
+ throw e;
}
- return ret;
}
-
}
class PrivateClassLoader
@@ -380,60 +370,22 @@ public class ClassManager
this.grand_parent = grand_parent;
}
-
- public Class<?> loadClass(String clname)
- throws ClassNotFoundException
- {
- if ( DEBUG ) System.out.println("---- A ------- load class " + clname + " from " + this);
- Class<?> ret = super.loadClass(clname);
- if ( DEBUG ) {
- System.out.println("---- A ------- load class " + clname + " returns " + ret );
- try {
- throw new Exception("Stack trace:");
- } catch ( Throwable e ) {
- e.printStackTrace();
- System.out.println("--- A -----------------------------------------------------------------------------");
- }
- }
- return ret;
- }
-
public Class<?> loadClass(String clname, boolean resolve)
throws ClassNotFoundException
{
-
- if ( DEBUG ) System.out.println("---- B ------- load class " + clname + " from " + this);
- Class<?> ret = super.loadClass(clname, resolve);
- if ( DEBUG ) {
- System.out.println("---- B ------ load class " + clname + " returns " + ret);
- try {
- throw new Exception("Stack trace:");
- } catch ( Throwable e ) {
- e.printStackTrace();
- System.out.println("---- B -----------------------------------------------------------------------------");
- }
- }
- return ret;
- }
-
-
- public Class<?> findClass(final String clname)
- throws ClassNotFoundException
- {
- if ( DEBUG ) System.out.println("*********** find class ********** " + clname);
- // we want all the interfaces from "common" except UIOptions and IDuccMonitor which aren't well-placed
- // for this exercise so we need a special case for them
- Class<?> ret = grand_parent.findClass(clname);
- if ( ret == null ) {
- if ( DEBUG ) {
- System.out.println("*********** Looking in " + parent + " for " + clname);
- }
- return super.findClass(clname);
- } else {
+ Class<?> ret = null;
+ if ( DEBUG ) System.out.println("---- A ------- load class " + clname + " from " + this);
+ try {
+ ret = grand_parent.loadClass(clname, resolve);
+ if ( DEBUG ) System.out.println("---- A ------- returns " + clname + " from " + grand_parent);
+ return ret;
+ } catch ( ClassNotFoundException e ) {
+ if ( DEBUG ) System.out.println("---- A ------- looking in " + parent + " to load " + clname);
+ ret = super.loadClass(clname, resolve);
+ if ( DEBUG ) System.out.println("---- A ------- returns " + clname + " from " + parent);
return ret;
}
}
-
}
}
Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/DuccEventHttpDispatcher.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/DuccEventHttpDispatcher.java?rev=1640754&r1=1640753&r2=1640754&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/DuccEventHttpDispatcher.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/dispatcher/DuccEventHttpDispatcher.java Thu Nov 20 15:22:36 2014
@@ -172,9 +172,15 @@ public class DuccEventHttpDispatcher {
public DuccEvent dispatchAndWaitForDuccReply(DuccEvent duccEvent)
throws Exception
{
- String serBody = toXml(duccEvent);
- String response = dispatch(serBody, "text/xml");
- return (DuccEvent) fromXml(response);
+ String serBody = null;
+ try{
+ serBody = toXml(duccEvent);
+ String response = dispatch(serBody, "text/xml");
+ return (DuccEvent) fromXml(response);
+ } catch ( Throwable t ) {
+ t.printStackTrace();
+ }
+ return null;
}
Object fromJson(String str, Class<?> cl)