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

Duplicate closure of file descriptors leads to unexpected and incorrect closure of sockets

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 7
    • Fix Version/s: 9
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b31
    • CPU:
      x86
    • OS:
      windows_2008

      Backports

        Description

        SYNOPSIS
        --------
        Duplicate closure of file descriptors leads to unexpected and incorrect closure of sockets

        OPERATING SYSTEM
        ----------------
        Reported on Windows Server 2008 SP2

        FULL JDK VERSION
        ----------------
        All Java 6
        Not able to test JDK 7 (see below for JDK 7 details)

        PROBLEM DESCRIPTION from LICENSEE
        ---------------------------------
        Consider a java application that opens a DatagramSocket, binds it to an address, sends a packet to destination and closes it. In IPv6 enabled systems, when the destination address is INADDR_ANY and the bind operation on the socket fails for some reason, the NET_BindV6 function in net_util_md.c closes both the IPv4 and IPv6 sockets and returns SOCKET_ERROR.

        Upon returning, execution enters the following else block in PlainDatagramSocketImpl.c (line numbers correct in 6u23 code):
         
          471: } else {
          472: NET_ThrowCurrent (env, "Cannot bind");
          473: return;
          474: }

        Note that the code does not nullify the 'fd' and 'fd1' values. This leads to a duplicate closure of the same fds (in Datagramsocket.close()).

        This duplicate closure causes a significant problem in a multi-threaded environment where sockets are being opened and closed very frequently. In NET_BindV6(), as soon as the b->ipv4_fd and b->ipv6_fd descriptors are closed via the closesocket() call in the CLOSE_SOCKETS_AND_RETURN macro, the OS layer adds both the fd values to a free list. The OS can now assign these fd values to a new socket created by a different thread, *before* Datagramsocket.close() is executed by the thread that just freed the fd values. This means that the second (duplicate) closure of the fd on the first thread can inadvertently close sockets created on another thread! When this happens it causes WSAENOTSOCK errors, as the application attempts to conduct an operation on a closed fd. Once this error happens, it continues to cause multiple socket failures in a row.

        PROPOSED FIX
        ------------
        src/j2se/src/windows/native/java/net/PlainDatagramSocketImpl.c:

          471: } else {
          472: NET_ThrowCurrent (env, "Cannot bind");
        > 473: (*env)->SetObjectField(env, this, pdsi_fdID, NULL); <
        > 474: (*env)->SetObjectField(env, this, pdsi_fd1ID, NULL); <
          475: return;
          476: }

        TESTCASE
        --------
        None. We were not able to replicate the high load and consequent timing characteristics of the application environment in a standalone testcase.

        JDK 7
        -----
        Licensee did have a quick look at the JDK7 code, and noticed that the Windows version of PlainDatagramSocketImpl.c does not exist from JDK 7b15 onwards. It is uncertain what that means in terms of the problem itself, but it does mean that the Licensee's suggested fix (above) cannot be applied to JDK7 as-is. Licensee suggested that might might be to TwoStacksPlainDatagramSocketImpl.c.

        WORKAROUND
        ----------
        None

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                igerasim Ivan Gerasimov
                Reporter:
                dkorbel David Korbel (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: