[ipsec-doze] Add fchown capabilities, and fw rules

Add some firewall rules to allow doze mode packets to be sent/received
on ESP & no-socket packets. No-socket packets are no security risk
because they are either forwarded, going to be forwarded, or will be
dropped at routing tables (unless they are ESP).

Bug: 62994731
Test: New tests added, run
Change-Id: I2d8704498b564403d94123e4938091dee8fb98c1
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index e70ed49..7f0c761 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -340,6 +340,39 @@
 //
 XfrmController::XfrmController(void) {}
 
+netdutils::Status XfrmController::ipSecSetEncapSocketOwner(const android::base::unique_fd& socket,
+                                                           int newUid, uid_t callerUid) {
+    ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
+
+    const int fd = socket.get();
+    struct stat info;
+    if (fstat(fd, &info)) {
+        return netdutils::statusFromErrno(errno, "Failed to stat socket file descriptor");
+    }
+    if (info.st_uid != callerUid) {
+        return netdutils::statusFromErrno(EPERM, "fchown disabled for non-owner calls");
+    }
+    if (S_ISSOCK(info.st_mode) == 0){
+        return netdutils::statusFromErrno(EINVAL, "File descriptor was not a socket");
+    }
+
+    int optval;
+    socklen_t optlen;
+    netdutils::Status status = getSyscallInstance().getsockopt(Fd(socket), IPPROTO_UDP, UDP_ENCAP,
+                                                               &optval, &optlen);
+    if (status != netdutils::status::ok) {
+        return status;
+    }
+    if (optval != UDP_ENCAP_ESPINUDP && optval != UDP_ENCAP_ESPINUDP_NON_IKE){
+        return netdutils::statusFromErrno(EINVAL, "Socket did not have UDP-encap sockopt set");
+    }
+    if (fchown(fd, newUid, -1)) {
+        return netdutils::statusFromErrno(errno, "Failed to fchown socket file descriptor");
+    }
+
+    return netdutils::status::ok;
+}
+
 netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId, int32_t direction,
                                                    const std::string& localAddress,
                                                    const std::string& remoteAddress, int32_t inSpi,