Crash due to missing synchronization on 'gconf_client' in 'jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c'

Christian Schulte cs at schulte.it
Thu Aug 2 03:54:01 PDT 2012


Hi,

using the system property 'java.net.useSystemProxies', JDK 7 crashes on 
OpenBSD 5.2.

$ /usr/local/jre-1.7.0/bin/java -version
openjdk version "1.7.0_03"
OpenJDK Runtime Environment (build 1.7.0_03-b04)
OpenJDK Server VM (build 22.1-b02, mixed mode)

$ /usr/local/jre-1.7.0/bin/java -cp . Crash
2538: assertion failed "allocator->lock_loc == NULL" file 
"/usr/ports/pobj/dbus-1.6.2/dbus-1.6.2/dbus/dbus-dataslot.c" line 79 
function _dbus_data_slot_allocator_alloc
2538: assertion failed "allocator->lock_loc == NULL" file 
"/usr/ports/pobj/dbus-1.6.2/dbus-1.6.2/dbus/dbus-dataslot.c" line 79 
function _dbus_data_slot_allocator_alloc
2538: assertion failed "allocator->lock_loc == NULL" file 
"/usr/ports/pobj/dbus-1.6.2/dbus-1.6.2/dbus/dbus-dataslot.c" line 79 
function _dbus_data_slot_allocator_alloc
2538: assertion failed "allocator->lock_loc == NULL" file 
"/usr/ports/pobj/dbus-1.6.2/dbus-1.6.2/dbus/dbus-dataslot.c" line 79 
function _dbus_data_slot_allocator_alloc
   D-Bus not compiled with backtrace support so unable to print a backtrace
   D-Bus not compiled with backtrace support so unable to print a backtrace

$ /usr/local/jre-1.7.0/bin/java -cp . Crash
27421: assertion failed "!(connection)->have_connection_lock" file 
"/usr/ports/pobj/dbus-1.6.2/dbus-1.6.2/dbus/dbus-connection.c" line 1133 
function _dbus_connection_acquire_io_path
   D-Bus not compiled with backtrace support so unable to print a backtrace
Abort trap (core dumped)

Looking at 
'openjdk/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c', 
there is a 'static void* gconf_client' which is initialized by calling 
'gconf_client_get_default' from 'libgconf-2'. Uses of that client are 
not protected against concurrent accesses by multiple threads although 
that gconf client is not thread-safe. Trying to add some protection 
myself resulted in the attached patch. Rebuilding JDK 1.7 with this 
patch applied, the 'gconf'/'dbus' related crashes no longer happen.

Regards,

-- 
Christian
-------------- next part --------------

public class Crash
{

    public static void main( final String... args ) throws Exception
    {
        System.setProperty( "java.net.useSystemProxies", "true" );

        for ( int i = 0; i < 10; i++ )
        {
            new Thread()
            {

                public void run()
                {
                    try
                    {
                        final java.net.URL url = new java.net.URL( "http://openjdk.java.net/index.html" );
                        final java.net.URLConnection con = url.openConnection();
                        System.out.println( con.getContent() );
                    }
                    catch ( final java.io.IOException e )
                    {
                        e.printStackTrace();
                    }
                }

            }.start();
        }
    }

}
-------------- next part --------------
diff -ruN openjdk.original/jdk/src/share/native/java/net/net_util.c openjdk/jdk/src/share/native/java/net/net_util.c
--- openjdk.original/jdk/src/share/native/java/net/net_util.c	Thu May  3 13:17:28 2012
+++ openjdk/jdk/src/share/native/java/net/net_util.c	Thu Aug  2 12:31:30 2012
@@ -68,6 +68,11 @@
     */
     IPv6_available = IPv6_supported() & (!preferIPv4Stack);
     initLocalAddrTable ();
+
+    iCls = (*env)->FindClass(env, "java/lang/Object");
+    CHECK_NULL_RETURN(iCls, JNI_VERSION_1_2);
+    dps_gconfLock = (*env)->AllocObject(env, iCls);
+    dps_gconfLock = (*env)->NewGlobalRef(env, dps_gconfLock);
     return JNI_VERSION_1_2;
 }
 
diff -ruN openjdk.original/jdk/src/share/native/java/net/net_util.h openjdk/jdk/src/share/native/java/net/net_util.h
--- openjdk.original/jdk/src/share/native/java/net/net_util.h	Thu May  3 13:17:28 2012
+++ openjdk/jdk/src/share/native/java/net/net_util.h	Thu Aug  2 12:31:27 2012
@@ -93,6 +93,9 @@
 extern jfieldID ia6_scopeifnamesetID;
 extern jmethodID ia6_ctrID;
 
+/* DefaultProxySelector */
+extern jobject dps_gconfLock;
+
 /************************************************************************
  *  Utilities
  */
diff -ruN openjdk.original/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c openjdk/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c
--- openjdk.original/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c	Thu May  3 13:17:48 2012
+++ openjdk/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c	Thu Aug  2 12:35:48 2012
@@ -85,6 +85,7 @@
 
 static int gconf_ver = 0;
 static void* gconf_client = NULL;
+jobject dps_gconfLock = NULL;
 
 #define CHECK_NULL(X) { if ((X) == NULL) fprintf (stderr,"JNI errror at line %d\n", __LINE__); }
 
@@ -95,6 +96,7 @@
  */
 JNIEXPORT jboolean JNICALL
 Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
+  (*env)->MonitorEnter(env, dps_gconfLock);
   jclass cls = NULL;
   CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy"));
   proxy_class = (*env)->NewGlobalRef(env, cls);
@@ -137,11 +139,13 @@
           /**
            * We did get all we need. Let's enable the System Proxy Settings.
            */
+          (*env)->MonitorExit(env, dps_gconfLock);
           return JNI_TRUE;
         }
       }
     }
   }
+  (*env)->MonitorExit(env, dps_gconfLock);
   return JNI_FALSE;
 }
 
@@ -170,6 +174,8 @@
   const char *cproto;
   jboolean isCopy;
 
+  (*env)->MonitorEnter(env, dps_gconfLock);
+
   if (gconf_ver > 0) {
     if (gconf_client == NULL) {
       (*my_g_type_init_func)();
@@ -323,6 +329,7 @@
             jhost = (*env)->NewStringUTF(env, phost);
             isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
             proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
+            (*env)->MonitorExit(env, dps_gconfLock);
             return proxy;
           }
         }
@@ -331,5 +338,6 @@
   }
 
   CHECK_NULL(no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID));
+  (*env)->MonitorExit(env, dps_gconfLock);
   return no_proxy;
 }


More information about the jdk7u-dev mailing list