Return -EAFNOSUPPORT for invalid sockets
Previously NetworkTest#testBindSocketOfLocalSocketThrows would fail when
selinux is disabled because netd does not check for local sockets.
Bug: b/78484123
Test: NetworkTest#testBindSocketOfLocalSocketThrows passes w/o selinux
Change-Id: Ia696bb9f25df46177303bac5127ed2f6ada56e7d
diff --git a/client/NetdClient.cpp b/client/NetdClient.cpp
index 821f488..076a769 100644
--- a/client/NetdClient.cpp
+++ b/client/NetdClient.cpp
@@ -154,8 +154,31 @@
return error;
}
+int checkSocket(int socketFd) {
+ if (socketFd < 0) {
+ return -EBADF;
+ }
+ int family;
+ socklen_t familyLen = sizeof(family);
+ if (getsockopt(socketFd, SOL_SOCKET, SO_DOMAIN, &family, &familyLen) == -1) {
+ return -errno;
+ }
+ if (!FwmarkClient::shouldSetFwmark(family)) {
+ return -EAFNOSUPPORT;
+ }
+ return 0;
+}
+
} // namespace
+#define CHECK_SOCKET_IS_MARKABLE(sock) \
+ do { \
+ int err; \
+ if ((err = checkSocket(sock)) != 0) { \
+ return err; \
+ } \
+ } while (false);
+
// accept() just calls accept4(..., 0), so there's no need to handle accept() separately.
extern "C" void netdClientInitAccept4(Accept4FunctionType* function) {
if (function && *function) {
@@ -202,9 +225,7 @@
}
extern "C" int setNetworkForSocket(unsigned netId, int socketFd) {
- if (socketFd < 0) {
- return -EBADF;
- }
+ CHECK_SOCKET_IS_MARKABLE(socketFd);
FwmarkCommand command = {FwmarkCommand::SELECT_NETWORK, netId, 0, 0};
return FwmarkClient().send(&command, socketFd, nullptr);
}
@@ -226,9 +247,7 @@
}
extern "C" int setNetworkForUser(uid_t uid, int socketFd) {
- if (socketFd < 0) {
- return -EBADF;
- }
+ CHECK_SOCKET_IS_MARKABLE(socketFd);
FwmarkCommand command = {FwmarkCommand::SELECT_FOR_USER, 0, uid, 0};
return FwmarkClient().send(&command, socketFd, nullptr);
}
@@ -239,11 +258,13 @@
}
extern "C" int tagSocket(int socketFd, uint32_t tag, uid_t uid) {
+ CHECK_SOCKET_IS_MARKABLE(socketFd);
FwmarkCommand command = {FwmarkCommand::TAG_SOCKET, 0, uid, tag};
return FwmarkClient().send(&command, socketFd, nullptr);
}
extern "C" int untagSocket(int socketFd) {
+ CHECK_SOCKET_IS_MARKABLE(socketFd);
FwmarkCommand command = {FwmarkCommand::UNTAG_SOCKET, 0, 0, 0};
return FwmarkClient().send(&command, socketFd, nullptr);
}