Merge "Fix fd leak in KeepaliveTracker." am: c6a527351f am: 759c08d0f4 am: 93e0ec070a

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1361907

Change-Id: I69f4f8073b057f294e0665ab7b1dcf57818d3089
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 02c08cc..ef62a99 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -220,6 +220,8 @@
 
 import com.google.android.collect.Lists;
 
+import libcore.io.IoUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -7513,18 +7515,34 @@
     public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId,
             int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
             String dstAddr) {
-        mKeepaliveTracker.startNattKeepalive(
-                getNetworkAgentInfoForNetwork(network), fd, resourceId,
-                intervalSeconds, cb,
-                srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
+        try {
+            mKeepaliveTracker.startNattKeepalive(
+                    getNetworkAgentInfoForNetwork(network), fd, resourceId,
+                    intervalSeconds, cb,
+                    srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
+        } finally {
+            // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
+            // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
+            if (fd != null && Binder.getCallingPid() != Process.myPid()) {
+                IoUtils.closeQuietly(fd);
+            }
+        }
     }
 
     @Override
     public void startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds,
             ISocketKeepaliveCallback cb) {
-        enforceKeepalivePermission();
-        mKeepaliveTracker.startTcpKeepalive(
-                getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
+        try {
+            enforceKeepalivePermission();
+            mKeepaliveTracker.startTcpKeepalive(
+                    getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
+        } finally {
+            // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
+            // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately.
+            if (fd != null && Binder.getCallingPid() != Process.myPid()) {
+                IoUtils.closeQuietly(fd);
+            }
+        }
     }
 
     @Override