db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r543524 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/services/reflect/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Fri, 01 Jun 2007 16:24:48 GMT
Author: djd
Date: Fri Jun  1 09:24:46 2007
New Revision: 543524

URL: http://svn.apache.org/viewvc?view=rev&rev=543524
Log:
DERBY-538 (partial) Switch the parent class loader for JarLoader to SecureClassLoader.
Add the restriction that javax. and org.apache.derby. classes
cannot be loaded from installed jars. Add test cases for loading various illegal
classes (java, javax and org.apache.derby) to DatabaseClassLoadingTest.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/dcl_java.jar
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java?view=diff&rev=543524&r1=543523&r2=543524
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java
Fri Jun  1 09:24:46 2007
@@ -30,7 +30,9 @@
 import java.io.InputStream;
 import java.io.IOException;
 
+import java.security.CodeSource;
 import java.security.GeneralSecurityException;
+import java.security.SecureClassLoader;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.jar.JarEntry;
@@ -47,7 +49,7 @@
 import org.apache.derby.io.StorageFile;
 
 
-class JarLoader extends ClassLoader {
+class JarLoader extends SecureClassLoader {
     
     /**
      * Two part name for the jar file.
@@ -280,14 +282,14 @@
 
 		byte[] data = readData(e, in, className);
 
-		Object[] signers = getSigners(className, e);
+		Certificate[] signers = getSigners(className, e);
 
 		synchronized (updateLoader) {
 			// see if someone else loaded it while we
 			// were getting the bytes ...
 			Class c = updateLoader.checkLoaded(className, resolve);
 			if (c == null) {
-				c = defineClass(className, data, 0, data.length);
+				c = defineClass(className, data, 0, data.length, (CodeSource) null);
 				if (signers != null) {
 					setSigners(c, signers);
 				}
@@ -437,7 +439,7 @@
     /**
      * Validate the security certificates (signers) for the class data.
      */
-    Object[] getSigners(String className, JarEntry je) throws IOException {
+    private Certificate[] getSigners(String className, JarEntry je) throws IOException {
 
         try {
             Certificate[] list = je.getCertificates();

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java?view=diff&rev=543524&r1=543523&r2=543524
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/UpdateLoader.java
Fri Jun  1 09:24:46 2007
@@ -48,6 +48,22 @@
 import org.apache.derby.iapi.services.locks.CompatibilitySpace;
 
 class UpdateLoader {
+    
+    /**
+     * List of packages that Derby will not support being loaded
+     * from an installed jar file.
+     */
+    private static final String[] RESTRICTED_PACKAGES = {
+        // While loading java. classes is blocked by the standard
+        // class loading mechanism, javax. ones are not. However
+        // allowing database applications to override jvm classes
+        // seems a bad idea.
+        "javax.",
+        
+        // Allowing an application to possible override the engine's
+        // own classes also seems dangerous.
+        "org.apache.derby.",
+    };
 
 	private JarLoader[] jarList;
 	private HeaderPrintWriter vs;
@@ -136,6 +152,13 @@
 				Class clazz = checkLoaded(className, resolve);
 				if (clazz != null)
 					return clazz;
+                
+                // Refuse to load classes from restricted name spaces
+                for (int i = 0; i < RESTRICTED_PACKAGES.length; i++)
+                {
+                    if (className.startsWith(RESTRICTED_PACKAGES[i]))
+                        throw new ClassNotFoundException(className);
+                }
 
 				String jvmClassName = className.replace('.', '/').concat(".class");
 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java?view=diff&rev=543524&r1=543523&r2=543524
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java
Fri Jun  1 09:24:46 2007
@@ -122,7 +122,17 @@
                    new DatabaseClassLoadingTest("testInvalidJar")));           
            suite.addTest(SecurityManagerSetup.noSecurityManager(
                    new DatabaseClassLoadingTest("testRemoveJar"))); 
-
+           
+           suite.addTest(SecurityManagerSetup.noSecurityManager(
+                   new DatabaseClassLoadingTest("testLoadJavaClassIndirectly"))); 
+           suite.addTest(SecurityManagerSetup.noSecurityManager(
+                   new DatabaseClassLoadingTest("testLoadJavaClassDirectly")));
+           suite.addTest(SecurityManagerSetup.noSecurityManager(
+                   new DatabaseClassLoadingTest("testLoadJavaClassDirectly2")));
+           suite.addTest(SecurityManagerSetup.noSecurityManager(
+                   new DatabaseClassLoadingTest("testLoadJavaClassDirectly3")));
+           suite.addTest(SecurityManagerSetup.noSecurityManager(
+                   new DatabaseClassLoadingTest("testLoadDerbyClassIndirectly")));
        
            suite.addTest(SecurityManagerSetup.noSecurityManager(
                    new DatabaseClassLoadingTest("testDatabaseInJar"))); 
@@ -137,7 +147,8 @@
                    "functionTests/tests/lang/dcl_emc2.jar",
                    "functionTests/tests/lang/dcl_emc2s.jar",
                    "functionTests/tests/lang/dcl_emc2sm.jar",
-                   "functionTests/tests/lang/dcl_emc2l.jar"
+                   "functionTests/tests/lang/dcl_emc2l.jar",
+                   "functionTests/tests/lang/dcl_java.jar",
                    });
            
            }
@@ -663,6 +674,94 @@
         } finally {
             //setContextClassLoader(null);
         } 
+    }
+    
+    /**
+     * Load a java.sql class indirectly (ie. through a valid class
+     * in the installed jar file) from the jar file.
+     */
+    public void testLoadJavaClassIndirectly() throws SQLException, MalformedURLException
+    {
+        loadJavaClass(
+                "org.apache.derbyTesting.databaseclassloader.cracker.C1.simple",
+                "38000");
+    }
+    
+    /**
+     * Load a java.sql class directly (ie. through a direct procedure call)
+     * from the jar file.
+     */    
+    public void testLoadJavaClassDirectly() throws SQLException, MalformedURLException
+    {
+        loadJavaClass("java.sql.J1.simple", "XJ001");
+    }
+    
+    /**
+     * Load a java.derby99 class directly (ie. through a direct procedure call)
+     * from the jar file. This is to see if additional non-standard java.* packages
+     * can be added into the JVM
+     */    
+    public void testLoadJavaClassDirectly2() throws SQLException, MalformedURLException
+    {
+        loadJavaClass("java.derby99.J2.simple", "XJ001");
+    }
+    
+    /**
+     * Load a javax.derby99 class directly (ie. through a direct procedure call)
+     * from the jar file. This is to see if additional non-standard javax.* packages
+     * can be added into the JVM. As an implementation note this is blocked
+     * by Derby's class loader, not the JVM's security mechanism.
+     */    
+    public void testLoadJavaClassDirectly3() throws SQLException, MalformedURLException
+    {
+        loadJavaClass("javax.derby99.J3.simple", "XJ001");
+    }
+    
+    /**
+     * Load a org.apache.derby class directly (ie. through a direct procedure call)
+     * from the jar file. As an implementation note this is blocked
+     * by Derby's class loader, not the JVM's security mechanism.
+     */    
+    public void testLoadDerbyClassIndirectly() throws SQLException, MalformedURLException
+    {
+        loadJavaClass(
+                "org.apache.derbyTesting.databaseclassloader.cracker.C1.derby",
+                "38000");
+    }
+    
+    /**
+     * Test loading classes in the java. and javax. namespaces
+     * from a jar, it should be disallowed or be ignored. These tests
+     * are run as separate fixtures to ensure the failed loading
+     * does not affect subsequent attempts to load.
+     * @throws MalformedURLException 
+     */
+    private void loadJavaClass(String method, String expectedSQLState)
+        throws SQLException, MalformedURLException
+    {
+        String jarName = "EMC.MY_JAVA";
+        
+        installJar("dcl_java.jar", jarName);
+        setDBClasspath(jarName);
+        
+        Statement s = createStatement();
+        s.execute("CREATE PROCEDURE C1() LANGUAGE JAVA PARAMETER STYLE JAVA " +
+                "NO SQL EXTERNAL NAME " +
+                "'" + method + "'");
+       
+        try {
+            s.execute("CALL C1()");
+            fail("Call to procedure loading java class from installed jar");
+        } catch (SQLException sqle)
+        {
+            assertSQLState(expectedSQLState, sqle);
+        }
+        
+        s.execute("DROP PROCEDURE C1");
+        s.close();
+        setDBClasspath(null);
+        removeJar(jarName);
+
     }
     
     /**

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/dcl_java.jar
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/dcl_java.jar?view=auto&rev=543524
==============================================================================
Binary file - no diff available.

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/dcl_java.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



Mime
View raw message