You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2014/08/20 00:52:42 UTC
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...
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");
+ }
+ }
}