diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp index 1e47ea3e91..f3dfb57cde 100644 --- a/netd/BpfHandler.cpp +++ b/netd/BpfHandler.cpp @@ -146,20 +146,32 @@ int BpfHandler::tagSocket(int sockFd, uint32_t tag, uid_t chargeUid, uid_t realU // 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 - // entries. - // See TrafficController::makeSkDestroyListener in + // 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 + // TrafficController::makeSkDestroyListener in // packages/modules/Connectivity/service/native/TrafficController.cpp // TODO: remove this once the socket destroy listener can detect more types of socket destroy. - int socketProto; - socklen_t intSize = sizeof(socketProto); - if (getsockopt(sockFd, SOL_SOCKET, SO_PROTOCOL, &socketProto, &intSize)) { - ALOGE("Failed to getsockopt: %s, fd: %d", strerror(errno), sockFd); + int socketFamily; + socklen_t familyLen = sizeof(socketFamily); + if (getsockopt(sockFd, SOL_SOCKET, SO_DOMAIN, &socketFamily, &familyLen)) { + ALOGE("Failed to getsockopt SO_DOMAIN: %s, fd: %d", strerror(errno), sockFd); return -errno; - } else { - if (socketProto != IPPROTO_UDP && socketProto != IPPROTO_TCP) { - ALOGE("Unsupported protocol: %d", socketProto); - return -EPROTONOSUPPORT; - } + } + if (socketFamily != AF_INET && socketFamily != AF_INET6) { + ALOGE("Unsupported family: %d", socketFamily); + 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) { + ALOGE("Unsupported protocol: %d", socketProto); + return -EPROTONOSUPPORT; } uint64_t sock_cookie = getSocketCookie(sockFd); diff --git a/netd/BpfHandlerTest.cpp b/netd/BpfHandlerTest.cpp index 66a2f803a3..cd6b565653 100644 --- a/netd/BpfHandlerTest.cpp +++ b/netd/BpfHandlerTest.cpp @@ -188,11 +188,17 @@ TEST_F(BpfHandlerTest, TestTagInvalidSocket) { expectMapEmpty(mFakeCookieTagMap); } +TEST_F(BpfHandlerTest, TestTagSocketWithUnsupportedFamily) { + int packetSocket = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + EXPECT_LE(0, packetSocket); + EXPECT_NE(NONEXISTENT_COOKIE, getSocketCookie(packetSocket)); + EXPECT_EQ(-EAFNOSUPPORT, mBh.tagSocket(packetSocket, TEST_TAG, TEST_UID, TEST_UID)); +} + TEST_F(BpfHandlerTest, TestTagSocketWithUnsupportedProtocol) { int rawSocket = socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW); EXPECT_LE(0, rawSocket); - uint64_t sockCookie = getSocketCookie(rawSocket); - EXPECT_NE(NONEXISTENT_COOKIE, sockCookie); + EXPECT_NE(NONEXISTENT_COOKIE, getSocketCookie(rawSocket)); EXPECT_EQ(-EPROTONOSUPPORT, mBh.tagSocket(rawSocket, TEST_TAG, TEST_UID, TEST_UID)); }