Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8067680

(sctp) Possible race initializing native IDs

XMLWordPrintable

    • b49

        The SCTP native code lazily initializes the shared global InetSocketAddress class ( isaCls ) and constructor ID ( isaCtrID ) in the initializeISA() function. Calling code, that uses the class or ID first checks that they are set, calling initializeISA if needed, before using the global shared state.

        Unfortunately, as can be seen from the code snippet below, the code using isaCls and isaCtrID only checks that isaCls is set. It assumes that isaCtrID must be set, which may not always be the case, since initializeISA sets isaCls first, and then isaCtrID. For example, if two threads, thread A and thread B, are executing SCTP native code, thread A may call initializeISA, set isaCls, and then be swapped out by the scheduler allowing thread B to run. Thread B would see that isaCls is non-null and assume that isaCtrID has been set ( which is not the case ).

        The pattern checking, if (isaCLS == 0), is in several places, so it is probably best to just change the order of setting isaCls and isaCtrID in initializeISA().


        --- code snippet ---

        void initializeISA
          (JNIEnv* env) {
            if (isaCls == 0) {
                jclass c = (*env)->FindClass(env, "java/net/InetSocketAddress");
                CHECK_NULL(c);
                isaCls = (*env)->NewGlobalRef(env, c);
                CHECK_NULL(isaCls);
                (*env)->DeleteLocalRef(env, c);
                isaCtrID = (*env)->GetMethodID(env, isaCls, "<init>",
                                             "(Ljava/net/InetAddress;I)V");
            }
        }

        jobject SockAddrToInetSocketAddress(JNIEnv *env, struct sockaddr* sap) {
            ...
            if (isaCls == 0) {
                initializeISA(env);
                CHECK_NULL_RETURN(isaCls, NULL);
            }

             // Use isaCls and isaCtrID
        }
        ---

        Sample crash output resulting from this issue, as seen with 7u72b14:

        Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
        V [libjvm.so+0x726bde] jni_NewObject+0x38a
        C [libsctp.so+0x27dd] SockAddrToInetSocketAddress+0x6d
        C [libsctp.so+0x38fc] handlePeerAddrChange+0x64
        C [libsctp.so+0x39b6] handleNotification+0x2e
        C [libsctp.so+0x3cb5] Java_sun_nio_ch_SctpChannelImpl_receive0+0x1c5
        j sun.nio.ch.SctpChannelImpl.receive0(ILsun/nio/ch/SctpResultContainer;JIZ)I+0
        j sun.nio.ch.SctpChannelImpl.receiveIntoNativeBuffer(ILsun/nio/ch/SctpResultContainer;Ljava/nio/ByteBuffer;IIZ)I+19
        j sun.nio.ch.SctpChannelImpl.receive(ILjava/nio/ByteBuffer;Lsun/nio/ch/SctpResultContainer;Z)I+102
        j sun.nio.ch.SctpChannelImpl.receive(Ljava/nio/ByteBuffer;Ljava/lang/Object;Lcom/sun/nio/sctp/NotificationHandler;Z)Lcom/sun/nio/sctp/MessageInfo;+237
        j sun.nio.ch.SctpChannelImpl.receive(Ljava/nio/ByteBuffer;Ljava/lang/Object;Lcom/sun/nio/sctp/NotificationHandler;)Lcom/sun/nio/sctp/MessageInfo;+5

              robm Robert Mckenna
              shadowbug Shadow Bug
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

                Created:
                Updated:
                Resolved: