libcore: BlockGuard: untag socket on close

java.net.Socket creates the socket on connect(). But in case of failure
during the connect() it closes the socket.
During the create, BlockGuard's socket() is the one tagging the socket.
But in case of failure, nobody untags that socket.
So now we untag scokets on close() in BlockGuard

Bug: 5274621
Change-Id: I282665a05e2dc184df77c84ceab49fb55b7695af
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index 07ee520..4f2858d 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -42,6 +42,14 @@
         }
     }
 
+    private void untagSocket(FileDescriptor fd) throws ErrnoException {
+        try {
+            SocketTagger.get().untag(fd);
+        } catch (SocketException e) {
+            throw new ErrnoException("socket", EINVAL, e);
+        }
+    }
+
     @Override public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException {
         BlockGuard.getThreadPolicy().onNetwork();
         return tagSocket(os.accept(fd, peerAddress));
@@ -49,11 +57,14 @@
 
     @Override public void close(FileDescriptor fd) throws ErrnoException {
         try {
-            if (S_ISSOCK(Libcore.os.fstat(fd).st_mode) && isLingerSocket(fd)) {
-                // If the fd is a socket with SO_LINGER set, we might block indefinitely.
-                // We allow non-linger sockets so that apps can close their network connections in
-                // methods like onDestroy which will run on the UI thread.
-                BlockGuard.getThreadPolicy().onNetwork();
+            if (S_ISSOCK(Libcore.os.fstat(fd).st_mode)) {
+                if (isLingerSocket(fd)) {
+                    // If the fd is a socket with SO_LINGER set, we might block indefinitely.
+                    // We allow non-linger sockets so that apps can close their network
+                    // connections in methods like onDestroy which will run on the UI thread.
+                    BlockGuard.getThreadPolicy().onNetwork();
+                }
+                untagSocket(fd);
             }
         } catch (ErrnoException ignored) {
             // We're called via Socket.close (which doesn't ask for us to be called), so we
@@ -74,6 +85,8 @@
         os.connect(fd, address, port);
     }
 
+    // TODO: Untag newFd when needed for dup2(FileDescriptor oldFd, int newFd)
+
     @Override public void fdatasync(FileDescriptor fd) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
         os.fdatasync(fd);