db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmars...@apache.org
Subject svn commit: r675648 - in /db/derby/code/branches/10.3/java: engine/org/apache/derby/iapi/util/ engine/org/apache/derby/impl/services/monitor/ engine/org/apache/derby/impl/services/timer/ testing/org/apache/derbyTesting/functionTests/util/
Date Thu, 10 Jul 2008 16:58:37 GMT
Author: kmarsden
Date: Thu Jul 10 09:58:36 2008
New Revision: 675648

URL: http://svn.apache.org/viewvc?rev=675648&view=rev
Log:
DERBY-3745  Derby can leak classloaders in an app server environment


Added:
    db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/util/PrivilegedThreadOps.java
  (with props)
Modified:
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy

Added: db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/util/PrivilegedThreadOps.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/util/PrivilegedThreadOps.java?rev=675648&view=auto
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/util/PrivilegedThreadOps.java
(added)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/util/PrivilegedThreadOps.java
Thu Jul 10 09:58:36 2008
@@ -0,0 +1,97 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.util.PrivilegedThreadOps
+
+   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.derby.iapi.util;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * A collection of operations on {@link java.lang.Thread} that wraps the
+ * operations in privileged block of code.
+ * <p>
+ * Derby needs to use privileged blocks in some places to avoid
+ * {@link SecurityException}s being thrown, as the required privileges are
+ * often granted to Derby itself, but not the higher level application code.
+ * <p>
+ * Feel free to add new operations as they are needed. This class is not
+ * intended to implement the full set of operations defined by
+ * {@link java.lang.Thread}.
+ */
+
+public class PrivilegedThreadOps {
+
+    /**
+     * Sets the context ClassLoader for this Thread. The context ClassLoader 
+     * can be set when a thread is created, and allows the creator of the 
+     * thread to provide the appropriate class loader to code running in 
+     * the thread when loading classes 
+     * and resources.
+     * 
+     * First, if there is a security manager, its <code> checkPermission </code>
+     * method is called with a 
+     * <code> RuntimePermission("setContextClassLoader") </code> permission 
+     * to see if it's ok to set the context ClassLoader.. 
+     * @param t  Thread for which we are setting the context class loader
+     * @param cl the context class loader for t
+     */
+    public static void setContextClassLoader(final Thread t, final ClassLoader cl) {
+            AccessController.doPrivileged(
+                        new PrivilegedAction() {
+                            public Object run()  {
+                                t.setContextClassLoader(cl);
+                                return null;
+                            }
+                        });
+    }
+    
+    /**
+     * Set the thread's context class loader if privileged.  If not ignore 
+     * security exception and continue. 
+     * @param t  Thread for which we are setting the context class loader
+     * @param cl the context class loader for t
+     */
+    public static void setContextClassLoaderIfPrivileged(Thread t, ClassLoader cl) {
+        try {
+            setContextClassLoader(t,cl);
+        } catch (SecurityException se) {
+            // ignore security exception.  Earlier versions of Derby, before 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.
+        }
+    }
+    
+    public static ClassLoader getContextClassLoader(final Thread t) {
+            return (ClassLoader)AccessController.doPrivileged(
+                        new PrivilegedAction() {
+                            public Object run()  {
+                                return t.getContextClassLoader();
+                            }
+                        });
+        
+    }
+    
+   
+       
+}

