Commit 6d580b69 authored by Tobias Thierer's avatar Tobias Thierer
Browse files

Deal with preclosed fd in IoBridge.getLocalInetSocketAddress().

Five out of six callers, in particular ConnectDetail (which is used
to construct an exception message), pass in an fd value representing
an AbstractPlainSocketImpl on which another thread may concurrently
call close(). While PlainSocketImpl delays final closing of the socket
until all threads have completed their ongoing calls,
PlainSocketImpl.socketClose0(true) will still preclose the socket,
during which the fd will be dup2'ed to an AF_UNIX socket.

For such preclosed sockets, getsockname() will return the
UnixSocketAddress of the marker FileDescriptor, leading to a
ClassCastException in IoBridge.getLocalInetSocketAddress(), which
causes crash bugs in applications.

To fix the common use case without needing to touch the preclose logic,
this CL changes IoBridge.getLocalInetSocketAddress() to throw a
SocketException rather than a ClassCastException in the case where
(socketAddress != null) && !(socketAddress instanceof InetSocketAddress).
The case of socketAddress == null should not normally occur, but
also wouldn't have resulted in a ClassCastException so was not touched
by this CL, in order to minimize behavior changes.

Note on why SocketException is the correct behavior for all
current callers that previously might have encountered
ClassCastException:
- In connectDetail(), the SocketException is caught and leads to
  no inetAddress being included in the exception message constructed
  for its caller. This is correct behavior.
- Inet6AddressImpl.icmpEcho() uses a fd that is confined to the current
  thread, and therefore not at risk of concurrent preclose.
- All other callers are in the middle of accept(), bind(), or connect().
  For these, SocketException is the correct response when the socket
  has been preclosed.

Test: LibcoreTestCases
Bug: 64209834

Change-Id: Id0b0880ed3825f6b8be1caf6236f925a77ba1543
parent 308eba82
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment