db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r1619008 - in /db/derby/code/branches/10.11: ./ java/engine/org/apache/derby/impl/services/monitor/ java/engine/org/apache/derby/impl/services/timer/ java/engine/org/apache/derby/loc/ java/shared/org/apache/derby/shared/common/reference/ ja...
Date Tue, 19 Aug 2014 22:52:42 GMT
Author: dag
Date: Tue Aug 19 22:52:41 2014
New Revision: 1619008

URL: http://svn.apache.org/r1619008
Log:
DERBY-6619 After silently swallowing SecurityExceptions, Derby can leak class loaders

Backported from trunk svn 1618955.

Patch derby-6619 which prints warnings on derby.log if permissions are
missing to get and set the context class loader in
SingletonTimerFactory (which can lead to classloader leak). Also adds
a test of this by checking derby.log in SecureServerTest.


Modified:
    db/derby/code/branches/10.11/   (props changed)
    db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
    db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
    db/derby/code/branches/10.11/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/branches/10.11/java/shared/org/apache/derby/shared/common/reference/MessageId.java
    db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DerbyNetAutoStartTest.java
    db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/SecureServerTest.java

Propchange: db/derby/code/branches/10.11/
------------------------------------------------------------------------------
  Merged /db/derby/code/trunk:r1618955

Modified: db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java?rev=1619008&r1=1619007&r2=1619008&view=diff
==============================================================================
--- db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
(original)
+++ db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
Tue Aug 19 22:52:41 2014
@@ -21,75 +21,64 @@
 
 package org.apache.derby.impl.services.monitor;
 
-import org.apache.derby.iapi.services.monitor.Monitor;
-import org.apache.derby.iapi.services.monitor.ModuleFactory;
-import org.apache.derby.iapi.services.monitor.ModuleControl;
-import org.apache.derby.iapi.services.monitor.ModuleSupportable;
-
-import org.apache.derby.iapi.services.monitor.PersistentService;
-
-import org.apache.derby.iapi.services.io.FormatIdUtil;
-import org.apache.derby.iapi.services.io.RegisteredFormatIds;
-import org.apache.derby.iapi.services.io.StoredFormatIds;
-
-import org.apache.derby.iapi.services.context.ContextManager;
-import org.apache.derby.iapi.services.context.Context;
-import org.apache.derby.iapi.services.context.ContextService;
-
-import org.apache.derby.iapi.services.stream.InfoStreams;
-import org.apache.derby.iapi.services.stream.PrintWriterGetHeader;
-
-import org.apache.derby.shared.common.sanity.SanityManager;
-import org.apache.derby.iapi.error.ErrorStringBuilder;
-import org.apache.derby.iapi.error.ShutdownException;
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.services.uuid.UUIDFactory;
-import org.apache.derby.iapi.services.timer.TimerFactory;
-import org.apache.derby.iapi.reference.MessageId;
-import org.apache.derby.iapi.reference.Module;
-import org.apache.derby.iapi.reference.Property;
-import org.apache.derby.iapi.reference.SQLState;
-import org.apache.derby.iapi.reference.Attribute;
-import org.apache.derby.iapi.services.property.PropertyUtil;
-
-import org.apache.derby.iapi.services.io.AccessibleByteArrayOutputStream;
-import org.apache.derby.iapi.services.loader.ClassInfo;
-import org.apache.derby.iapi.services.loader.InstanceGetter;
-import org.apache.derby.iapi.services.io.FormatableInstanceGetter;
-import org.apache.derby.iapi.error.ExceptionSeverity;
-
-import  org.apache.derby.io.StorageFactory;
-
-import org.apache.derby.iapi.services.info.JVMInfo;
-import org.apache.derby.iapi.services.i18n.BundleFinder;
-import org.apache.derby.iapi.services.i18n.MessageService;
-
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.BufferedInputStream;
-import java.io.PrintWriter;
 import java.io.BufferedReader;
-import java.io.InputStreamReader;
 import java.io.ByteArrayInputStream;
-
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.AccessControlException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
+import java.util.NoSuchElementException;
 import java.util.Properties;
-import java.util.Enumeration;
+import java.util.ResourceBundle;
 import java.util.StringTokenizer;
 import java.util.Vector;
-import java.util.Locale;
-import java.util.ResourceBundle;
-import java.util.NoSuchElementException;
-
-import java.lang.reflect.InvocationTargetException;
-
-import java.net.URL;
-import java.security.AccessControlException;
+import org.apache.derby.iapi.error.ErrorStringBuilder;
+import org.apache.derby.iapi.error.ExceptionSeverity;
+import org.apache.derby.iapi.error.ShutdownException;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.Attribute;
+import org.apache.derby.iapi.reference.MessageId;
+import org.apache.derby.iapi.reference.Module;
+import org.apache.derby.iapi.reference.Property;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.services.context.Context;
+import org.apache.derby.iapi.services.context.ContextManager;
+import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.services.i18n.BundleFinder;
+import org.apache.derby.iapi.services.i18n.MessageService;
+import org.apache.derby.iapi.services.info.JVMInfo;
+import org.apache.derby.iapi.services.io.AccessibleByteArrayOutputStream;
+import org.apache.derby.iapi.services.io.FormatIdUtil;
+import org.apache.derby.iapi.services.io.FormatableInstanceGetter;
+import org.apache.derby.iapi.services.io.RegisteredFormatIds;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
+import org.apache.derby.iapi.services.loader.ClassInfo;
+import org.apache.derby.iapi.services.loader.InstanceGetter;
+import org.apache.derby.iapi.services.monitor.ModuleControl;
+import org.apache.derby.iapi.services.monitor.ModuleFactory;
+import org.apache.derby.iapi.services.monitor.ModuleSupportable;
+import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.services.monitor.PersistentService;
+import org.apache.derby.iapi.services.property.PropertyUtil;
+import org.apache.derby.iapi.services.stream.InfoStreams;
+import org.apache.derby.iapi.services.stream.PrintWriterGetHeader;
+import org.apache.derby.iapi.services.timer.TimerFactory;
+import org.apache.derby.iapi.services.uuid.UUIDFactory;
+import org.apache.derby.io.StorageFactory;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
 	Implementation of the monitor that uses the class loader
@@ -105,7 +94,8 @@ abstract class BaseMonitor
 	/**
 		Hash table of objects that implement PersistentService keyed by their getType() method.
 	*/
-	private HashMap<String,PersistentService> serviceProviders = new HashMap<String,PersistentService>();
+    private final HashMap<String,PersistentService> serviceProviders =
+            new HashMap<String,PersistentService>();
 	private static final String LINE = 
         "----------------------------------------------------------------";
 
@@ -114,7 +104,7 @@ abstract class BaseMonitor
 
     private List<List<Class<?>>> implementationSets;
 
-	private Vector<TopService>	  services;					// Vector of TopServices
+    private final Vector<TopService> services; // Vector of TopServices
 
 	Properties bootProperties;		// specifc properties provided by the boot method, override
everything else
 	Properties applicationProperties;
@@ -779,11 +769,35 @@ abstract class BaseMonitor
 	}
 
 	/**
-	*/
-	private Object newInstance(Class classObject) {
+     * Return a new instance of class {@code classObject} using
+     * a no-param constructor.
+     * @param classObject the class to instantiate
+     * @return the instantiated object
+     */
+    private Object newInstance(Class<?> classObject) {
 
 		try {
-			return classObject.newInstance();
+            final Object module = classObject.newInstance();
+
+            // Get and report any warnings generated during initialization
+            try {
+                final Method getWarn = classObject.getMethod("getWarnings");
+                final String warnings = (String)getWarn.invoke(module);
+
+                if (warnings != null) {
+                    report(warnings);
+                }
+            } catch (NoSuchMethodException e) {
+                // Ok, not all modules support this method
+            } catch (InvocationTargetException e) {
+                // Should never happen
+                if (SanityManager.DEBUG) {
+                    SanityManager.NOTREACHED();
+                }
+                report(e.toString());
+            }
+
+            return module;
 		}
 		catch (InstantiationException e) {
 			report(classObject.getName() + " " + e.toString());

Modified: db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java?rev=1619008&r1=1619007&r2=1619008&view=diff
==============================================================================
--- db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
(original)
+++ db/derby/code/branches/10.11/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
Tue Aug 19 22:52:41 2014
@@ -21,16 +21,18 @@
 
 package org.apache.derby.impl.services.timer;
 
-import org.apache.derby.iapi.services.timer.TimerFactory;
-import org.apache.derby.iapi.services.monitor.ModuleControl;
-import org.apache.derby.iapi.error.StandardException;
-
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.Timer;
 import java.util.Properties;
+import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.i18n.MessageService;
+import org.apache.derby.iapi.services.monitor.ModuleControl;
+import org.apache.derby.iapi.services.timer.TimerFactory;
+import org.apache.derby.shared.common.reference.MessageId;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 
 /**
@@ -51,7 +53,7 @@ public class SingletonTimerFactory
     /**
      * Singleton Timer instance.
      */
-    private Timer singletonTimer;
+    private final Timer singletonTimer;
 
     /**
      * The number of times {@link #cancel(TimerTask)} has been called.
@@ -61,6 +63,11 @@ public class SingletonTimerFactory
     private final AtomicInteger cancelCount = new AtomicInteger();
 
     /**
+     * Initialization warnings. See {@link #getWarnings}.
+     */
+    private StringBuilder warnings = new StringBuilder();
+
+    /**
      * Initializes this TimerFactory with a singleton Timer instance.
      */
     public SingletonTimerFactory()
@@ -89,12 +96,12 @@ public class SingletonTimerFactory
 
     // TimerFactory interface methods
 
-    /** {@inheritDoc} */
+    @Override
     public void schedule(TimerTask task, long delay) {
         singletonTimer.schedule(task, delay);
     }
 
-    /** {@inheritDoc} */
+    @Override
     public void cancel(TimerTask task) {
         task.cancel();
 
@@ -124,8 +131,12 @@ public class SingletonTimerFactory
      *
      * Implements the ModuleControl interface.
      *
+     * @param create not used
+     * @param properties not used
+     * @throws StandardException not used
      * @see ModuleControl
      */
+    @Override
     public void boot(boolean create, Properties properties)
         throws
             StandardException
@@ -140,6 +151,7 @@ public class SingletonTimerFactory
      *
      * @see ModuleControl
      */
+    @Override
     public void stop()
     {
         singletonTimer.cancel();
@@ -147,10 +159,11 @@ public class SingletonTimerFactory
 
     // Helper methods
 
-    private static ClassLoader getContextClassLoader() {
+    private ClassLoader getContextClassLoader() {
         try {
             return AccessController.doPrivileged(
                     new PrivilegedAction<ClassLoader>() {
+                @Override
                 public ClassLoader run() {
                     return Thread.currentThread().getContextClassLoader();
                 }
@@ -160,13 +173,15 @@ public class SingletonTimerFactory
             // the DERBY-3745 fix did not require getContextClassLoader
             // privileges. We may leak class loaders if we are not
             // able to do this, but we can't just fail.
+            report(se, MessageId.CANNOT_GET_CLASSLOADER);
             return null;
         }
     }
 
-    private static void setContextClassLoader(final ClassLoader cl) {
+    private void setContextClassLoader(final ClassLoader cl) {
         try {
             AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                @Override
                 public Void run() {
                     Thread.currentThread().setContextClassLoader(cl);
                     return null;
@@ -177,7 +192,30 @@ public class SingletonTimerFactory
             // the DERBY-3745 fix, did not require setContextClassLoader
             // permissions. We may leak class loaders if we are not able to
             // set this, but cannot just fail.
+            report(se, MessageId.CANNOT_SET_CLASSLOADER);
         }
     }
 
+    private void report (SecurityException se, String id) {
+        warnings.append(MessageService.getTextMessage(id, se.toString()));
+        warnings.append('\n');
+
+        if (SanityManager.DEBUG) {
+            for (StackTraceElement elt : se.getStackTrace()) {
+                warnings.append(elt.toString());
+                warnings.append('\n');
+            }
+            warnings.append('\n');
+        }
+    }
+    /**
+     * Return any warnings generated during the initialization of this class, or
+     * null if none
+     * @return See legend
+     */
+    public String getWarnings() {
+        String result = warnings.toString();
+        warnings = null;
+        return "".equals(result) ? null : result;
+    }
 }

Modified: db/derby/code/branches/10.11/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.11/java/engine/org/apache/derby/loc/messages.xml?rev=1619008&r1=1619007&r2=1619008&view=diff
==============================================================================
--- db/derby/code/branches/10.11/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/branches/10.11/java/engine/org/apache/derby/loc/messages.xml Tue Aug 19
22:52:41 2014
@@ -8882,6 +8882,20 @@ page id:            {0}
             </msg>
 
             <msg>
+                <name>M00A</name>
+                <text>WARNING: cannot get the context class loader due to a security
exception: {0}. This may lead to class loader leak.
+                </text>
+                <arg>error</arg>
+            </msg>
+
+            <msg>
+                <name>M00B</name>
+                <text>WARNING: cannot set the context class loader due to a security
exception: {0}. This may lead to class loader leak.
+                </text>
+                <arg>error</arg>
+            </msg>
+
+            <msg>
                 <name>M010</name>
                 <text>WARNING: could not do ThreadGroup#setDaemon on Derby daemons
due to a security exception: {0}. This may impact operation.
                 </text>

Modified: db/derby/code/branches/10.11/java/shared/org/apache/derby/shared/common/reference/MessageId.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.11/java/shared/org/apache/derby/shared/common/reference/MessageId.java?rev=1619008&r1=1619007&r2=1619008&view=diff
==============================================================================
--- db/derby/code/branches/10.11/java/shared/org/apache/derby/shared/common/reference/MessageId.java
(original)
+++ db/derby/code/branches/10.11/java/shared/org/apache/derby/shared/common/reference/MessageId.java
Tue Aug 19 22:52:41 2014
@@ -226,11 +226,14 @@ public interface MessageId {
     String README_AT_SEG_LEVEL                               = "M007";
 
     /**
-     * Could not read security related Derby properties when running under a
-     * security manager
+     * Security related Derby messages used when running under the
+     * Java security manager and something doesn't work, possibly leading
+     * to lower security unless fixed.
      */
     String CANNOT_READ_SECURITY_PROPERTY                     = "M008";
     String CANNOT_CREATE_FILE_OR_DIRECTORY                   = "M009";
+    String CANNOT_GET_CLASSLOADER                            = "M00A";
+    String CANNOT_SET_CLASSLOADER                            = "M00B";
     String CANNOT_SET_DAEMON                                 = "M010";
     /*
      * Misc

Modified: db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DerbyNetAutoStartTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DerbyNetAutoStartTest.java?rev=1619008&r1=1619007&r2=1619008&view=diff
==============================================================================
--- db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DerbyNetAutoStartTest.java
(original)
+++ db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DerbyNetAutoStartTest.java
Tue Aug 19 22:52:41 2014
@@ -277,7 +277,7 @@ public class DerbyNetAutoStartTest exten
         ns.shutdown();
     }
 
-    private static boolean checkLog( String logFileName, String[] expected)
+    static boolean checkLog( String logFileName, String[] expected)
             throws IOException
     {
         boolean allFound = true;
@@ -293,8 +293,9 @@ public class DerbyNetAutoStartTest exten
             // System.out.println(logLine);
             for( int i = 0; i < expected.length; i++)
             {
-                if( (! found[i]) && logLine.indexOf( expected[i]) >= 0)
+                if( (! found[i]) && logLine.contains( expected[i])) {
                     found[i] = true;
+                }
             }
         }
         for( int i = 0; i < expected.length; i++)
@@ -304,6 +305,7 @@ public class DerbyNetAutoStartTest exten
                 allFound = false;
             }
         }
+        br.close();
         return allFound;
     } // end of checkLog
 

Modified: db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/SecureServerTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/SecureServerTest.java?rev=1619008&r1=1619007&r2=1619008&view=diff
==============================================================================
--- db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/SecureServerTest.java
(original)
+++ db/derby/code/branches/10.11/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/SecureServerTest.java
Tue Aug 19 22:52:41 2014
@@ -21,7 +21,11 @@
 
 package org.apache.derbyTesting.functionTests.tests.derbynet;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.util.ArrayList;
@@ -321,6 +325,10 @@ public class SecureServerTest extends Ba
 
         assertEquals( myName + ": serverCameUp = " + serverCameUp, _outcome.serverShouldComeUp(),
serverCameUp );
 
+        if (!_unsecureSet) {
+            assertWarningDerby6619();
+        }
+
         if (!(runsWithEmma() || runsWithJaCoCo())) {
             // With Emma we run without the security manager, so we can't
             // assert on seeing it.
@@ -493,5 +501,19 @@ public class SecureServerTest extends Ba
             nsTestSetup.getServerProcess().getProcess(), true);
     }
 
+    final String[] expected6619 =
+         new String[]{
+             "WARNING: cannot set the context class loader due to a " +
+                 "security exception:",
+             "This may lead to class loader leak"};
+
+    private void assertWarningDerby6619() throws IOException {
+        final String logFileName =
+                getSystemProperty("derby.system.home").replace("/system","") +
+                File.separator + "/derby.log";
+        if (!DerbyNetAutoStartTest.checkLog(logFileName, expected6619)) {
+            fail("Expected warning on derby.log cf DERBY-6619");
+        }
+    }
 }
 



Mime
View raw message