Ensure created fd being closed

If exception s thrown while calling bindSocket(fd), the temporary
created ParcelFileDescriptor may not be closed as expected.

Ensure it's closed eventually.

Bug: 206042872
Test: atest FrameworksNetTests
Change-Id: Icde895978ab9281006ffd56335d1247462d9da28
This commit is contained in:
Chiachang Wang
2021-11-29 17:42:08 +08:00
parent 44a20af4a3
commit 0209c36662

View File

@@ -382,13 +382,14 @@ public class Network implements Parcelable {
// Query a property of the underlying socket to ensure that the socket's file descriptor // Query a property of the underlying socket to ensure that the socket's file descriptor
// exists, is available to bind to a network and is not closed. // exists, is available to bind to a network and is not closed.
socket.getReuseAddress(); socket.getReuseAddress();
final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket);
bindSocket(pfd.getFileDescriptor()); // ParcelFileDescriptor.fromDatagramSocket() creates a dup of the original fd. The original
// ParcelFileDescriptor.fromSocket() creates a dup of the original fd. The original and the // and the dup share the underlying socket in the kernel. The socket is never truly closed
// dup share the underlying socket in the kernel. The socket is never truly closed until the // until the last fd pointing to the socket being closed. Try and eventually close the dup
// last fd pointing to the socket being closed. So close the dup one after binding the // one after binding the socket to control the lifetime of the dup fd.
// socket to control the lifetime of the dup fd. try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket)) {
pfd.close(); bindSocket(pfd.getFileDescriptor());
}
} }
/** /**
@@ -400,13 +401,13 @@ public class Network implements Parcelable {
// Query a property of the underlying socket to ensure that the socket's file descriptor // Query a property of the underlying socket to ensure that the socket's file descriptor
// exists, is available to bind to a network and is not closed. // exists, is available to bind to a network and is not closed.
socket.getReuseAddress(); socket.getReuseAddress();
final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket); // ParcelFileDescriptor.fromSocket() creates a dup of the original fd. The original and
bindSocket(pfd.getFileDescriptor()); // the dup share the underlying socket in the kernel. The socket is never truly closed
// ParcelFileDescriptor.fromSocket() creates a dup of the original fd. The original and the // until the last fd pointing to the socket being closed. Try and eventually close the dup
// dup share the underlying socket in the kernel. The socket is never truly closed until the // one after binding the socket to control the lifetime of the dup fd.
// last fd pointing to the socket being closed. So close the dup one after binding the try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket)) {
// socket to control the lifetime of the dup fd. bindSocket(pfd.getFileDescriptor());
pfd.close(); }
} }
/** /**