Provide a way to disable socket() and DNS lookups in libnetd_client.
This is a Client-only solution.
- Add to NetdClient a per-process std::atomic_boolean
similar to netIdForProcess and netIdForResolv.
- The boolean says whether the process should be
allowed Internet connectivity.
- Add an @hide method to NetUtils.java to set the boolean;
call it from the initialization code of the new
process just after forking from zygote.
- Make netdClientSocket and dnsOpenProxy check the
boolean. If the boolean is false, return EPERM from
socket calls.
Bug: 150028556
Test: atest netd_integration_test
Test: atest CtsAppSecurityHostTestCases:UseProcessTest
Change-Id: Ic697afd284ba250e56bd9492241452762da15770
diff --git a/client/NetdClient.cpp b/client/NetdClient.cpp
index 74a441a..0105a04 100644
--- a/client/NetdClient.cpp
+++ b/client/NetdClient.cpp
@@ -60,6 +60,7 @@
std::atomic_uint netIdForProcess(NETID_UNSET);
std::atomic_uint netIdForResolv(NETID_UNSET);
+std::atomic_bool allowNetworkingForProcess(true);
typedef int (*Accept4FunctionType)(int, sockaddr*, socklen_t*, int);
typedef int (*ConnectFunctionType)(int, const sockaddr*, socklen_t);
@@ -182,6 +183,11 @@
}
int netdClientSocket(int domain, int type, int protocol) {
+ // Block creating AF_INET/AF_INET6 socket if networking is not allowed.
+ if (FwmarkCommand::isSupportedFamily(domain) && !allowNetworkingForProcess.load()) {
+ errno = EPERM;
+ return -1;
+ }
int socketFd = libcSocket(domain, type, protocol);
if (socketFd == -1) {
return -1;
@@ -285,6 +291,13 @@
return -1;
}
+ // If networking is not allowed, dns_open_proxy should just fail here.
+ // Then eventually, the DNS related functions in local mode will get
+ // EPERM while creating socket.
+ if (!allowNetworkingForProcess.load()) {
+ errno = EPERM;
+ return -1;
+ }
const auto socketFunc = libcSocket ? libcSocket : socket;
int s = socketFunc(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (s == -1) {
@@ -593,6 +606,10 @@
close(fd);
}
+extern "C" void setAllowNetworkingForProcess(bool allowNetworking) {
+ allowNetworkingForProcess.store(allowNetworking);
+}
+
extern "C" int getNetworkForDns(unsigned* dnsNetId) {
if (dnsNetId == nullptr) return -EFAULT;
int fd = dns_open_proxy();