Pass connectInfo only if ro.vendor.redirect_socket_calls is set
There is a dependency between libnetd_client and netd. The netd checks
size of each FwmarkCommand. The earlier built netd does not expect that
ON_CONNECT command from libnetd_client includes connectInfo. It causes
connect() fail in the combination of new libnetd_client + old netd. With
this commit, the ON_CONNECT pass connectInfo only if OEM sets the
property ro.vendor.redirect_socket_calls. It's OEM responsibility to
ensure that the property is set only on the platform with netd that can
support connectInfo in ON_CONNECT command.
Minor changes:
1. Remove length protection on property retrieval. The
__system_property_get() has built-in length protection. No need to
append Null character.
2. refactor some code by macro.
Bug: 141611769
Bug: 150126287
Test: atest
Test: ./art/tools/run-libcore-tests.sh w/ current and earlier netd, pass
Test: ./art/tools/run-libjdwp-tests.sh w/ current and earlier netd, pass
Change-Id: I90ecba761effa0a5bc403876b9c3de8e77038232
Merged-In: I90ecba761effa0a5bc403876b9c3de8e77038232
diff --git a/client/NetdClient.cpp b/client/NetdClient.cpp
index 634480b..147e63e 100644
--- a/client/NetdClient.cpp
+++ b/client/NetdClient.cpp
@@ -51,7 +51,7 @@
// Keep this in sync with CMD_BUF_SIZE in FrameworkListener.cpp.
constexpr size_t MAX_CMD_SIZE = 4096;
// Whether sendto(), sendmsg(), sendmmsg() in libc are shimmed or not. This property is evaluated at
-// process start time and is cannot change at runtime on a given device.
+// process start time and cannot change at runtime on a given device.
constexpr char PROPERTY_REDIRECT_SOCKET_CALLS[] = "ro.vendor.redirect_socket_calls";
// Whether some shimmed functions dispatch FwmarkCommand or not. The property can be changed by
// System Server at runtime. Note: accept4(), socket(), connect() are always shimmed.
@@ -80,9 +80,7 @@
static bool propertyValueIsTrue(const char* prop_name) {
char prop_value[PROP_VALUE_MAX] = {0};
- int length = __system_property_get(prop_name, prop_value);
- if (length > 0 && length < PROP_VALUE_MAX) {
- prop_value[length] = '\0';
+ if (__system_property_get(prop_name, prop_value) > 0) {
if (strcmp(prop_value, "true") == 0) {
return true;
}
@@ -90,6 +88,11 @@
return false;
}
+static bool redirectSocketCallsIsTrue() {
+ static bool cached_result = propertyValueIsTrue("ro.vendor.redirect_socket_calls");
+ return cached_result;
+}
+
int checkSocket(int socketFd) {
if (socketFd < 0) {
return -EBADF;
@@ -144,9 +147,16 @@
int netdClientConnect(int sockfd, const sockaddr* addr, socklen_t addrlen) {
const bool shouldSetFwmark = shouldMarkSocket(sockfd, addr);
if (shouldSetFwmark) {
- FwmarkConnectInfo connectInfo(0, 0, addr);
FwmarkCommand command = {FwmarkCommand::ON_CONNECT, 0, 0, 0};
- if (int error = FwmarkClient().send(&command, sockfd, &connectInfo)) {
+ int error;
+ if (redirectSocketCallsIsTrue()) {
+ FwmarkConnectInfo connectInfo(0, 0, addr);
+ error = FwmarkClient().send(&command, sockfd, &connectInfo);
+ } else {
+ error = FwmarkClient().send(&command, sockfd, nullptr);
+ }
+
+ if (error) {
errno = -error;
return -1;
}
@@ -380,59 +390,46 @@
} \
} while (false);
+#define HOOK_ON_FUNC(remoteFunc, nativeFunc, localFunc) \
+ do { \
+ if (remoteFunc && *remoteFunc) { \
+ nativeFunc = *remoteFunc; \
+ *remoteFunc = localFunc; \
+ } \
+ } 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) {
- libcAccept4 = *function;
- *function = netdClientAccept4;
- }
+ HOOK_ON_FUNC(function, libcAccept4, netdClientAccept4);
}
extern "C" void netdClientInitConnect(ConnectFunctionType* function) {
- if (function && *function) {
- libcConnect = *function;
- *function = netdClientConnect;
- }
+ HOOK_ON_FUNC(function, libcConnect, netdClientConnect);
}
extern "C" void netdClientInitSocket(SocketFunctionType* function) {
- if (function && *function) {
- libcSocket = *function;
- *function = netdClientSocket;
- }
+ HOOK_ON_FUNC(function, libcSocket, netdClientSocket);
}
extern "C" void netdClientInitSendmmsg(SendmmsgFunctionType* function) {
if (!propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS)) {
return;
}
-
- if (function && *function) {
- libcSendmmsg = *function;
- *function = netdClientSendmmsg;
- }
+ HOOK_ON_FUNC(function, libcSendmmsg, netdClientSendmmsg);
}
extern "C" void netdClientInitSendmsg(SendmsgFunctionType* function) {
if (!propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS)) {
return;
}
-
- if (function && *function) {
- libcSendmsg = *function;
- *function = netdClientSendmsg;
- }
+ HOOK_ON_FUNC(function, libcSendmsg, netdClientSendmsg);
}
extern "C" void netdClientInitSendto(SendtoFunctionType* function) {
if (!propertyValueIsTrue(PROPERTY_REDIRECT_SOCKET_CALLS)) {
return;
}
-
- if (function && *function) {
- libcSendto = *function;
- *function = netdClientSendto;
- }
+ HOOK_ON_FUNC(function, libcSendto, netdClientSendto);
}
extern "C" void netdClientInitNetIdForResolv(NetIdForResolvFunctionType* function) {