netdclient - attempt to eliminate spurious netd selinux denials on unix_stream_sockets
This should hopefully fix for example:
avc: denied { read write } for comm="netd" path="socket:[1580915]" dev="sockfs" ino=1580915 scontext=u:r:netd:s0 tcontext=u:r:untrusted_app_25:s0:c512,c768 tclass=unix_stream_socket permissive=0
Make sure protectFromVpn() only passes AF_INET/AF_INET6 sockets to netd.
Let us make sure that we pass real AF_INET/AF_INET6 sockets to netd
from sendmmsg/sendmsg/sendto - the type of the socket when erroneously
used by an app might not necessarily match the address family of the
passed in sockaddr. ie. sendto(AF_LOCAL_socket, AF_INET_sockaddr)
Note that this also means these system calls will now honour the
'ANDROID_NO_USE_FWMARK_CLIENT' env variable for euid=0 processes.
While we're at it also add some missing parentheses in a macro.
Test: build, atest netdclient_test
Bug: 77870037
Change-Id: I1040838950d363f08a02593e9b669fec31fa847b
Merged-In: I1040838950d363f08a02593e9b669fec31fa847b
diff --git a/client/NetdClient.cpp b/client/NetdClient.cpp
index 147e63e..643188b 100644
--- a/client/NetdClient.cpp
+++ b/client/NetdClient.cpp
@@ -195,7 +195,7 @@
}
int netdClientSendmmsg(int sockfd, const mmsghdr* msgs, unsigned int msgcount, int flags) {
- if (propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS_HOOKED)) {
+ if (propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS_HOOKED) && !checkSocket(sockfd)) {
const sockaddr* addr = nullptr;
if ((msgcount > 0) && (msgs != nullptr) && (msgs[0].msg_hdr.msg_name != nullptr)) {
addr = reinterpret_cast<const sockaddr*>(msgs[0].msg_hdr.msg_name);
@@ -210,7 +210,7 @@
}
ssize_t netdClientSendmsg(int sockfd, const msghdr* msg, unsigned int flags) {
- if (propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS_HOOKED)) {
+ if (propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS_HOOKED) && !checkSocket(sockfd)) {
const sockaddr* addr = nullptr;
if ((msg != nullptr) && (msg->msg_name != nullptr)) {
addr = reinterpret_cast<const sockaddr*>(msg->msg_name);
@@ -226,7 +226,7 @@
int netdClientSendto(int sockfd, const void* buf, size_t bufsize, int flags, const sockaddr* addr,
socklen_t addrlen) {
- if (propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS_HOOKED)) {
+ if (propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS_HOOKED) && !checkSocket(sockfd)) {
if ((addr != nullptr) && (FwmarkCommand::isSupportedFamily(addr->sa_family))) {
FwmarkConnectInfo sendtoInfo(0, 0, addr);
FwmarkCommand command = {FwmarkCommand::ON_SENDTO, 0, 0, 0};
@@ -382,19 +382,17 @@
} // namespace
-#define CHECK_SOCKET_IS_MARKABLE(sock) \
- do { \
- int err; \
- if ((err = checkSocket(sock)) != 0) { \
- return err; \
- } \
- } while (false);
+#define CHECK_SOCKET_IS_MARKABLE(sock) \
+ do { \
+ int err = checkSocket(sock); \
+ if (err) return err; \
+ } while (false)
#define HOOK_ON_FUNC(remoteFunc, nativeFunc, localFunc) \
do { \
- if (remoteFunc && *remoteFunc) { \
- nativeFunc = *remoteFunc; \
- *remoteFunc = localFunc; \
+ if ((remoteFunc) && *(remoteFunc)) { \
+ (nativeFunc) = *(remoteFunc); \
+ *(remoteFunc) = (localFunc); \
} \
} while (false)
@@ -476,9 +474,7 @@
}
extern "C" int protectFromVpn(int socketFd) {
- if (socketFd < 0) {
- return -EBADF;
- }
+ CHECK_SOCKET_IS_MARKABLE(socketFd);
FwmarkCommand command = {FwmarkCommand::PROTECT_FROM_VPN, 0, 0, 0};
return FwmarkClient().send(&command, socketFd, nullptr);
}