Propchange: db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/util/PrivilegedThreadOps.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java?rev=675648&r1=675647&r2=675648&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
(original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
Thu Jul 10 09:58:36 2008
@@ -54,6 +54,7 @@
 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.iapi.util.PrivilegedThreadOps;
 
 import  org.apache.derby.io.StorageFactory;
 
@@ -2071,8 +2072,30 @@
 	}
 
 	public Thread getDaemonThread(Runnable task, String name, boolean setMinPriority) {
+		// DERBY-3745 We want to avoid the thread leaking class loaders,
+		// so we make the context class loader null before we create the
+		// thread.
+		ClassLoader savecl = null;
+		boolean hasGetClassLoaderPerms = false;
+		try {
+			savecl = PrivilegedThreadOps.getContextClassLoader(Thread.currentThread());
+			hasGetClassLoaderPerms = true;
+		}  catch (SecurityException se) {
+			// ignore security exception. Earlier versions of Derby, before
+			// the DERBY-3745 fix did not require getClassLoader permissions.
+			// We may leak class loaders if we are not able to get the 
+			// class loader, but we cannot just fail.
+		}
+		if (hasGetClassLoaderPerms)
+			PrivilegedThreadOps.setContextClassLoaderIfPrivileged(
+								 Thread.currentThread(), null);
 		Thread t =  new Thread(daemonGroup, task, "derby.".concat(name));
+		if (hasGetClassLoaderPerms)
+			PrivilegedThreadOps.setContextClassLoaderIfPrivileged(
+							  Thread.currentThread(), savecl);
+
 		t.setDaemon(true);
+
 		if (setMinPriority) {
 			t.setPriority(Thread.MIN_PRIORITY);
 		}

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java?rev=675648&r1=675647&r2=675648&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
(original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
Thu Jul 10 09:58:36 2008
@@ -23,7 +23,7 @@
 
 import org.apache.derby.iapi.services.timer.TimerFactory;
 import org.apache.derby.iapi.services.monitor.ModuleControl;
-
+import org.apache.derby.iapi.util.PrivilegedThreadOps;
 import org.apache.derby.iapi.error.StandardException;
 
 import java.util.Timer;
@@ -61,7 +61,28 @@
          * a) We avoid synchronizing access to singletonTimer later
          * b) We don't need any properties
          */
+         // DERBY-3745 We want to avoid leaking class loaders, so 
+         // we make sure the context class loader is null before
+         // creating the thread
+        ClassLoader savecl = null;
+        boolean hasGetClassLoaderPerms = false;
+        try {
+            savecl = PrivilegedThreadOps.getContextClassLoader(
+                    Thread.currentThread());
+            hasGetClassLoaderPerms = true;
+        } catch (SecurityException se) {
+            // Ignore security exception. Versions of Derby before
+            // the DERBY-3745 fix did not require getClassLoader 
+            // privs.  We may leak class loaders if we are not
+            // able to do this but we can't just fail.
+        }
+        if (hasGetClassLoaderPerms)
+            PrivilegedThreadOps.setContextClassLoaderIfPrivileged(
+                    Thread.currentThread(), null);
         singletonTimer = new Timer(true); // Run as daemon
+        if (hasGetClassLoaderPerms)
+            PrivilegedThreadOps.setContextClassLoaderIfPrivileged(
+                    Thread.currentThread(), savecl);
     }
 
     /**

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy?rev=675648&r1=675647&r2=675648&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/util/derby_tests.policy
Thu Jul 10 09:58:36 2008
@@ -56,6 +56,13 @@
   permission java.util.PropertyPermission "derbyTesting.unittest.*", "write";
 
   permission java.lang.RuntimePermission "createClassLoader";
+
+  // permissions so that we can set the context class loader to
+  // null for daemon threads to avoid class loader leak.
+  // DERBY-3745
+  permission java.lang.RuntimePermission "getClassLoader";
+  permission java.lang.RuntimePermission "setContextClassLoader";
+
   permission java.security.SecurityPermission "getPolicy";
   
   permission java.io.FilePermission "${derby.system.home}${/}derby.properties", "read";
@@ -175,6 +182,13 @@
   
   permission java.util.PropertyPermission "derby.*", "read";
   permission java.lang.RuntimePermission "createClassLoader";
+
+  // permissions so that we can set the context class loader to
+  // null for daemon threads to avoid class loader leak.
+  // DERBY-3745
+  permission java.lang.RuntimePermission "getClassLoader";
+  permission java.lang.RuntimePermission "setContextClassLoader";
+
   permission java.security.SecurityPermission "getPolicy";
    
   permission java.io.FilePermission "${derby.system.home}${/}derby.properties", "read";



Mime
View raw message