bpf: allow tagging non-tcp/udp sockets on T+ & 5.10+

Possible since inet_sock_release hook is now enabled on T+ 5.10+
and that will perform map cleanup for us without reliance on
netlink notifications (which aren't available for other types).

Test: atest netd_updatable_unit_test TagSocketTest, adbz_cookies
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I141b1f98ae8e4ce80813194a66a26755925b6683
diff --git a/bpf/netd/BpfHandler.cpp b/bpf/netd/BpfHandler.cpp
index e3e508b..d41aa81 100644
--- a/bpf/netd/BpfHandler.cpp
+++ b/bpf/netd/BpfHandler.cpp
@@ -341,8 +341,8 @@
     if (chargeUid == AID_CLAT) return -EPERM;
 
     // The socket destroy listener only monitors on the group {INET_TCP, INET_UDP, INET6_TCP,
-    // INET6_UDP}. Tagging listener unsupported socket causes that the tag can't be removed from
-    // tag map automatically. Eventually, the tag map may run out of space because of dead tag
+    // INET6_UDP}. Tagging listener unsupported sockets (on <5.10) means the tag cannot be
+    // removed from tag map automatically. Eventually, it may run out of space due to dead tag
     // entries. Note that although tagSocket() of net client has already denied the family which
     // is neither AF_INET nor AF_INET6, the family validation is still added here just in case.
     // See tagSocket in system/netd/client/NetdClient.cpp and
@@ -360,15 +360,19 @@
         return -EAFNOSUPPORT;
     }
 
-    int socketProto;
-    socklen_t protoLen = sizeof(socketProto);
-    if (getsockopt(sockFd, SOL_SOCKET, SO_PROTOCOL, &socketProto, &protoLen)) {
-        ALOGE("Failed to getsockopt SO_PROTOCOL: %s, fd: %d", strerror(errno), sockFd);
-        return -errno;
-    }
-    if (socketProto != IPPROTO_UDP && socketProto != IPPROTO_TCP) {
-        ALOGV("Unsupported protocol: %d", socketProto);
-        return -EPROTONOSUPPORT;
+    // On 5.10+ the BPF_CGROUP_INET_SOCK_RELEASE hook takes care of cookie tag map cleanup
+    // during socket destruction. As such the socket destroy listener is superfluous.
+    if (!isAtLeastKernelVersion(5, 10, 0)) {
+        int socketProto;
+        socklen_t protoLen = sizeof(socketProto);
+        if (getsockopt(sockFd, SOL_SOCKET, SO_PROTOCOL, &socketProto, &protoLen)) {
+            ALOGE("Failed to getsockopt SO_PROTOCOL: %s, fd: %d", strerror(errno), sockFd);
+            return -errno;
+        }
+        if (socketProto != IPPROTO_UDP && socketProto != IPPROTO_TCP) {
+            ALOGV("Unsupported protocol: %d", socketProto);
+            return -EPROTONOSUPPORT;
+        }
     }
 
     uint64_t sock_cookie = getSocketCookie(sockFd);